/*
What is the deal with 'var self = this;'?
There are scoping issues in Javascript. Want more info?
http://mikewest.org/archive/component-encapsulation-using-object-oriented-javascript
or http://www.crockford.com/javascript/private.html

If defining a class then just use it to save yourself some nightmares involved
once you start event handling.

DEPENDS ON: jquery
*/

/*
Way to keep track of the points on the map.
*/
var MAPPABLE_POINTS = new Array();
// WAY to configure which id element the map will be in
var MAP_HTML_ID = null;
// Way to keep track of single instance of the controller
var MAP_CONTROLLER = null;

function MappablePoint(lat, lon, key) {
	/*
	We must store a reference to the object so that
	later on when an event fires off then we can
	us things assigned to the object.
	This is probably the kind of thing that drives one crazy about
	javascript. However it is what it is.
	*/
	var self = this;

	self.key = key;
	self.lat = lat;
	self.lon = lon;
	self.glatlng = null;
	self.gmarker = null;
	self.gmarkerOptions = null;
	self.displayed = false;
	self.iconPath = null;
	self.infoWindowHTML = null;
	
	self.setGMarkerOptions = function(options) {
		self.gmarkerOptions = options;
	}
	self.getGPoint = function() {
		if(self.glatlng == null) {
			self.glatlng = new GLatLng(self.lat, self.lon);
		}
		return self.glatlng;
	}
	self.getGMarker = function() {
		if(self.gmarker == null) {
			if(self.gmarkerOptions != null) {
				self.gmarker = new GMarker(self.getGPoint(), self.gmarkerOptions);
			}
			else {
				self.gmarker = new GMarker(self.getGPoint());
			}
		}
		return self.gmarker;
	}
	
	
	self.setIcon = function(iconPath) {
		if(self.displayed) {
			self.getGMarker().setImage(iconPath);
		}
		else {
			console.log('Probably not going to work.. trying to store for later anyway');
			self.iconPath = iconPath;
		}
	}
	
	self.display = function(gmap) {
		gmap.addOverlay(self.getGMarker());
		if(!self.displayed && self.iconPath != null) {
			self.setIcon(self.iconPath);
		}
		self.displayed = true;
	}
	
	self.addListener = function(eventString, callback) {
		/*
		Common event strings: click, mouseout, mouseover
		*/
		GEvent.addListener(self.getGMarker(), eventString, callback);
	}
	
	self.displayInfoWindow = function() {
		if(self.infoWindowHTML != null) {
			self.getGMarker().openInfoWindowHtml(self.infoWindowHTML);
		}
	}

	self.closeInfoWindow = function() {
		self.getGMarker().closeInfoWindow();
	}
	
}

function MapController(googleMap) {
	// Part of class definition
	var self = this;

	self.bounds = new GLatLngBounds();

	self.gmap = googleMap;

	self.gmap.addControl(new GLargeMapControl());
	self.gmap.addControl(new GMapTypeControl());

	self.centerOnPoint = function(point) {
		self.gmap.setCenter(point.getGPoint());
	}
	self.displayPoint = function(point) {
		point.display(self.gmap);
	}
	self.displayMappablePoints = function() {
		// Just tell the points to display themselves
		// since they are all setup with the map.
		for(var i=0; i<MAPPABLE_POINTS.length; i++) {
			point = MAPPABLE_POINTS[i];
			if(typeof(point) != 'undefined') {
				point.display(self.gmap);
				self.bounds.extend(point.getGPoint());
			}
		}
		self.gmap.setZoom(self.gmap.getBoundsZoomLevel(self.bounds));
		self.centerOnBounds();
	}
	
	self.centerOnBounds = function() {
		self.gmap.setCenter(self.bounds.getCenter());
	}

	self.addPoint = function(lat, lon, key) {
		p = new MappablePoint(lat, lon, key);
		// Append it to the list of all mappable points
		// Javascript please give me a damn append method on arrays
		MAPPABLE_POINTS.push(p);
		return p;
	}

	self.findPoint = function(key) {
		for(var i=0; i<MAPPABLE_POINTS.length; i++) {
			point = MAPPABLE_POINTS[i];
			if(point.key == key) {
				return point;
			}
		}
		return null;
	}
}


// Call this function when the page has been loaded
function initializeMap() {
	if(typeof(MAP_HTML_ID) == 'undefined' || MAP_HTML_ID == null) {
		console.log('Varibale MAP_HTML_ID is not set');
		MAP_HTML_ID = 'map';
	}
	var googleMap = new google.maps.Map2(document.getElementById(MAP_HTML_ID));

	if(MAP_CONTROLLER == null) {
		MAP_CONTROLLER = new MapController(googleMap);
	}
}



