
// Global Members
var Container = $([]);
var Header = $([]);
var Navigation = $([]);
var Content = $([]);
var MapHeader = $([]);
var MapSources = $([]);
var MapSend = $([]);
var MapPrint = $([]);
var MapArea = $([]);
var Footer = $([]);

var MaskScreen = $([]);
var MaskPanel = $([]);

var TabHeader = $([]);
var TabButtons = $([]);
var TabContent = $([]);

var NavigationViews = $([]);
var ClickModeButtons = $([]);
var ClickModeData = $([]);
var ClickModeTooltip = $([]);
var ClickModeCSHelp = $([]);

var SearchForm = $([]);
var SearchInputs = $([]);
var SearchExecute = $([]);
var PlacesLocation = $([]);
var PlacesSets = $([]);
var PlacesSetsInputs = $([]);
var PlacesResults = $([]);
var ProximityResults = $([]);
var UnitResults = $([]);
var PlacesResultsMsg = $([]);
var DirectionsResults = $([]);
var DirectionsViews = $([]);
var DirectionsStart = $([]);
var DirectionsSteps = $([]);
var DirectionsSummary = $([]);
var DirectionsItems = $([]);
var DirectionsEmpty = $([]);
var DirectionsEnd = $([]);
var DirectionsForm = $([]);
var DirectionsInputs = $([]);
var DirectionsExecute = $([]);
var UnitButtons = $([]);

var NoMarkerInfo = $([]);

var Map = null;

var PWindows = null;

// Global Values
var appTitle = null;
var tabActiveClass = "ui-tabs-selected";
var heightMin = 400;
var heightOffset = 5;
var cmCursor = "url('images/clickmode.png') 13 37, url('images/clickmode.cur'), crosshair";
var cMap = "MapSource";
var cType = "MapType";
var cMiniMap = "ShowMiniMap";
var cMetrics = "Metrics";
var cOptions = {expires:30};
var dirFormat = null;
var dirFrame = false;
var layerfix = "<iframe class=\"layerfix\" frameborder=\"0\" scrolling=\"no\"/>";

// Initialize
$(function() {
	InitializeMembers();
	InitializeAjaxMembers();
	
	InitializeValues();
	
	InitializeMetrics();

	InitializeEvents();
	InitializeAjaxEvents();
	
	ResetView();
	
	Preload();

	// private functions
});

// public functions

// Initializing Functions

function InitializeMembers() {
	Container = $("#container");
	Header = Container.find("#header");
	Navigation = Container.find("#navigation");
	Content = Container.find("#content");
	MapHeader = Content.find("#map-header");
	MapSources = MapHeader.find("#map-options input");
	MapSend = MapHeader.find("#map-send a");
	MapPrint = MapHeader.find("#map-print a");
	MapArea = Content.find("#map");
	Footer = Container.find("#footer");
	MaskScreen = $("<div/>").addClass("mask").append(layerfix);
	MaskPanel = $(document.body).children(".mask-panel").remove();

	TabHeader = Navigation.find("#tabs");
	TabButtons = TabHeader.find("a");
	TabContent = Navigation.find("#tabs-content");

	NavigationViews = TabContent.find("#search-edit, #search-vague, #places-search, #places-results, #directions-search, #directions-places, #directions-results");
	ClickModeButtons = Container.find(".clickmode a");
	ClickModeData = MapHeader.find("div.clickmode-data");
	ClickModeTooltip = $("<div/>").addClass("tooltip").text(MapHeader.find("#map-clickmode a").attr("tooltip"));
	ClickModeCSHelp = TabContent.find("a.clickmode-help");

	SearchForm = TabContent.find("#search-form");
	SearchInputs = SearchForm.find(":text,#search-form\\:latitude,#search-form\\:longitude");
	SearchExecute = SearchForm.find("#search-form\\:execute");
	PlacesLocation = TabContent.find("#places-location");
	PlacesSets = TabContent.find("#places .places-sets");
	PlacesSetsInputs = PlacesSets.find("input");
	DirectionsResults = TabContent.find("#directions-results");
	DirectionsViews = DirectionsResults.find("#directions-start, #directions-edit, #directions-vague");
	DirectionsStart = DirectionsResults.find("#directions-start");
	DirectionsSteps = DirectionsResults.find("#directions-steps");
	DirectionsSummary = DirectionsSteps.find("thead span");
	DirectionsItems = DirectionsSteps.find("tbody");
	DirectionsEmpty = DirectionsResults.find("#directions-empty").hide();
	DirectionsEnd = DirectionsResults.find("#directions-end");
	DirectionsForm = DirectionsResults.find("#directions-form");
	DirectionsInputs = DirectionsForm.find(":text,#directions-form\\:latitude,#directions-form\\:longitude");
	DirectionsExecute = DirectionsForm.find("#directions-form\\:execute");
	UnitButtons = DirectionsSteps.find("tfoot a");
	
	Map = new Mapper(MapArea.attr("id"), {google: GoogleMap, microsoft: MSMap});
	
	PWindows = new Array();
	
	NoMarkerInfo = $("<div/>").addClass("nomarker-info").append(layerfix).append($("<img/>").attr("src","images/close.gif").addClass("marker-info-close").click(HideNoMarkerInfo)).appendTo(MapArea).hide();
}

function InitializeAjaxMembers() {
	PlacesResults = TabContent.find("#places-results > div > table");
	ProximityResults = PlacesResults.not("[uid]");
	UnitResults = PlacesResults.filter("[uid]");
	PlacesResultsMsg = TabContent.find("#places-results > #message-results > .message-result");
}

function InitializeValues() {
	appTitle = document.title;
	dirFormat = DirectionsSummary.text();
}

function InitializeMetrics() {
	if (window["s_gi"] != undefined) {
		var ma = "ldsmaps";
	
		SearchExecute.click(function() {
			var s = s_gi(ma);
			s.linkTrackVars = "prop1, events";
			s.events = s.linkTrackEvents = "event1";
			s.prop1 = "";		
			SearchInputs.filter(":text").each(function() {
				if ($(this).val()) {
					s.prop1 += $(this).val() + " ";
				}
			});
			if (SearchInputs.filter(":hidden:eq(0)").val()) {
				s.prop1 += "{point}";
			}
			s.prop1 = $.trim(s.prop1);
		});
		
		PlacesSetsInputs.click(function() {
			var s = s_gi(ma);
			s.linkTrackVars = "prop2, events";
			s.events = s.linkTrackEvents = "event2";
			s.prop2 = $(this).attr("title");
		});
		
		MapSources.click(function() {
			var s = s_gi(ma);
			s.linkTrackVars = "prop3, events";
			s.events = s.linkTrackEvents = "event3";
			s.prop3 = $(this).val();
		});
		
		MapSend.click(function() {
			var s = s_gi(ma);
			s.linkTrackVars = "events";
			s.events = s.linkTrackEvents = "event4";
		});
	
		MapPrint.click(function() {
			var s = s_gi(ma);
			s.linkTrackVars = "events";
			s.events = s.linkTrackEvents = "event5";
		});
		
		var _ShowResultsDetails = ShowResultsDetails;
		ShowResultsDetails = function(obj) {
			var s = s_gi(ma);
			s.linkTrackVars = "events";
			s.events = s.linkTrackEvents = "event6";
			return _ShowResultsDetails(obj);
		};
		
		UnitButtons.click(function() {
			var s = s_gi(ma);
			s.linkTrackVars = "prop7, events";
			s.events = s.linkTrackEvents = "event7";
			s.prop7 = $(this).text();
		});
		
		ClickModeCSHelp.click(function() {
			var s = s_gi(ma);
			s.linkTrackVars = "events";
			s.events = s.linkTrackEvents = "event8";
		});
		
		TabContent.find("#search-edit div:last a[href*='mormon.org']").click(function() {
			var s = s_gi(ma);
			s.tl(this, "e", $(this).text());
		});
	}
}

function InitializeEvents() {
	TabButtons.click(function() {
		ClickTab(TabButtons.index(this));
		return false;
	}).eq(0).click();

	$(window).unload(function() {
		$.cookie(cMap, MapSources.filter(":checked").val(), cOptions);
		$.cookie(cType, Map.getMapType(), cOptions);
		$.cookie(cMiniMap, Map.getOverviewVisible(), cOptions);
		$.cookie(cMetrics, Map.getMapUnit(), cOptions);
	}).resize(function() {
		var h = $(window).height() - Header.outerHeight({margin:true}) - heightOffset;
		h  = (h > heightMin) ? h : heightMin;
		TabContent.height(h - TabHeader.outerHeight({margin:true}) - (TabContent.outerHeight({margin:true}) - TabContent.height()));
		MapArea.height(h - MapHeader.outerHeight({margin:true}) - (MapArea.outerHeight({margin:true}) - MapArea.height()));
		Map.resize();
	}).resize();
	
	MapSend.click(function() {
		var subject = (TabButtons.index(GetCurrentTab().get(0)) == 2) ? directionsFromMaps : mapFromMaps;
		var link = GenerateLink();
		var body = link;
		//$(this).attr("href","mailto:?subject=" + subject + "&body=" + escape(body));
		$(this).attr("href","mailto:?body=" + escape(body));
	});

	var val = $.cookie(cMap);
	MapSources.click(function() {
		var params = {};
		if (!Map.isLoaded) {
			val = $.cookie(cType);
			if (val) {
				$.extend(params, {type:parseInt(val)});
			}
			val = $.cookie(cMiniMap);
			if (val) {
				$.extend(params, {overview:(val == "true")});
			}
			val = $.cookie(cMetrics);
			if (val) {
				$.extend(params, {unit:parseInt(val)});
			}
		}
		Map.load($(this).val(), params);
	}).filter(val ? "[value="+val+"]" : ":checked").click();	

	ClickModeCSHelp.csHelp({useSelf:true, targetCorner:"bl", helpCorner:"tl", closeText:learnHowClose});

	Container.find("a[href='#search']").click(function() {
		NavigationViews.filter("#search-vague").hide();
		NavigationViews.filter("#search-edit").show();
		ClickTab(0);
		SearchInputs.filter(":first").focus();
		return false;
	})
	
	TabContent.find("form").each(function() {
		var c = $(this).find("#" + $(this).attr("id") + "\\:country");
		c.autocomplete(countries,{matchContains:true,max:50,scroll:true});
		c.result(function() {
			setTimeout(function(){c.focus();},0);
		});
	});
	
	SearchForm.add(DirectionsForm).keypress(function(e) {
		if (e.which == 13) {
			$(this).find(".button").click();
			return false;
		}
	});
		
	ClickModeButtons.click(ToggleClickMode);

	PlacesLocation.click(function() {
		var items = TabContent.find("#places-results > div:visible > table:visible");
		var fm = new Array();	
		items.not("[uid]").each(function() {
			fm.push($(this).attr("mid"));
		});
		if (!fm.length) {
			items.each(function() {
				fm.push($(this).attr("mid"));
			});
		}
		fm.push($(this).attr("mid"));
		Map.frameMarkers(fm);
		return false;
	});
	
	PlacesSetsInputs.click(function() {
		if ($(this).filter(":checked").length) {
			$("#" + $(this).val()).slideDown("normal", ResetMarkers);
		} else {
			$("#" + $(this).val()).slideUp("normal", ResetMarkers);
		}		
	});

	DirectionsViews.children("a[href^='#directions']").click(function() {
		SetDirectionsView($(this).attr("href"));
		return false;
	});
	
	DirectionsStart.add(DirectionsEnd).click(function() {
		Map.frameMarkers([$(this).attr("mid")]);
		return false;	
	});
	
	DirectionsSteps.find("thead").add(DirectionsEmpty.find(".summary")).click(function() {
		Map.frameDirections();
		return false;	
	});
	
	UnitButtons.click(function() {
		if (!$(this).hasClass("disabled")) {
			Map.setMapUnit($(this).attr("href") == "#km" ? MapUnits.Kilometers : MapUnits.Miles);
			GenerateRoute();
			DisableUnit($(this).attr("href"));
		}
		return false;
	});
	DisableUnit(Map.getMapUnit() == MapUnits.Kilometers ? "#km" : "#mi");
}

function InitializeAjaxEvents() {
	PlacesResults.click(function() {
		ShowResultsDetails($(this));
		return false;
	});
	
	ProximityResults.find("tbody > tr[uid]").click(function() {
		ShowUnitDetails($(this).attr("uid"));
		return false;
	});
	
	if ($.cssHoverActivate && $.browser.msie && parseInt($.browser.version) < 7) {
		$.cssHoverActivate();
	}	
}

// Universal Functions

function Preload() {
	if (InQuery("m")) {
		MapSources.filter("[value="+$.query.get("m")+"]").click();
	}

	if (InQuery("mt")) {
		Map.setMapType($.query.get("mt"));
	}

	var counts = SearchForm.find("#search-form\\:search-count");
	var addresses = parseInt(counts.children(".addresses").text());
	var properties = parseInt(counts.children(".properties").text());
	var units = parseInt(counts.children(".units").text());
	
	if (addresses) {
		SearchReturned();
		
		if (InQuery("sel")) {
			ShowResultsDetails(PlacesResults.eq($.query.get("sel") || 0));
		}
	} else if (properties || units) {
		PlacesLocation.hide();
		PlacesSetsInputs.get(0).checked = false;
		PlacesSetsInputs.eq(0).click();
		PlacesSets.hide();
		
		SetView("#search-edit, #places-results, #directions-places");
		
		MarkProperties();
		
		ShowResultsDetails(UnitResults.eq(0));
	}
	
	if (InQuery("dlat") && InQuery("dlng")) {
		DirectionsSearch($.query.get("da"), $.query.get("dc"), $.query.get("ds"), $.query.get("dp"), $.query.get("dn"), $.query.get("dlat") || 0, $.query.get("dlng") || 0)
	}

	if (InQuery("t")) {
		setTimeout(function(){ClickTab($.query.get("t") || 0)},0);
	}

	if (InQuery("mlat") || InQuery("mlng")) {
		Map.setPosition(new MapPoint($.query.get("mlat") || 0, $.query.get("mlng") || 0), (InQuery("mz") ? $.query.get("mz") : null));
	} else if (InQuery("mz")) {
		Map.setZoom($.query.get("mz"));
	}
}

function InQuery(key) {
	return ($.query.keys[key] != undefined);
}

function ResetView() {
	SetView();
	SetDirectionsView();
	ClickTab(0);
	SearchInputs.filter(":first").focus();
	return false;
}

function SetView(viewable) {
	NavigationViews.not(NavigationViews.filter(viewable || "#search-edit, #places-search, #directions-search").show()).hide();
}

function GetCurrentTab() {
	return TabHeader.find("."+tabActiveClass+" a");
}

function ClickTab(tab) {
	var oldTab = GetCurrentTab();
	var newTab = TabButtons.eq(tab);
	
	if (newTab.attr("href") != oldTab.attr("href")) {
		var p = newTab.parent().addClass(tabActiveClass);
		var s = p.siblings().removeClass(tabActiveClass);
		$(newTab.attr("href")).show();
		s.children("a").each(function() {
			$($(this).attr("href")).hide();
		});
		document.title = appTitle + " - " + newTab.text();
	
		if (oldTab.attr("href") == "#directions") {
			Map.setMarkerVisibility(DirectionsStart.attr("mid"),false);
			Map.setMarkerVisibility(DirectionsEnd.attr("mid"),false);				
			Map.setDirectionsVisibility(false);
			Map.setMarkerVisibility(PlacesLocation.attr("mid"),true);
			ResetMarkers();
		} else if (newTab.attr("href") == "#directions") {
			Map.setMarkerVisibility(PlacesLocation.attr("mid"),false);
			ProximityResults.each(function() {
				Map.setMarkerVisibility($(this).attr("mid"),false);
			});
			HideNoMarkerInfo();
			ShowDirections();
		}
	}
	
	// clean up
	TabContent.find("#help-text a.closer").click();
	if (InClickMode()) {
		ToggleClickMode();
	}
	
	return false;
}

function LoadingScreen(activate) {
	if (activate) {
		EnableSearch(false);
		if ($.browser.msie && parseInt($.browser.version) < 7) {
			$("html").css("overflow","hidden");
		}
		MaskScreen.add(MaskPanel).appendTo(document.body).css({opacity:0,display:"block"}).fadeTo("normal",0.5,function(){MaskPanel.fadeTo("fast",1,function(){MaskPanel.css("filter","");});});
	} else {
		EnableSearch(true);
		if ($.browser.msie && parseInt($.browser.version) < 7) {
			$("html").css("overflow","");
		}
		MaskScreen.add(MaskPanel).fadeOut("fast",function(){$(this).remove()});
	}
}

function PopupWindow(sender, title, height, width) {
	var fetch = true;
	if (sender && sender.tagName) {
		sender = $(sender).blur().attr("href");
		fetch = false;
	}
	title = title || "";
	height = height || 500;
	width = width || 775;
	var top = parseInt(($(window).height() - height) / 2);
	var left = parseInt(($(window).width() - width) / 2);
	var w = window.open(sender,title,"top="+top+",left="+left+",height="+height+",width="+width+",resizable,scrollbars");
	if (window.focus) {
		w.focus();
	}
	for (var i = PWindows.length - 1; i >= 0; i--) {
		if (PWindows[i].closed) {
			PWindows.splice(i, 1);
		}
	}
	PWindows.push(w);
	return (fetch) ? w : false;
}

function GenerateLink() {
	var link = window.location.protocol + "//" + window.location.host + window.location.pathname + "?";

	// Current Tab
	link += "t=" + TabButtons.index(GetCurrentTab().get(0));
	
	// Site ID
	if (InQuery("id")) {
		link += "&id=" + $.query.get("id");
	}
	
	// Map Type / Extent
	link += "&m=" + MapSources.filter(":checked").val();
	link += "&mt=" + Map.getMapType();
	link += "&mlat=" + Map.getLatitude();
	link += "&mlng=" + Map.getLongitude();
	link += "&mz=" + Map.getZoom();
	
	// Selected Location
	var pl = GenerateMarkerQuery(PlacesLocation);
	if (pl != "") {
		link += pl;
	} else {
		// Unit View Only
		if (InQuery("unitId")) {
			link += "&unitId=" + $.query.get("unitId");;
		}
	}

	// Selected Item
	var sel = PlacesResults.index(PlacesResults.filter(".active").get(0));
	if (sel >= 0) {
		link += "&sel=" + sel;
	}

	// Directions Start
	link += GenerateMarkerQuery(DirectionsStart, "d");
	
	return link;
}

function GenerateMarkerQuery(obj, prefix) {
	prefix = prefix || "";

	var link = "";
	
	var m = Map.getMarker(obj.attr("mid"));
	if (m) {
		link += "&" + prefix + "lat=" + escape(m.point.latitude);
		link += "&" + prefix + "lng=" + escape(m.point.longitude);
		
		if (!obj.find("address").hasClass("point")) {
			var a = obj.find(".street").text();
			if (a != "") {
				link += "&" + prefix + "a=" + escape(a);				
			}
			var c = obj.find(".city").text();
			if (c != "") {
				link += "&" + prefix + "c=" + escape(TrimEnd(c, ','));				
			}
			var s = obj.find(".state").text();
			if (s != "") {
				link += "&" + prefix + "s=" + escape(s);				
			}
			var p = obj.find(".postal").text();
			if (p != "") {
				link += "&" + prefix + "p=" + escape(p);				
			}
			var n = obj.find(".country").text();
			if (n != "") {
				link += "&" + prefix + "n=" + escape(n);				
			}
		}
	}
	
	return link;
}

function TrimEnd(text, trim) {
	trim = trim || ' ';
	if (text.charAt(text.length-1) == trim) {
		text = text.substr(0,text.length-1);
	}
	return text;
}


// Search Functions

function ToggleClickMode(e) {
	if ($(document.body).hasClass("clickmode")) {
		EnableSearch(true);
		Map.setCursor();
		Map.unbind("click", ClickModeSubmit);
		ClickModeTooltip.remove();
		$(document.body).unbind("mousemove", MoveClickModeTooltip).unbind("click", ToggleClickMode).unbind("keypress", ClickModeKeys);
	} else {
		EnableSearch(false);
		Map.setCursor(cmCursor);
		Map.bind("click", ClickModeSubmit);
		$(document.body).append(ClickModeTooltip.hide()).mousemove(MoveClickModeTooltip).click(ToggleClickMode).keypress(ClickModeKeys);
		if (e == 1) {
			$(document.body).addClass("feedbackmode");
		} else {
			$(document.body).removeClass("feedbackmode");
		}
	}
	$(document.body).toggleClass("clickmode");
	ClickModeButtons.each(function() {
		$(this).attr({title:$(this).attr("alt"), alt:$(this).attr("title")});
	});
	return false;
}

function InClickMode() {
	return $(document.body).hasClass("clickmode");
}

function MoveClickModeTooltip(e) {
	if (e.target.tagName) {
		ClickModeTooltip.show().css({top:e.pageY + 15, left:e.pageX + 12});
	} else {
		ClickModeTooltip.hide();
	}
}

// TODO: Accessability Clickmode
function ClickModeKeys(e) {
	switch (e.which) {
		case 27:	// Esc
			ToggleClickMode();
			return false;
			break;
		case 13:	// Enter
			break;
		case 38:	// Up
			break;
		case 40:	// Down
			break;
		case 37:	// Left
			break;
		case 39:	// Right
			break;
	}
}

function ClickModeSubmit(args) {
	if (InClickMode()) {
		ToggleClickMode();
	}
	
	var point = args["point"] || args["marker"].point;
	
	ClickModeData.find(".latitude").text(PrintCoordinates(point.latitude,true,true));
	ClickModeData.find(".longitude").text(PrintCoordinates(point.longitude,false,true));
	var data = $.html(ClickModeData);
	
	var m = ClickModeData.attr("mid") ? Map.getMarker(ClickModeData.attr("mid")) : null;
	if (m) {
		Map.moveMarker(ClickModeData.attr("mid"), point);
		Map.updateMarkerContent(ClickModeData.attr("mid"), data);
	} else {
		m = new MapMarker(point, data);
		m.icon = new MapMarkerIcon("images/markers/clickmode.png", new MapPixel(26,32));
		m.icon.offset = new MapPixel(13,32);
		m.draggable = true;
		m.bind("dragend", ClickModeSubmit);
		Map.mark(m);
		ClickModeData.attr("mid", m.id);
	}
	Map.showMarkerContent(ClickModeData.attr("mid"));
}

function ClickModeExecute(mode) {
	Map.hideMarkerContent();
	var m = Map.getMarker(ClickModeData.attr("mid"));
	if (m) {
		switch (mode) {
			case 0:		// Search
				ExecuteSearch("","","","","",m.point.latitude,m.point.longitude);
				break;
			case 1:		// Directions
				DirectionsSearch("","","","","",m.point.latitude,m.point.longitude);
				break;
			case 2:		// Feedback
				PopupWindow(MapHeader.find("#map-feedback a").attr("href") + "?c=1&p", "feedback");
				break;
			case 3:		// Feedback Mode
				var opened = false;
				for (w in PWindows) {
					if (!PWindows[w].closed && PWindows[w].name == "feedback") {
						PWindows[w].LoadPointData();
						if (window.focus) {
							PWindows[w].focus();
						}
						opened = true;
						break;
					}
				}
				if (!opened) {
					return ClickModeExecute(2);
				}
				break;
		}
	}
	Map.unmark(m.id);
	ClickModeData.attr("mid","")
	return false;
}

function UpdateLocationDetails(args) {
	var m = args["marker"];
	ExecuteSearch("","","","","",m.point.latitude,m.point.longitude);		
}

function ExecuteSearch(street, city, state, postal, country, latitude, longitude, useAlternate) {
	var form = useAlternate ? DirectionsForm : SearchForm;
	var id = "#" + form.attr("id") + "\\:";
	form.find(id+"street").val(street);
	form.find(id+"city").val(city);
	form.find(id+"state").val(state);
	form.find(id+"postal").val(postal);
	form.find(id+"country").val(country);
	form.find(id+"latitude").val(latitude);
	form.find(id+"longitude").val(longitude);
	// TODO: fix this hack. for some reason FF doesn't click without it
	setTimeout(function(){form.find(id+"execute").click();},0);
	return false;
}

function AbortSearch() {
	if (A4J.AJAX._eventsQueues.execute) {
		if (A4J.AJAX._eventsQueues.execute.request) {
			A4J.AJAX._eventsQueues.execute.request.abort();
		}
		A4J.AJAX._eventsQueues.execute = false;
	}
	LoadingScreen(false);
	return false;
}

function ClearForm(directionsForm) {
	if (directionsForm) {
		DirectionsInputs.val("").blur().filter(":first").focus();
	} else {
		SearchInputs.val("").blur().filter(":first").focus();
	}
	return false;
}

function ResetSearch(leaveMap) {
	SearchInputs.add(DirectionsInputs).filter(":hidden").val("");
	EnableSearch(true);
	if (!leaveMap) {
		HideNoMarkerInfo();
		Map.unmarkAll();
		DirectionsEnd.removeAttr("pid").add(PlacesLocation).add(DirectionsStart).add(ClickModeData).removeAttr("mid");
		PlacesLocation.show();
		PlacesSets.show();
		PlacesSetsInputs.attr("checked","checked");
		DirectionsInputs.filter(":text").val("").blur();
		$(document.body).removeClass("active");
	}
}

function EnableSearch(enable) {
	if (enable) {
		TabContent.find(":input").removeAttr("disabled").removeAttr("readonly");
		ClickModeButtons.children("img").each(function() {
			$(this).attr("src", $(this).attr("src").replace("-a","-i"));
		});
	} else {
		TabContent.find(":input").attr({disabled:"disabled", readonly:"readonly"});
		ClickModeButtons.children("img").each(function() {
			$(this).attr("src", $(this).attr("src").replace("-i","-a"));
		});
	}
}

function SearchSubmitted(useAlternate) {
	var inputs = useAlternate ? DirectionsInputs : SearchInputs;
	inputs.each(function() {
		if ($(this).hasClass("text-hint")) {
			$(this).val("");
		}
	});
	if (inputs.filter("[value!='']").length) {
		LoadingScreen(true);
		return true;
	} else {
		return false;
	}
}

function SearchReturned() { //(request, event, data) {
	ResetSearch();	

	var count = parseInt(SearchForm.find("#search-form\\:search-count .addresses").text());
	if (count == 1) {
		InitializeAjaxMembers();
		InitializeAjaxEvents();
		
		PlacesLocation.children("address").replaceWith(TabContent.find("#places-new address"));
		if (PlacesResultsMsg.length) {
			PlacesSets.hide();
		}

		SetView("#search-edit, #places-results, #directions-places");
		
		// Set Markers
		var m = new MapMarker(new MapPoint(PlacesLocation.find(".latitude").text(), PlacesLocation.find(".longitude").text()));
		m.icon = new MapMarkerIcon("images/markers/selected.png", new MapPixel(26,32));
		m.icon.offset = new MapPixel(13,32);
		m.draggable = true;
		m.bind("drag", UpdateStartDetails);
		m.bind("dragend", UpdateLocationDetails);
		m.tooltip = PlacesLocation.attr("mtitle");
		Map.mark(m);
		PlacesLocation.attr("mid", m.id);
		PlacesLocation.find(".latitude").text(PrintCoordinates(m.point.latitude,true,true));
		PlacesLocation.find(".longitude").text(PrintCoordinates(m.point.longitude,false,true));
		
		if (MarkProperties()) {
			PlacesLocation.click();
		} else {
			Map.setPosition(m.point, 10);
		}
		ClickTab(1);
		
		var id = "#" + DirectionsForm.attr("id") + "\\:";
		DirectionsInputs.filter(id+"street").val(PlacesLocation.find(".street").text());
		DirectionsInputs.filter(id+"city").val(TrimEnd(PlacesLocation.find(".city").text(),','));
		DirectionsInputs.filter(id+"state").val(PlacesLocation.find(".state").text());
		DirectionsInputs.filter(id+"postal").val(PlacesLocation.find(".postal").text());
		DirectionsInputs.filter(id+"country").val(PlacesLocation.find(".country").text());
		DirectionsInputs.filter(":text").removeClass("text-hint").blur();
	} else {
		SetView("#search-vague, #places-search, #directions-search");
		ClickTab(0);
	}
	LoadingScreen(false);
}

function MarkProperties() {
	var count = 0;
	PlacesResults.not("[uid]").each(function() {
		if ($(this).attr("pvalid") == "true") {
			var data = $(this).find("tfoot tr");
			var m = new MapMarker(new MapPoint(data.find("th .latitude").text(), data.find("th .longitude").text()), data.find("td").html());
			m.icon = new MapMarkerIcon("images/markers/circle"+$(this).attr("pid")+".gif", new MapPixel(21,23));
			m.icon.offset = new MapPixel(8,9);
			m.bind("click", ShowResultsDetailsHandler);
			m.tooltip = PlacesSets.attr("mtitle");
			$(this).add(UnitResults.filter("[pid="+$(this).attr("pid")+"]")).attr("mid", m.id);
			Map.mark(m);
			count++;
		}
	});
	return count;
}


// Places Functions

function ShowResultsDetails(obj) {
	PlacesResults.removeClass("active");
	obj.add(document.body).addClass("active");
	HideNoMarkerInfo();
	if (obj.attr("pvalid") == "true") {
		var mid = obj.attr("mid");
		Map.frameMarkers([PlacesLocation.attr("mid"),mid]);
		var content = null;
		if (obj.attr("uid")) {
			content = obj.find("tfoot td").html();
		}
		Map.showMarkerContent(mid,content);
		DirectionsEnd.attr("pid", obj.attr("pid"));
		NavigationViews.filter("#directions-places").hide();
		NavigationViews.filter("#directions-results").show();
	} else {
		Map.hideMarkerContent();
		NoMarkerInfo.append(obj.find("tfoot div.marker-info").clone()).show();
		DirectionsEnd.removeAttr("pid");
		NavigationViews.filter("#directions-results").hide();
		NavigationViews.filter("#directions-places").show();
	}
	ClickTab(1);
	return false;
}
function ShowResultsDetailsHandler(args) {
	return ShowResultsDetails(ProximityResults.filter("[mid="+args["marker"].id+"]"));
}
function ShowPropertyDetails(pid) {
	return ShowResultsDetails(ProximityResults.filter("[pid="+pid+"]"));
} 
function ShowUnitDetails(uid) {
	return ShowResultsDetails(UnitResults.filter("[uid="+uid+"]"));
}

function HideNoMarkerInfo() {
	NoMarkerInfo.hide().find("div.marker-info").remove();
	return false;
}

function ResetMarkers() {
	var mids = new Array();
	TabContent.find("#places-results > div:visible > table:visible").each(function() {
		mids.push($(this).attr("mid"));
	});
	mids = $.unique(mids);
	ProximityResults.each(function() {
		var mid = $(this).attr("mid");
		Map.setMarkerVisibility(mid, ($.inArray(mid, mids) >= 0))
	});
}



// Directions Functions

function SetDirectionsView(viewable) {
	viewable = viewable || "#directions-start";
	if (viewable == "#directions-start") {
		if (DirectionsViews.filter(viewable).children("address").children().length) {
			if (Map.getDirections() && Map.getDirections().steps && Map.getDirections().steps.length) {
				DirectionsEmpty.hide();
				DirectionsSteps.show();
			} else {
				DirectionsSteps.hide();
				DirectionsEmpty.show();
			}
		} else {
			ClickTab(1);
			viewable = "#directions-edit";
		}
	} else {
		DirectionsSteps.hide();
		DirectionsEmpty.hide();
	}
	DirectionsViews.not(DirectionsViews.filter(viewable).show()).hide();	
}

function UpdateStartDetails(args) {
	var m = args["marker"];
	var loc = TabContent.find(".location[mid="+m.id+"]");
	loc.find(".latitude").text(PrintCoordinates(m.point.latitude,true,true));
	loc.find(".longitude").text(PrintCoordinates(m.point.longitude,false,true));
	loc.find("address").addClass("point");
}

function UpdateStartDirections(args) {
	dirFrame = true;
	UpdateStartDetails(args);
}

function ShowDirections(start) {
	var ready = false;
	var redraw = false;
	
	// Start Point
	if (DirectionsStart.attr("mid")) {
		if (Map.getMarker(DirectionsStart.attr("mid"))) {
			ready = true;
			if (start) {
				Map.moveMarker(DirectionsStart.attr("mid"),start);
				redraw = true;
			}
		} else {
			DirectionsStart.removeAttr("mid");
		}
	} 
	if (!DirectionsStart.attr("mid")) {
		var pl = Map.getMarker(PlacesLocation.attr("mid"));
		if (pl || start) {
			if (pl && !start) {
				start = pl.point;
				DirectionsStart.children("address").replaceWith(PlacesLocation.find("address").clone());
			}
			if (start) {
				var m = new MapMarker(start);
				m.icon = new MapMarkerIcon("images/markers/start.png", new MapPixel(26,32));
				m.icon.offset = new MapPixel(13,32);
				m.draggable = true;
				m.bind("drag", UpdateStartDetails);
				m.bind("dragend", UpdateStartDirections);
				m.tooltip = DirectionsStart.attr("mtitle");
				Map.mark(m);
				DirectionsStart.attr("mid", m.id);
			}
			redraw = true;
			ready = true;
		} else {
			SetDirectionsView("#directions-edit");
		}
	}
	Map.setMarkerVisibility(DirectionsStart.attr("mid"),true);
	
	// End Point
	var end = ProximityResults.filter("[pid="+DirectionsEnd.attr("pid")+"]");
	if (end.length) {
		var point = new MapPoint(end.find("tfoot .latitude").text(), end.find("tfoot .longitude").text());
		var redrawEnd = false;
		if (DirectionsEnd.attr("mid")) {
			var m = Map.getMarker(DirectionsEnd.attr("mid"));
			if (m) {
				if (m.point.latitude != point.latitude ||  m.point.longitude != point.longitude) {
					Map.moveMarker(m.id, point);
					redrawEnd = true;
				}
			} else {
				DirectionsEnd.removeAttr("mid");
			}
		}
		if (!DirectionsEnd.attr("mid")) {
			var m = new MapMarker(point);
			m.icon = new MapMarkerIcon("images/markers/end.png", new MapPixel(26,32));
			m.icon.offset = new MapPixel(13,32);
			m.clickable = false;
			m.tooltip = DirectionsEnd.attr("mtitle");
			Map.mark(m);
			DirectionsEnd.attr("mid", m.id);
			redrawEnd = true;
		}
		if (redrawEnd) {
			DirectionsEnd.children("address").replaceWith(end.find("thead address").clone());
			var street = DirectionsEnd.find(".street");
			street.text(TrimEnd(street.text(),','));
			redraw = true;
		}
		Map.setMarkerVisibility(DirectionsEnd.attr("mid"),true);				
	} else {
		ready = false;
	}

	// Route
	if (ready) {
		if (redraw) {
			ClearDirectionsPane();
			dirFrame = true;
			Map.setDirections([DirectionsStart.attr("mid"),DirectionsEnd.attr("mid")],GenerateRoute);	
		} else {
			Map.setDirectionsVisibility(true);
		}
	}
}

function GenerateRoute() {
	var directions = Map.getDirections();

	if (directions) {
		var unit = Map.getMapUnit();

		if (directions.steps && directions.steps.length) {
			DirectionsSummary.text(dirFormat.replace("{0}",PrintDistance(directions.distance,unit,true)).replace("{1}",PrintTime(directions.time)));
		
			DirectionsItems.empty();
			for (var i in directions.steps) {
				$("<tr/>").append($("<th/>").text((i*1+1) + ". " + directions.steps[i].instruction)).append($("<td/>").text(PrintDistance(directions.steps[i].distance,unit))).attr("step",i).click(function() {		
					Map.framePoints([directions.steps[$(this).attr("step")].point]);
				}).appendTo(DirectionsItems);
			}
			
			DirectionsEmpty.hide();
			DirectionsSteps.show()
		} else {
			DirectionsEmpty.find(".summary span").text(PrintDistance(directions.distance,MapUnits.Miles) + " / " + PrintDistance(directions.distance,MapUnits.Kilometers));
						
			DirectionsSteps.hide();
			DirectionsEmpty.show();
		}
		
		if (dirFrame) {
			Map.frameDirections();
			SetView("#search-edit, #places-results, #directions-results");
			SetDirectionsView();
			ClickTab(2);
			dirFrame = false;
		}
	}
}

function ClearDirectionsPane() {
	DirectionsSummary.text(dirFormat.replace("{0}",PrintDistance(0,Map.getMapUnit(),true)).replace("{1}",PrintTime(0)));
	DirectionsItems.empty();
}

function RequestRoute(pid) {
	DirectionsEnd.attr("pid", pid);
	ClickTab(2);
	return false;
}

function DirectionsSearch(street, city, state, postal, country, latitude, longitude) {
	if (latitude && longitude) {		
		DirectionsStart.children("address").replaceWith(DirectionsResults.find("#directions-new address").clone());
		DirectionsStart.find(".street").text(street);
		DirectionsStart.find(".city").text(city + (city.length ? "," : ""));
		DirectionsStart.find(".state").text(state);
		DirectionsStart.find(".postal").text(postal);
		DirectionsStart.find(".country").text(country);
		DirectionsStart.find(".latitude").text(PrintCoordinates(latitude,true,true));
		DirectionsStart.find(".longitude").text(PrintCoordinates(longitude,false,true));
		if (street.length || city.length || state.length || postal.length || country.length) {
			DirectionsStart.children("address").removeClass("point");
		} else {
			DirectionsStart.children("address").addClass("point");
		}
		ShowDirections(new MapPoint(latitude, longitude));
	} else {
		ExecuteSearch(street, city, state, postal, country, latitude, longitude, true);
	}
	return false;
}

function DirectionsSearchReturned() {  //(request, event, data) {
	ResetSearch(true);
	
	DirectionsInputs.filter(".text-hint").each(function() {
		$(this).blur();
	});

	var count = parseInt(DirectionsForm.find("#directions-form\\:directions-count .addresses").text());
	if (count == 1) {
		DirectionsStart.children("address").replaceWith(DirectionsResults.find("#directions-new address").clone());
		var point = new MapPoint(DirectionsStart.find(".latitude").text(), DirectionsStart.find(".longitude").text());
		DirectionsStart.find(".latitude").text(PrintCoordinates(point.latitude,true,true));
		DirectionsStart.find(".longitude").text(PrintCoordinates(point.longitude,false,true));		
		ShowDirections(point);
		SetDirectionsView();
	} else {
		SetDirectionsView("#directions-vague");
	}
	ClickTab(2);
	LoadingScreen(false);
}

function DisableUnit(val) {
	UnitButtons.filter(".disabled").removeClass("disabled").each(function() {
		$(this).attr({title:$(this).attr("alt"), alt:$(this).attr("title")});
	});
	UnitButtons.filter("[href="+val+"]").addClass("disabled").each(function() {
		$(this).attr({title:$(this).attr("alt"), alt:$(this).attr("title")});
	});
}
