/**
 * GoogleMap wrapper class
 */
GoogleMap=Jclass.create({
  Extends			: GMap2,
  smallMapControl	: false,
  smallZoomControl	: true,
  overviewMapControl: false,
  mapTypeControl	: null,
  mapType			: G_PHYSICAL_MAP,   //G_PHYSICAL_MAP, G_NORMAL_MAP
  zoom				: null,
  polylines			: null,
  gpoints			: null, 	//polyline
  glevels			: null,
  infoHtmlTemplate	: "<b>@{id} - @{name}</b><br/>@{address}", //html info template
  icon				: null, 	// marker icon
  bigIcon			: null, 	// marker big icon
  markerIcon		: null, 	// marker icon image
  startMarkerIcon	: null,		// start marker icon image
  endMarkerIcon		: null,		// end marker icon image
  points			: [],  		// marker geo points
  cmarkers			: [],
  hmarkers			: [],  
  /* 
   * constructor 
   */
  constructor: function GoogleMap(div,object){
    //this.map=new GMap2(typeof(div)=="string"?document.getElementById(div):div);
	GMap2.apply(this,[typeof(div)=="string"?document.getElementById(div):div]);
	this.map=this;
    //assegno le proprietà passate al construttore con l'oggetto object
    //nb alcune proprietà potrebbero non essere ancora disponibili sull'oggetto GMap2...(es mapType)
    if(object!=null){
     for(var p in this)
      if(object[p]!=null)
        this[p]=object[p];
    }
    if(this.icon==null)
      this.icon=new GIcon({
 		    shadow : "http://labs.google.com/ridefinder/images/mm_20_shadow.png",
 		    iconSize : new GSize(8, 8),
 		    shadowSize : new GSize(12, 12),
 		    iconAnchor : new GPoint(4, 4),
 		    infoWindowAnchor : new GPoint(4, 4)
      });         
    this.icon.image=(this.markerIcon!=null?this.markerIcon:this.icon.image);  
    if(this.bigIcon==null){   
      this.bigIcon = new GIcon(this.icon);
      this.bigIcon.iconSize = new GSize(12, 12);
    }
    
    if (GBrowserIsCompatible()) {
      if(this.smallMapControl)
      	this.map.addControl(new GSmallMapControl());
      
      if(this.smallZoomControl)
        	this.map.addControl(new GSmallZoomControl3D());
      
      this.map.removeMapType(G_HYBRID_MAP);
      this.map.addMapType(G_PHYSICAL_MAP);
      
      if(!this.mapTypeControl){					//se non passato, istanzio il classico GmapTypeControl
    	this.map.addControl(new GMapTypeControl());
    	}
      else{
    	this.map.addControl(this.mapTypeControl);//se passato da chi istanzia, uso quello (es: ExtMapTypeControl)
      }
      
      this.map.setMapType(object['mapType']);//setta il tipo mappa passato da chi istanzia, o il default NORMAL
      
	  if(this.overviewMapControl){
		this.map.addControl(new GOverviewMapControl());
		/*ovcontrol=new GOverviewMapControl();
		  this.map.addControl(ovcontrol);
		  ovcontrol.hide(true);*/
		}
	  this.map.enableDoubleClickZoom();
      //settaggio centro iniziale... 
	  this.map.setCenter(new GLatLng(45.07393,7.67220),13);
	  this.map.setZoom((this.zoom!=null?this.zoom:13));
	  
	  if (this.polylines!=null){
		  for(var i=0; i<this.polylines.length;i++){
			  var polyline = new Polyline(this.polylines[i]);
			  this.map.addOverlay(polyline._source);
		  }
		  if(this.gpoints!=null){
			  var polyline = new GPolyline.fromEncoded({
				  color:"#FF0000", weight:10, opacity:0.5, zoomFactor:2, numLevels:18,
				  points:this.gpoints, levels:this.glevels		
			  });		    
			  var bounds = polyline.getBounds();
			  this.map.setZoom(this.map.getBoundsZoomLevel(bounds));
			  this.map.setCenter(bounds.getCenter(),this.map.getBoundsZoomLevel(bounds),this.mapType);		    
			  //this.glevels=this.gpoints=null;
		  }
	  } else if(this.gpoints!=null){
		  var polyline = new GPolyline.fromEncoded({
			  color:"#FF0000", weight:10, opacity:0.5, zoomFactor:2, numLevels:18,
			  points:this.gpoints, levels:this.glevels		
		  });
		  this.map.addOverlay(polyline);
		  var bounds = polyline.getBounds();
		  this.map.setZoom(this.map.getBoundsZoomLevel(bounds));
		  this.map.setCenter(bounds.getCenter(),this.map.getBoundsZoomLevel(bounds),this.mapType);
	  }else if(this.points!=null && this.points.length>=1){
		  this.map.setCenter(new GLatLng(this.points[0].wgsLat, this.points[0].wgsLng), 13,this.mapType);
		  this.map.setZoom((this.zoom!=null?this.zoom:15));
	  }
    }      
  },
  /*addControl: function(ctl){
	  GMap2.addControl.apply(this,[ctl]);
  },*/
  /** load & design markers on the map */
  load: function() {
	  var flag_icon = new GIcon();
	  flag_icon.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png";
	  flag_icon.iconSize = new GSize(26, 26);
	  flag_icon.shadowSize = new GSize(12, 12);
	  flag_icon.iconAnchor = new GPoint(13,26);
	  flag_icon.infoWindowAnchor = new GPoint(4, 4);
	  var points=this.points;
	  var size=(points.length>0?(points[points.length-1]==null?points.length-1:points.length):0)
	  for(var i=0;i<points.length;i++){
	   if(points[i]!=null){
	     if(i==0 && this.startMarkerIcon!=null){
	       var flag_icon_start = new GIcon(flag_icon, this.startMarkerIcon);
	       this.map.addOverlay(new GMarker(new GLatLng(points[i].wgsLat ,points[i].wgsLng),
	                           {icon:flag_icon_start, title:'partenza'}));
	     }else if (i==(size-1) && this.endMarkerIcon!=null){
	       var flag_icon_end = new GIcon(flag_icon, this.endMarkerIcon);
	       this.map.addOverlay(new GMarker(new GLatLng(points[i].wgsLat ,points[i].wgsLng),
	                           {icon:flag_icon_end, title:'arrivo'}));
	     }
	     this.map.addOverlay(this.createMarker(new GLatLng(points[i].wgsLat ,points[i].wgsLng),points[i]));
	   }
	  }
     
  },
  /**create map marker.
   */
  createMarker: function(point, object){
    var name=object.name;
	  var icon = this.icon;
	  if(object.icon!=null){
	    if(typeof(object.icon)=="string")
	      icon=new GeoIcon({image:object.icon,iconSize : new GSize(20, 16)});//width=20,height=16
		  else
	    	icon=object.icon;
	  }
    var marker = new GMarker(point,{icon:icon, title:name});
    marker.object=object;
    var self=this;
    GEvent.addListener(marker, "click", function() {
         var html=self.infoHtmlTemplate;
         var object=marker.object;
         if(object.infoHtmlTemplate!=null)
           html=object.infoHtmlTemplate;
         for(var p in object){
           var pattern="@\\{"+p+"\\}";
           var regexp=new RegExp(pattern,"g")
           html=html.replace(regexp,object[p]);
         }
         marker.openInfoWindowHtml(html);
       }
     );
    // save two markers for each point, one with each of the possible icons
    this.cmarkers[object.id] = marker;
    var hmarker=new GMarker(point,{icon:icon, title:name}/*this.bigIcon*/);
    this.hmarkers[object.id] = hmarker;
    GEvent.addListener(hmarker, "click", function() {
         var html=self.infoHtmlTemplate;
         var object=hmarker.object;
         if(object.infoHtmlTemplate!=null)
           html=object.infoHtmlTemplate;
         for(var p in object){
           var pattern="@\\{"+p+"\\}";
           var regexp=new RegExp(pattern,"g")
           html=html.replace(regexp,object[p]);
         }
         hmarker.openInfoWindowHtml(html);
       }
     );    
    this.hmarkers[object.id].object=object;
    return marker;
  },
  /** doclick */
  doclick: function(id, name) {
    this.mouseover(id);
    var object=this.cmarkers[id].object;
    var html=this.infoHtmlTemplate;
    if(object.infoHtmlTemplate!=null)
      html=object.infoHtmlTemplate;
    for(var p in object){
      var pattern="@\\{"+p+"\\}";
      var regexp=new RegExp(pattern,"g")
      html=html.replace(regexp,object[p]);
    }    
    this.hmarkers[id].openInfoWindowHtml(html);
  },
  /** do mouseover */
  mouseover: function mymouseover(id) {
    this.map.removeOverlay(this.cmarkers[id]);
    this.map.addOverlay(this.hmarkers[id]);
  },
  /** do mouseout */
  mouseout: function mymouseout(id) {
    this.map.removeOverlay(this.hmarkers[id]);
    this.map.addOverlay(this.cmarkers[id]);
  }/*,
  setZoom: function(zoomLevel){
    this.map.setZoom(zoomLevel);
  }*/
});
/**
 * Google polyline wrapper.
 */
Polyline=Jclass.create({
	color		: "#FF0000", 
	weight		: 7, 
	opacity		: 0.8, 
	zoomFactor	: 2, 
	numLevels	: 18,
	points		: null, 
	levels		: null,
  /** constructor */
	constructor: function Polyline(object){
		for(var p in this)
			if(object[p]!=null)
				this[p]=object[p];
		var polyline = new GPolyline.fromEncoded(this);    	  
		this._source=polyline;
	},
	getBounds: function() {
		return this._source.getBounds();
	}
});
/**
 * Google geo icon wrapper 
 */
 GeoIcon=Jclass.create({
	 Extends	: GIcon,
	 //shadow : "http://labs.google.com/ridefinder/images/mm_20_shadow.png",
  	 //shadowSize : new GSize(12, 12),
 	 iconAnchor : new GPoint(4, 4), 	 
 	 infoWindowAnchor : new GPoint(4, 4),   
 	 //constructor
 	 constructor: function GeoIcon(object) {
	 	GIcon.apply(this,arguments);
   	 }
 });
