/* ---------------------------------------------------------------------
*
* Lanarkshire council maps
* powered by google maps
* by 2Fluid creative 2006 (AB)
*
* Requires: 
*  : prototype [ http://prototype.conio.net/ ] 
*  : pdmarker [ http://www.pixeldevelopment.com/pdmarker.asp#download ]
*
* -------------------------------------------------------------------*/

ppConfig.dMapZoomLevel = ($('mapZoom')) ? parseInt($('mapZoom').value) : ppConfig.dMapZoomLevel;

Lmap={

	/* The actual map
	        - transformations should be called on this */

	/* ----------------------------------------------[ Settings ] */
	scriptUrl:"/maps/fetchData.php",
	startAt: { "lat":null, "long":null, "zoom":null },
	dataTypes: new Array("postcode", "place", "group"),
	divId:null,

	/* ----------------------------------------------[ Init Map ] */
	init: function(event, divId, type, ref, zoom) {

		Lmap.divId = divId;

		// Get Default settings from PP if present
		this.startAt['zoom'] = ppConfig.dMapZoomLevel || 13;
		this.startAt['lat'] = ppConfig.dMapZoomLatitude || "55.7354";
		this.startAt['long'] = ppConfig.dMapZoomLongditude || "-3.8365";

		if (GBrowserIsCompatible()) {

			if(waitingXHR) Element.setOpacity($(waitingId), 0.05);
			if($('ind')) Element.removeClassName($('ind'), "hidden");

			this.map = new GMap2($(divId));
			this.map.addControl(new GLargeMapControl());
			//this.map.addControl(new GOverviewMapControl());
			this.map.addControl(new GMapTypeControl(G_ANCHOR_TOP_RIGHT));

			//if(!type) { this.map.addControl(new GMapTypeControl()); }

			if(ref && zoom) { this.startAt['zoom'] = zoom }

			var qsZoom = this.qs.get('mapZoom');
			if(qsZoom) { this.startAt['zoom'] = parseInt(qsZoom); }

			/* long is a reserved word so quoted incase of probs, others using same method for consistancy */
			this.map.setCenter(new GLatLng(this.startAt['lat'], this.startAt['long']), this.startAt['zoom']);
			
			if(type && ref) {
				Lmap.loadData.start(type, ref);
			} else {
				this.checkUrl();
			}
			this.attachEvents();
		}
	},
	
	attachEvents:function() {
		var mapLinks = document.getElementsByClassName("mapLink");
		for(var i = mapLinks.length-1; i >= 0; --i) {
			Event.observe(mapLinks[i], 'click', Lmap.locationLink, false);
		}

		if($('lmapSearchInput')) { Event.observe('lmapSearchInput', 'blur', Lmap.loadData.fetchSearchData, false); }

		if($('lmapOptions-azLinks')) {
			var azLinks = $('lmapOptions-azLinks').getElementsByTagName("a");
			for(var j = azLinks.length-1; j >= 0; --j) {
				Event.observe(azLinks[j], 'click', Lmap.loadData.fetchAZLinksData, false);
			}
		}
	},
	
	locationLink:function(e) {
		Event.stop(e);
		var type = this.getAttribute("locationType");
		var val = this.getAttribute("locationReference");
		Lmap.loadData.start(type, val);
	},
	
	checkUrl:function() {
		var qsValue = null;
		var dt = this.dataTypes;
		var dtl = dt.length;

		var post = this.qs.get("postcode");
		var town = this.qs.get("place");

		if(post && town) {
			Lmap.loadData.fetchExtendedPlaceData(post, town);
		} else {
			for(var i = 0; i < dtl; i++) {
				qsValue = this.qs.get(dt[i]);
				if(qsValue) {
					this.loadData.start(dt[i], qsValue);
					return;
				}
			}
		}
	},
	
	loadData: {
		start:function(type, val) {
			switch(type) {
				case "postcode":
					this.fetchPostcodeData(val);
					break;
				case "place":
					this.fetchPlaceData(val);
					break;
				case "group":
					this.fetchGroupData(val);
					break;
				default:
					return;
			}
		},
		
		/* Postcode vars found in qs */
		fetchExtendedPlaceData:function(postcode, town) {
			var time = new Date();
			var uri = Lmap.scriptUrl + "?type=ExtendedPlace&postcode=" + postcode + "&town=" + town + "&nocache=" + time.getTime();
			var fetch = new Ajax.Request( uri, { method: 'get', onComplete: Lmap.loadData.parsePostcodeData.bind(this) } );
		},
		parseExtendedPlaceData:function(request) {
			var data = request.responseText.parseJSON();
			if(data['lat'] && data['long']) {
				if(data['zoom']) {
					Lmap.map.setCenter(new GLatLng(Lmap.dms2lat(data['lat']), Lmap.dms2long(data['long'])), data['zoom']);
					
				} else {
					Lmap.map.setCenter(new GLatLng(Lmap.dms2lat(data['lat']), Lmap.dms2long(data['long'])));
					
				}
				if(waitingXHR) {
					Element.setOpacity($(waitingId), 1);
					if($('ind')) Element.addClassName($('ind'), "hidden");
					waitingXHR = false;
				}
			} else {
				Lmap.showError("Error: Could not find postcode. Please adjust your search.");
			}
		},
		
		/* Postcode vars found in qs */
		fetchPostcodeData:function(data) {
			var time = new Date();
			var uri = Lmap.scriptUrl + "?type=postcode&ref=" + data + "&nocache=" + time.getTime();
			var fetch = new Ajax.Request( uri, { method: 'get', onComplete: Lmap.loadData.parsePostcodeData.bind(this) } );
		},
		parsePostcodeData:function(request) {
			var data = request.responseText.parseJSON();
			if(data['lat'] && data['long']) {
				if(data['zoom']) {
					Lmap.map.setCenter(new GLatLng(Lmap.dms2lat(data['lat']), Lmap.dms2long(data['long'])), data['zoom']);
				} else {
					Lmap.map.setCenter(new GLatLng(Lmap.dms2lat(data['lat']), Lmap.dms2long(data['long'])));
				}
				if(waitingXHR) {
					Element.setOpacity($(waitingId), 1);
					if($('ind')) Element.addClassName($('ind'), "hidden");
					waitingXHR = false;
				}
				
			} else {
				Lmap.showError("Error: Could not find postcode. Please adjust your search.");
			}
		},
		
		fetchPlaceData:function(data) {
			var time = new Date();
			var uri = Lmap.scriptUrl + "?type=place&ref=" + data + "&nocache=" + time.getTime();
			var fetch = new Ajax.Request( uri, { method: 'get', onComplete: this.parsePlaceData.bind(this) });
		},
		parsePlaceData:function(request) {
			var data = request.responseText.parseJSON();
			if(data['lat'] && data['long']) {
				if(data['zoom']) {
					Lmap.map.setCenter(new GLatLng(Lmap.dms2lat(data['lat']), Lmap.dms2long(data['long'])), data['zoom']);
				} else {
					Lmap.map.setCenter(new GLatLng(Lmap.dms2lat(data['lat']), Lmap.dms2long(data['long'])));
				}
				if(waitingXHR) {
					Element.setOpacity($(waitingId), 1);
					if($('ind')) Element.addClassName($('ind'), "hidden");
					waitingXHR = false;
				}
			} else {
				Lmap.showError("Error: Could not find that place name. Please check your spelling and try again.");
			}
		},
		

		/* Groups can contain multiple markers 
		     - Lat/Long is set automatically as is zoom */
		fetchGroupData:function(data) {
			var time = new Date();
			var uri = Lmap.scriptUrl + "?type=group&ref=" + data + "&nocache=" + time.getTime();
			var fetch = new Ajax.Request( uri, { method: 'get', onComplete: this.parseGroupData.bind(this) });
		},
		parseGroupData:function(request) {
			var data = request.responseText.parseJSON();
			if(data.markers.length > 0) {
				var mark, marker = null;
				for(var i = data.markers.length-1; i >= 0; --i) {
					mark = data.markers[i];

					// Create new marker on map
					if(mark.icon && mark.title) {
						marker = new PdMarker(new GLatLng(Lmap.dms2lat(mark['lat']), Lmap.dms2long(mark['long'])), Lmap.icon[mark['icon']], mark['title']);
					} else if(mark.icon) {
						marker = new PdMarker(new GLatLng(Lmap.dms2lat(mark['lat']), Lmap.dms2long(mark['long'])), Lmap.icon[mark['icon']]);
					} else if(mark.title) {
						marker = new PdMarker(new GLatLng(Lmap.dms2lat(mark['lat']), Lmap.dms2long(mark['long'])), Lmap.icon[mark['icon']]);
					} else {
						marker = new PdMarker(new GLatLng(Lmap.dms2lat(mark['lat']), Lmap.dms2long(mark['long'])));
					}
					// Additional marker options
					if(mark.html) {
						marker.setDetailWinHTML(mark.html);
					}
					if(mark.hoverImg) {
						marker.setHoverImage(mark.hoverImg);
					}
					map.addOverlay(marker);
				}
				map.zoomToMarkers();
			} else {
				Lmap.showError("Error: Unable to find any matching locations. Please adjust your search.");
			}
		},

		fetchSearchData:function() {
			var time = new Date();
			var data = $('lmapSearchInput').value;
			if(data.length > 0) {
				var uri = Lmap.scriptUrl + "?type=search&ref=" + data + "&nocache=" + time.getTime();
				var fetch = new Ajax.Request( uri, { method: 'get', onComplete: Lmap.loadData.parseSearchData.bind(this) });
			}
		},
		parseSearchData:function(request) {
			var data = request.responseText.parseJSON();
			if(data['lat'] && data['long']) {
				if(data['zoom']) {
					map.setCenter(new GLatLng(Lmap.dms2lat(data['lat']), Lmap.dms2long(data['long'])), data['zoom']);
				} else {
					map.setCenter(new GLatLng(Lmap.dms2lat(data['lat']), Lmap.dms2long(data['long'])));
				}
				if(waitingXHR) {
					Element.setOpacity($(waitingId), 1);
					if($('ind')) Element.addClassName($('ind'), "hidden");
					waitingXHR = false;
				}
			} else {
				Lmap.showError("Error: Your search returned no results. Please try again.");
			}
		},
		
		fetchAZLinksData:function(e) {
			Event.stop(e);

			if(document.all && navigator.userAgent.match(/MSIE/) && !window.opera) {
				var trigger = Event.element(e);
			} else {
				trigger = this;
			}

			var time = new Date();
			var letter = trigger.firstChild.nodeValue;
			var uri = Lmap.scriptUrl + "?type=azlink&ref=" + letter + "&nocache=" + time.getTime();
			var fetch = new Ajax.Request( uri, { method: 'get', onComplete: Lmap.loadData.parseAZLinksData.bind(this) });
		},
		parseAZLinksData:function(request) {
			if(request.responseText == "null") {
				$('lmapOptions-results').innerHTML = "";
				Lmap.showError("Error: Unable to find any matching locations. Please adjust your search.");
				return;
				}
			var data = request.responseText.parseJSON();
			$('lmapOptions-results').innerHTML = "";
			var ul, li, a, txt, zLvl = null;
			ul = document.createElement("ul");
			for(var i = 0; i < data.length; i++) {
				zLvl = data[i].zoomLevel || ppConfig.dTownZoomLevel;
				li = document.createElement("li");
				a = document.createElement("a");
				txt = document.createTextNode(data[i].name);
				a.appendChild(txt);
				a.setAttribute("href", "#");
				a.setAttribute("title", "View " + data[i].name + " on the map");
				a.setAttribute("zoomLevel", zLvl);
				Event.observe(a, 'click', Lmap.loadData.loadAZLink, false);
				li.appendChild(a);
				ul.appendChild(li);
			}
			$('lmapOptions-results').appendChild(ul);
		},
		loadAZLink:function(e) {
			Event.stop(e);

			if(document.all && navigator.userAgent.match(/MSIE/) && !window.opera) {
				var trigger = Event.element(e);
			} else {
				trigger = this;
			}
			if(trigger.getAttribute("zoomLevel")) { map.setZoom(parseInt(trigger.getAttribute("zoomLevel"))); }
			var town = trigger.firstChild.nodeValue;
			Lmap.loadData.start("place", town);
		}
	},
	
	showError:function(msg) {
		var time = new Date();
		time = time.getTime();
		var p = document.createElement("p");
		var txt = document.createTextNode(msg);
		p.appendChild(txt);
		p.setAttribute("id", "LmapErrorMsg" + time);

		if($('lmapError').childNodes.length > 0) {
			$('lmapError').innerHTML = "";
			$('lmapError').insertBefore(p, $('lmapError').firstChild);
		} else {
			$('lmapError').appendChild(p);
		}
		//Fat.fade_element("LmapErrorMsg" + time);
		setTimeout("Lmap.removeError('LmapErrorMsg" + time + "')", 10000);
	},
	
	removeError:function(id) {
		if($(id)) {
			$(id).parentNode.removeChild($(id));
		}
		$('ind').hide();
	},
	
	dms2lat:function(str) {
		var sections = str.split(" ");
		var degrees = sections[0];
		var minutes = sections[1];
		var seconds = sections[2];
		var direction = seconds.charAt(seconds.length);

		return parseFloat(degrees) + (parseFloat(minutes)/60) + (parseFloat(seconds)/3600);
	},
	dms2long:function(str) {
		var parts = str.split(" ");
		
		if(parts[2].indexOf("W") != -1) { return (parseFloat(parts[0]) + (parseFloat(parts[1])/60) + (parseFloat(parts[2])/3600)) * -1; }
		return parseFloat(parts[0]) + (parseFloat(parts[1])/60) + (parseFloat(parts[2])/3600);
	},
	

	icon: {
	
		hospital:function() {
			var icon = new GIcon();
			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.iconSize = new GSize(12, 20);
			icon.shadowSize = new GSize(22, 20);
			icon.iconAnchor = new GPoint(6, 20);
			icon.infoWindowAnchor = new GPoint(5, 1);
			return icon;
		},
		
		school:function() {
			var icon = new GIcon();
			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.iconSize = new GSize(12, 20);
			icon.shadowSize = new GSize(22, 20);
			icon.iconAnchor = new GPoint(6, 20);
			icon.infoWindowAnchor = new GPoint(5, 1);
			return icon;
		},
		
		venue:function() {
			var icon = new GIcon();
			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.iconSize = new GSize(12, 20);
			icon.shadowSize = new GSize(22, 20);
			icon.iconAnchor = new GPoint(6, 20);
			icon.infoWindowAnchor = new GPoint(5, 1);
			return icon;
		}
	
	},
	
	/* ----------------------------------------------[ Querystring ] */
	qs: {
		get:function(name, url) {
			url = url || location.search.substring(1,location.search.length);
			if(url.length == 0) {
				return false;
			} else {
				var pair = null;
				var args = url.split('&');
				for (var i = 0; i < args.length; i++){
					pair = args[i].split("=");
					if(unescape(pair[0]) == name && unescape(pair[1]).length > 0) {
						return unescape(pair[1]);
					}
				}
				return false;
			}
		}
	}
}