//global variables
var map = null;
var markers = new Array();

// Create a base icon for all of our markers that specifies the
// shadow, icon dimensions, etc.
// We can then use this base to use images with numbers on them.
var baseIcon = new GIcon();
baseIcon.shadow = "http://www.google.com/mapfiles/shadow50.png";
baseIcon.iconSize = new GSize(20, 34);
baseIcon.shadowSize = new GSize(37, 34);
baseIcon.iconAnchor = new GPoint(9, 34);
baseIcon.infoWindowAnchor = new GPoint(9, 2);
baseIcon.infoShadowAnchor = new GPoint(18, 25);

//take an array of GLatLng and make sure the map displays
//all pins with these coordinates
GMap2.prototype.centerAndZoomOnPoints = function(points)
{
	var bounds = new GLatLngBounds();

	// extend the bounds to include all the points.
	for (var i = 0; i < points.length; i++) {
		bounds.extend(points[i]);
	} 

	var center = bounds.getCenter();
	var newZoom = this.getBoundsZoomLevel(bounds);
	
	if (this.getZoom() != newZoom)
	{
		this.setCenter(center, newZoom);
	}
	else
	{
		this.panTo(center);
	}
};

//returns a copy of the array passed as argument without duplicate records
function uniqueArray(array) {
	var hash = new Object();
	
	for (var i = 0; i < array.length; i++) {
		hash[array[i]] = true; 
	}
	
	var newArray = new Array();
	
	for (value in hash) {	
		newArray.push(value)
	};
	
	return newArray;
}

//checks wether an array of GLatLng objects contains
//another GLatLng object
function containsPoint(array, p)
{
	for(var i = 0; i < array.length; i++) {
		if((array[i].lat() == p.lat()) && (array[i].lng() == p.lng()))
			return true; 
	}
	
	return false;
}

//create markers and store them in an array along with
//the ids (linkId) to the divs for the info windows. makers are not added to the map at 
//this stage.
//if there is more than one offer with the same geocode
//don't create a new marker but rather add the new offer id
//to the offer id array of the marker
function rememberMarker(point, linkId, linkName)
{	
	var found = null;
	for(key in markers)
	{
		if(markers[key].marker.getPoint().equals(point))
		{
			found = markers[key];
			break;
		}
	}

	if(found == null)
	{
		var obj = new Object();
		obj.linkIds = new Array();
		obj.linkIds[0] = linkId;
		obj.linkName = linkName;
		var icon = new GIcon(baseIcon);
		icon.image = "../images/map/markers/iconr1.png";
		obj.marker = new GMarker(point, {icon: icon, title: "1 " + linkName});
		markers.push(obj);
	}
	else
	{	
		found.linkIds.push(linkId);
		var icon = new GIcon(baseIcon);
		icon.image = "../images/map/markers/iconr" + (found.linkIds.length) + ".png";
		found.marker = new GMarker(point, {icon: icon, title: (found.linkIds.length) + " " + linkName + "s"});
	}
}

//loop over marker array and add all markers to the map.
//if a marker has multiple offers, create div and put all
//divs which contain the html for the offers inside the created
//div.
//note that the created html element is _not_ inserted into the document
//and therefore can't be retrieved with document.getElementById or with $("#id").
//therefore we need to store the element in a variables and we can access all other element
//which are inside this element via $(element).find()
function addMarkers()
{
	for(key in markers)
	{
		if(markers[key].linkIds.length > 1)
		{
			var element = $("<div id='marker_container_" + key +"'><div id='marker_container_title_" + key + "' style='font-size: 1.2em; font-weight: bold; padding-bottom: 5px;'><a href='javascript:void(0)' onclick=\"changeLink('" + key + "', 'prev')\" style='font-size: 1em; font-weight: normal;'>(prev.)</a> " + markers[key].linkName + " <span id='marker_container_title_link_" + key + "'>1</span>/" + markers[key].linkIds.length + " <a href='javascript:void(0)' onclick=\"changeLink('" + key + "', 'next')\" style='font-size: 1em; font-weight: normal;'>(next)</a></div></div>").get(0);
			for(var i = 0; i < markers[key].linkIds.length; i++)
			{	
				$(element).append($("#infowindow_" + markers[key].linkIds[i]));
			}
			
			markers[key].marker.hothouse_element = element;
			
			GEvent.addListener(markers[key].marker, "click", function() {
				this.openInfoWindow(this.hothouse_element);
				
				//only show the first offer if this is the first time the info window is shown
				if($(this.hothouse_element).find("[@id*='marker_container_title_link']").text() == "1")
				{
					var divs = $(this.hothouse_element).children("div").not("[@id*='marker_container']");
					$(divs[0]).show();
				}
			});
		}
		else
		{
			var element = document.getElementById("infowindow_" + markers[key].linkIds[0]);
			
			markers[key].marker.hothouse_element = element;
			GEvent.addListener(markers[key].marker, "click", function() {
				this.openInfoWindow(this.hothouse_element);
				$(this.hothouse_element).show();
			});
		}
		
		map.addOverlay(markers[key].marker);
	}
}

//loop over offers for a particular marker and hide the current one and show the next or previous one
function changeLink(key, dir)
{
	//var iw = map.getInfoWindow();

	var divs = $("#marker_container_" + key).children("div").not($("#marker_container_title_" + key));
	var j = 0;
	
	for(var i = 0; i < divs.length; i++)
	{
		if($(divs[i]).css("display") != "none")
		{
			$(divs[i]).hide();
			
			if(dir == "next")
			{
				//last element
				if(i == divs.length - 1)
					j = 0;
				else
					j = i + 1;
			}
			//previous
			else
			{
				//first element
				if(i == 0)
					j = divs.length - 1;
				else
					j = i - 1;
			}
			
			$(divs[j]).show();
			break;
		}
	}
	
	$("#marker_container_title_link_" + key).text("" + (j + 1));
	
	//this function should be available in v2.84 but it is not.
	//once it is available we should be able to use it to recalculate
	//the size of the info window on each "next" or "previous" click
	//map.updateInfoWindow(null, null);
}

function GMap_computeAngle(endLatLng, startLatLng) {
	var DEGREE_PER_RADIAN = 57.2957795;
	var RADIAN_PER_DEGREE = 0.017453;
	
	var dlat = endLatLng.lat() - startLatLng.lat();
	var dlng = endLatLng.lng() - startLatLng.lng();
	// We multiply dlng with cos(endLat), since the two points are very closeby,
	// so we assume their cos values are approximately equal.
	var yaw = Math.atan2(dlng * Math.cos(endLatLng.lat() * RADIAN_PER_DEGREE), dlat)
	     * DEGREE_PER_RADIAN;
	return GMap_wrapAngle(yaw);
}

function GMap_wrapAngle(angle) {
	if (angle >= 360) {
	  angle -= 360;
	} else if (angle < 0) {
	 angle += 360;
	}
	return angle;
};
