/**
 * Script	maps.js
 * Created	13/06/2011
 * Author	Nicholas Masters
 * 
 * This script is based on code written by Google.
 * 
 * This script creates a new map object and then finds the locations to plot on it based
 * on search criteria entered.
 * 
 * Copyright (c) 2011 Sotic Ltd
 */

var map;
var markers = [];
var infoWindow;
var locationSelect;
var resultsi	=	0;

/**
 * Function loadmap
 * Setup map and find markers
 */
function loadmap()
{
	map	=	new google.maps.Map(document.getElementById("map"),
			{
			center: new google.maps.LatLng(startlat, startlng),
			zoom: startzoom,
			mapTypeId: 'roadmap',
			mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU}
			});
	/* InfoWindow is the box that opens when you click on a marker */
	infoWindow = new google.maps.InfoWindow();
	/* Select box which lists all locations */
	try
	{
		locationSelect = document.getElementById("locationSelect");
		locationSelect.onchange = function()
		{
			var markerNum = locationSelect.options[locationSelect.selectedIndex].value;
			if (markerNum != "none")
			{
				google.maps.event.trigger(markers[markerNum], 'click');
			}
		};
	}
	catch(e){}
	if(preload=='Yes')
	{
		findLocations();
	}
}

/**
 * Function geoCodeAddress
 * Finds the location of a given address and then finds markers near this location
 * @param string address
 */
function geocodeAddress(address)
{
	var geocoder	=	new google.maps.Geocoder();
	geocoder.geocode
	(
		{address: address},
		function(results, status)
		{
			if(status==google.maps.GeocoderStatus.OK)
			{
				getLocations(results[0].geometry.location);
			}
			else
			{
				alert('Unable to find location. Please try again.');
			}
		}
	);
}

/**
 * Function findLocations
 * If location is entered, geocode it else find all locations
 */
function findLocations()
{
	var address;
	try{address	=	document.getElementById('address').value;}
	catch(e){address	=	'';}
	if(address!='')
	{
		geocodeAddress(address);
	}
	else
	{
		getLocations();
	}
}

/**
 * Function getLocations
 * Get locations within specified parameters
 * @param location latlng
 */
function getLocations(latlng)
{
	var lat	=	'';
	var lng	=	'';
	if(latlng)
	{
		lat	=	latlng.lat();
		lng	=	latlng.lng();
	}
	var radius;
	var limit;
	try{radius	=	document.getElementById('rad').value;}
	catch(e){radius	=	0;}
	try{limit	=	document.getElementById('lim').value;}
	catch(e){limit	=	0;}
	var markers2	=	[];
	var xmlUrl	=	'/tools/ajax/include.php?unit='+unit+'&projectguid='+projectguid+'&langvariant='+langvariant+'&module=maps&type=locationfinderxml&refreshcache='+refreshcache+'&method='+method+'&lat='+lat+'&lng='+lng+'&rad='+radius+'&category='+category+'&lim='+limit;
	var request	=	window.ActiveXObject ?
		new ActiveXObject('Microsoft.XMLHTTP') :
		new XMLHttpRequest;
	request.onreadystatechange	=	function()
	{
		if(request.readyState==4)
		{
			request.onreadystatechange	=	doNothing;
			markers2	=	parseLocations(request.responseText);
			var bounds	=	new google.maps.LatLngBounds();
			var i = 0;
			var len	=	markers2.length;
			clearLocations();
			while(i<len)
			{
				createMarker(markers2[i]);
				bounds.extend(markers2[i].latlng);
				/* We only want to list results if user searched for them, not if we're returning all results */
				if(lat!=''&&lng!=''&&radius>0)
				{
					createResult(markers2[i].distance, markers2[i].name, markers2[i].link, markers2[i].description, i);
					if(locationSelect)
					{
						locationSelect.style.display	=	'block';
						createOption(markers2[i].name, markers2[i].distance, i);
					}
				}
				i++
			}
			if (bounds.getNorthEast().equals(bounds.getSouthWest()))
			{
				var extendPoint1 = new google.maps.LatLng(bounds.getNorthEast().lat() + 0.02, bounds.getNorthEast().lng() + 0.02);
				var extendPoint2 = new google.maps.LatLng(bounds.getNorthEast().lat() - 0.02, bounds.getNorthEast().lng() - 0.02);
				bounds.extend(extendPoint1);
				bounds.extend(extendPoint2);
			}
			if(markers2.length==0)
			{
				alert('No results found.');
			}
			/* Sometimes we want to specify where the map loads so don't use fitbounds */
			else if(firstrun==1)
			{
				firstrun	=	0;
			}
			else
			{
				map.fitBounds(bounds);
			}
		}
	};
	request.open('GET', xmlUrl, true);
	request.send(null);
}

/**
 * Function parseLocations
 * @param string xmlData
 */
function parseLocations(xmldata)
{
	var xml	=	parseXml(xmldata);
	var markerNodes	=	xml.documentElement.getElementsByTagName('marker');
	var newmarkers	=	[];
	for(var i=0; i<markerNodes.length; i++)
	{
		var newmarker	=	[];
		for(var j=0; j<markerNodes[i].attributes.length; j++)
		{
			var nodeName	=	markerNodes[i].attributes[j].nodeName;
			var nodeValue	=	markerNodes[i].attributes[j].nodeValue;
			newmarker[nodeName]	=	nodeValue;
		}
		if(newmarker.website)
		{
			newmarker.website	=	'<a target="_blank" href="http://'+newmarker.website+'">'+newmarker.website+'</a>'
		}
		if(newmarker.email)
		{
			newmarker.email	=	'<a href="mailto:'+newmarker.email+'">'+newmarker.email+'</a>'
		}
		newmarker.latlng		=	new google.maps.LatLng(
				parseFloat(newmarker.lat),
				parseFloat(newmarker.lng)
				);
		newmarker.distance	=	parseFloat(newmarker.distance).toFixed(1);
		newmarkers.push(newmarker);
	}
	return newmarkers;
}

/**
 * Function clearLocations
 */
function clearLocations()
{
	try
	{
		var resultdiv	=	document.getElementById('results');
		resultdiv.innerHTML	=	'';
	}
	catch(e){}
	infoWindow.close();
	for (var i=0; i<markers.length; i++)
	{
		markers[i].setMap(null);
	}
	markers.length = 0;
	try
	{
		locationSelect.innerHTML = "";
		var option = document.createElement("option");
		option.value = "none";
		option.innerHTML = "See all results:";
		locationSelect.appendChild(option);
	}
	catch(e){}
	content	=	[];
}

/**
 * @var array
 */
var content	=	[];
/**
 * Function createMarker
 * @param array marker
 */
function createMarker(marker)
{
	var markercontent	=	'';
	var name		=	marker.name;
	var description	=	marker.description;
	var link		=	marker.link;
	var latlng		=	marker.latlng;
	var phone		=	marker.phone;
	var email		=	marker.email;
	var website		=	marker.website;
	var details		=	marker.details;
	var contact		=	'';
	if(link)
	{
		name = '<b><a href="'+link+'">' + name + '</a></b>';
	}
	else
	{
		name = '<b>' + name + '</b>';
	}
	if(name)
	{
		markercontent	+=	name;
	}
	if(description)
	{
		markercontent	+=	'<br />'+description;
	}
	if(phone)
	{
		markercontent	+=	'<br />Tel: '+phone;
	}
	if(email)
	{
		markercontent	+=	'<br />Email: '+email;
	}
	if(website)
	{
		markercontent	+=	'<br />Website: '+website;
	}
	if(details)
	{
		markercontent	+=	'<br /><br /><span class="details">'+details+'</span>';
	}
	if(content[latlng])
	{
		content[latlng]	=	name +'<br />'+ content[latlng];
	}
	else
	{
		content[latlng]	=	markercontent;
	}
	var marker = new google.maps.Marker({
		map: map,
		position: latlng
	});
	var listener	=	google.maps.event.addListener(marker, 'click', function()
	{
		infoWindow.setContent(content[latlng]);
		infoWindow.open(map, marker);
	});
	markers.push(marker);
}

/**
 * Function createResult
 * @param float distance
 * @param string name
 * @param string link
 * @param string description
 */
function createResult(distance, name, link, description, num)
{
	try
	{
		var resultdiv	=	document.getElementById('results');
		var result	=	document.createElement('div');
		result.className	=	'result';
		if(link)
		{
			result.innerHTML	=	'<b><a href="'+link+'">' + name + '</a></b><br/>' + description + '<span class="distance">' + distance + ' '+unit+'</span><br/><a href="#" onclick="google.maps.event.trigger(markers['+num+'],\'click\');">Click here to find on map</a>';
		}
		else
		{
			result.innerHTML	=	'<b>' + name + '</b><br/>' + description + '<span class="distance">' + distance + ' '+unit+'</span><br/><a href="#" onclick="google.maps.event.trigger(markers['+num+'],\'click\');">Click here to find on map</a>';
		}
		resultdiv.appendChild(result);
	}
	catch(e){}
}

/**
 * Function createOptions
 * @param string name
 * @param float distance
 * @param int num
 */
function createOption(name, distance, num)
{
	var option = document.createElement("option");
	option.value = num;
	option.innerHTML = name + " (" + distance + " "+unit+")";
	locationSelect.appendChild(option);
}

/**
 * Function parseXml
 * @param string str
 * @returns ActiveXObject or DOMParser
 */
function parseXml(str)
{
	if (window.ActiveXObject)
	{
		var doc = new ActiveXObject('Microsoft.XMLDOM');
		doc.loadXML(str);
		return doc;
	}
	else if(window.DOMParser)
	{
		return (new DOMParser).parseFromString(str, 'text/xml');
	}
}

/**
 * Function doNothing
 */
function doNothing() {}
