/*
   Class: stGoogleMap 
   Description:  This class is intended to simplify the basic 
   implementation of a goggle map, by reducing the number of 
   calls required to setup and include the map.
   
   
   options:
	MapContainer: ID String or DOM reference to the element that will contain the map.
	MapNavControls: String value of none, small or large; determines the which navigation controls will be used
	MapTypeControl: bool; Specifies to use the google maps type control (map, hybrid, satalite... buttons)
	MapScaleControl: bool; specifies to show the map scale or not. 
	MapOverviewControl: bool; specifies wether or not to show the overview control
	DefaultCenter: object; specifies the latitude and longitude to center the map on by default e.g. {la: 43.8028187190472, lo: -94.19677734375}
	DefaultZoom: integer; specifies the maps inital zoom level.
	DoubleClickZoom: bool; turns zoom and center on double click on and off 
	ScrollWheelZoom: bool; turns zoom with mouse wheel on and off 
*/
	var stGoogleMap = new Class({
		options: {
			MapContainer: null,
			AddressItemContainer: null,
			MapNavControls: 'small', //none, small, large
			MapTypeControl: true,
			MapScaleControl: true,
			MapOverviewControl: true,
			DefaultCenter: {la:0, lo:0},
			DefaultZoom: 7,
			DoubleClickZoom: true,
			ScrollWheelZoom: true
		},
		initialize: function(options){
			this.setOptions(options);
			//addDomListener(document.getElementsByTagName("body"),  onunload,  GUnload);
			this.MarkerArray = Array();
			this.Areas = Array();
			if(typeof this.options.MapContainer == 'string'){
				this.options.MapContainer = $(this.options.MapContainer);
			}
			if(this.options.MapContainer != null){
				this.map = new GMap2(this.options.MapContainer);
			}
			switch(this.options.MapNavControls){
				case 'small':
					this.map.addControl(new GSmallMapControl());
					break;
				case 'large':
					this.map.addControl(new GLargeMapControl());
					break;
				case 'none':
					break;
			}
			if(this.options.MapTypeControl){
				this.map.addControl(new GMapTypeControl());	
			}
			if(this.options.MapScaleControl){
				this.map.addControl(new GScaleControl());
			}
			if(this.options.MapOverviewControl){
				this.map.addControl(new GOverviewMapControl());
			}
			if(this.options.DoubleClickZoom){
				this.map.enableDoubleClickZoom();
			}
			if(this.options.ScrollWheelZoom){
				this.map.enableScrollWheelZoom();
			}

			this.map.setCenter(new GLatLng(this.options.DefaultCenter.la,this.options.DefaultCenter.lo), this.options.DefaultZoom); 
		},
		AddMarker: function(la, lo, title, bubbleText){
			//curmark = new starGMarkerOnPoint(this.map, la, lo, {address:curLoc.Address, Info:curLoc.Info, Title:curLoc.Title, AddressItemContainer: "LocationHolder"})
			curmark = new stGMarker(this.map, la, lo, {Info:bubbleText, Title:title, AddressItemContainer: this.options.AddressItemContainer});
			this.MarkerArray.push(curmark);
			curmark.MakeMark();
			if(this.options.AddressItemContainer){
				curmark.AddToListDiv();
			}
		},
		AddArea: function(points, strokeColor, strokeWidth, strokeOpacity, fillColor, fillOpacity, label){
			if(fillColor == null){
				curArea = new GPolyline(points, '#444444', 3, 0.8);
			}else{
				curArea = new GPolygon(points, '#444444', 3, 0.8, '#999999', 0.5);
			}
			AreaEntry = {};
			AreaEntry.Polygon = curArea;
			if(label != null){
				AreaEntry.Label =  label;
			}
			this.Areas.push(AreaEntry);
			this.map.addOverlay(curArea);
			this.map.addOverlay(new st_map_lable_overlay(label, curArea.getBounds()));
			this.map.addOverlay(new st_map_lable_overlay(label, curArea.getBounds()));
			this.map.addOverlay(new st_map_lable_overlay(label, curArea.getBounds()));
		},
		AddCircle: function(Center, Radius, objOptions){
			//objOptions info
			//strokeColor: Hex Color Value
			//strokeWidth: int stroke width
			//strokeOpacity: float 0.0 - 1.0 
			//fillColor:   Hex Color Value
			//fillOpacity: float 0.0 - 1.0 
			//label: String
			var circlePoints = this.genCirclePoints(Center, Radius);
			this.AddArea(circlePoints, objOptions.strokeColor, objOptions.strokeWidth, objOptions.strokeOpacity, objOptions.fillColor, objOptions.fillOpacity, objOptions.label);
		},//GLatLng Center: center of circle, float radius: distance in miles
		genCirclePoints: function(Center, Radius){
			//var center = this.map.getCenter();
			var circlePoints = Array();
			var bounds = new GLatLngBounds();
			with (Math) {
				//if (circleUnits == 'KM') {
				//	var rLat = (Radius/6378.8) * (180/PI);
				//}
				//else { //miles
					var rLat = (Radius/3963.189) * (180/PI);
				//}
				var rLng = rLat/cos(Center.lat() * (PI/180));

				for (var a = 0 ; a < 361 ; a+=1 ) {
					var aRad = a*(PI/180);
					var x = Center.lng() + (rLng * cos(aRad));
					var y = Center.lat() + (rLat * sin(aRad));
					var point = new GLatLng(parseFloat(y),parseFloat(x));
					bounds.extend(point);
					circlePoints.push(point);
				}
			}

			//map.removeOverlay(centerMarker);
			//centerMarker = new GMarker(center);
			//map.addOverlay(centerMarker);

			//map.removeOverlay(circle); 
			//circle = new GPolygon(circlePoints, true, '#ff0000', 0.25, true);    
			//map.addOverlay(circle); 

			//map.setZoom(map.getBoundsZoomLevel(bounds));
			return circlePoints;
		}
	})
	stGoogleMap.implement(new Options);
	
	var stGMarker = new Class({
	options: {
		Title: null,
		Info: null,
		address: null,
		AddressItemContainer: null,
		Icon: null
	},
	initialize: function(map, lat, lng, options){
		this.setOptions(options);
		this.marker = null;
		this.map = map;
		if(lat){
			this.lat = lat;
		}else{
			this.lat = 0;
		}

		if(lng){
			this.lng = lng;
		}else{
			this.lng = 0;
		}
		mp = GLatLng(0, 0);
		this.markerPoint = new GLatLng(this.lat, this.lng);
		markerOptions = {};
		if(this.options.Title != null){
			markerOptions.title = this.options.Title;
		}
		if(this.options.Icon != null){
			markerOptions.icon = this.options.Icon;
		}
		this.marker = new GMarker(this.markerPoint, markerOptions);
	},
	MakeMark: function(){
			this.map.addOverlay(this.marker);
			if(this.options.Info != null){
				//this.marker.bindInfoWindow("<div class=\"stMapBubble\">" + this.options.Info + "</div>");
				this.marker.bindInfoWindowHtml("<div class=\"stMapBubble\">" + this.options.Info + "</div>");
				GEvent.addListener(this.marker,  "mouseover",  this.HandleMarkerOver.bind(this));
				GEvent.addListener(this.marker,  "mouseout",  this.HandleMarkerOut.bind(this));
			}
	},
	AddToListDiv: function(){
		if(this.options.AddressItemContainer != null){
			if($type(this.options.AddressItemContainer) == "string"){
				objLocationHolder = $(this.options.AddressItemContainer);
			}else{
				objLocationHolder = this.options.AddressItemContainer;
			}
			addressdiv = document.createElement("div");
			//addressdiv.style.backgroundColor = "#aaaa88";
			addressdiv.innerHTML = "<h3 style='cursor: pointer;'>" + this.options.Title + "</h3>"/* + this.options.address */;  //dh: not wanting to display address - Also, this option doesn't get set by stGoogleMap.AddMarker().
			addressdiv.onclick = this.HandleAddressClick.bind(this);
			//addressdiv.onmouseover = this.HandleAddressOver.bind(this);
			//addressdiv.onmouseout = this.HandleAddressOut.bind(this);
			objLocationHolder.appendChild(addressdiv);            
		}
	},
	HandleMarkerOver: function(e, o){
		//GEvent.trigger(this.marker,  "click");
	},
	HandleMarkerOut: function(e, o){
		//this.marker.closeInfoWindow();
	},
	HandleAddressOver: function(e, o){
		GEvent.trigger(this.marker,  "click");
	},
	HandleAddressOut: function(e, o){
		this.marker.closeInfoWindow();
	},
	HandleAddressClick: function(e, o){
		GEvent.trigger(this.marker,  "click");
	}
});

stGMarker.implement(new Options);



function st_map_lable_overlay(text, Bounds) {
	this.text = text;
	this.Bounds = Bounds;
	this.areaBounds = {}; 

}
st_map_lable_overlay.prototype = new GOverlay();

st_map_lable_overlay.prototype.initialize = function(map) {
	this.map = map;
	this.customDiv = document.createElement("div");
	this.customDiv.style.position = "absolute";
	this.customDiv.id = "lbl_" + this.text;
	this.Draw();
}
st_map_lable_overlay.prototype.Draw = function() {
	ll = this.Bounds.getNorthEast();
	pp = this.map.fromLatLngToDivPixel(ll);
	this.areaBounds.top = pp.y;
	this.areaBounds.right = pp.x;
	ll = this.Bounds.getSouthWest();
	pp = this.map.fromLatLngToDivPixel(ll);
	this.areaBounds.bottom = pp.y;
	this.areaBounds.left = pp.x;

	this.customDiv.style.fontSize = this.map.getZoom() *3;
	this.customDiv.style.width = this.areaBounds.right - this.areaBounds.left;
	this.customDiv.style.height = this.areaBounds.bottom - this.areaBounds.top;
	this.customDiv.style.left = this.areaBounds.left + (this.areaBounds.right - this.areaBounds.left)/2;
	this.customDiv.style.top = this.areaBounds.top + (this.areaBounds.bottom - this.areaBounds.top)/2;
	this.customDiv.style.zIndex = 10000; 
	this.customDiv.innerHTML = this.text;
	mpane = this.map.getPane(G_MAP_MAP_PANE);
	mpaneParent = mpane.parentNode;
	mpaneParent.appendChild(this.customDiv);
}

st_map_lable_overlay.prototype.Update = function() {
	ll = this.Bounds.getNorthEast();
	pp = this.map.fromLatLngToDivPixel(ll);
	this.areaBounds.top = pp.y;
	this.areaBounds.right = pp.x;
	ll = this.Bounds.getSouthWest();
	pp = this.map.fromLatLngToDivPixel(ll);
	this.areaBounds.bottom = pp.y;
	this.areaBounds.left = pp.x;
	
	this.customDiv.style.fontSize = this.map.getZoom() *3;
	this.customDiv.style.width = this.areaBounds.right - this.areaBounds.left;
	this.customDiv.style.height = this.areaBounds.bottom - this.areaBounds.top;
	this.customDiv.style.left = this.areaBounds.left + (this.areaBounds.right - this.areaBounds.left)/2;
	this.customDiv.style.top = this.areaBounds.top + (this.areaBounds.bottom - this.areaBounds.top)/2;
	//customDiv.style.zIndex = 10000; 
	//customDiv.innerHTML = this.text;
	//mpane = map.getPane(G_MAP_MAP_PANE);
	//mpaneParent = mpane.parentNode;
	//mpaneParent.appendChild(customDiv);
}

st_map_lable_overlay.prototype.redraw = function(force){
	this.Update();
};
