/* 
	Hire and Rental Industry Association Australia
	Javascript functions for mapping HRIA member locations
*/


// Google maps variables
var myMap;
var bubble;
var pxSize = new Array();
pxSize['x'] = 240;
pxSize['y'] = 150;
var cluster;
var markersArray = [];
var limitMarkers = 20;
var useCluster = true;

// path to named URL members
var memberUrl = "";

var AusGeoCentre = new GLatLng(-28.0, 133.417);
var ReqCentre = null;
var InitCentre = (ReqCentre) ? ReqCentre : AusGeoCentre;
var InitZoom = 4;

// number of pages, number of results per-page
var srPage = 0;
var srMaxPage = 0;
var srPerPage = 7;
var srCellHeight = 60;
var srPageHeight = srPerPage * srCellHeight;
var srHeight = 0;
var srPos = 0;
var srPosMax = 0;
// results
var srResults;
var srNumResults = 0;
// order of results
var srOrderBy = "";

document.observe('dom:loaded', function() { 
	if ($('search-results')) {
		Element.absolutize($('search-results'));
		srTop = $('search-results').offsetTop;
	}
	if ($('search-results-inner')) {
		Element.absolutize($('search-results-inner'));
	}
	if ($('search-results-list')) {
		// count the number of results
		srResults = $('search-results-list').childElements();
		srNumResults = srResults.length;
		srMaxPage = Math.ceil(srNumResults / srPerPage);
		srHeight = srNumResults * srCellHeight;
		srPosMax = srHeight - srPageHeight;
		if (srPosMax < 0) srPosMax = 0;
		// disable all button click events to start with
		['first', 'prev', 'next', 'last'].each(function(s) {
		  disablePageClick(s)
		});
		// check if pages required
		if (srMaxPage > 1) {
			// register the button click events
			['next', 'last'].each(function(s) {
			  enablePageClick(s);
			});
		}
	}
	
	// load search results map
	if ($('search-results-map')) {
		initMap('search-results-map');
	}
	
	// load any single maps
	$$('.map-single').each(function(s) {
		var mapid = s.id;
		if (mapid != '' && mapid != undefined) {
			initMap(mapid);
		}
	});
});

function enablePageClick(id) {
	if ($('search-results-nav-'+id) && $('search-results-nav-'+id).hasClassName('disabled')) {
		$('search-results-nav-'+id).observe('click', evScrollResults);
		$('search-results-nav-'+id).removeClassName('disabled');
	}
}

function disablePageClick(id) {
	if ($('search-results-nav-'+id)) {
		$('search-results-nav-'+id).stopObserving('click', evScrollResults);
		$('search-results-nav-'+id).addClassName('disabled');
	}
}

function evScrollResults(event) {
	var el = Event.element(event);
	var elid = el.id;
	if (elid != undefined && elid != '') {
		var elparts = elid.split("-");
		var to = elparts[elparts.length-1];
		scrollResults(to);
	}
}

function scrollResults(to) {
	if (to == 'first') {
		scrollToFirst();
	}
	else if (to == 'last') {
		scrollToLast();
	}
	else if (to == 'prev') {
		scrollUp();
	}
	else { // default is "next"
		scrollDown();
	}
}

function scrollToFirst() {
	// disable the "first" and "prev" links
	['first', 'prev'].each(function(s) {
	  disablePageClick(s);
	});
	// start the move
	srPage = 0;
	srPos = 0;
	new Effect.Move($('search-results-inner'), { x:0, y:srPos, mode:'absolute', queue:'end' });
	// enable the "next" and "last" links (if more than one page)
	if (srMaxPage > 1) {
		['next', 'last'].each(function(s) {
			enablePageClick(s);
		});
	}
}

function scrollToLast() {
	// disable the "next" and "last" links
	['next', 'last'].each(function(s) {
	  disablePageClick(s);
	});
	// start the move
	srPage = srMaxPage;
	srPos = srPosMax;
	new Effect.Move($('search-results-inner'), { x:0, y:-srPos, mode:'absolute', queue:'end' });
	// enable the "first" and "prev" links (if more than one page)
	if (srMaxPage > 1) {
		['first', 'prev'].each(function(s) {
		  enablePageClick(s);
		});
	}
}

function scrollUp() {	// go to previous "page", move the inner box down
	srPage -= 1;
	if (srPage <= 0) {
		scrollToFirst();
	}
	else {
		srPos -= srPageHeight;
		if (srPos <= 0) {
			scrollToFirst();
		}
		else {
			new Effect.Move($('search-results-inner'), { x:0, y:-srPos, mode:'absolute', queue:'end' });
			['next', 'last'].each(function(s) {
			  enablePageClick(s);
			});
		}
	}
}

function scrollDown() {	// go to next "page", move the inner box up
	srPage += 1;
	if (srPage >= srMaxPage-1) {
		scrollToLast();
	}
	else {
		srPos += srPageHeight;
		if (srPos >= srPosMax) {
			scrollToLast();
		}
		else {
			new Effect.Move($('search-results-inner'), { x:0, y:-srPos, mode:'absolute', queue:'end' });
			['first', 'prev'].each(function(s) {
			  enablePageClick(s);
			});
		}
	}
}

function sortByName() {
	if (srNumResults > 0) {
		sorted = srResults;
		var desc = (srOrderBy == 'name') ? true : false;
		if (desc) {
			srOrderBy = 'namedesc';
			// sort reverse alphabetically Z-A
			sorted.sort(function(a,b) { 
				return (a.innerHTML < b.innerHTML) ? 1 : ((a.innerHTML == b.innerHTML) ? 0 : -1);
			});
		}
		else {
			srOrderBy = 'name';
			// sort alphabetically A-Z
			sorted.sort(function(a,b) { 
				return (a.innerHTML < b.innerHTML) ? -1 : ((a.innerHTML == b.innerHTML) ? 0 : 1);
			});
		}
		// append new ordered list
		for (var i=0; i<sorted.length; i++) {
			$('search-results-list').appendChild(sorted[i]);
		}
	}
}

function sortByCity() {
	if (srNumResults > 0) {
		sorted = srResults;
		var desc = (srOrderBy == 'city') ? true : false;
		// sort by city/suburb name A-Z
		sorted.sort(function(a,b) { 
			var c1 = extractCity(a);
			var s1 = extractStreet(a);
			var c2 = extractCity(b);
			var s2 = extractStreet(b);
			return (c1<c2) ? -1 : ((c1==c2) ? ((s1<s2) ? -1 : ((s1==s2) ? 0 : 1)) : 1);
		});
		if (desc) {
			srOrderBy = 'citydesc';
			// reverse order (Z-A)
			sorted.reverse();
		}
		else {
			srOrderBy = 'city';
		}
		// append new ordered list
		for (var i=0; i<sorted.length; i++) {
			$('search-results-list').appendChild(sorted[i]);
		}
	}
}

function sortByDistance() {
	if (srNumResults > 0) {
		sorted = srResults;
		var desc = (srOrderBy == 'dist') ? true : false;
		// sort distance closest-furthest
		sorted.sort(function(a,b) { 
			var d1 = extractDistance(a);
			var d2 = extractDistance(b);
			return d1-d2;
		});
		if (desc) {
			srOrderBy = 'distdesc';
			// reverse order (furthest-closest)
			sorted.reverse();
		}
		else {
			srOrderBy = 'dist';
		}
		// append new ordered list
		for (var i=0; i<sorted.length; i++) {
			$('search-results-list').appendChild(sorted[i]);
		}
	}
}

function extractStreet(el) {
	var slist = el.select('.street');
	return (slist && slist.length > 0) ? slist[0].innerHTML : '';
}

function extractCity(el) {
	var clist = el.select('.city');
	return (clist && clist.length > 0) ? clist[0].innerHTML : '';
}

function extractDistance(el) {
	var dlist = el.select('.km');
	return (dlist && dlist.length > 0) ? dlist[0].getAttribute('value') : 0;
}

function initMap(id) {
  if (GBrowserIsCompatible()) {
    var map = new GMap2($(id));
		// zoom in/out map control
		map.addControl(new GLargeMapControl3D());
		// map, satellite, hybrid selector
		map.addControl(new GMapTypeControl());
		// double click on map to zoom in
		map.enableDoubleClickZoom();
		// setCenter(location object, zoom level)
    map.setCenter(InitCentre, InitZoom);			
		
		// when the map is zoomed remove info box
		GEvent.addListener(map, "zoomend", function() { 
			if (bubble) map.removeOverlay(bubble);
		});
		
		myMap = map;
		
		loadMarkers();
	}
}

function resetMap() {
	myMap.setCenter(InitCentre, InitZoom);
}

function myClusterClick(args) {
	cluster.defaultClickAction = function() {
		myMap.setCenter(args.clusterMarker.getLatLng(), myMap.getBoundsZoomLevel(args.clusterMarker.clusterGroupBounds));
		delete cluster.defaultClickAction;
	}
	var html = '<div><h4>' + args.clusteredMarkers.length + ' businesses:</h4>';
	for (i=0; i<args.clusteredMarkers.length; i++) {
		html += '<a href="javascript:cluster.triggerClick('+args.clusteredMarkers[i].index+')">'+args.clusteredMarkers[i].getTitle()+'</a><br />';
		if (i > 8) {
			html += '<i>...</i><br />';
			break;
		}
	}
	html += '<br /><a href="javascript:void(0)" onclick="cluster.defaultClickAction()">Zoom</a> in to show these locations</div>';
	args.clusterMarker.openInfoWindowHtml(html);
}

function loadMarkers() {
	if (window.createMarkers) {
		// create new markers
		createMarkers();
		if (markersArray.length > 0) {
			// clear any existing markers
			myMap.clearOverlays();
			// load markers into cluster manager
			cluster = new ClusterMarker(myMap, { markers:markersArray, clusterMarkerTitle:'Click to see info about %count businesses',  clusterMarkerClick:myClusterClick } );
			cluster.intersectPadding = -5;
			cluster.fitMapToMarkers();
			// save initial center and zoom
			InitCentre = myMap.getCenter();
			InitZoom = myMap.getZoom();
		}
	}
}

function businessClick(marker) {
	try {
   	GEvent.trigger(marker, 'click');
	}
	catch (e) {
		// marker has been "clustered" - need to zoom in
		var clickFound = false;
		var zoomLevel = (myMap.getZoom() < 16) ? myMap.getZoom() + 1 : 16;
		maxZoomLevel = 20;
		while (zoomLevel < maxZoomLevel && !clickFound) {
			try {
				myMap.setCenter(marker.getLatLng(), zoomLevel);
				GEvent.trigger(marker, 'click');
				clickFound = true;
			}
			catch (ez) {
				zoomLevel ++;
			}
		}
	}
}

function createMarker(point, name, address, phone, id) {
	var marker = new GMarker(point, {title:name});
	var html = '<div style="width:'+pxSize['x']+'px;">';
	html += '<div style="background-color:#fff;">';
	html += '<b>'+ name+'</b>';
	html += '<br>'+address;
	if (phone != '') html += '<br>Telephone: '+phone;
	html += '<div><a href="#" onClick="zoomMarker(' + point.lat() + ',' + point.lng() + ');return false;">[zoom in]</a> <a href="'+memberUrl+escape((name.replace("&", "and")))+'/'+id+'/">[show detail]</a></div>';
	html += '</div>';
	html += '</div>';
	GEvent.addListener(marker, 'click', function() {
	  marker.openInfoWindowHtml(html);
	});
	return marker;
}

function tidyZoom(currentZoom) {
	return (currentZoom > 16) ? 16 : currentZoom;
}

function tidyDistance(dist) {
	return (dist == "") ? "" : '(' + Math.round(dist, 2) + 'km)';
}

function zoomMarker(lat, lng) {
	if (lat != "" && lng != "") {
		var zoomLevel = (myMap.getZoom() > 14) ? myMap.getZoom() + 1 : 15;
		myMap.setCenter(new GLatLng(lat, lng), zoomLevel);
	}
}