
//importXML("xml/services.xml");
//importOfficesXML("1","xml/locations_medicare.xml");
//importXML("xml/locations_medicare.xml");

String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g, ''); }

// define script vars
var OfficeLocations = new Object(); //Array();
var SelectedServices = new Object(); //Array();

var xmlDocLoading;
var xmlDocService;
var pageLoaded = false;
var locationsLoaded = false;
var map;
var geocoder;

var interval;
var destinationLeft = 20;
var startLeft = -800;
var animkeys = Array();

var pos = startLeft;
var pos_index = 0;

var overlay;
var ClosestLocationsToReturn = 6;

var backOn = new Image(); backOn.src = "images/back_on.gif";
var backOff = new Image(); backOff.src = "images/back_off.gif";
var printOn = new Image(); printOn.src = "images/print_on.gif";
var printOff = new Image(); printOff.src = "images/print_off.gif";

var zone=0;

var firstID;
var secondID;

var GLatLngFrom;
var GLatLngTo;

var directionsPanel;
var directions;

var address;
var mapPositioned = true;
var mapShowing = false;

addLoadEvent(load);
function load() {
	// generate the animation sequence
	while (pos < (destinationLeft-10)) {
		pos = parseInt((destinationLeft - (pos*-1)) / 1.5);
		animkeys[pos_index++] = pos + "px";
	}
	
	document.getElementById("fromAddress").focus();
	
	//setLocations();
	overlay = document.getElementById("overlaydiv");
	var searchbox = document.getElementById("search_box");
	//overlay.style.left = startLeft+"px";
	//overlay.style.top = (findPos(searchbox)[1]-10) + "px";
	
	if (GBrowserIsCompatible()) {
		geocoder = new GClientGeocoder();
		map = new GMap2(document.getElementById("map"));
		map.addControl(new GSmallMapControl());
		map.addControl(new GMapTypeControl());
		directionsPanel = document.getElementById("directions");
		directions = new GDirections(map, directionsPanel);
	}
	
	clearSearchString();
}


function popup(url) {
	var p = window.open(url,"popup","location=yes, menubar=yes, resizable=yes, scrollbars=yes, status=yes, toolbar=yes, left=15, top=15");
	p.focus();
}

function addtoSelectedServices(serviceId) {
	SelectedServices[serviceId] = serviceId;
	SelectedServices = sortAssoc(SelectedServices);
}

function deletefromSelectedServices(serviceId) {
	delete(SelectedServices[serviceId]);
//	OfficeLocations = Array();
//	SelectedServices = sortAssoc(SelectedServices);
}

function deleteOfficesForService(serviceId) {
	for (var officeId in OfficeLocations) {
		if (OfficeLocations[officeId].serviceid == serviceId) {
			delete(OfficeLocations[officeId]);
		}
	}
}


function resetScreen() {
	
	var proceed = confirm("This will reset the map and the search results. \n Do you want to continue?");

	if (proceed) 
	{
		clearSearchString();
		clearSelectedServices();
		thisMovie("mapapp").resetMap();
		if (mapShowing) {
			hideGoogle();
		}
		hideAlertMsg();
		hideStatusMsg();
	} 
}

function clearOfficeLocations() {
	OfficeLocations = new Object(); //Array();
}


function clearSelectedServices() {
	SelectedServices = new Object(); //Array();
	clearOfficeLocations();
	clearCloseLocationsAndDirections();
}

// this is sorting by key
function sortAssoc(aInput)
{
    var aTemp = [];
    for (var sKey in aInput) {
        aTemp.push(sKey);
	}
	
    aTemp.sort();

    var aOutput = new Object(); //[];
    for (var nIndex=0; nIndex < aTemp.length; nIndex++)
        aOutput[aTemp[nIndex]] = aTemp[nIndex];

    return aOutput;
} 

// this is sorting by value
function sortAssoc2(oAssoc) {
	var idx; var key; var arVal = []; var arValKey = new Object(); var oRes = new Object();;
	for (key in oAssoc) {
		arVal[arVal.length] = oAssoc[key]+ "#" + key;
		arValKey[oAssoc[key]+ "#" + key] = key;
	}

	arVal.sort();
	
	for (var idx=0;idx<arVal.length;idx++) {
		oRes[arValKey[arVal[idx]]] = arVal[idx].split("#")[0];
	}
		
	return oRes;
}


function findPos(obj) {
	var curleft = curtop = 0;
	if (obj.offsetParent) {
		curleft = obj.offsetLeft
		curtop = obj.offsetTop
		while (obj = obj.offsetParent) {
			curleft += obj.offsetLeft
			curtop += obj.offsetTop
		}
	}
	return [curleft,curtop];
}

function OfficeLocation(id, serviceid, type, name, state, country, description, address, fulladdress, pcode, website, phone, businesshours, lat, lng, utc, directions) {

    this.id = id;
	this.serviceid = serviceid;
	this.type = type;
	this.name = name;
	this.state = state;
	this.country = country;
	this.description = description;
	this.address = address;
	this.fulladdress = fulladdress;
	this.pcode = pcode;
	this.website = website; 
	this.phone = phone;
	this.businesshours = businesshours;
	this.lat = lat;
	this.lng = lng;
	this.utc = utc;
	this.directions = directions;
	this.marker = false;
	
}
	
function importXML(filename)
{
	if (document.implementation && document.implementation.createDocument) {
		xmlDocService = document.implementation.createDocument("", "", null);
		xmlDocService.onload = readServiceXML;
	}
	else if (window.ActiveXObject) {
		xmlDocService = new ActiveXObject("Microsoft.XMLDOM");
		xmlDocService.onreadystatechange = function () {
			if (xmlDocService.readyState == 4) readServiceXML()
		};
 	}
	else {
		alert('Your browser can\'t handle this script');
		return;
	}
	xmlDocService.load(filename);
}

function readServiceXML() {
	var rootNode = xmlDocService.getElementsByTagName("services");
	var serviceNodes = rootNode[0].getElementsByTagName("service");
	var service;
	var serviceId;
	var officesXmlUrl;
	for (var i=0; i<serviceNodes.length; i++) {
		service = serviceNodes[i];
		serviceId = service.getAttribute("id");
		officesXmlUrl = service.getAttribute("xml_url");
		importOfficesXML(serviceId, officesXmlUrl);
	}
}

function importOfficesXML(serviceId, filename)
{
	addtoSelectedServices(serviceId);

	var success;
	var xmlDoc;
	
	if (document.implementation && document.implementation.createDocument) {

		var request = XmlHttpObject();
		var type = '';
		url = mappingBaseURL + filename;
		
		request.open("GET", url, true);
		request.onreadystatechange = function()
		{
		
			if (request.readyState == 4) {
				xmlDoc = request.responseXML;
				var rootNode = xmlDoc.getElementsByTagName("service_locations");
				readOfficesXML(serviceId, rootNode);
				
			}
		}
  		request.send(null);


	}
	else if (window.ActiveXObject) {
		xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
		xmlDoc.onreadystatechange = function () {
			if (xmlDoc.readyState == 4) {
				var rootNode = xmlDoc.getElementsByTagName("service_locations");
				
				readOfficesXML(serviceId, rootNode)
			}
		};
		xmlDoc.load(filename);
 	}
	else {
		alert('Your browser can\'t handle this script');
		return;
	}


}

function readOfficesXML(serviceId, rootNode) {

	if (rootNode[0].hasChildNodes()) {

		var locations = rootNode[0].getElementsByTagName("location");
		var location;
		for (var i=0; i<locations.length; i++) {
			location = locations[i];
			OfficeLocations[serviceId + "_" + locations[i].getAttribute("id")] = new OfficeLocation(
				serviceId + "_" + locations[i].getAttribute("id"),	
				serviceId,
				location.getAttribute("provider"),
				location.getAttribute("name"),
				location.getAttribute("state"),
				location.getAttribute("iso_country"),
				location.getAttribute("description"),
				location.getAttribute("address"),
				location.getElementsByTagName("street_address")[0].firstChild.nodeValue,
				location.getAttribute("pcode"),
				location.getAttribute("website"),
				location.getAttribute("phone"),
				location.getAttribute("business_hours"),
				location.getAttribute("lat"),
				location.getAttribute("lng"),
				location.getAttribute("utc_offset"),
				location.getAttribute("directions")
			);
		}		
	}

}



function loadOfficeDetails(id) {
	document.getElementById("office_name").innerHTML = OfficeLocations[id].type + ": " + OfficeLocations[id].name;
	document.getElementById("office_details").innerHTML = "";
	if (OfficeLocations[id].description != "") {
		document.getElementById("office_details").innerHTML += "<i>" + OfficeLocations[id].description + "</i><br />";
	}

	if (OfficeLocations[id].fulladdress != "") {
		document.getElementById("office_details").innerHTML += "<br /> <b>Address:</b> " + OfficeLocations[id].fulladdress + ", " + OfficeLocations[id].state + " " + OfficeLocations[id].pcode;
	}
	if (OfficeLocations[id].phone != "") {
		document.getElementById("office_details").innerHTML += "<br /> <b>Phone:</b> " + OfficeLocations[id].phone;
	}
	if (OfficeLocations[id].businesshours != "") {
		document.getElementById("office_details").innerHTML += "<br /> <b>Business Hours:</b> " + OfficeLocations[id].businesshours;
	}
	if (OfficeLocations[id].website != "") {
		document.getElementById("office_details").innerHTML += "<br /> <b>Website: </b> <a href=\"" + OfficeLocations[id].website + "\" target=\"_new\">" + OfficeLocations[id].website;
	}

}

function showGoogle(id) {

	directions.clear();
	map.clearOverlays();
	
	document.getElementById("directions").innerHTML = "";

	if (OfficeLocations[id].address+"" != "") {
		thisMovie("mapapp").showOffice(id);
		if (!mapShowing) {
			thisMovie("mapapp").zoomOffices();
		}
		var xmlpoint = new GLatLng(OfficeLocations[id].lat, OfficeLocations[id].lng);
		map.setCenter(xmlpoint, 15);
		map.addOverlay(new GMarker(xmlpoint));
		OfficeLocations[id].marker = true;
	}


	if (mapPositioned) {
		mapPositioned = false;
		pos_index = 0;
    	interval = setInterval("pullDown()",2);
	}

    loadOfficeDetails(id);

}

function hideGoogle() {
	document.getElementById("directions").innerHTML = "";
	if (mapPositioned) {
		mapPositioned = false;
		//document.getElementById("flashmap").className = "show";
		pos_index = animkeys.length-1;
    	interval = setInterval("pullUp()",2);
	}
}

function pullDown() {
	if (pos_index < animkeys.length) {
		overlay.style.left = animkeys[pos_index++];
	}
	else {
		clearInterval(interval);
        overlay.style.left = destinationLeft + "px";
		//document.getElementById("flashmap").className = "hide";
		mapPositioned = true;
		mapShowing = true;
	}
}

function pullUp() {
	if (pos_index >= 0) {
		overlay.style.left = animkeys[pos_index];
		pos_index--;
	} else {
		clearInterval(interval);
        overlay.style.left = startLeft + "px";
		mapPositioned = true;
		mapShowing = false;
		thisMovie("mapapp").unzoomOffices();
	}
}

function lengthAssoc(AssocArray) {
	var alength = 0;
	for (var sid in AssocArray) {
		alength++;
	}
	return alength;
}

function clearSearchString() {
	document.searchform.fromAddress.value = "";

}

function clearCloseLocationsAndDirections() {
	document.getElementById("directions").innerHTML = "";
	document.getElementById("cl").innerHTML = "";	
}

function showStatusMsg(message) {
	document.getElementById("statusmsg").style.display = "block";	
	document.getElementById("statusmsg").innerHTML = message;	
}

function hideStatusMsg() {
	document.getElementById("statusmsg").style.display = "none";	
	document.getElementById("statusmsg").innerHTML = "";	
}

function showAlertMsg(message) {
	hideStatusMsg();			
	document.getElementById("alertmsg").style.display = "block";	
	document.getElementById("alertmsg").innerHTML = message;	
}

function hideAlertMsg() {
	document.getElementById("alertmsg").style.display = "none";	
	document.getElementById("alertmsg").innerHTML = "";	
}


function processLocation(searchaddr) {
	showStatusMsg("Processing...");	
	
	if (mapShowing) {
		hideGoogle();
	}
	hideAlertMsg();
	
	var addr;
	clearCloseLocationsAndDirections();

	if (searchaddr == null) {
		addr = document.searchform.fromAddress.value;
		if (addr.trim() == "") {
			showAlertMsg("Please enter your location.");
			return false;
		}
	} else addr = searchaddr;

	if (isNumeric(addr)) {
		var flashLastState = thisMovie("mapapp").GetVariable("_root.Map.LastState");
		var newState = parseStateFromPostcode(addr);
		if (flashLastState != newState && newState != "") {
			thisMovie("mapapp").GoToCountryFromJS("AU_" + newState);
			showStatusMsg("Looking for closest locations...");
			

			setTimeout("getClosestLocation()", 2000);
			return true;
		}
		if (newState == "" || isValidPostcode(addr)) {
			showAlertMsg("You have entered an invalid postcode.");
			return false;
		}
	}

	getClosestLocation(addr);	
}

function getClosestLocation(addr) {

	if (lengthAssoc(SelectedServices) == 0) {
		hideStatusMsg();
		if (addr == null) {   //means search is postcode
			showAlertMsg("To use search by postcode, please select at least one service.");
		}
		else {
			showAlertMsg("To use search by address, please select at least one service and click on the map to select the state/territory.");
		}
		return false;
	} 

	var searchAddress;

	if (addr == null) {
		addr = document.searchform.fromAddress.value;
	}

	if (addr.trim() != "") {
		// strip some potentially dangerous chars from the user input
		address = addr.replace(/[\>\<]/g, '');
		searchAddress = address;
		// if user has entered only a postcode then append " Australia" to search to limit to Aus

		if (IsNumeric(addr)) {
			searchAddress += " Australia";
			showStatusMsg("<strong>NOTE:</strong> In order to receive accurate driving directions to and from a point you need to enter a FULL address.");
		} 
		else {
			hideStatusMsg();
		}

		if (geocoder) {

			geocoder.getLatLng(
			searchAddress,
			function(point) {
				GLatLngFrom = point;

				if (point == null) {
					showAlertMsg("Address not found.");
					// point = new GLatLng(OfficeLocations[id].lat, OfficeLocations[id].lng);
				}
				
				else {
					
					latitude = point.lat();
					longitude = point.lng();

					// check that the location is roughly within the bounds of Australia
					if ((latitude > -10) || (latitude < -143) || (longitude > 154) || (longitude < 112)) {
						showAlertMsg(address + " not found");
					}
					else {
						var indexOfSecondClosest;
						var temp;

						var str = "<table width=245 id=\"closest_locations\" style=\"margin: 8px 0 0 0;\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\">";

						var foundOne = false;
						for (var sid in SelectedServices) {
							var distance1 = 1000000000000; //some number bigger than the largest likely distance
							var lastIndexOfArray;
							var arrayClosest = new Object(); //Array();

							// find closest
							for (var i in OfficeLocations) {
								if (OfficeLocations[i].serviceid == sid) {
									temp = getDistance(latitude, longitude, OfficeLocations[i].lat, OfficeLocations[i].lng);
									if (lengthAssoc(arrayClosest) < ClosestLocationsToReturn) {
										arrayClosest[i] = temp;
										arrayClosest = sortAssoc2(arrayClosest);
										for (var k in arrayClosest) {
											lastIndexOfArray = k;
										}
									} else {
										if (temp <= distance1) {
											delete(arrayClosest[lastIndexOfArray]);
											arrayClosest[i] = temp;
											arrayClosest = sortAssoc2(arrayClosest);
											for (var k in arrayClosest) {
												lastIndexOfArray = k;
											}
										}
									}
									distance1 = arrayClosest[lastIndexOfArray];
								}
							}

							if (lengthAssoc(arrayClosest) > 0) {
								if (!foundOne) {
									str += "<tr><td style=\"background: #eeeeee; font-size:1.2em; line-height: 1.2em; font-family: Arial;\">The closest service centres to<br><b>'" + address + "'</b> are:</td></tr>";
									foundOne = true;
								}
								
								for (var j in arrayClosest) {
									var officeId = OfficeLocations[j].id;
									str += showFoundCloseLocation(officeId);
								}
							}
						}

						str +=	"</table>";
						document.getElementById("cl").innerHTML = str;
						//document.getElementById("statusmsg").style.display = "none";	

						
						//if (foundOne) {
						//	thisMovie("mapapp").showOffice( officeId );
						//}
						
					}
					
				}
				
			});
		} // close if (geocoder) 
		
	} // close if (addr.trim() != "")
}

function showFoundCloseLocation(officeID) {
	
	var loc1 = OfficeLocations[officeID].type + ": " + OfficeLocations[officeID].name;
	var str = "<tr><td>";
	str +=  return2br(formatLocation(officeID));
	str += 	"<br /><div class=\"drivelinks\" style=\"text-align:right\"><a href=\"javascript:highlight('" + officeID + "');\" title=\"Highlight " + loc1 + " on map\">highlight on map</a> ";
	str += "| <a href=\"javascript:showDirections('" + officeID + "');\" title=\"Get driving directions from " + address + " to " + OfficeLocations[officeID].type + ": " + OfficeLocations[officeID].name + "\">driving directions</a>";
	str +=  "</div>"
	str +=	"</td></tr>";
	
	return str;
}

function formatLocation(id) {
	return "<span title=\"Show " + OfficeLocations[id].type + ": " + OfficeLocations[id].name + " street map\" class=\"address\"><a href=\"javascript:showGoogle('" + id + "')\">" + OfficeLocations[id].type + ": " + OfficeLocations[id].name + "</a></span><br />" + OfficeLocations[id].fulladdress + ", " + OfficeLocations[id].state + " " + OfficeLocations[id].pcode;
}

function return2br(dataStr) {
	return dataStr.replace(/(\r\n|\r|\n)/g, "<br />");
}

function IsNumeric(sText) {
	var ValidChars = "0123456789";
	var IsNumber=true;
	var Char;
	
	for (i = 0; i < sText.length && IsNumber == true; i++) { 
		Char = sText.charAt(i); 
		if (ValidChars.indexOf(Char) == -1) {
			IsNumber = false;
		}
	}
	return IsNumber;
}

function getDistance(lat1, lng1, lat2, lng2) {
	var latFrom = (lat1 < 0) ? lat1 *-1 : lat1 ;
	var lngFrom = (lng1 < 0) ? lng1 *-1 : lng1 ;
	var latTo = (lat2 < 0) ? lat2 *-1 : lat2 ;
	var lngTo = (lng2 < 0) ? lng2 *-1 : lng2 ;
	return Math.sqrt( Math.pow( (Math.max(latFrom,latTo) - Math.min(latFrom,latTo)),2) + Math.pow( (Math.max(lngFrom,lngTo) - Math.min(lngFrom,lngTo)),2) );
}

function thisMovie(movie) {
	/*
	var isIE = navigator.appName.indexOf("Microsoft") != -1;
    return (isIE) ? window[movie] : document[movie];
	*/
	if (window.document[movie]) {
		return window.document[movie];
	}
	if (navigator.appName.indexOf("Microsoft Internet")==-1) {
		if (document.embeds && document.embeds[movie]) {
			return document.embeds[movie]; 
		}
	} else {
		return document.getElementById(movie);
	}
}

function highlight(id) {
	
	thisMovie("mapapp").showOffice( id );
	
	if ((mapPositioned) && (mapShowing)) {
		mapPositioned = false;
		//document.getElementById("flashmap").className = "hide";
		pos_index = animkeys.length-1;
		interval = setInterval("pullUp()",2);
	}
}

function parseStateFromPostcode(pcode) {
	if ((pcode >= 800) && (pcode < 1000)) {
		return "NT";		
	} else if ((pcode >= 1000) && (pcode <= 2999)) {
		if (((pcode >= 2600) && (pcode < 2620)) || ((pcode >= 2900) && (pcode < 2999))) {
			return "ACT";
		} else { 
			return "NSW";
		}
	} else if ((pcode >= 3000) && (pcode <= 3999)) {
		return "VIC";
	} else if ((pcode >= 4000) && (pcode <= 4999)) {
		return "QLD";
	} else if ((pcode >= 5000) && (pcode <= 5999)) {
		return "SA";
	} else if ((pcode >= 6000) && (pcode <= 6999)) {
		return "WA";
	} else if ((pcode >= 7000) && (pcode <= 7999)) {
		return "TAS";
	} else {
		return "";
	} 
}


function showDirections(id) {
	showStatusMsg("Processing...");	

	if (!mapShowing) {
		thisMovie("mapapp").zoomOffices();			
		thisMovie("mapapp").showOffice(id);
	}

	map.clearOverlays();
	GLatLngTo =  new GLatLng(OfficeLocations[id].lat, OfficeLocations[id].lng);
	directions.loadFromWaypoints(Array(GLatLngFrom, GLatLngTo));
	//directions.load("from: " + address + " to: " + OfficeLocations[id].address + " " + OfficeLocations[id].state + " " + OfficeLocations[id].pcode);
	
	setTimeout("processDirections('" + id + "')", 1000);
}


function processDirections(id) {
	if (document.getElementById("directions").innerHTML == "") {
		hideStatusMsg();	
		alert("Sorry, the driving instruction is not available for this location.");
	} else {
		loadOfficeDetails(id);
	
		if (mapPositioned) {
			mapPositioned = false;
			pos_index = 0;
			interval = setInterval("pullDown()",2);
		}
		hideStatusMsg();	
	}
}

function isNumeric(sText) {
   var ValidChars = "0123456789.";
   var IsNumber=true;
   var Char;

   for (var i = 0; i < sText.length && IsNumber == true; i++) { 
      Char = sText.charAt(i); 	  
      if (ValidChars.indexOf(Char) == -1) {
         IsNumber = false;
      }
   }
   return IsNumber;
}

function isValidPostcode(pcode) {
	geocoder.getLatLng(
		pcode + " Australia",
		function(point) {
			if (point != null) {
				return true;
			} else {
				return false;
			}
		}
	);
}


// *******************************************************************			
function XmlHttpObject() {

	var xmlHttp;
	try
	{    
		// Firefox, Opera 8.0+, Safari    
		xmlHttp=new XMLHttpRequest();   
	}
	catch (e)
	{    
		// Internet Explorer    
		try
		{      
			xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
		}
		catch (e)
		{      
			try
			{
				xmlHttp=new ActiveXObject("Microsoft.XMLHTTP"); 
			}
			catch (e)
			{
				alert("Your browser does not support AJAX!");
				return false;
			}
		}
	}
	return xmlHttp;
}
