/**
 * The input map facilitates the marking of a user's geographic location
 */
HYSMaps.InputMap = function (factory, coords, location, clear, icon) {
	
	this.factory = factory; // map factory	
	this.dom = {
		coords: coords, // HTML form element to contain user given coordinates
		location: location, // HTML form element to contain user given locality
		clear: clear // HTML form button to clear location information
	}
	
	this.iconpath = icon;
	
	
	this.geo = new GReverseGeocoder(this.map); // class to lookup locality from lat / long
	
	this.hasLocationField = (this.dom.location == undefined) ? false : true;
};

HYSMaps.InputMap.prototype.initialise = function () {
	
	// select map implementation
	this.map = this.factory.createMap("Microsoft", "Road", "Input");
	if (!this.map) return false;
	
	/*
	TODO: JSON response to populate this as per OutputMap
	*/
	
	// set the map centre
	if (geoData) {
		this.map.setCentre(new HYSMaps.GeoCoords(geoData.lat, geoData.lon), HYSMaps.zoom.maximum);
	}
	else {
		this.map.setCentre();
	}
	if (this.hasLocationField){
		// location alert (DP)
		this.dom.message = document.createElement('span');
		this.dom.message.className = 'location-alert';
		this.dom.location.parentNode.insertBefore(this.dom.message, this.dom.location.nextSibling);
	}
	
	// bind event handlers
	this.map.bind(null, 'mouseup', this, this.onMouseUp);
	
	// Reverse GeoCode fuctionality; bound to Google
	// FIXME:: Abstract away from Google
	this.geodecoder = new GReverseGeocoder(this.map);
	GEvent.bind(this.geo, 'load', this, this.onGeocode); // bind reverse geocode load
	
	this.dom.clear.onclick = this.onClear.bind(this); // bind clear button click
};

HYSMaps.InputMap.prototype.onMouseUp = function (map, event) 
{		
	// create marker if it doesn't exist and the map wasn't dragged but clicked
	if (!this.event && !event.wasMoving) {
		this.event = event;
		event.movedMarker = true;
		marker = this.map.addMarker(new HYSMaps.GeoCoords(event.latitude,event.longitude), new HYSMaps.Icon(this.iconpath, true), false, true, true);

		this.map.redraw();
	}
	if (event.movedMarker) {
		this.dom.coords.value = event.longitude.toFixed(4) + ',' + event.latitude.toFixed(4);
		this.reverseGeocode(new GLatLng(event.latitude, event.longitude));
	}
	
	//alert(event.longitude.toFixed(4) + ',' + event.latitude.toFixed(4));
};

// maintain reference to input map in global scope since JSON callback is in global scope also
var HYSMaps_InputMap;

HYSMaps.InputMap.prototype.reverseGeocode = function(coords) 
{
	// FIXME:: Abstract away from Google
	this.geo.reverseGeocode(coords);
};

HYSMaps.InputMap.reverseGeocodeLoaded = function(data) {
	var self = HYSMaps_InputMap;
	self.onGeocode(data);
};


HYSMaps.InputMap.prototype.onClear = function () { // called when user clicks clear button
	
	this.dom.location.value = '';
	this.dom.message.innerHTML = '';
	
	this.map.clearMarkers();
	this.event = null;
	this.map.redraw();	
};

// called when geocode data is received

HYSMaps.InputMap.prototype.onGeocode = function (data) 
{ 
	if (this.hasLocationField){
		// FIXME:: Abstract away from Google
		var locality = this.geo.getPlacemarkProperty(data, 'LocalityName');
		var subadminarea = this.geo.getPlacemarkProperty(data, 'SubAdministrativeAreaName');
		this.dom.location.value = locality ? locality : subadminarea ? subadminarea : '';
		this.dom.message.innerHTML = 'Not what you expected? Type your location here.'; 
	}
};

HYSMaps.InputMap.prototype.unload = function () {
	
	this.dom.clear.onclick(Function.prototype.unbind); // prevent memory leaks
};