/**
 * @author Marco Alionso Ramirez, marco@onemarco.com
 * @url http://onemarco.com
 * This code is public domain
 */

//load and unload the map
GEvent.addDomListener(window,'load',loadGeoCoder);
GEvent.addDomListener(window,'unload',GUnload);

//check for google maps compatibility, if so, load xml
function loadGeoCoder(){
	if(!GBrowserIsCompatible()){
		alert('Sorry, the Google Maps API is not compatible with this browser.');
		return;
	}else{
		createMap();
	}
}

//create map icon and sidebar
function createMap(){
	
	var map = new GMap2(document.getElementById('map'));
	map.setCenter(new GLatLng(13,-21),2);
	map.addControl(new GMapTypeControl());
	map.addControl(new GLargeMapControl());
	
	var icon = new GIcon();
	icon.image = "/examples/Geocoder/marker.png";
	icon.shadow = "/examples/Geocoder/marker_shadow.png";
	icon.iconSize = new GSize(20, 26);
	icon.shadowSize = new GSize(32, 28);
	icon.iconAnchor = new GPoint(10, 25);
	icon.infoWindowAnchor = new GPoint(10, 0);
	icon.infoShadowAnchor = new GPoint(25, 7);
	
	var sidebarList = document.getElementById('historyItems');
	var addressForm = document.getElementById('addressForm');
	var markerForm = document.getElementById('markerForm');
	var coder = new GClientGeocoder();
	
	GEvent.addDomListener(addressForm,'submit', function(evt){
		evt = standardizeEvent(evt);
		evt.preventDefault();
		getCoordinates.call(map,addressForm,coder,icon,sidebarList);
	});
	
	GEvent.addDomListener(markerForm,'submit', function(evt){
		evt = standardizeEvent(evt);
		evt.preventDefault();
		createDraggableMarker.call(map,markerForm,icon,sidebarList);
	})
}

//request coordinates
function getCoordinates(form,coder,icon,list){
	var map = this;
	var cb = function(response){
		processCoordinates.call(map,response,icon,list);
	}
	if(form.batchSeparator.value.length > 0){
		var inputs = form.addressInput.value.split(form.batchSeparator.value);
		for(var i in inputs){
			coder.getLocations(inputs[i],cb);
		}
	}else{
		coder.getLocations(form.addressInput.value,cb);
	}
	//coder.getLocations(form.addressInput.value,cb);
}
var x = '';

//process coordinates
function processCoordinates(locations,icon,list){
	if(locations.Status.code != G_GEO_SUCCESS){
		list.appendChild(jsonToDom({
			el:'li',att:{Class:'error'},ch:[
				{txt:locations.name + ' '},
				{el:'span',ch:[
					{txt:'(Error: ' + locations.Status.code + ')'}
				]}
			]
		})); //('Error: ' + locations.Status.code);
		return;
	}
	for(var i = 0; i < locations.Placemark.length; i++){
		createMarker.call(this,locations,locations.Placemark[i],icon,list);
	}
}

//create a draggable marker
function createDraggableMarker(form,icon,list){
	var name = /^\s*$/.test(form.markerInput.value) ? '[unnamed]' : form.markerInput.value;
	var coords = this.getCenter();
	var placemark =
		{Point:
			{coordinates:[coords.lng(),coords.lat()]},
		address:name};
	createMarker.call(this,{name:name},placemark,icon,list,true);
}

//create the marker
function createMarker(locations,placemark,icon,list,draggable){
	var lat = placemark.Point.coordinates[1];
	var lng = placemark.Point.coordinates[0];
	
	var opts = draggable ? {draggable:true,icon:icon} : {icon:icon};
	var marker = new GMarker(new GLatLng(lat,lng),opts);
	marker.tooltip = new Tooltip(marker,lat + ', ' + lng,5);
	createTab(marker,placemark.address,lat,lng,draggable);
	marker.isInfoWindowOpen = false;
	
	var sidebarLink = jsonToDom({
		el:'li',ch:[
			{txt:locations.name + ' '},
			{el:'span',att:{Class:'geocode'},ch:[
				{txt:'(' + lat + ', ' + lng + ')'}
			]}
		]});
	list.appendChild(sidebarLink);
	
	var ttmover = GEvent.callbackArgs(marker,tooltipMouseover,sidebarLink);
	var ttmout = GEvent.callbackArgs(marker,tooltipMouseout,sidebarLink);
	var mclick = GEvent.callback(marker,markerClick);
	
	GEvent.addDomListener(sidebarLink,'mouseover',ttmover);
	GEvent.addDomListener(sidebarLink,'mouseout',ttmout);
	GEvent.addDomListener(sidebarLink,'click',mclick);	
	GEvent.addListener(marker,'mouseover',ttmover);
	GEvent.addListener(marker,'mouseout',ttmout);
	GEvent.addListener(marker,'click',mclick);
	GEvent.addListener(marker,'infowindowopen',GEvent.callbackArgs(marker,infoWindowOpen,sidebarLink));
	GEvent.addListener(marker,'infowindowclose',GEvent.callbackArgs(marker,infoWindowClose,sidebarLink));
	if(draggable){
		GEvent.addListener(marker,'dragstart',GEvent.callbackArgs(marker,markerDragStart,this,sidebarLink));
		GEvent.addListener(marker,'dragend',GEvent.callbackArgs(marker,markerDragged,sidebarLink.getElementsByTagName('span')[0]));
	}
	
	this.addOverlay(marker);	
	this.addOverlay(marker.tooltip);
	this.setCenter(marker.getPoint());
	
	return marker;
}

//create the tab(s) for the GInfoWindow
function createTab(marker,address,lat,lng){
	var element = jsonToDom(
		{el:'div',att:{Class:'googleMarkerTab'},ch:[
			{el:'div',att:{Class:'address'},ch:[
				{txt:address}
			]},
			{el:'input',att:{Class:'coordinates',readOnly:'readonly',value:lat + ', ' + lng}
			}
		]});
	marker.tab = [new GInfoWindowTab('Address',element)];
	marker.coords = element.getElementsByTagName('input')[0];
}

//makrer,sidebar mouseover handler
function tooltipMouseover(sidebarLink){
	if(!(this.isInfoWindowOpen) && !(this.isHidden())){
		this.tooltip.show();
		if(sidebarLink) addClassToElement(sidebarLink,'hover');
	}
}

//marker,sidebar mouseout handler
function tooltipMouseout(sidebarLink){
	this.tooltip.hide();
	if(sidebarLink) removeClassFromElement(sidebarLink,'hover');
}

//marker click handler
function markerClick(){
	this.tooltip.hide();
	this.openInfoWindowTabs(this.tab);
}

//infowindowopen handler
function infoWindowOpen(sidebarLink){
	this.isInfoWindowOpen = true;
	removeClassFromElement(sidebarLink,'hover');
	addClassToElement(sidebarLink,'active');	
}

//infowindowclose handler
function infoWindowClose(sidebarLink){
	this.isInfoWindowOpen = false;
	removeClassFromElement(sidebarLink,'active');
}

//clear tooltip,infowindow when marker is dragged
function markerDragStart(map,sidebarLink){
	removeClassFromElement(sidebarLink,'hover');
	map.closeInfoWindow();
	this.tooltip.hide();
}

//update coordinates after marker has been dragged
function markerDragged(geocode){
	var coords = this.getPoint();
	clearChildren(this.tooltip.div_);
	this.tooltip.div_.appendChild(document.createTextNode(
		coords.lat() + ', ' + coords.lng()));
	this.tooltip.redraw(true);
	this.coords.value = coords.lat() + ', ' + coords.lng(); 
	clearChildren(geocode);
	geocode.appendChild(document.createTextNode('(' + coords.lat() + ', ' + coords.lng() + ')'));
}