var _tmplCache = {}
this.parseTemplate = function(str, data) {
    var err = "";
    try {
        var func = _tmplCache[str];
        if (!func) {
            var strFunc =
            "var p=[],print=function(){p.push.apply(p,arguments);};" +
                        "with(obj){p.push('" +

            str.replace(/[\r\t\n]/g, " ")
               .replace(/'(?=[^#]*#>)/g, "\t")
               .split("'").join("\\'")
               .split("\t").join("'")
               .replace(/<#=(.+?)#>/g, "',$1,'")
               .split("<#").join("');")
               .split("#>").join("p.push('")
               + "');}return p.join('');";

            //alert(strFunc);
            func = new Function("obj", strFunc);
            _tmplCache[str] = func;
        }
        return func(data);
    } catch (e) { err = e.message; }
    return "< # ERROR: " + err.htmlEncode() + " # >";
}

// Takes a 10 digit phone number 2085551234 and returns (208) 555-1234.
// The orginal phone number is returned if it is not 10 characters containing digits only.
var formatPhone = function(phone) {
    var regex = /^(\d{3})(\d{3})(\d{4})$/;
    var phoneParts = regex.exec(phone);
    return (phoneParts.length == 4) ? "(" + phoneParts[1] + ") " + phoneParts[2] + "-" + phoneParts[3] : phone;
}

function getParameterByName( name )
{
  name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
  var regexS = "[\\?&]"+name+"=([^&#]*)";
  var regex = new RegExp( regexS );
  var results = regex.exec( window.location.href );
  if( results == null )
    return "";
  else
    return decodeURIComponent(results[1].replace(/\+/g, " "));
}

var avMap = function() {
	var map;
	var mapCenter = new google.maps.LatLng(33.576200130000004, -117.72858243499999);
	var mapOptions = {
		zoom: 13,
		center: mapCenter,
		disableDefaultUI: true,
		mapTypeId: google.maps.MapTypeId.ROADMAP,
		draggable: false,
		disableDoubleClickZoom: true,
		keyboardShortcuts: false,
		scrollwheel: false
	};
	
	var cityLimitsOptions = {
		path: avCityLimitCoordinates,
		strokeColor: "#0000ff",
		strokeOpacity: 0.8,
		strokeWeight: 2
	};
	var circleOptions = {
		radius: 300,
		strokeColor: "#FF0000",
		strokeWeight: 2
	};
	var circle = new google.maps.Circle(circleOptions);

	var markerShape = {
		coord: [0, 0, 0, 19,18,19,18,0],
		type: 'poly' 
	};
	var markers = new Array(); 
	var infoWindow = new google.maps.InfoWindow({maxWidth: 250});
	
	//Re-centers the map after the InfoWindow is closed.  This is needed
	//because the draggabilty of the map has been disabled.
	google.maps.event.addListener(infoWindow, "closeclick", function() {
		map.setCenter(mapCenter);
	});
    	
	var cityLimitsPolyline = new google.maps.Polyline(cityLimitsOptions);
	
	function createMarkerImage(url) {
		return new google.maps.MarkerImage(url, 
			new google.maps.Size(18,19),
			new google.maps.Point(0,0),
			new google.maps.Point(9,9));
	}
	
	function createMarkerShadow(url) {
		return new google.maps.MarkerImage(url,
			new google.maps.Size(32,19),
			new google.maps.Point(0,0),
			new google.maps.Point(9,9));
	}
	
	
 	function setMarkers(map, locations, areaId) {
 		for(var i = 0; i < locations.length; i++) {
 			var area = locations[i];
 			var latlng = new google.maps.LatLng(area.Location[0], area.Location[1]);
 			var marker = new google.maps.Marker({
 				position: latlng,
 				map: map,
 				shadow: createMarkerShadow(area.MarkerShadow),
 				icon: createMarkerImage(area.MarkerImage),
 				shape: markerShape,
 				title: area.Name
 			});
 			marker.set('area', area);
 			google.maps.event.addListener(marker, "click", function(event) {
				var area = this.get('area');
				setSelectedLocation(area);
				
				var infoWindowHtml = parseTemplate($("#MarkerTemplate").html(), { area : area } );
 				infoWindow.setContent(infoWindowHtml);
 				infoWindow.open(map, this);
 				
 				highlightMarker(this);
 				
 				clearListings();
				if (area.Category == 8 || !area.Category)
				{
 					loadListingsByArea(area);	 				
 				}
 			});
 			markers.push(marker);
 		}
 	}
 	
 	function highlightMarker(marker) {
 		circle.setCenter(marker.getPosition());
 		circle.setMap(map);
 	}
 	
 	function loadListingsByArea(area) {
 	    $("#av-map-listings h3").show();
 		$("#av-map-listings-list").show();
 		
 		getListings(area.AreaId);
 	}
 	
 	function setSelectedLocation(location) {
		var selectedLocationHtml = parseTemplate($("#SelectedLocationTemplate").html(), { area : location } );
		$("#av-map-selected-location").html( selectedLocationHtml ).show("fast");
 	}
 	
 	function clearListings() {
 	    $("#av-map-listings h3").hide();
 		$("#av-map-listings-list").hide();
 	}
 	
 	function getListings(areaId) {
		$.getJSON("/map/data/getshoppinglisting.php", {areaid: areaId}, function(json){
		   setListings(json);
		});
 	}
 	
 	function setListings(listings) {
 		var s = parseTemplate($("#ListingTemplate").html(), { listings : listings } );
 		$("#av-map-listings-list").html(s);
 		$("#av-map-listings-list dl dt a").click(function() {
 			$(this).parent().parent().children("dd").toggle("fast");
 			$(this).parent().parent().children("dt").toggleClass("collapse");
 			$(this).parent().parent().children("dt").toggleClass("expand");
 			return false;
 		});
 	}
 	
 	function clearMarkers() {
 		infoWindow.close();
 		circle.setMap(null);
 		for(var i = 0; i < markers.length; i++) {
 			markers[i].setMap(null);
 		}
 		markers.length = 0;
 		map.setCenter(mapCenter);
 	}
 	
 	//Returns the integer part of an element id were id uses the format [name]_[id].
 	//If element id does not follow the expected format then -1 is returned.
 	//Example: element.id='Category_1' returns 1
 	function getElementIdAsInt(element) {
 	    var elementIdRegex = /^(\w+)_(\d+)$/;
 	    var elementIdParts = elementIdRegex.exec($(element).attr('id'));
 	    return (elementIdParts.length == 3) ? elementIdParts[2] : -1;
 	}
 	
 	function onMapLegendClicked() {
 		loadMapByCategory(this);
 		return false;
 	}
 	
 	function loadMapByCategory(element) {
 	    //Update the legend and show selected category.
 		$("#av-map-legend a").removeClass("av-active");
 		$(element).addClass("av-active");
 		$("#av-map-listings-title").text($(element).attr("title")).attr("class", $(element).attr("class"));
 		
		//Update the map with markers for category. 		
 		clearMarkers();
 		var categoryId = getElementIdAsInt(element);
 		
 		if (categoryId == 2) {
	 		$.getJSON("/map/data/getmaplocations.php", function(json){
			   setMarkers(map, json, 1);
			   if (markers.length > 0) {
			    setSelectedLocation(markers[0].get('area'));
			   	loadListingsByArea(markers[0].get('area'));
			   	highlightMarker(markers[0]); 
			   }
			});
		} else if (categoryId == 8) {
		  clearListings();
	 		$.getJSON("/map/data/getcityfacilities.php", {category: categoryId}, function(json){
			   setMarkers(map, json, 1);
			   if (markers.length > 0) {
			    setSelectedLocation(markers[0].get('area'));
			   	loadListingsByArea(markers[0].get('area'));
			   	highlightMarker(markers[0]); 
			   }
			});		  
		} else {
			clearListings();

	 		$.getJSON("/map/data/getcityfacilities.php", {category: categoryId}, function(json){
			   setMarkers(map, json, 1);
			   if (markers.length > 0) {


					setSelectedLocation(markers[0].get('area'));
					highlightMarker(markers[0]); 

			   	
			   }
			});
		}
 	}
	
	return {
		Init : function() {
			$.getScript("/map/js/jquery.blockUI.js", avMap.OnLoad);
		},
		OnLoad : function() {		
			//Map Init
			map = new google.maps.Map(document.getElementById("av-map-googlemap"), mapOptions);	
			cityLimitsPolyline.setMap(map);	
			
			//Legend Init	
			$("#av-map-legend a").click(onMapLegendClicked);
			
			//AJAX Init
			$("#av-errors").ajaxError(function(event, request, settings) {
				$(this).text("AJAX Error");
			});
		    $("#av-map-listings").ajaxStart(function() {
		        $(this).block({
		            message: 'Loading...',
		            css: { border: '2px solid #a00' }
		        });
		    }).ajaxStop(function() {
		        $(this).unblock();
		    });	
		    
		    //Default map view.
			var category = 2;
			
			var queryCategory = getParameterByName("category");
			if (queryCategory && queryCategory > 0 && queryCategory < 8)
				category = queryCategory;
			
			loadMapByCategory($("#category_" + category));		
		}
	};
}();
google.load("jquery", "1.4.2");
google.setOnLoadCallback(avMap.Init);
