//	LBi.Maps v 1.0
//
if ( typeof LBi == 'undefined' ) { self.LBi = {}; }

google.load("maps", "2");

LBi.Maps = {

	PanLimiter : {
		map: null,
		sw: null,
		ne: null,
		bounds: null,
		checkingBounds: false,
		init: function(map, sw, ne) {
			this.map = map;
			google.maps.Event.addListener(map, "drag", function() {LBi.Maps.PanLimiter.checkBounds(arguments,this);});
			google.maps.Event.addListener(map, "zoomend", function() {LBi.Maps.PanLimiter.checkZoom(arguments,this);});
			if (arguments.length < 3) {
				ne = new google.maps.LatLng( 63, 2.2 );
			}
			if (arguments.length < 2) {
				sw = new google.maps.LatLng( 49.9, -10.8 );
			}
			this.sw = sw;
			this.ne = ne;
			this.bounds = new google.maps.LatLngBounds( sw, ne );
		},
		checkZoom: function() {
			var minZoom = this.map.getBoundsZoomLevel(this.bounds);
			var currentZoom = this.map.getZoom();
			if (currentZoom < minZoom) {
				this.map.setZoom(minZoom);
			}
		},
		checkBounds: function() {
			var center = this.map.getCenter();
			var outsideBounds = false;
			var lat = null, lng = null;
			//check lon
			if ( center.lng() > this.ne.lng() ) {
				outsideBounds = true;
				lng = this.ne.lng();
			} else if ( center.lng() < this.sw.lng() ) {
				outsideBounds = true;
				lng = this.sw.lng();
			}
			//check lat
			if ( center.lat() > this.ne.lat() ) {
				outsideBounds = true;
				lat = this.ne.lat();
			} else if ( center.lat() < this.sw.lat() ) {
				outsideBounds = true;
				lat = this.sw.lat();
			}
			if (outsideBounds) {
				if (!this.checkingBounds) {
					this.checkingBounds = true;
					if (lat == null) {
						lat = center.lat();
					}
					if (lng == null) {
						lng = center.lng();
					}
					//set new position
					this.map.setCenter( new google.maps.LatLng(lat, lng) );
					this.checkingBounds = false;
				}
			}
		}
	},
	
	iconLibrary :  [
			{
				type 					: 'leaf',
				numeric					: false,
				image 					: '/assets/img/maps/marker_basic.png',
				keyImage 				: '/assets/img/maps/marker_basic_key.gif',
				alt						: 'Postcode searched on',
				iconWidth				: 34,
				iconHeight				: 60,
				iconOffsetX				: 9,
				iconOffsetY				: 53,
				iconInfoWindowOffsetX 	: 9,
				iconInfoWindowOffsetY 	: 53
			},
			{
				type 					: 'unregistered', 
				numeric					: true,
				image 					: '/assets/img/maps/marker_school_unreg.png',
				keyImage 				: '/assets/img/maps/marker_school_unreg_key.gif',
				alt						: 'School unregistered',
				iconWidth				: 30,
				iconHeight				: 30,
				iconOffsetX				: 0,
				iconOffsetY				: 0,
				iconInfoWindowOffsetX 	: 15,
				iconInfoWindowOffsetY 	: 14
			},
			{
				type 					: 'registered', 
				numeric					: true,
				image 					: '/assets/img/maps/marker_school_reg.png',
				keyImage 				: '/assets/img/maps/marker_school_reg_key.gif',
				alt						: 'School registered - currently working towards leaf target',
				iconWidth				: 30,
				iconHeight				: 30,
				iconOffsetX				: 0,
				iconOffsetY				: 0,
				iconInfoWindowOffsetX 	: 15,
				iconInfoWindowOffsetY 	: 14
			},
			{
				type 					: 'registeredTarget', 
				numeric					: true,
				image 					: '/assets/img/maps/marker_school_regtarget.png',
				keyImage 				: '/assets/img/maps/marker_school_regtarget_key.gif',
				alt						: 'School registered - has achieved leaf target',
				iconWidth				: 30,
				iconHeight				: 30,
				iconOffsetX				: 0,
				iconOffsetY				: 0,
				iconInfoWindowOffsetX 	: 15,
				iconInfoWindowOffsetY 	: 14
			}
	],
	getIcon: function(iconType,index) {
		var maxIndex = 30;
		var iconItem = null;
		var numImgPath = '/assets/img/maps/num_';
		var numImgSuffix = '.png';
		LBi.Maps.iconLibrary.each(function(iconDef){					
			if (iconDef.type == iconType) {
				 iconItem = iconDef;
			}				
		});	
		var icon = null;
		icon = new google.maps.Icon();
		/*if (iconItem.numeric == true && index && index <= maxIndex) {
			var sourceImg = iconItem.image;
			var integerImg = sourceImg.split('.png');
			integerImg = integerImg[0] + '_' + index + '.png';
			icon.image = integerImg;
		} else {
			icon.image = iconItem.image;
		}
		*/
		if (iconItem.numeric == true && index && index <= maxIndex) {
			icon.shadow = iconItem.image;
			icon.shadowSize = new google.maps.Size(iconItem.iconWidth, iconItem.iconHeight);
			icon.image = numImgPath + index + numImgSuffix;
		} else {
			icon.image = iconItem.image;
		}		
		icon.iconSize = new google.maps.Size(iconItem.iconWidth, iconItem.iconHeight);
		icon.iconAnchor = new google.maps.Point(iconItem.iconOffsetX, iconItem.iconOffsetY);
		icon.infoWindowAnchor = new GPoint(iconItem.iconInfoWindowOffsetX,iconItem.iconInfoWindowOffsetY);
		return icon;
	},

	SearchMap : {
		// Requires LBi.quickFinder

		intitialLat						: 54.5,
		intitialLon						: -4.1,
		searchByPostcodeMap				: null,
		jsIdentClass					: 'hasJS',
		mapClass						: 'map',
		resultsClass					: 'results',
		ajaxPath						: '/htmltemplates/modules/stub_quickfinder_map.shtml',

		infoWindowWrapperClass			: 'schoolInfoWindow',
		infoWindowTitleWrapperClass		: 'schoolInfoTitle',
		infoWindowCopyWrapperClass		: 'schoolInfoCopy',
		infoWindowButtonWrapperClass	: 'schoolInfoLink',
		infoWindowButtonID				: 'schoolInfoLinkAction',

		submitImgPath					: '/images/buttons/view_schools_profile.gif',
		submitImgAlt					: "View School's profile",
		submitImgWidth					: 182,
		submitImgHeight					: 37,
		queryStateParameters			: '',
		
		keyClass						: 'mapKey',
		keyHeading						: 'Key:',

		init: function() {
			//
			// Setup initial layout and events for search
			//
			if ( !GBrowserIsCompatible() ) { return false }
			window.onunload=google.maps.Unload;
			if ( !$(LBi.quickFinder.finderID) ) { return false }
			this.finder = $(LBi.quickFinder.finderID);
			if ( !this.finder.hasClass(LBi.quickFinder.identSelectorPostCodeMap) ) { return false }
			this.wrapper = $(LBi.quickFinder.resultsWrapperID);
			this.wrapper.empty(); // Remove pre-populated content from page in default fallback version

			// Add class to handle layout
			this.finder.addClass(LBi.Maps.SearchMap.jsIdentClass);
			// Add wrapper for results content
			this.resultDiv = new Element('div');
			this.resultDiv.addClass(LBi.Maps.SearchMap.resultsClass);
			this.resultDiv.injectInside(this.wrapper);
			// Add scroller to results
			this.resultsScroll = new Fx.Scroll(this.resultDiv, {
				wait: false,
				duration: 500,
				transition: Fx.Transitions.Quad.easeInOut
			});
			// Add empty map
			this.mapDiv = new Element('div');
			this.mapDiv.addClass(LBi.Maps.SearchMap.mapClass);
			this.mapDiv.injectInside(this.wrapper);
			LBi.Maps.SearchMap.insertMap();

			// Setup state tokens
			this.postcodeField = $E(LBi.quickFinder.typeAheadSelector,this.finder);

			// Insert hidden spinner for display on getRemote()
			var spinner = LBi.spinner.buildSpinner();
			spinner.injectInside($(LBi.quickFinder.finderContID));
			
			// Insert map key
			LBi.Maps.SearchMap.buildMapKey().injectInside($(LBi.quickFinder.finderContID));

			// Do search if field is pre-populated
			LBi.Maps.SearchMap.getRemote();
			// Prevent default submission on 'enter' and use getRemote() instead
			this.postcodeField.addEvent('keydown',function(e){
				var e = new Event(e);
				if (e.key == 'enter'){
					e.preventDefault();
					LBi.Maps.SearchMap.getRemote();
				}
			});
			// Add click event to submit button
			$E(LBi.quickFinder.submitSelector,this.finder).addEvent('click',function(e){
				var e=new Event(e).preventDefault();
				LBi.Maps.SearchMap.getRemote();
			});
		},
		
		buildMapKey: function() {
			// Builds the map key from the available icons
			// Available icons specified in LBi.Maps.iconLibrary
			var key = new Element('div');
			if(LBi.Maps.iconLibrary) {
				var iconLibrary = LBi.Maps.iconLibrary;
				key.addClass(LBi.Maps.SearchMap.keyClass);
				
				var heading = new Element('h2');
				heading.setHTML(LBi.Maps.SearchMap.keyHeading);
				heading.injectInside(key);
				
				var icons = new Element('ul');				
				iconLibrary.each(function(iconType){
					var icon = new Element('li');
					var iconImg = new Element('img');
					iconImg.src = iconType.keyImage;
					iconImg.alt = '';
					iconImg.injectInside(icon);
					icon.appendChild(document.createTextNode(iconType.alt));
					icon.injectInside(icons);
				});									
				icons.injectInside(key);
			}
			return key;
		},

		insertMap: function() {
			//
			// Populate mapDiv with initial all-of-UK map, ready for getRemote()
			//
			if ( GBrowserIsCompatible() && this.mapDiv ) {
				searchByPostcodeMap = new google.maps.Map2(this.mapDiv);
				// get the default position for the map...
				this.initialMap = {pos: new google.maps.LatLng(LBi.Maps.SearchMap.intitialLat, LBi.Maps.SearchMap.intitialLon), zoom: 5};
				searchByPostcodeMap.setCenter(this.initialMap.pos, this.initialMap.zoom);
				searchByPostcodeMap.addControl(new GSmallMapControl());
				searchByPostcodeMap.enableScrollWheelZoom();
				// Stop the map moving outside of the UK or near area
				LBi.Maps.PanLimiter.init(this.getMap());
				// Setup event on infoWindow close event to remove listing highlight
				google.maps.Event.addListener(searchByPostcodeMap,"infowindowclose", function() {
					LBi.Maps.SearchMap.highlightListing();
				});
			}
		},
		getMap: function() {
			return searchByPostcodeMap;
		},
		clearMap: function() {
			if (!this.getMap()) { return false }
			this.getMap().clearOverlays();
		},
		resetMap: function() {
			if (!this.getMap()) { return false }
			this.clearMap();
			this.getMap().setCenter(this.initialMap.pos, this.initialMap.zoom);
		},

		getRemote: function() {
			//
			// Get remote data and setup the map markers
			//
			if(!this.postcodeField) { return false }
			if( this.postcodeField.value.trim().length > 0 ){
				// Pick up search string
				var query = this.postcodeField.value;
				var remotePath = LBi.Maps.SearchMap.ajaxPath + "?map=1&text=" + escape(query);
				// Pick up state parameters if present and append to path
				if (LBi.Maps.SearchMap.queryStateParameters) {
					remotePath = remotePath  + LBi.Maps.SearchMap.queryStateParameters;
				}

				// Identify wrapper for spinner display
				var wrapper = $(LBi.quickFinder.finderContID);

				// Get remote data
				var userSearch = new Ajax(remotePath, {
					method: 'get',
					update: this.resultDiv,
					evalScripts: true,
					onRequest: function(){
						LBi.spinner.show(wrapper,true);
					},
					onFailure: function(){
						LBi.spinner.show(wrapper,false);
						LBi.Maps.SearchMap.resultDiv.setHTML(LBi.quickFinder.remoteErrorMsg);
						LBi.Maps.SearchMap.resetMap();
					},
					onComplete: function(){
						LBi.spinner.show(wrapper,false);
						LBi.Maps.SearchMap.showResults();
					}
				}).request();
			}
		},

		showResults: function (markerData) {
			//
			// Build results listing and Plot markers on map
			//

			if( searchResults && searchResults.locale ) {
				this.clearMap();

				// Plot the postcode focus point
				var pos1 = new google.maps.LatLng(searchResults.locale[0].lat, searchResults.locale[0].lon);
				this.getMap().setCenter(pos1, 13);
				var marker = new google.maps.Marker(pos1, {
					icon: LBi.Maps.getIcon("leaf"),
					title: searchResults.locale[0].code
				});
				this.getMap().addOverlay(marker);
				google.maps.Event.addListener(marker, "click", function(){
		          	var html = '<div class="localePinInfoWindow"><h3>' + marker.getTitle() + '<\/h3><\/div>';
					this.openInfoWindow(html, {maxWidth:200});
				});

				// Plot the result markers
				if ( searchResults.results ) {
					var rList = new Element('ul');
					searchResults.results.each(function(searchResult,i){
						var numCount = i+1;
						// Build the marker
						var pos = new google.maps.LatLng(searchResult.lat, searchResult.lon);
						var title = searchResult.name;
						var marker = new google.maps.Marker(pos, {
							icon: LBi.Maps.getIcon(searchResult.type,numCount),
							title: title
						});
						marker.markerLink = searchResult.link;
						marker.newsHeadline = searchResult.newsHeadline;

						// Clear current link in cases of second data call
						if (LBi.quickFinder.activeLink) {
							LBi.quickFinder.activeLink = null;
						}
						// Build the listing
						var listing = new Element('li');
						var listingLink = new Element('a');
						listingLink.href = marker.markerLink;
						listingLink.setHTML('<span class="numCount">' + numCount + '</span> <span class="schoolName">' + searchResult.name + ' </span>' + searchResult.distance);
						listingLink.addEvent('click',function(e){
							var e=new Event(e).preventDefault();
							LBi.Maps.SearchMap.launchInfoWindow(listingLink, marker, false);
						});
						listingLink.addEvent('focus',function(e){
							this.toggleClass(LBi.quickFinder.focusClass);
						});
						listingLink.addEvent('blur',function(e){
							this.toggleClass(LBi.quickFinder.focusClass);
						});
						listingLink.injectInside(listing);
						listing.injectInside(rList);
						
			          	// Give the marker events
						google.maps.Event.addListener(marker, "click", function(){
							LBi.Maps.SearchMap.launchInfoWindow(listingLink, marker, true);
						});

						// Populate map with this marker
						LBi.Maps.SearchMap.getMap().addOverlay(marker);
					});

					// Populate listing
					rList.injectTop(LBi.Maps.SearchMap.resultDiv);					
				}
				//LBi.Custom.ajax.updateBuffer();
			} else {
				this.resetMap();
			}
		},

		highlightListing: function(listingItem,scroll) {
			// Remove highlighting regardless so we can do so where needed
			if (LBi.quickFinder.activeLink) {
				LBi.quickFinder.activeLink.removeClass(LBi.quickFinder.activeClass);
			}
			// If a listing is supplied highlight it
			if(listingItem) {
				LBi.quickFinder.activeLink = listingItem;
				listingItem.addClass(LBi.quickFinder.activeClass);
				if(scroll) {
					this.resultsScroll.toElement(listingItem);
				}
			}
		},
		launchInfoWindow: function(listingLink, marker, scroll) {
			var html = LBi.Maps.SearchMap.handleInfoWindowContent(marker);
			marker.openInfoWindow(html, {maxWidth:200});
			LBi.Maps.SearchMap.highlightListing(listingLink, scroll);
			// Removed focusing as it causes the page to jump
			//$('schoolInfoLinkAction').focus();
		},
		handleInfoWindowContent : function (marker) {
			if(!marker || !marker.markerLink) { return false }

			var html = new Element('div');
			html.addClass(this.infoWindowWrapperClass);
			var heading = new Element('h3');
			heading.addClass(this.infoWindowTitleWrapperClass);
			heading.setHTML(marker.getTitle());
			heading.injectInside(html);
			// Add optional headline
			if(marker.newsHeadline) {
				var optText = new Element('p');
				optText.addClass(this.infoWindowCopyWrapperClass);
				optText.setHTML(marker.newsHeadline);
				optText.injectInside(html);
			}
			// Setup correct button depending on tokens
			var schoolLinkPara = new Element('p');
			schoolLinkPara.addClass(this.infoWindowButtonWrapperClass);
			var schoolLink = new Element('a');
			schoolLink.id = this.infoWindowButtonID;
			schoolLink.href = marker.markerLink;
			var schoolLinkImg = new Element('img');
			schoolLinkImg.src = this.submitImgPath;
			schoolLinkImg.alt = this.submitImgAlt;
			schoolLinkImg.width = this.submitImgWidth;
			schoolLinkImg.height = this.submitImgHeight;
			schoolLinkImg.injectInside(schoolLink);
			schoolLink.injectInside(schoolLinkPara);
			schoolLinkPara.injectInside(html);

			return html;
		}

	}, /* /LBi.Maps.SearchMap */

	QuickMaps : {

		zoomLevel			: 15,
		enlargeText			: 'click to enlarge map \u00BB',
		viewSchoolText		: 'View your school \u00BB',
		enlargeTriggerClass	: 'largeMapTrigger',
		viewSchoolClass		: 'viewSchool',

		popUpWrapperClass	: 'mapPopup',
		popUpInnerClass		: 'mapPopupInner',
		popMapClass			: 'largeMap',
		popUpCloseClass		: 'close',
		popUpCloseTxt		: 'Close',

		createMarker: function(posn) {
			var marker = new google.maps.Marker(posn,LBi.Maps.getIcon('leaf'));
			return marker;
		},
		doMap: function(target,lat,lng) {
			if ( GBrowserIsCompatible() && target && lat && lng ) {
				// Setup map
				var target = $(target);
				var map = new google.maps.Map2(target);
				var latlng = new google.maps.LatLng(lat,lng);
				map.setCenter(latlng, LBi.Maps.QuickMaps.zoomLevel);
				map.addOverlay(LBi.Maps.QuickMaps.createMarker(latlng));
				map.disableDoubleClickZoom()
				google.maps.Event.addListener(map, "dblclick", function() {
					LBi.Maps.QuickMaps.enlargeMap(target,lat,lng);
				});

				// Setup enlarge map behaviour or if home page setup View your school link
				if ($$('body')[0].hasClass('home') && window.viewYourSchoolLink && window.viewYourSchoolLink != null) {
					var viewSchool = new Element('p');
					viewSchool.addClass(LBi.Maps.QuickMaps.viewSchoolClass);
					var viewSchoolLink = new Element('a');
					viewSchoolLink.href = window.viewYourSchoolLink;						
					viewSchoolLink.setText(LBi.Maps.QuickMaps.viewSchoolText);
					viewSchoolLink.injectInside(viewSchool);
					viewSchool.injectBefore(target);
				}
				else {
					var enlargeMe = new Element('p');
					enlargeMe.addClass(LBi.Maps.QuickMaps.enlargeTriggerClass);
					var enlargeMeLink = new Element('a');
					enlargeMeLink.href = '#';
					enlargeMeLink.setText(LBi.Maps.QuickMaps.enlargeText);
					enlargeMeLink.addEvent('click',function(e){
						var e=new Event(e).preventDefault();
						LBi.Maps.QuickMaps.enlargeMap(target,lat,lng);
					});
					enlargeMeLink.injectInside(enlargeMe);
					enlargeMe.injectBefore(target);
				}
			}
		},
		enlargeMap: function(source,lat,lng) {

			var popUp = new Element('div');
			popUp.addClass(LBi.Maps.QuickMaps.popUpWrapperClass);
			var popUpInner = new Element('div');
			popUpInner.addClass(LBi.Maps.QuickMaps.popUpInnerClass);
			popUpInner.injectInside(popUp);

			var vcard = $E('.vcard',source.getParent()).clone();
			vcard.injectInside(popUpInner);

			var closeMe = new Element('p');
			closeMe.addClass(LBi.Maps.QuickMaps.popUpCloseClass);
			var closeMeLink = new Element('a');
			closeMeLink.href = '#';
			closeMeLink.setText(LBi.Maps.QuickMaps.popUpCloseTxt);
			closeMeLink.addEvent('click',function(e){
					popUp.remove();
				});
			closeMeLink.injectInside(closeMe);
			closeMe.injectInside(popUpInner);

			var gMap = new Element('div');
			gMap.addClass(LBi.Maps.QuickMaps.popMapClass);
			gMap.injectInside(popUpInner);

			popUp.injectAfter(source);

			// Setup large map
			var map2 = new google.maps.Map2(gMap);
			var latlng2 = new google.maps.LatLng(lat,lng);
			map2.setCenter(latlng2, LBi.Maps.QuickMaps.zoomLevel);
			map2.addOverlay(LBi.Maps.QuickMaps.createMarker(latlng2));
			map2.addControl(new google.maps.LargeMapControl());
			LBi.Maps.PanLimiter.init(map2);

		}

	} /* /LBi.Maps.QuickMaps */

}/* /LBi.Maps */
