/**
 * Object to contain the google map marker stuff
 */

function showDirectionsFromHere(){
	var footerNode = document.getElementById('popup-footer');
	markertools.infoWindowShowFrom = false;
	markertools.infoWindowShowTo = true;
	var sHtml = markertools.getDirectionsHtml();
	footerNode.innerHTML = sHtml;
	Event.onAvailable('infoWindowInput', function(){
		markertools.initAutocompleteAddress('infoWindowInput', 'infoWindowInputSuggestions');
	});
}

function showDirectionsToHere(){
	var footerNode = document.getElementById('popup-footer');
	markertools.infoWindowShowFrom = true;
	markertools.infoWindowShowTo = false;
	var sHtml = markertools.getDirectionsHtml();
	footerNode.innerHTML = sHtml;
	Event.onAvailable('infoWindowInput', function(){
		markertools.initAutocompleteAddress('infoWindowInput', 'infoWindowInputSuggestions');
	});
}

/** called when the "to" or "from" directions links are clicked in the info window. */
function callbackInfoWindowShowLinkClicked(event, data) {
	var marker = findMarker(data.id);
	marker.showInfoWindowInputField(data.showTo); //recreates the info window
	Event.stopEvent(event); //stops the href=# action
}


function GoogleMapMarkerTools() {

	var me = this; // reference to this object (avoids the nasty "this doesn't mean this!" js quirk)

	this._googlemap = null;
	this._map = null;
	this._baseIcon = null;

	this._searchResults = new Array();
	this._all_markers = new Array();

	this.min_zoom = 12;

	this.pois_markers = {
		carparks : null,
		atms : null,
		petrol : null,
		cafes : null
	};
	this.checkboxes = {
		carparks : 'featureControlPARKING_AREA',
		atms : 'featureControlATM',
		petrol : 'featureControlPETROL_STATION',
		cafes : 'featureControlCAFES'
	}

	this._offset = new GSize(0, -25);
	this._infoShownLoc;

	this._subdomain = 'www';

	this.site = 'finda';

	if(typeof isMenus !== 'undefined' && isMenus){
		this.site = 'menus';
	}

	this.init = function(googlemap, searchResults) {
		this._googlemap = googlemap;
		this._map = this._googlemap.map;

		if (searchResults && typeof searchResults == 'object' && searchResults.length) {
			this._searchResults = searchResults;
		}
		
		this._baseIcon = new GIcon();
		this._baseIcon.image = '/images/';
		this._baseIcon.iconAnchor = new GPoint(11, 24);
		this._baseIcon.iconSize = new GSize(21, 24);
		this._baseIcon.infoWindowAnchor = new GPoint(11, 0);
		this._baseIcon.transparent = '/images/icons/trans.png';
		this._baseIcon.imageMap = [0, 0, 21, 0, 21, 24, 0, 24];

		this.addSearchResultMarkers();
		this.addHandlers();

		this._subdomain = window.location.hostname.split('.')[0];
	}

	this.findaSearchMarker = function(point, data) {
		data.icon_filename = 'icons/'+data.icon_filename;
		return this.findaPOIMarker(point, data);
	}
	this.findaPOIMarker = function(point, data) {
		var properties = {title:this.cleanTitle(data.name)};
		var icon = this._getIcon(data.icon_filename);
		this.data = data;
		if (icon) {
			properties.icon = icon;
		}
		var marker = new GMarker(point, properties);
		if (data.slug) {
			marker.html = this.getBusinessDetailHtml(data, marker);
		} else if (data.icon_filename && data.icon_filename == 'icon-traffic-cam.gif') {
			marker.html = this.getTrafficHTML(data);
			GEvent.addListener(marker, "click", function() {me.setTrafficRefresh(data.id);} );
			GEvent.addListener(this._map, "infowindowclose", function() {me.stopTrafficRefresh();} );
		} else {
			marker.html = '<p><strong>'+data.name+'</strong></p>';
			if (data.html_address) {
				marker.html += data.html_address;
			}
		}
		marker.openInfoWin = function() {
			me.openInfoWindowHtml(this.getLatLng(), this.html);
		};
		GEvent.addListener(marker, "click", function() {this.openInfoWin();} );
		
		return marker;
	}

	this.getDirectionsHtml = function(){
		var sHtml;
		sHtml = '';

		if (this.infoWindowShowTo) {
			sHtml += '<label>Destination</label>';
		}
		else if (this.infoWindowShowFrom) {
			sHtml += '<label>Starting Point</label>';
		}
		if (this.infoWindowShowFrom || this.infoWindowShowTo) {
			sHtml += '<input id="infoWindowInput" type="text" />' +
					'<img class="go" id="infoImage" src="/images/button_go.gif" alt="Go!" /><br style="clear:both" />'+
					'<div id="infoWindowInputSuggestions"></div>';

			Event.onAvailable("infoImage", function() {
				Event.addListener("infoImage", "click", function() {
					markertools.infoWindowDirectionsSearch();
				});
			});
			Event.onAvailable("infoWindowInput", function() {
				initWaterMark(this.id, '604 Great South Road, Ellerslie');
			});
		}

		return sHtml;
	}

	this.infoWindowDirectionsSearch = function() {
		var search = $('infoWindowInput').valueOrWaterMark();
		if(this.infoWindowShowTo) {
			window.location.pathname = '/d/'+getAddrLength(this.data.full_address)+getAddrLength(search)+'/'+encodeAddressComponent(this.data.full_address)+'/'+encodeAddressComponent(search)+'/';
		} else {
			window.location.pathname = '/d/'+getAddrLength(search)+getAddrLength(this.data.full_address)+'/'+encodeAddressComponent(search)+'/'+encodeAddressComponent(this.data.full_address)+'/';
		}
	}

	this.initAutocompleteAddress = function(sourceId, resultsId){
		var oAutoCompleteDSInfo = new YAHOO.widget.DS_XHR('/address_proxy.php', ['results', 'full_address']);
		oAutoCompleteDSInfo.scriptQueryParam = "address";
		oAutoCompleteDSInfo.scriptQueryAppend = "countitem=1&counttype=available";

		var oSearchAutoComp = new YAHOO.widget.AutoComplete(sourceId
				, resultsId
				, oAutoCompleteDSInfo);
		oSearchAutoComp.autoHighlight = false;
		oSearchAutoComp.animVert = false;
		oSearchAutoComp.queryDelay = 0;
		oSearchAutoComp.minQueryLength = 3;
		oSearchAutoComp.maxResultsDisplayed	= 11;
		oSearchAutoComp.formatResult = onFormatAddressResult;

		oSearchAutoComp.itemSelectEvent.subscribe(function(sType, aArgs){markertools.autocomplete_data = aArgs[2][1];});
	}

	this.addBusinessMarker = function(point, business) {
		this._googlemap.setMarkerManager(new SimpleMarkerManager(this._map)); // reset to use the simple marker manager
		business.icon_filename = null;
		var marker = this.findaPOIMarker(point, business);
		this._googlemap.addMarker(marker, 0);
		this._googlemap.setCenter(point, this._googlemap.maxZoom() - 2); // back off a bit
		this._map.savePosition();
	}
	this._getIcon = function(filename) {
		var icon;
		if (filename) {
			icon = new GIcon(this._baseIcon);
			icon.image = filename.search(new RegExp('^https?://', 'i')) != -1 ? filename : icon.image + filename;
		}
		return icon;
	}

	this.openInfoWindowHtml = function(point, html) {
		this._map.openInfoWindowHtml(point, html, {noCloseOnClick:true, pixelOffset:this._offset, maxWidth:300});
		this._infoShownLoc = point;
	}

	this.getBusinessDetailHtml = function(data, marker) {
		var html = '';
		switch(this.site) {
			case 'wises': {
				html = this._getWisesBusinessHtml(data, marker);
				break;
			}
			case 'yellowvouchers': {
				html = this._getYellowVouchersHtml(data);
				break;
			}
			case 'menus': {
				html = this._getMenusBusinessHtml(data);
				break;
			}
			case 'finda':
			default: {
				html = this._getFindaBusinessHtml(data);
			}
		}
		return html;
	}
	this._getFindaBusinessHtml = function(data) {
		var sHtml = '<div class="info-window">';
		var more_info_url = '/business/listing/'+data.id+'/'+data.slug+'/';
		sHtml += '<a class="name" href="'+ more_info_url+'" >'
				+ '<strong>'+ data.name+'</strong></a>';
		if (data.wises_image && data.wises_image.length !== 0 && data.listing_type >= 4) {
			if (this._infoAdvertIsFlash(data)) {
				if (data.listing_type == 6 || data.listing_type == 5) {
					sHtml += '<div id="FlashAdvert"></div>';
				}
			} else {
				sHtml += '<img class="thumb" src="http://'+this._subdomain+'.finda.co.nz/images/thumb/'+ data.wises_image+'/80x60/'+ data.slug+'.jpg" />';
			}
		}

		sHtml += '<div class="info">';
		sHtml += data.html_address;

		if (data.phone_number) {
			sHtml += '<em><tel>Tel ' + data.phone_number+ '</tel></em>';
		}
		sHtml += '<a class="more" href="'+ more_info_url+'" >More info</a>';
		sHtml += '</div>';

		sHtml += '<div class="popup-footer" id="popup-footer">';

		var iRating = data.rating;

		for (var i=0; i<iRating; i++) {
			sHtml += '<img src="/images/icons/review-star-full.png" alt="" />';
		}
		for (i=iRating; i<5; i++) {
			sHtml += '<img src="/images/icons/review-star-empty.png" alt="" />';
		}
		if (iRating === 0) {
			sHtml += '&nbsp;(Not reviewed)';
		} else {
			sHtml += '&nbsp;&nbsp;<a href="http://'+this._subdomain+'.finda.co.nz/business/listing/'+ data.id+'/'+ data.slug+'/review/">Read reviews</a>';
		}
		sHtml += '&nbsp;&nbsp;<a href="http://'+this._subdomain+'.finda.co.nz/business/listing/'+data.id+'/'+data.slug+'/#myRating">Write review</a><br/>';
		if(typeof toUrl !== 'undefined' && typeof fromUrl !== 'undefined' && toUrl && fromUrl){
			sHtml += '<div class="directions">Get directions: ';
			sHtml += '<a href="'+toUrl+'">To here</a> - <a href="'+fromUrl+'">From here</a>';
			sHtml += '</div>';// .directions
		}else{
			sHtml += '<div class="directions">Get directions: ';
			sHtml += '<a href="#" id="infoWindowLinkTo" onclick="showDirectionsToHere()">To here</a> - <a href="#" id="infoWindowLinkFrom" onclick="showDirectionsFromHere()">From here</a>';
			sHtml += '</div>';// .directions
		}
		sHtml += '</div>';// .popup-footer
		sHtml += '</div>';// .info-window
		return sHtml;
	}


	this._getMenusBusinessHtml = function(data) {
		var sHtml = '<div class="info-window">';
		var more_info_url = '/listing/'+data.id+'/'+data.slug+'/';
		sHtml += '<a class="name" href="'+ more_info_url+'" >'
				+ '<strong>'+ data.name+'</strong></a>';
		if (data.wises_image && data.wises_image.length !== 0 && data.listing_type >= 4) {
			if (this._infoAdvertIsFlash(data)) {
				if (data.listing_type == 6 || data.listing_type == 5) {
					sHtml += '<div id="FlashAdvert"></div>';
				}
			} else {
				sHtml += '<img class="thumb" src="http://'+this._subdomain+'.finda.co.nz/images/thumb/'+ data.wises_image+'/80x60/'+ data.slug+'.jpg" />';
			}
		}

		sHtml += '<div class="info">';
		sHtml += data.html_address;

		if (data.phone_number) {
			sHtml += '<em><tel>Tel ' + data.phone_number+ '</tel></em>';
		}
		sHtml += '<a class="more" href="'+ more_info_url+'" >More info</a>';
		sHtml += '</div>';

		sHtml += '<div class="popup-footer" id="popup-footer">';

		var iRating = data.rating;

		for (var i=0; i<iRating; i++) {
			sHtml += '<img src="/images/icons/review-star-full.png" alt="" />';
		}
		for (i=iRating; i<5; i++) {
			sHtml += '<img src="/images/icons/review-star-empty.png" alt="" />';
		}
		if (iRating === 0) {
			sHtml += '&nbsp;(Not reviewed)';
		} else {
			sHtml += '&nbsp;&nbsp;<a href="http://'+this._subdomain+'.menus.co.nz/listing/'+ data.id+'/'+ data.slug+'/#read_reviews">Read reviews</a>';
		}
		sHtml += '&nbsp;&nbsp;<a href="http://'+this._subdomain+'.menus.co.nz/listing/'+data.id+'/'+data.slug+'/#write_review">Write review</a><br/>';

		sHtml += '</div>';// .popup-footer
		sHtml += '</div>';// .info-window
		return sHtml;
	}



	this.showInfoWindowInputField = function(bToAddress) {
		this.infoWindowShowTo = bToAddress;
		this.infoWindowShowFrom = !bToAddress;

		this.showInfoWindow();

		var iFeatureId = this.id;
		Event.addListener('infoWindowInput', 'keypress', function(oEvent) {
					if (Event.getCharCode(oEvent) == 13) {
						var marker = findMarker(iFeatureId);
						marker.infoWindowDirectionsSearch();
					}
				});

		var oAutoCompleteDSInfo = new YAHOO.widget.DS_XHR('/address_proxy.php', ["results", "full_address"]);
		oAutoCompleteDSInfo.scriptQueryParam = "address";
		oAutoCompleteDSInfo.scriptQueryAppend = "countitem=1&counttype=available";

		var oSearchAutoComp = new YAHOO.widget.AutoComplete("infoWindowInput"
				, "infoWindowInputSuggestions"
				, oAutoCompleteDSInfo);
		oSearchAutoComp.autoHighlight = false;
		oSearchAutoComp.animVert = false;
		oSearchAutoComp.queryDelay = 0;
		oSearchAutoComp.minQueryLength = 3;
		oSearchAutoComp.maxResultsDisplayed	= 11;
		oSearchAutoComp.formatResult = onFormatAddressResult;
	};

	this._getWisesBusinessHtml = function(data, marker) {
		data.listing_type = data.product_id;
		marker.type = 'business';
		marker.data = data;
		markersObj[marker.data.id] = marker;
		return '<div id="mapBubble">'+marker.getBusinessDetailHtml()+'</div>';
	}
	this._getYellowVouchersHtml = function(data) {
		var sHtml = '<div class="info-window">';

		sHtml += '<strong>'+ data.name+'</strong>';
		if (data.wises_image && data.wises_image.length !== 0 && data.listing_type >= 4) {
				if (this._infoAdvertIsFlash(data)) {
						if (data.listing_type == 6 || data.listing_type == 5) {
								sHtml += '<div id="FlashAdvert"></div>';
						}
				} else {
						sHtml += '<img class="thumb" src="http://'+this._subdomain+'.finda.co.nz/images/thumb/'+ data.wises_image+'/80x60/'+ data.slug+'.jpg" />';
				}
		}

		sHtml += '<div class="info">';
		sHtml += data.html_address;

		if (data.phone_number) {
				sHtml += '<em><tel>Tel ' + data.phone_number+ '</tel></em>';
		}
		sHtml += '</div>';

		sHtml += '<div class="popup-footer">';

		var iRating = data.rating;

		sHtml += '<a class="direction" href="'+'http://www.wises.co.nz/p/'+data.slug+'/'+data.id+'/" > Get driving directions at wises.co.nz</a><br />' + '</div>';
		sHtml += '</div>';
		return sHtml;

	}
	
	this._infoAdvertIsFlash = function(data) {
		if (data.image_mime_type.search(/shockwave/) != -1) {
			return true;
		}
		return false;
	}
	this.showFlashAdvert = function(data) {
		var sImageFilename = data.wises_image;
		var sFlashUrl = '/media/'
				+ sImageFilename.substr(sImageFilename.length-3,1)+'/'
				+ sImageFilename.substr(sImageFilename.length-2,1)+'/'
				+ sImageFilename.substr(sImageFilename.length-1,1)+'/'
				+ sImageFilename+'.swf';
		var oSwf = new SWFObject(sFlashUrl, "finda", "100", "76", "7");
		oSwf.addParam("wmode","transparent");
		oSwf.write("FlashAdvert");
	}

	this.getTrafficHTML = function(data) {
		var date = new Date();
		this.oTime = date.getTime();
		var srcString = this.oTime.toString(16);
		var sHtml = '';
		sHtml += '<div>\n\
					<img class="thumb" width="352" height="288" src="/traffic/image/'+data.id +'_' + srcString +'.jpg"  name="traffic_cam'+data.id+'" id="traffic_cam'+data.id+'" />\n\
				</div>';
		sHtml += '<div style="float:right; clear: both; width:100%">\n\
					<label style="float:left; font-size:10px">'+data.name+'</label>&nbsp;\n\
					<label style="float:right;font-size:9px">Image will refresh in <strong id="cameraRemainTime_'+data.id+'">60</strong> seconds</label>\n\
				</div>';
		return sHtml;
	};
	this.setTrafficRefresh = function(id) {
		if (me.camera_interval) {
			clearInterval(me.camera_interval);
			var date = new Date();
			me.oTime = date.getTime();
		}
		me.camera_interval = setInterval("markertools.refreshTrafficInfo('"+id+"')", 1000);
	}
	this.stopTrafficRefresh = function() {
		if (me.camera_interval) {
			clearInterval(me.camera_interval);
			var date = new Date();
			me.oTime = date.getTime();
		}
	}
	this.refreshTrafficInfo = function(id) {
		var traffic_item = 'traffic_cam' + id;
		var timeoutItem = 'cameraRemainTime_' + id;
		if (!$(traffic_item)) return;
		var date = new Date();
		var time = date.getTime();
		if (time < me.oTime) return;
		if (60 - Math.round((time-this.oTime)/1000) <= 0) {
			var srcString = time.toString(16);
			$(traffic_item).src = '/traffic/image/' +id +'_'+ srcString +'.jpg';
			me.oTime = time;
		} else {
			$(timeoutItem).innerHTML = 60 - Math.round((time-me.oTime)/1000);
		}
	}

	this.addSearchResultMarkers = function() {
		if(this._all_markers.length > 0){
			for(var i=0; i<this._all_markers.length; i++){
				this._googlemap.removeMarker(this._all_markers[i]);
			}
			this._all_markers = new Array();
		}
		if (this._searchResults.length > 0) {
			var view = new GLatLngBounds();
			var businesses = this._searchResults;
			for (var i=0; i<businesses.length; i++) {
				var business = businesses[i];
				if(business.lat*1!=0 && business.lat*1!=0){
					var p = new GLatLng(business.lat*1, business.lng*1);
					if (!view.containsLatLng(p)) {
						view.extend(p);
					}
					var marker = this.findaSearchMarker(p, business);
					this._all_markers[this._all_markers.length] = marker;
				}
			}
			var zoom = this._map.getBoundsZoomLevel(view);
			this._googlemap.setCenter(view.getCenter(), zoom);
			this._googlemap.addMarkers(this._all_markers, 0);
			this._map.savePosition();
		}
	}

	this.refreshPOIs = function() {
		for (var i in me.checkboxes) {
			var elem = document.getElementById(me.checkboxes[i]);
			if (elem) {
				var li = elem.parentNode.parentNode;
				if (me._map.getZoom() >= me.min_zoom) { // skip if the zoom is too low
					if (elem.disabled) {
						elem.disabled = false;
						li.title = '';
					}
					if (elem.checked || me.pois_markers[i] != null) {
						me.getPOIs(i);
					}
				} else if (!elem.disabled) {
					elem.disabled = true;
					li.title = 'Disabled at the current zoom level.';
				}
			}
		}
	}
	
	this.loadPOIs = function() {
		var type;
		for (var i in me.checkboxes) {
			if (me.checkboxes[i] == this.id) {
				type = i;
				break;
			}
		}
		var show = this.checked;
		var markermanager;
		if (me.pois_markers[type] != null) {
			markermanager = me.pois_markers[type];
		} else {
			markermanager = new MarkerManager(me._map);
			me.pois_markers[type] = markermanager;
		}
		if (show && me._map.getZoom() >= me.min_zoom) {
			if (markermanager.getMarkerCount(me._map.getZoom()) > 0) {
				markermanager.show();
				GEvent.trigger(me, 'markers_shown', type);
			} else {
				me.getPOIs(type);
			}
		} else if (!markermanager.isHidden()) {
			if (me._infoShownLoc) {
				var marker = markermanager.getMarker(me._infoShownLoc.lat(), me._infoShownLoc.lng(), me._map.getZoom());
				if (marker != null) {
					me._map.closeInfoWindow();
				}
			}
			markermanager.hide();
			GEvent.trigger(me, 'markers_hidden', type);
		}
	}
	this.getPOIs = function(type) {
		var bounds = this._map.getBounds();
		var url = '/services/poi_proxy.php?'+type;
		ne = googlemap.normaliseLatLng(bounds.getNorthEast());
		sw = googlemap.normaliseLatLng(bounds.getSouthWest());
		url += '&' + ne.toUrlValue();
		url += '&' + sw.toUrlValue();
		YAHOO.util.Connect.asyncRequest( 'GET', url,
			{ success: this.loadMarkers, argument: { type: type } }
		);

	}
	this.loadMarkers = function(response) {
		try {
			var result = eval('(' + response.responseText + ')');
			var pois = result.pois;
			var type = response.argument.type;
		} catch (e) {
			GEvent.trigger(me, 'pois_load_error', e);
			if (window['console']) {
				console.log('Failed to parse response.');
				console.log(e);
			}
			//alert('Failed to parse response.');
			return;
		}
		var markers = new Array();
		var markermanager = me.pois_markers[type];
		if (result.extra.type) {
			markermanager.type = result.extra.type;
		}
		var elem = $(me.checkboxes[type]);
		if (elem && elem.icon) {
			var icon_filename = elem.icon;
		}
		GEvent.trigger(me, 'pois_loaded', type);
		var zoom = me._map.getZoom();
		for (var i=0; i<pois.length; i++) {
			var poi = pois[i];
			var marker = markermanager.getMarker(poi.lat, poi.lng, zoom);
			if (marker == null || marker.getTitle() == undefined) {
				var p = new GLatLng(poi.lat, poi.lng);
				poi.icon_filename = icon_filename;
				marker = me.findaPOIMarker(p, poi);
				markers.push(marker);
			}
		}
		if (markers.length > 0) {
			markermanager.addMarkers(markers, me.min_zoom);
			markermanager.refresh();
			GEvent.trigger(me, 'markers_shown', type);
		}
	}
	
	this.addHandlers = function () { // handlers for the checkboxes
		for (var i in this.checkboxes) {
			var elem = document.getElementById(this.checkboxes[i]);
			if (elem) {
				GEvent.addDomListener(elem, 'click', this.loadPOIs);
			}
		}
		GEvent.addListener(this._map, 'moveend', this.refreshPOIs);
	}
	var ta;
	this.cleanTitle = function(title) {
		/* This script and many more are available free online at
		The JavaScript Source!! http://javascript.internet.com
		Created by: Ultimater | http://webdeveloper.com/forum/member.php?u=30185 */
		if (!ta) {
			ta = document.createElement("textarea");
		}
		ta.innerHTML = title.replace(/</g, "&lt;").replace(/>/g, "&gt;");
		return ta.value;
	}
}
