﻿// variables
var _defaultMapCenter = null
var _defaultMapZoom = null;


String.format =
	function()
	{
		var currentString = null;
		if (arguments.length != 0)
		{
			currentString = arguments[0];
			for (var argumentIndex = 1; argumentIndex < arguments.length; argumentIndex++)
			{
				var modifiedString = new RegExp('\\{' + (argumentIndex - 1) + '\\}','gm');
				currentString = currentString.replace(modifiedString, arguments[argumentIndex]);
			}
		}
		
		return currentString;
	};

// This function is called once after the Google Map has loaded
function postPopulateMap()
{
	var googleMap = _grosvenorMap.getGoogleMap();
	_defaultMapCenter = googleMap.getCenter();
	_defaultMapZoom = googleMap.getZoom();

	updateGoogleMap();
}

// Calculates the image used for the index for a result list item
function getResultItemImage(index, selected)
{
	var imageURL = "";
	if (selected)
	{
		imageURL = String.format("/images/Map/resultItem-{0}-selected.gif", index);
	}
	else
	{
		imageURL = String.format("/images//Map/resultItem-{0}.gif", index);
	}
	
	return imageURL
}

function getAdditionalPlaceImage()
{
	return imageURL = "/images/Map/propertyLocation.gif";
}

// Creates an individual result item's HTML
function createResultItem(retailerModel, index)
{
	var resultItemHTML = 
		"<li class='googlelist'>" +
			"<img src='{0}' alt='{1}' />" +
			"<div>" +
			  "<a>{2} <small>({5})</small></a>" +
			  "<p>{3}<br />{4}</p>" +
			"</div>" + 
		"</li>";

	resultItemHTML = String.format(
		resultItemHTML,
		getResultItemImage(index, false),
		index,
		retailerModel.placeName,
		retailerModel.fullAddress,
		retailerModel.telephone,
		retailerModel.subCategory);
			  
	return resultItemHTML;
}

// Sets the image source of result list item dependent on state
function setResultListItemImage(resultListItemJQ, selected)
{
	var imageSource = getResultItemImage(resultListItemJQ[0].retailerModel.listItemIndex, selected);
	$("img", resultListItemJQ).attr("src", imageSource);
}

// Removes the selected class from selected list items.
// Resets the item image to default for the list item
function clearSelectedResultListItem()
{
	var selectedListItemsJQ = $(".retailerResultsContainer .results .googlelist-selected");
	
	selectedListItemsJQ.each(
		function()
		{
			setResultListItemImage($(this), false);
		});
	
	selectedListItemsJQ.removeClass("googlelist-selected");
}

// Resets previous selected item to normal.
// Sets current selected item to selected state
function styleSelectedResultItem(resultListItemJQ)
{
	clearSelectedResultListItem();
	resultListItemJQ.addClass("googlelist-selected");
	
	setResultListItemImage(resultListItemJQ, true);
}

// Display the placemarker associated with a ListItem
function showPlacemarker(listItemJQ)
{
	var placeMarker = listItemJQ[0].retailerModel.placeMarker;
	placeMarker.openInfoWindowHtml(placeMarker.infoWindowHTML);
}

function displayNoResults(resultsContainerJQ)
{
	resultsContainerJQ.append("<p>Your search did not find any Retailers.</p>");
}

// Iterates of the Retailer List, creating HTML for each item and added it to the Results container
function updateSearchResults(retailerList)
{
	var itemIndex = 1;
	var retailerModel;
	var resultItemHTML = "";
	var resultItemJQ;
	var resultsContainerJQ = $(".retailerResultsContainer .results");
	resultsContainerJQ.empty();

	if (retailerList.length > 0)
	{
		// Creates all the result items
		for (index = 0; index < retailerList.length; index++)
		{
			retailerModel = retailerList[index];
			resultItemHTML = createResultItem(retailerModel, itemIndex);

			resultItemJQ = $(resultItemHTML);
			// Attach the index for the specific RetailerItem
			retailerModel.listItemIndex = itemIndex;
			resultItemJQ[0].retailerModel = retailerModel;
			
			resultsContainerJQ.append(resultItemJQ);
			
			if ((++itemIndex) > 10)
			{
				itemIndex = 1;
			}
		}
		
		//  Bind click event to the Result Item
		$("li.googlelist", resultsContainerJQ).click(
			function()
			{
				var listItemJQ = $(this);
				// Set the item as selected
				styleSelectedResultItem(listItemJQ);
				
				// Display the place marker
				showPlacemarker(listItemJQ);
			});
		
		// Convert result list into a paged result list with navigation
		resultsContainerJQ.pager(
			'li.googlelist',
			{
				navigationAttachPositions: ['append', 'prepend'],
				nextPageText: '&nbsp;',
				previousPageText: '&nbsp;',			
				rowsPerPage: 10,
				pagesPerMenu: 10,
				customMessage: 'Page %p of %pt',
				navigationClass: 'pagination',
				customMessageClass: 'pagination-numpages',
				highlightClass: 'pagingCurrentPage',
				pagingLinksContainerClass: 'pagination-prevnext',
				pageIndexClass: 'pagination-num',
				pagingQuickLinksClass: 'pagination-image',
				previousPageClass: 'pagination-previous',
				nextPageClass: 'pagination-next'
			});
			
		resultsContainerJQ.pager.onChange = pagerOnChange;
	}
	else
	{
		displayNoResults(resultsContainerJQ);
	}
	
	updateGoogleMap();
}

function resetMapBounds()
{
	// Reset Map location and zoom
	_grosvenorMap.getGoogleMap().setCenter(_defaultMapCenter, _defaultMapZoom);
}

// Removes all PlaceMarkers from the Map
function clearMarkers()
{
	_grosvenorMap.getGoogleMap().clearOverlays();
	resetMapBounds();
}

// If the image src is not found, then use a default image
function processImageError(element)
{
	var retailerThumbnailJQ = $(element);
	retailerThumbnailJQ.attr("src", "/Images/Map/missingThumbnail.gif");
	retailerThumbnailJQ.attr("title", "missing thumbnail");
	retailerThumbnailJQ.attr("alt", "missing thumbnail");
}

// Formats the website url to be fully qualified.
function cleanWebsiteAddress(websiteAddress)
{
	var cleanAddress = websiteAddress.toLowerCase();
	var urlPrefix = "http://";

	if (cleanAddress.substring(0, 7) !== urlPrefix)
	{
		cleanAddress = urlPrefix + cleanAddress;
	}
	
	return cleanAddress;
}

// Create the html with details to be used for the Information Windows on the map
function buildMapInfoWindow(retailerModel)
{
	var websiteAddressHTML = "";
	// Add a link to 
	if (retailerModel.website != "")
	{
		websiteAddressHTML = String.format(
			"<p>" +
				"<a href='{0}' target='_blank'>view website</a>" +
				"<img class='externalLink' alt='view external website' src='../images/Map/externalLink.gif'/>" +
			"</p>",
			cleanWebsiteAddress(retailerModel.website));
	}
	
	var informationBoxHTML = String.format(
		"<div class='info-content'>" +
			"<h2>{0}</h2>" + 
			"<p>{1}<br />" +
			"{2}</p>" +
			"<p>{3}</p>" +
			"{4}" +
		"</div>",
		retailerModel.placeName,
		retailerModel.fullAddress,
		retailerModel.telephone,
		retailerModel.description,
		websiteAddressHTML);

	return informationBoxHTML;
}

function buildAdditionalPlaceInfoWindow(description)
{
	// Currently assumes the input is HTML encoded.
	return description;
}

function highlightResultListItem(retailerItemJQ)
{
	styleSelectedResultItem(retailerItemJQ);
}

function createPlaceMarker(retailerItemJQ)
{
	var placeMarker = null;
	var position = null;
	var retailerModel = retailerItemJQ[0].retailerModel;
	
	if (retailerModel.placeMarker)
	{
		placeMarker = retailerModel.placeMarker;
	}
	else
	{
		position = new GLatLng(retailerModel.latitude, retailerModel.longitude);
		
		var icon = new GIcon();
		icon.image = getResultItemImage(retailerModel.listItemIndex, false);
		icon.iconSize = new GSize(15, 19);
		icon.iconAnchor = new GPoint(8, 11);
		icon.infoWindowAnchor = new GPoint(8, 11);
		placeMarker = new GMarker(position,
			{
				draggable: false,
				icon: icon
			});

		var infoWindowHTML = buildMapInfoWindow(retailerModel);
		placeMarker.bindInfoWindowHtml(infoWindowHTML);
		placeMarker.infoWindowHTML = infoWindowHTML;
		
		GEvent.addListener(placeMarker, "click",
			function()
			{
				highlightResultListItem(retailerItemJQ);
			});
			
		retailerModel.placeMarker = placeMarker;	
	}
	
	return placeMarker;
}

// Allows markers to be placed above others
function layerOrderCallback(marker, unusedParameter)
{
	return 1;
}

function createAdditionalPlaceMarker(additionalPlaceJQ)
{
	var placeMarker = null;
	var position = null;
	var latitude = $(".latitude", additionalPlaceJQ).val();
	var longitude = $(".longitude", additionalPlaceJQ).val();
	var description = $(".description", additionalPlaceJQ).val();
	
	position = new GLatLng(latitude, longitude);
	
	
	var icon = new GIcon();
	icon.image = getAdditionalPlaceImage();
	icon.iconSize = new GSize(32, 32);
	icon.iconAnchor = new GPoint(16, 16);
	icon.infoWindowAnchor = new GPoint(16, 16);
	placeMarker = new GMarker(position,
		{
			draggable: false,
			icon: icon,
			zIndexProcess: layerOrderCallback
		});

	var infoWindowHTML = buildAdditionalPlaceInfoWindow(description);
	placeMarker.bindInfoWindowHtml(infoWindowHTML);
	placeMarker.infoWindowHTML = infoWindowHTML;
	
	return placeMarker;
}

function updateGoogleMap()
{
	if (_grosvenorMap != null)
	{
		// Obtain the items from the visible list from the search results
		var visibleListItemsJQ = $(".retailerResultsContainer .results .googlelist:visible");
		
		// Obtain the items of the additional places to add to the Map
		var additionalPlacesJQ = $(".additionalPlaces .additionalPlace");
		var mapDataBounds = new GLatLngBounds();
		var googleMap = _grosvenorMap.getGoogleMap();
		
		clearMarkers();
		
		googleMap.clearOverlays();

		visibleListItemsJQ.each(
			function()
			{
				var placeMarker = createPlaceMarker($(this));
				mapDataBounds.extend(placeMarker.getPoint());
				_grosvenorMap.addMarker(placeMarker);
			});
			
		additionalPlacesJQ.each(
			function()
			{
				var placeMarker = createAdditionalPlaceMarker($(this));
				mapDataBounds.extend(placeMarker.getPoint());
				_grosvenorMap.addMarker(placeMarker);
			});
			
		// Reset the viewport to encompass all placeholders, only if they or additional places
		// have been added to the map
		if (
			(visibleListItemsJQ.length > 0)
			||
			(additionalPlacesJQ.length > 0))
		{	
			googleMap.setZoom(googleMap.getBoundsZoomLevel(mapDataBounds));
			googleMap.setCenter(mapDataBounds.getCenter());
		}
	}
}

function pagerOnChange()
{
	updateGoogleMap();
}

// Calls the server with the Categorisation Type and ID and retrieves a list of Retailers
function retrieveServerData(categorisationType, categorisationID)
{
	var businessHandler = new BusinessHandler();
	var retailerListString = businessHandler.GetRetailers(categorisationType, categorisationID);
	var retailerList = eval(retailerListString);
	
	updateSearchResults(retailerList);
}

// Calls the server for data on the Categorisation Type and ID and
// populates the list and map
function populateResults(categorisationType, categorisationID)
{
	var resultsArePopulated = false;
	
	if (categorisationID > 0)
	{
		retrieveServerData(categorisationType, categorisationID);
		resultsArePopulated = true;
	}
	
	return resultsArePopulated;
}

