//TODO: custom icons
//TODO: replace as much as possible with jquery
var range = -1;
var categories = new Array();
var organic = false;
var lfp = false;
var markers = new Array();
	var coords = new Array();
var map;
var home;
var clusterer;
//var region = new GLatLng(43.45242042822461, -80.51605224609375); // get this from the database
var InfoWindowHeight = 385;

var selectedIcon = new GIcon(G_DEFAULT_ICON);
selectedIcon.image = 'files/map/images/icons/glow.png';
selectedIcon.shadow = 'files/map/images/icons/glow.png';
selectedIcon.iconSize = new GSize(0, 0);
selectedIcon.shadowSize = new GSize(50, 50);
selectedIcon.iconAnchor = new GPoint(23, 39);
selectedIcon.imageMap = [0,0, 0,50, 50,50, 50,0]; //define boundary of image

var clusterIcon = new GIcon(G_DEFAULT_ICON);
clusterIcon.image = 'files/map/images/icons/glow_cluster.png';
clusterIcon.shadow = 'files/map/images/icons/glow_cluster.png';
clusterIcon.iconSize = new GSize(0, 0);
clusterIcon.shadowSize = new GSize(70, 70);
clusterIcon.iconAnchor = new GPoint(33, 59);
clusterIcon.imageMap = [0,0, 0,70, 70,70, 70,0]; //define boundary of image

var MarkerSelect = new Object();
MarkerSelect.target = null;

MarkerSelect.init = function()
{
	this.marker = new GMarker( new GLatLng(0, 0), {icon: selectedIcon, clickable: "false"} );
	this.clustermarker = new GMarker( new GLatLng(0, 0), {icon: clusterIcon, clickable: "false"} );
	this.marker.hide();
	this.clustermarker.hide();
	map.addOverlay(this.marker);
	map.addOverlay(this.clustermarker);
	
	
	GEvent.addListener( map, "zoomend", MarkerSelect.MakeCaller( MarkerSelect.checkCluster, this ) );
	GEvent.addListener( map, "moveend", MarkerSelect.MakeCaller( MarkerSelect.checkCluster, this ) );
}

MarkerSelect.setTarget = function( marker ) {
	this.target = marker;
	if (marker == null)
	{
		this.target_id = null;
		this.marker.hide();
		this.clustermarker.hide();
		return;
	}

	var cluster = clusterer.getClusterMarker(this.target);
	var point = null;
	if (cluster) {
		point = cluster.getPoint();
		this.showCluster();
		this.clustermarker.setLatLng(point);
	} else {
		point = marker.marker.getLatLng();
		this.showMarker();
		this.marker.setLatLng(point);		
	}
}
MarkerSelect.MakeCaller = function ( func, arg )
    {
    return function () { func( arg ); };
    };
MarkerSelect.showCluster = function() {
	this.clustermarker.show();
	this.marker.hide();
}
MarkerSelect.showMarker = function() {
	this.marker.show();
	this.clustermarker.hide();
}

MarkerSelect.checkCluster = function( mselect ) {
	if (mselect.target == null)
		return null;

	mselect.setTarget(mselect.target);
}

function load()
{	
  if (GBrowserIsCompatible())
  {
	map = new GMap2(document.getElementById("map"));
	
	var mapheight = $("#map").height();
	var PADDING = 10;
	InfoWindowHeight = Math.min(mapheight - PADDING * 2, InfoWindowHeight);
	
	point = new GLatLng(43.45242042822461, -80.51605224609375);
	map.setCenter(point, 12);
	map.addControl(new GLargeMapControl(), new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(7, 27)) );
	map.addControl(new GMapTypeControl(), new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(15, 7)) );
	map.enableScrollWheelZoom();

	// from http://econym.org.uk/gmap/example_range.htm
	//setMapBounds(coords);
	var mt = map.getMapTypes();
	// Overwrite the getMinimumResolution() and getMaximumResolution() methods
	for (var i=0; i<mt.length; i++) {
		mt[i].getMinimumResolution = function() {return 11;}
	}

	
	clusterer = new Clusterer(map);
	clusterer.SetMaxVisibleMarkers(4);
	clusterer.SetMinMarkersPerCluster(4);
	
	var baseIcon = new GIcon(G_DEFAULT_ICON);
	baseIcon.image = "files/map/images/icons/plus.png";
	baseIcon.iconSize = new GSize(49,49);
	baseIcon.shadowSize = new GSize(0, 0);
	baseIcon.iconAnchor = new GPoint(24, 48);
	baseIcon.imageMap = [0,0, 0,48, 48,48, 48,0]; //define boundary of image
	baseIcon.infoWindowAnchor = new GPoint(24, 48);	
	clusterer.SetIcon(baseIcon);
	
		
	initialPlot();
	refineSearch( true, true );
  }
}

function setMapBounds(viewBounds) {
	var mapbounds = new GLatLngBounds( new GLatLng( viewBounds.minlat - .1, viewBounds.minlng - .1 ), new GLatLng( viewBounds.maxlat + .1, viewBounds.maxlng + .1 ) );
	
	GEvent.clearListeners( map, "move" );
	GEvent.addListener( map, "move", function() {
		if (mapbounds.contains( map.getCenter() ) )
			return;
		
		// It`s not OK, so find the nearest allowed point and move there
		var C = map.getCenter();
		var X = C.lng();
		var Y = C.lat();

		var AmaxX = mapbounds.getNorthEast().lng();
		var AmaxY = mapbounds.getNorthEast().lat();
		var AminX = mapbounds.getSouthWest().lng();
		var AminY = mapbounds.getSouthWest().lat();

		if (X < AminX) {X = AminX;}
		if (X > AmaxX) {X = AmaxX;}
		if (Y < AminY) {Y = AminY;}
		if (Y > AmaxY) {Y = AmaxY;}
		map.setCenter(new GLatLng(Y,X));
	});
}
function getMapBounds() {
	return new GLatLngBounds( new GLatLng( coords.minlat, coords.minlng ), new GLatLng( coords.maxlat, coords.maxlng ) );
}
function addToBounds( point ) {
	var x = point.lng();
	var y = point.lat();
	
	// keep "viewing" bounds separate from "search" bounds to help when refining the search
	var newbounds = new Array();
	newbounds.minlng = coords.minlng;
	newbounds.minlat = coords.minlat;
	newbounds.maxlng = coords.maxlng;
	newbounds.maxlat = coords.maxlat;
	
	if (x < newbounds.minlng)
		newbounds.minlng = x;
	else if (x > newbounds.maxlng)
		newbounds.maxlng = x;
	if (y < newbounds.minlat)
		newbounds.minlat = y;
	if (y > newbounds.maxlat)
		newbounds.maxlat = y;
	
	setMapBounds( newbounds );
}

//home doesn't exist when setRange is called....
function plotAddress( )
{
	var address = $("#refinesearch")[0].value;
	if( address == "" )
	{
		return;
	}
	
	var distances = $("#sidebar_top div input.radiocontrol");
	var range = 0;
	for(var i = 0; i < distances.length; i++) {
		if (distances[i].checked) {
			range = distances[i].value;
		}
	}
	if (range == 0) return false;
	
	var geocoder = new GClientGeocoder();
	geocoder.setBaseCountryCode(".ca");
	geocoder.setViewport( getMapBounds() );
	
	geocoder.getLocations(address,
		function(response) {
			if (!response.Placemark) {
				alert(address + " could not be found.");
				return;
			}
			
			var point = new GLatLng( response.Placemark[0].Point.coordinates[1], response.Placemark[0].Point.coordinates[0] );
			var minDist = point.distanceFrom( region );
			var text = "";
			for( var i = 0; i < response.Placemark.length; i++) {
				var nextPoint = new GLatLng( response.Placemark[i].Point.coordinates[1], response.Placemark[i].Point.coordinates[0] );
				var newDist = nextPoint.distanceFrom(region);
				text += response.Placemark[i].address + ": " + newDist / 1000.0 + "km\n";
				if (newDist < minDist) {
					point = nextPoint;
					minDist = newDist;
				}
			}
			
			addToBounds(point);
			map.panTo(point);
			marker = new GMarker(point, {draggable: true, icon: getIcon(0)});

			GEvent.addListener(marker, "dragend", function() {
				refineSearch();
			});

			if(home != null && home.marker != null)
				map.removeOverlay(home.marker);
			
			map.addOverlay(marker);
			
			home = {};
			home.marker = marker;
			setRange(range);
		}
	);
}

//on toggle, add / remove category
function toggleCategory ( name )
{
	switch(name)
	{
		case "organic":
			organic = !organic;
		break;
		
		case "lfp":
			lfp = !lfp;
		break;
		
		default:
			if(jQuery.inArray(name,categories) >= 0)
			{	
				for(var i = 0; i < categories.length; i++)
					if (categories[i] == name)
						break;
						
				categories.splice(i,1);
			} else
			{
				categories[categories.length] = name;
			}
	}
	
	refineSearch(true);
}

function setRange ( newRange )
{
	range = newRange;
	refineSearch();
}

function showLoading()
{
	if( $("#canvas").length == 0 )
		$("body").append("<div id='canvas' style='display:none;'><div id='temp' style='display:none;'></div></div>");
	if( $("#canvas #spinner").length == 0 )
	{
		$("#canvas").append("<div id='spinner' style='display:none; width:100%; text-align:center;'><img src='/files/map/images/icons/spinner.gif' width=100 height=100 /></div>");
		$("#spinner").css("margin-top", $(window).height() / 2);
	}
	
	$("#canvas").css("display", "");
	$("#spinner").css("display", "");
	
	$("#canvas").css("width", $(window).width() );
	$("#canvas").css("height", $(window).height() );
	$("#canvas").resize( function(){
		$("#canvas").css("width", $(window).width() );
		$("#canvas").css("height", $(window).height() );
		$("#spinner").css("margin-top", $(window).height() / 2);
	});
}
function hideLoading()
{
	$("#spinner").css("display", "none");
	$("#canvas").css("display", "none");
}

//refine our search by available criteria
// optionally pass "true" for parameter mass to skip setting classes on outlets individually
function refineSearch( mass, initial )
{
	if( typeof mass == 'undefined' )
		mass = false;
	if( typeof initial == 'undefined' )
		initial = false;
	
	$("#outlets").accordion("disable");
	var Outlets = $("#outlets");
	
	if( !initial )
	{
		var outlet_list = $("#outlets div.outlet_result");
		outlet_list.removeClass("hidden");
		outlet_list.addClass("visible");
		var hideselectors = new Array();
		if( organic )
			hideselectors[0] = "div.no_cert_organic";
		if( lfp )
			hideselectors[1] = "div.no_cert_lfp";
		var toHide = $(hideselectors.join(', '));
		toHide.removeClass('visible');
		toHide.addClass('hidden');
	}

	var toHide = "";
	var toShow = "";
	for(var i = 0; i < markers.length; i++)
	{
		if(!markers[i])
			continue;
			
		//if a marker is in our category list
		jQuery.each(markers[i].categories, 
		function(){
			if(jQuery.inArray(this.toString(),categories) >= 0)
			{
				showMarker(i, true);
				toShow += "#outlet"+i + ", ";
				markers[i].hidden = false;
			}
			else
			{
				hideMarker(i, true);
				toHide += "#outlet"+i + ", ";
				markers[i].hidden = true;
			}
		});
	}
	
	for(var i = 0; i < markers.length; i++)
	{
		//get more strict: remove any points that don't meet these properties
		if( (organic && !markers[i].organic) || (lfp && !markers[i].lfp) )
		{
			hideMarker(i, true);
			if( !markers[i].hidden )
			{
				toHide += "#outlet"+i + ", ";
				markers[i].hidden = true;
			}
		}
		
		if(home != null && range >= 0)
		{
			var point = home.marker.getLatLng();
			var distance = point.distanceFrom(markers[i].marker.getLatLng());
			if ( distance > range )
			{
				if( !markers[i].hidden )
				{
					markers[i].hidden = true;
					toHide += "#outlet"+i + ", ";
				}
				hideMarker(i, true);
			}
			else
			{
				var distance = point.distanceFrom(markers[i].marker.getLatLng());
				var km = distance / 1000;
				km = km.toFixed(1);
				markers[i].distance = parseFloat(km);
				$( "#outlet" + i + "_distance" ).text( km + "km" );
			}
		}
	}
	
	if( toHide.length > 0 )
	{
		var hides = Outlets.children(toHide);
		hides.removeClass('visible');
		hides.addClass('hidden');		
	}
	if( toShow.length > 0 )
	{
		var shows = Outlets.children(toShow);
		shows.removeClass('hidden');
		shows.addClass('visible');
	}
	$("#outlets").accordion("enable");

	Clusterer.Display(clusterer, true);

	if( home != null && range >= 0 )
		getDistances();
}

// Hide a marker (but do not remove it!)
function hideMarker( id, mass )
{
	if( typeof mass == 'undefined' )
		mass = false;
		
	if(markers[id] && !markers[id].marker.isHidden())
	{
		if( !mass )
		{
			$( "#outlet" + id ).removeClass('visible');
			$( "#outlet" + id ).addClass('hidden');
		}
		markers[id].marker.hide();
		
		if (markers[id] == MarkerSelect.target)
			MarkerSelect.setTarget(null);
	}
}

// Show a marker at its location
function showMarker( id, mass )
{
	if( typeof mass == 'undefined' )
		mass = false;
		
	if(markers[id] && markers[id].marker.isHidden())
	{
		if( !mass )
		{
			$( "#outlet" + id ).removeClass('hidden');
			$( "#outlet" + id ).addClass('visible');			
		}
		markers[id].marker.show();
	}
}

// Remove a marker from the map, permanently
function removeMarker ( id )
{
	clusterer.RemoveMarker(markers[id].marker);
	if ( markers[id].marker )
		delete markers[id];
}

function showOutlet()
{
	$(this).unbind("click");
	$(this).bind("click", hideOutlet);
	
	var id = $(this).attr("id").replace("outletdetails", "");
	$('span', this).text("Hide Details");
	$('img', this).attr("src", $('img', this).attr("src").replace("arrow_link", "close_link"));
	
	var marker = markers[id];
	var url = "/index.php?p=food_maps/outlets.LoadOutlet&outlet="+marker.outlet_id;
	
	if( $("body #canvas").length == 0 )
		$("body").append("<div id='canvas' style='display:none;'><div id='temp' style='display:none;'></div></div>");

	$("#canvas").fadeIn("fast");
	$("#canvas").css("width", $(window).width() );
	$("#canvas").css("height", $(window).height() );
	$("#canvas").resize( function(){
		$("#canvas").css("width", $(window).width() );
		$("#canvas").css("height", $(window).height() );
	});
	
	$.ajax({url: url, dataType: "html",
		success: function tabload(data)
		{			
			$("#temp").empty();
			$("#temp").append(data);
			$("#temp").append("<a href='#' class='closeButton'><img src='files/map/images/closebutton.png' alt='Close' /></a>");
			$("#temp").append("<a href='#' class='arrow_link_right moreResults'>Back to results<img src='files/map/images/arrow_link.png' alt='Close' /></a>");
			$("#temp .closeButton").bind("click", function(){
				var outlet = $("span.ui-state-active").parent().attr("id").replace("outlet", "outletdetails");
				$("#"+outlet).trigger("click");
				$("#canvas").css("display", "none");
				$("#temp").css("display", "none");
			});
			$("#temp .moreResults").bind("click", function(){
				var outlet = $("span.ui-state-active").parent().attr("id").replace("outlet", "outletdetails");
				$("#"+outlet).trigger("click");
				$("#canvas").css("display", "none");
				$("#temp").css("display", "none");
			});
			
			$("#temp").fadeIn("2000");
			
			// store initial time of the outlet window being opened
			$('#temp').data('time_of_open', new Date().getTime());
		}
	});
}
function hideOutlet()
{
	$(this).unbind("click");
	$(this).bind("click", showOutlet);
	
	var id = $(this).attr("id").replace("outletdetails", "");
	$('span', this).text("Show Details");
	$('img', this).attr("src", $('img', this).attr("src").replace("close_link", "arrow_link"));
	
	var marker = markers[id];
	marker.marker.closeCustomInfoWindow();
	
	var timeopen = $('#temp').data('time_of_open');
	var totalseconds = (new Date().getTime() - timeopen) / 1000.0;
	
	// track the view outlet event: send the name of the outlet (given in outlet window) and the total time spent viewing (in seconds)
	TrackMapEvent( 'Map', 'View Outlet', $('#temp .outlet_box h2').text(), Math.round(totalseconds) );
}

//remove an outlet from the list
//you can't label accordion panes with just an id, so you may need to add a prefix
function removeOutlet ( id )
{
	map.closeInfoWindow();
	var panel = document.getElementById( "outlet" + id );
	if(panel)
	{
		$("#outlets").accordion("activate", -1);
		$("#outlets").accordion("disable");
		var parent = panel.parentNode;
		parent.removeChild(panel);
		removeMarker( id );
		$("#outlets").accordion("enable");
	}
	
}

// Plot initial results on the map
function initialPlot()
{
	MarkerSelect.init();
	$("#outlets div.outlet_result").addClass("visible");
	
	for (var i = 0; i < markers.length; i++)
	{
		if(markers[i])
		{
			markers[i].marker.id = i;
			clusterer.AddMarker(markers[i].marker, markers[i].name);
			//map.addOverlay(markers[i].marker);
			
			GEvent.addListener(markers[i].marker,"click", function(latlng) {
				var target = -1;
				// already have this marker selected, trigger the details
				if( MarkerSelect.target != null)
					target = MarkerSelect.target.marker.id;
				
				if( this.id == target )
					$("#outlet"+this.id+" > div.outlets_details > div.show_details a").click();
				else
				{
					// click() instead of focus() to trigger changing the outlet icon in .head
					$("#outlet"+this.id+" > span.head > a").click();
				}
			});
			
		}

	}
	
	if (markers[0] != null) {
		var point = markers[0].marker.getLatLng();
		map.setCenter(point);
	}
}

function getIcon( cat_id, sel, icon )
{
	if (!sel)
		sel = false;
	
	var baseIcon = new GIcon(G_DEFAULT_ICON);
	
	if( icon != "" )
		baseIcon.image = "files/map/images/icons/"+cat_id+".png";
	else

		baseIcon.image = "files/map/images/icons/1.png";
	
	baseIcon.iconSize = new GSize(33,33);
	baseIcon.shadowSize = new GSize(0, 0);
	baseIcon.iconAnchor = new GPoint(16, 32);
	baseIcon.imageMap = [0,0, 0,32, 32,32, 32,0]; //define boundary of image
	baseIcon.infoWindowAnchor = new GPoint(9, 2);
	
	return baseIcon;
}

function getDistances()
{
	if(home == null || home.marker == null)
		return;
	
	point = home.marker.getLatLng();

	var outlets = $('#outlets>div.visible');
	outlets.selso( {type: 'alpha', orderFn:
		function(obj1, obj2)
		{
			var objA = markers[obj1.id.replace("outlet", "")];
			var objB = markers[obj2.id.replace("outlet", "")];
			if( objA.keywords_matched > objB.keywords_matched )
				return -1;
			else if (objA.keywords_matched < objB.keywords_matched)
				return 1;
			
			if( objA.distance < objB.distance )
				return -1;
			else if (objA.distance > objB.distance )
				return 1;
			
			if( objA.name < objB.name )
				return -1;
			else
				return 1;
			
			return 0;
		}
	});
}

function showAccordion( id )
{
	$("#outlets").accordion("activate", id);
	$("#outlet"+id+" > span.head > a").focus();
}

//this just calls  the built-in print function, but it is wrapped in case we decide to do more / less
function printMap() {
	window.print();
}

function processKey(e)
{
	if(null == e)
	{
		e = window.event;
	}
	if (e.keyCode == 13 )
	{
		$("#submit").click();
		//what if user was hitting 'enter' to select a dropdown result?
		return false;
	}
}

$(document).ready(function(){
	load();
	$("#outlets").accordion({
		alwaysOpen: false,
		active: false,
		collapsible: true,
		header: "span.head",
		autoHeight: false,
		animated: false
	});
	$('.show_details a').bind("click", showOutlet);
	
	$("#outlets").bind("accordionchange",
		function(event, ui) {
			var id = -1;
			if (ui.newHeader.length != 0) {
				MarkerSelect.marker.hide();
				id = ui.newHeader.parent().attr("id").replace("outlet", "");
				window.location.hash = "outlet" + id;
				// set "selected" icon for outlet in list
				var newImg = ui.newHeader.find("img");
				if( newImg.length != 0 )
				{
					if( newImg.attr("src").indexOf("/icons/closed_icon") != -1 )
						newImg.attr("src", newImg.attr("src").replace("/icons/closed_icon", "/icons/sel_closed_icon"));
					else
						newImg.attr("src", newImg.attr("src").replace("/icons/icon", "/icons/sel_icon"));
				}
				
				if (MarkerSelect.target != null)
				{
					var oldId = MarkerSelect.target.marker.id;
					if ($("#outletdetails" + oldId + " span").text() == "Hide Details")
						$("#outletdetails" + oldId + " span").click();
				
					var newImg = $("#outlet" + oldId + " .head").find("img");
					if( newImg.length != 0 )
					{
						if( newImg.attr("src").indexOf("/icons/sel_closed_icon") != -1 )
							newImg.attr("src", newImg.attr("src").replace("/icons/sel_closed_icon", "/icons/closed_icon"));
						else
							newImg.attr("src", newImg.attr("src").replace("/icons/sel_icon", "/icons/icon"));
					}
				}
			}
			if (ui.oldHeader.length != 0) {
				if ($(ui.oldHeader).parent().length != 0)
				{
					oldId = ui.oldHeader.parent().attr("id").replace("outlet", "");
					// set "selected" icon for outlet in list
					var newImg = ui.oldHeader.find("img");
					if( newImg.length != 0 )
					{
						if ( newImg.attr("src").indexOf("/icons/sel_closed_icon") != -1 )
							newImg.attr("src", newImg.attr("src").replace("/icons/sel_closed_icon", "/icons/closed_icon"));
						else
							newImg.attr("src", newImg.attr("src").replace("/icons/sel_icon", "/icons/icon"));
					}
				}
			}
			
			if(id == -1) {
				MarkerSelect.setTarget(null);
				return;
			}

			var point = markers[id].marker.getLatLng();
			MarkerSelect.setTarget(markers[id]);
			map.panTo(point);
		}
	);

	// one result found and component setting enables auto select
	if( markers.length == 1 && show_single_result )
	{
		$('#outlet0 span.head').trigger('click');
		$('#outletdetails0 span').trigger('click');
	}
});

function TrackMapEvent( Category, Action, Label, Value ) {
	try{
		pageTracker._trackEvent( Category, Action, Label, Value );
	} catch(err) {}
}


$(document).unload(function(){
	GUnload();
});

