function init_maps() {
	for(k in map_objects) {
		eval("init_map_"+k+"()");
	}
}

var directionDisplay;
var directionsService = new google.maps.DirectionsService();

var map_objects = Array();
function map_object(name) {
  this.name = name;  
  this.map;
  this.markers = Array();
  this.points = Array();
  this.overLays = Array();
  this.open_overlay;
  this.loaded=0;
  this.circle;
  
  map_objects[this.name] = this;
  
  this.initialize = function () {
		directionsDisplay = new google.maps.DirectionsRenderer();

    var ob = document.getElementById(this.name);
    var myLatlng = new google.maps.LatLng(-34.397, 150.644);
    if(ob==null) return;
    var myOptions = {
      mapTypeId: google.maps.MapTypeId.ROADMAP,
      scrollwheel:false,
      name:this.name
    };
    this.map = new google.maps.Map(ob, myOptions);   
    
    directionsDisplay.setMap(this.map); 
  }

  this.marker = function () {
    this.map;
    this.id;
    this.position;
    this.title;
    this.icon;
    this.zIndex=1;
    this.clickurl;
    this.markerGroup;
    
    this.create = function() {
      var marker = new google.maps.Marker({
        id:this.id,
        position: this.position,
        map: this.map,
        title:this.title,
        icon:this.icon,
        clickurl:this.clickurl,
        markerGroup:this.markerGroup,
        zIndex:this.zIndex
       });
       return marker;       
    }
  }
  
	this.drawCircle = function (lat,long,radius,strokeColor,strokeOpacity,strokeWeight,fillColor,fillOpacity) {
		
		try { this.circle.setMap(null); } catch (e) {}	

		var point = new google.maps.LatLng(lat,long);
		var d2r = Math.PI / 180;
		var circleLatLngs = new Array();
		var circleLat = radius;
		var circleLng = circleLat / Math.cos(point.lat() * d2r);
		var numPoints = 100;
    
		var latlngbounds = new google.maps.LatLngBounds( );
    
		for (var i = 0; i < numPoints + 1; i++) { 
			var theta = Math.PI * (i / (numPoints / 2)); 
			var vertexLat = point.lat() + (circleLat * Math.sin(theta)); 
			var vertexLng = parseFloat(point.lng()) + parseFloat((circleLng * Math.cos(theta)));
			var vertextLatLng = new google.maps.LatLng(vertexLat, vertexLng);
			circleLatLngs.push(vertextLatLng);
			latlngbounds.extend(vertextLatLng);
		}
    
		var polygon = new google.maps.Polygon({
			paths: circleLatLngs,
			strokeColor: strokeColor,
	  	strokeOpacity: strokeOpacity,
	  	strokeWeight: strokeWeight,
	  	fillColor: fillColor,
	  	fillOpacity: fillOpacity
		});
		
		this.circle = polygon;
		this.circle.setMap(this.map);
		this.map.fitBounds(latlngbounds);
	}  

  this.add_marker = function (id,position,title,clickurl,icon,markerGroup) {
    marker = new this.marker();
    marker.map = this.map;
    marker.id = id;
    marker.position = position;
    marker.title = title;
    marker.clickurl = clickurl;
    marker.icon = icon;
    marker.markerGroup = markerGroup;
    
    this.markers[marker.id] = marker.create();
    this.points[this.points.length] = position;
    return this.markers[marker.id];
  }
  
  this.fitBounds = function () {
    var bounds = new google.maps.LatLngBounds;
    for (var i = 0; i<this.points.length; i++) bounds.extend(this.points[i]);
    this.map.fitBounds(bounds); 
  }
  
  this.setCenter = function (lat,long) {
    this.map.setCenter(new google.maps.LatLng(lat,long));
    this.map.panTo(new google.maps.LatLng(lat,long));
  }
  
  this.setZoom = function (zoom) {
    this.map.setZoom(zoom);
		var bounds = new google.maps.LatLngBounds;
    for (var i = 0; i<this.points.length; i++) bounds.extend(this.points[i]);  
    this.map.panToBounds(bounds);  
  }    

  this.addListeners = function () {
  	
  	google.maps.event.addListener(this.map, 'zoom_changed',function() {
  		 if(map_objects[this.name].open_overlay) map_objects[this.name].hideOverlay('overlay1',map_objects[this.name].open_overlay);
    }); 
  	  	
    new google.maps.event.addListenerOnce(this.map, 'tilesloaded', function() {
    	for(k in map_objects[this.name].overLays) {
        if(map_objects[this.name].overLays[k].connectWith == "map") {
            if(map_objects[this.name].overLays[k].showEvent == 'fixed') {
            	map_objects[this.name].showStaticOverlay(map_objects[this.name].overLays[k]);
            }
        }
        if(map_objects[this.name].overLays[k].connectWith == "marker") {
            if(map_objects[this.name].overLays[k].showEvent == 'fixed') {
            	for(key in map_objects[this.name].markers) {
            		map_objects[this.name].showOverlay(map_objects[this.name].overLays[k].name,key,1);
            	}
            }
        }        
      }
  	});	
  	  	
    for(key in this.markers) {
      marker = this.markers[key];
      
      google.maps.event.addListener(marker, 'click', function() {
        document.location.href = this.clickurl;
				for(k in map_objects[this.map.name].overLays) {
          if(map_objects[this.map.name].overLays[k].connectWith == "marker" && map_objects[this.map.name].overLays[k].Group == this.markerGroup) {
        	  if(map_objects[this.map.name].overLays[k].showEvent == 'click') map_objects[this.map.name].showOverlay(map_objects[this.map.name].overLays[k].name,this.id);
        	  if(map_objects[this.map.name].overLays[k].hideEvent == 'click') map_objects[this.map.name].hideOverlay(map_objects[this.map.name].overLays[k].name,this.id);
        	}
        }
      });
      
      google.maps.event.addListener(marker, 'mouseover', function() {
        this.setZIndex(2);
        for(k in map_objects[this.map.name].overLays) {
          if(map_objects[this.map.name].overLays[k].connectWith == "marker" && map_objects[this.map.name].overLays[k].Group == this.markerGroup) {
        	  if(map_objects[this.map.name].overLays[k].showEvent == 'mouseover') map_objects[this.map.name].showOverlay(map_objects[this.map.name].overLays[k].name,this.id);
        	  if(map_objects[this.map.name].overLays[k].hideEvent == 'mouseover') map_objects[this.map.name].hideOverlay(map_objects[this.map.name].overLays[k].name,this.id);
        	}
        }
      });
      google.maps.event.addListener(marker, 'mouseout', function() {
        this.setZIndex(1);
        for(k in map_objects[this.map.name].overLays) {
          if(map_objects[this.map.name].overLays[k].connectWith == "marker" && map_objects[this.map.name].overLays[k].Group == this.markerGroup) {
            if(map_objects[this.map.name].overLays[k].showEvent == 'mouseout') {map_objects[this.map.name].showOverlay(map_objects[this.map.name].overLays[k].name,this.id);}
        	  if(map_objects[this.map.name].overLays[k].hideEvent == 'mouseout') map_objects[this.map.name].hideOverlay(map_objects[this.map.name].overLays[k].name,this.id);          
        	}
        }        
      });
    }
  }
    
  this.Overlay = function(map) {
    this.prototype = new google.maps.OverlayView();
    this.prototype.setMap(map);
    this.map = map;
    this.div;
    this.callback;
    this.showEvent;
    this.hideEvent;
    this.connectWith;
    this.Group;
    this.mtop;
    this.mleft;

    this.setDiv = function(div) {   this.div = div;  }
    this.setCallback = function(callback) { this.callback = callback; }
    this.setConnection = function(connectWith,Group) {this.connectWith = connectWith; this.Group = Group; }
    this.setShowEvent = function(sevent) { this.showEvent = sevent; }
    this.setHideEvent = function(hevent) { this.hideEvent = hevent; }
    this.setTopLeft = function(mtop,mleft) { this.mtop = mtop; this.mleft =mleft;  }
         
    this.open = function(marker) { 
      this.div.innerHTML="Loading...";
      if(this.callback) eval(this.callback+"('"+marker.id+"')");
      this.div.style.position = "absolute";
      panes = this.prototype.getPanes();
      panes.floatPane.appendChild(this.div);  
      var overlayProjection = this.prototype.getProjection();
      var sw = overlayProjection.fromLatLngToDivPixel(marker.position);
      var ne = overlayProjection.fromLatLngToDivPixel(marker.position);
      mleft = sw.x - ((parseInt(this.div.style.width)+(parseInt(this.div.style.padding)*2))/2);
      mtop = ne.y;
      this.div.style.left = mleft + 'px';
      this.div.style.top = mtop + 'px';
      this.div.style.display = "block";
    }
    
    this.close = function() { 
      var div = this.div;  
      this.div.style.display = "none";
    }
      
    this.prototype.draw = function() {} 
        
  }
  
  this.showOverlay = function(overlay,id,center) {
  	try{
  		activemarker.setZIndex(1);
  		//if(activemarker.markerGroup!="hotelMarkers") activemarker.setIcon(marker.icon+"&skin=default");
  	} catch (e) {}	
  	try {
    	marker = this.markers[id];
    	if(center==1) this.map.panTo(marker.getPosition());
    	this.overLays[overlay].open(marker);
			marker.setZIndex(2);
			activemarker = marker;
			//if(marker.markerGroup!="hotelMarkers") marker.setIcon(marker.icon+"&skin=hover");
    	this.open_overlay = id;
  	} catch (e) {}
  }
  
  this.showStaticOverlay = function(overlay) {
  	panes = overlay.prototype.getPanes();
  	div = document.getElementById(overlay.map.name).appendChild(overlay.div);
  	div.style.position = "absolute";
		div.style.left = overlay.mleft+'px';
    div.style.top = overlay.mtop+'px';  	
  	div.style.display = "block";
  }
  
  this.hideOverlay = function(overlay,id) {
    marker = this.markers[id];
		try{	activemarker.setZIndex(1);	} catch (e) {}	    
    try{	this.overLays[overlay].close(marker); } catch (e) {}	    
    this.open_overlay = null;
  }  
  
  this.addOverlay = function(name) {
    overlay = new this.Overlay(this.map);
    overlay.name = name;
    this.overLays[name] = overlay;
    return overlay;
  }
}


function calculateCenter(lats,longs) {
  var minLat = null;
  var maxLat = null;
  var minLng = null;
  var maxLng = null;  
  $.each(lats, function() {
                if (!minLat) {
                        minLat = this;
                } else if (this < minLat) {
                        minLat = this;
                }
                if (!maxLat) {
                        maxLat = this;
                } else if (this > maxLat) {
                        maxLat = this;
                }
  });
  $.each(longs, function() {
                if (!minLng) {
                        minLng = this;
                } else if (this < minLng) {
                        minLng = this;
                }
                if (!maxLng) {
                        maxLng = this;
                } else if (this > maxLng) {
                        maxLng = this;
                }
  });

  var x = ((minLng - maxLng) / 2);
  if (x < 0) x = -x;
  x = minLng + x;
  var y = ((minLat - maxLat) / 2)
  if (y < 0) y = -y;
  y = minLat + y;
  return new google.maps.LatLng(y, x); 
}

