var gMap;

function googMap ( obj ) {
	var latitude = ( obj.latitude ) ? obj.latitude: 0; 
	var longitude = ( obj.longitude ) ? obj.longitude : 0;  
	var zoom_level = ( obj.zoom_level ) ? obj.zoom_level : 6; 
	
	this.init = function(_lt, _ln, _zm) {
		if (GBrowserIsCompatible()) {
			var map = new GMap2(document.getElementById("map_canvas"));
			map.setCenter(new GLatLng(_lt, _ln), _zm);
			// get default UI
			var ui = map.getDefaultUI();
			// remove some stuff
			ui.controls.scalecontrol = false;
			ui.controls.maptypecontrol = false;
			ui.zoom.scrollwheel = false;
			// set the UI
			map.setUI(ui);
			map.setMapType(G_PHYSICAL_MAP);
			return map;
		}
		return null;
	};
	
	this.resetZoom = function() {
		this.map.setCenter(new GLatLng(latitude,longitude), zoom_level);
	};
	
	this.map = this.init(latitude, longitude, zoom_level);
	this.bounds = new GLatLngBounds();

	this.zipData = {};
	
	this.allMarkers = [];
}

googMap.prototype.addMarker = function( obj ) {
	this.allMarkers.push(obj);
}

googMap.prototype.setBorder = function( obj ) {
	this.border = obj;
}

googMap.prototype.drawBorder = function( obj ) {
	if (!obj.latLons) return;
	
	var latLons = obj.latLons;
	var lineWidth = ( obj.lineWidth ) ? obj.lineWidth: 4;
	var hexColor = ( obj.hexColor ) ? obj.hexColor: "#ff0000";
	var connectLast = (obj.connectLast && obj.connectLast == "yes") ? true: false;
	
	for ( var i = 0; i < latLons.length; i++) {
		var connectNext = ( latLons[i].connectNext && latLons[i].connectNext == "no") ? false: true;
		
		var j = ( (i+1) >= latLons.length) 
					? (connectLast) ? 0: i 
					: i+1;	
					
		var pntA = (connectNext) ? latLons[i] : latLons[j];
		var pntB = latLons[j];

		// create the line
		var line = new  GPolyline([
						new GLatLng(pntA.lat, pntA.lon),
						new GLatLng(pntB.lat, pntB.lon)
					], hexColor, lineWidth);
					
		// add line to map
		this.map.addOverlay(line);
	}
	
	// save border options
	if ( obj.stateBorder )
		this.setBorder( obj);
}

googMap.prototype.infoWindow = function ( obj ){
	if (!obj.domNode && !obj.html) return;
	
	var itm = ( obj.target ) ? obj.target: this.map;
	
	if ( obj.domNode ) itm.openInfoWindow(this.map.getCenter(), obj.domNode);
	if ( obj.html ) itm.openInfoWindowHtml(obj.html);	
}

/*
These are not mandatory. There are certain strange circumstances in which you might want to omit almost any parameter, 
but you should think carefully before omitting any of these parameters:

    * iconSize : without it your marker will have zero size and be invisible
    * iconAnchor : without it your marker won't appear in the correct place
    * infoWindowAnchor : without it marker.openInfoWindow() will fail
    * transparent : without it your marker won't be clickable in MSIE if there's an info window shadow nearby
    * imageMap : without it your marker won't be clickable in Firefox if there's an info window shadow nearby - this one may not be needed anymore
*/
googMap.prototype.setCustomMarker = function ( obj ) {
	if ( !obj.image ) return;
	
	// creat an icon instance
	var icn = new GIcon(G_DEFAULT_ICON);
	
	// the url of the main image for the marker 
	icn.image = obj.image;
	
	// url of the shadow image
	if ( obj.shadow ) icn.shadow = obj.shadow;
	// url of a GIF file to be used for printing
	if ( obj.printImage ) icn.printImage = obj.printImage;
	// url of a GIF file to be used for printing from the Mozilla/Firefox browser
	if ( obj.mozPrintImage ) icn.mozPrintImage = obj.mozPrintImage;
	// url of a GIF file to be used for printing the shadow
	if ( obj.printShadow ) icn.printShadow = obj.printShadow;
	
	// url of a transparent image used for capturing clicks and mouseovers in MSIE
	if ( obj.transparent ) icn.transparent = obj.transparent;
	// an array of integers representing the x/y coordinates of the image map used fopr capturing image clicks in non-IE browsers
	if ( obj.imageMap ) icn.imageMap = obj.imageMap;
	
	// pixel size of the Icon.image
	if ( obj.iconSize ) icn.iconSize = new GSize(obj.iconSize.height, obj.iconSize.width);
	// the pixel size of the Icon.shadow
	if ( obj.shadowSize ) icn.shadowSize = new GSize(obj.shadowSize.height, obj.shadowSize.width);
	
	// think of it as the point that the image points at - relative to the icn.images left/top
	if ( obj.iconAnchor ) icn.iconAnchor = new GPoint(obj.iconAnchor.left, obj.iconAnchor.top);
	// the pixel that the tip of the info Window stem will touch - relative to the icn.image left/top
	if ( obj.infoWindowAnchor ) icn.infoWindowAnchor = new GPoint(obj.infoWindowAnchor.left, obj.infoWindowAnchor.top);
	
	this.customMarker = { icon: icn };
}

googMap.prototype.startGeocoder = function () {
	this.geocoder = new GClientGeocoder();
}

							
googMap.prototype.createMarker = function ( obj ) {
	if (!obj.point) return;
	
	var point = obj.point;
	var customMarker = (this.customMarker) ? this.customMarker: 
							(obj.customMarker) ? obj.customMarker: false;
	var marker = (customMarker) ? new GMarker(point, customMarker): new GMarker(point);

	if ( obj.html ) {
		GEvent.addListener(marker, "click", function() {
			marker.openInfoWindowHtml( obj.html );
		});
	}
	if ( obj.domNode ) {
		GEvent.addListener(marker, "click", function() {
			marker.openInfoWindow( obj.domNode );
		});
	}
	
	this.addMarker({ marker: marker, obj: obj });
	
	return marker;
}

googMap.prototype.addMarkersToMap = function(obj, skipZoom) {
	if (!obj.latLons) return;
	
	var latLons = obj.latLons;
	for ( var i = 0; i < latLons.length; i++) {
		var markerX = latLons[i];
		
		var point;
		// check for address
		if (markerX.address) {
			var address = markerX.address;
			if (!this.geocoder) this.startGeocoder();
			
			if (this.geocoder) {
				var custMark = (this.customMarker) ? this.customMarker: false;
				var mp = this.map;
				var cmFn = this.createMarker;
				var myMarkX = markerX;

				var g = this.geocoder.getLatLng(
					address,
					function( _pnt ) {
						var str = "test";
						alert(str);
						if ( !_pnt ) {
							alert(address + " not found");
						} else {
							var _point = new GLatLng( _pnt.lat().toFixed(5), _pnt.lng().toFixed(5));
							var _marker = (custMark) ? new GMarker(_point, custMark): new GMarker(_point);
							this.bounds.extend(_point);
							var _o = { point: _point };
							if ( myMarkX.domNode ) _o.domNode = myMarkX.domNode;
							if ( myMarkX.html ) _o.html = myMarkX.html;
							if ( custMark ) _o.customMarker = custMark;
							if ( _o.html ) {
								GEvent.addListener(_marker, "click", function() {
									_marker.openInfoWindowHtml( _o.html );
								});
							}
							if ( _o.domNode ) {
								GEvent.addListener(_marker, "click", function() {
									_marker.openInfoWindow( _o.domNode );
								});
							}
							mp.addOverlay( cmFn( _o ) );
						}
					}
				);
			}
			
		// no address - use lat lons
		} else if (markerX.lat && markerX.lon) {
			var point = new GLatLng(markerX.lat, markerX.lon);
			this.bounds.extend(point);
			var o = { point: point };
			if ( markerX.domNode) o.domNode = markerX.domNode;
			if ( markerX.html ) o.html = markerX.html;

			this.map.addOverlay( this.createMarker( o ) );
		}
	}
	
	// link assoclinks 
	var extLinks = [ "meName", "meDate", "meAddy" ];
	for ( var i = 0; i < latLons.length; i++) {
		var markerX = latLons[i];
		
		for ( var j=0; j < extLinks.length; j++) {
			// if dom id exists make it clickable to open the info bubble
			if ( document.getElementById(extLinks[j] + markerX.id) ) {
				YAHOO.util.Event.addListener(extLinks[j] + markerX.id, "click", function( a, b ) {
					var center = new GLatLng(b.obj.point.lat(), b.obj.point.lng());
					var zoom = 7;
					gMap.map.setCenter(center,zoom);
					
					if ( b.obj.html ) b.marker.openInfoWindow( b.obj.html );
					if ( b.obj.domNode ) b.marker.openInfoWindow( b.obj.domNode );
					
				}, this.allMarkers[i] );
			}
		}
	}
	
	// zoom if zip is set
	if (this.zipData.hasOwnProperty('zip') && this.zipData.length > 4) {
		if (this.zipData.hasOwnProperty('latitude') && this.zipData.latitude != 0) {
			// center on zip code
			var center = new GLatLng(this.zipData.latitude, this.zipData.longitude);
			// hard coded, ~130 miles
			var zoom = 9;
		} else {
			// zooms to contain markers 
			var zoom = this.map.getBoundsZoomLevel(this.bounds);
			// centers to contain markers
			var center = this.bounds.getCenter();
		}
		this.map.setCenter(center,zoom);
	} else {
		// unzoom
		this.resetZoom();
	}
}

googMap.prototype.getMapBounds = function () {
	if (!this.map) return;
	
	var bounds = this.map.getBounds();
	var southWest = bounds.getSouthWest();
	var northEast = bounds.getNorthEast();
	var lngSpan = northEast.lng() - southWest.lng();
	var latSpan = northEast.lat() - southWest.lat();
	
	return { 
			bounds: bounds,
			southWest: southWest,
			northEast: northEast,
			lngSpan: lngSpan,
			latSpan: latSpan 
		};
}

googMap.prototype.clearMap = function () {
	this.map.clearOverlays();
	
	// redraw border
	if (this.border) this.drawBorder( this.border );
}

googMap.prototype.toString = function () {
	return "googMap";
}


