
SG.namespace("SG.geo");

SG.geo = function (id, geoConfig) {
	this.id = id;
	this.geoConfig = geoConfig;
	
	var key = this.geoConfig.geoMapKeys[window.location.host];
	var src = 'http://maps.google.com/maps?file=api&amp;v=2&amp;key=' + key;
	document.write('<' + 'script src="' + src + '"' +' type="text/javascript"><' + '/script>');
}
	
SG.geo.prototype.id = null;
SG.geo.prototype.geoConfig = null;
SG.geo.prototype.map = null;
SG.geo.prototype.funcPtr = [];
SG.geo.prototype.reasons = [];

SG.geo.prototype.createGeoMap = function() {
	
	if (GBrowserIsCompatible()) {
		this.map = new GMap2(document.getElementById(this.geoConfig.id));
		
		// ====== Array for decoding the failure codes ======
		this.reasons[G_GEO_SUCCESS]            = "Success";
		this.reasons[G_GEO_MISSING_ADDRESS]    = "Missing Address: The address was either missing or had no value.";
		this.reasons[G_GEO_UNKNOWN_ADDRESS]    = "Unknown Address:  No corresponding geographic location could be found for the specified address.";
		this.reasons[G_GEO_UNAVAILABLE_ADDRESS]= "Unavailable Address:  The geocode for the given address cannot be returned due to legal or contractual reasons.";
		this.reasons[G_GEO_BAD_KEY]            = "Bad Key: The API key is either invalid or does not match the domain for which it was given";
		this.reasons[G_GEO_TOO_MANY_QUERIES]   = "Too Many Queries: The daily geocoding quota for this site has been exceeded.";
		this.reasons[G_GEO_SERVER_ERROR]       = "Server error: The geocoding request could not be successfully processed.";
		
		if (this.geoConfig.typeControl && this.geoConfig.typeControl == true) {
			this.map.addControl(new GMapTypeControl());
		}
		if (this.geoConfig.scaleControl && this.geoConfig.scaleControl == true) {
			this.map.addControl(new GScaleControl());
		}
		if (this.geoConfig.largeMapControl && this.geoConfig.largeMapControl == true) {
			this.map.addControl(new GLargeMapControl());
		} else if (this.geoConfig.smallMapControl && this.geoConfig.smallMapControl == true) {
			this.map.addControl(new GSmallMapControl());
		} else if (this.geoConfig.smallZoomControl && this.geoConfig.smallZoomControl == true) {
			this.map.addControl(new GSmallZoomControl());
		}
		for (var i=0; i < this.geoConfig.geoMarkers.length; i++) {
			var geoMarker = this.geoConfig.geoMarkers[i];
			if (geoMarker.latitude == 0 && geoMarker.longitude == 0) {
				var geocoder = new GClientGeocoder();
				var address = this._formatAddress(geoMarker.street, geoMarker.postcode, geoMarker.city, geoMarker.country);
				var idstr="" + this.id;
				this.funcPtr[i] = new Function("point", "SG.geo."+this.id+"._latLngCallback.call(SG.geo."+this.id+", point, "+i+");");				
				geocoder.getLocations(address, this.funcPtr[i]);
			} else {
				var point = new GLatLng(geoMarker.latitude, geoMarker.longitude);
				this.map.setCenter(point, this.geoConfig.zoom);
				this.map.addOverlay(this._createMarker(point, 0, geoMarker.name, geoMarker.description, geoMarker.link, geoMarker.icon, geoMarker.iconAnchorWidth, geoMarker.iconAnchorHeight));
			}
		}
	}
}

SG.geo.prototype._formatAddress = function(street, postcode, city, country) {
		var address = "";
		if (!SG.cal.util.isEmpty(street)) {
			address = street + ", ";
		}
		if (!SG.cal.util.isEmpty(postcode)) {
			address += postcode + ", ";
		}
		if (!SG.cal.util.isEmpty(city)) {
			address += city + ", ";
		}
		if (!SG.cal.util.isEmpty(country)) {
			address += country;
		}
		return address;
	}
	
SG.geo.prototype._createMarker = function(point, colorNr, name, description, link, iconUrl, iconAnchorWidth, iconAnchorHeight) {
	var icon = new GIcon();
	if (iconUrl != undefined && iconUrl != "null" && iconUrl != "") {
		icon.image = iconUrl;
	} else {
		if (colorNr == 1 ){
			icon.image = "http://labs.google.com/ridefinder/images/mm_20_yellow.png";
		} else {
			icon.image = "http://labs.google.com/ridefinder/images/mm_20_red.png";
		}
	}
	icon.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png";
	icon.shadowSize = new GSize(22, 20);
	icon.iconAnchor = new GPoint(iconAnchorWidth, iconAnchorHeight);
	icon.infoWindowAnchor = new GPoint(5, 1);

	var marker = new GMarker(point, icon);
	GEvent.addListener(marker, "click", function() {
	  	var nameContent;
	  	var descriptionContent;

	  	if (description != undefined && description != "null" && description != "") {
			descriptionContent = '<br><div style="font-size:10; text-decoration: none;" > '+description + "</div>";
		} else {
			descriptionContent = "";
		}

	  	if (link != undefined && link != "null" && link != "") {
	  		nameContent = '<a href="'+link+'"> <b>' + name + "</b>"+descriptionContent+"</a>";
	  	} else if (name != "null" && name != "" && name != undefined) {
	  		nameContent = "<b>" + name + "</b>"+descriptionContent;
	  	}

	  	var content = nameContent;
	    marker.openInfoWindowHtml(content);
	  });
  return marker;
}

SG.geo.prototype._latLngCallback = function(result, id) {
	var geoMarker = this.geoConfig.geoMarkers[id];
	if (result.Status.code == G_GEO_SUCCESS) {
		this.funcPtr[id] = null;
		var p = result.Placemark[0].Point.coordinates;
		var point = new GLatLng(p[1],p[0]);
		this.map.setCenter(point, this.geoConfig.zoom);
		
		this.map.addOverlay(this._createMarker(point, 0, geoMarker.name, geoMarker.description, geoMarker.link, geoMarker.icon, geoMarker.iconAnchorWidth, geoMarker.iconAnchorHeight));
	} else {
		var address = this._formatAddress(geoMarker.street, geoMarker.postcode, geoMarker.city, geoMarker.country);
		/*var reason="Code "+result.Status.code;
		if (this.reasons[result.Status.code]) {
			reason = this.reasons[result.Status.code]
		} 
		alert('Could not find "' + address + '" ' + reason);*/
  
		if (result.Status.code != G_GEO_UNKNOWN_ADDRESS) {
			var geocoder = new GClientGeocoder();
			geocoder.getLocations(address, this.funcPtr[id]);
		}
	}
}