﻿
// Global Variables.
var map = null;
var ucSearchResultsMap = null;
var infoBox = null;
var mapContainer = null;
var selectedZIndex = 10001;
var centroidZIndex = 999;

(function($) {

    window["load_AutoOwners_AgencyLocator_ucSearchResultsMap"] = function(obj) {
        var ucSearchResultsMapLoadFunctionInterval = setInterval(function() { 
            if (typeof VEMap !== "undefined" && document.getElementById("search_results_map").attachEvent !== undefined) 
            {
                if (ucSearchResultsMapLoadFunctionInterval)
                {
                    clearInterval(ucSearchResultsMapLoadFunctionInterval);
                }
                
                ucSearchResultsMapLoadFunction(obj);
            } 
        }, 100);
    };
    
    
    var ucSearchResultsMapLoadFunction = function(obj) {
        
        // Variables.
        ucSearchResultsMap = {};
        ucSearchResultsMap.Agencies = [];
        ucSearchResultsMap.SelectedAgency = null;
        ucSearchResultsMap.SelectedClusterID = null;
        ucSearchResultsMap.ClusteredShapes = null;
        ucSearchResultsMap.InfoBoxIsVisible = false;
        ucSearchResultsMap.ShowInfoBoxFlag = false;
        ucSearchResultsMap.WithholdMouseMove = false;
        ucSearchResultsMap.DirectionsVisible = false;
        ucSearchResultsMap.CentroidShape = null;
        ucSearchResultsMap.CentroidVisible = false;
        ucSearchResultsMap.UniqueShapeID = 1000;
        
        
        map = new VEMap("search_results_map");
        map.SetCredentials(obj.getState()["BingMapsKey"]);
        map.LoadMap();
        map.ClearInfoBoxStyles();
        map.SetMouseWheelZoomToCenter(false);
        $("#MSVE_navAction_View3DMapMode").remove();
        $("#MSVE_navAction_FlatlandMapMode").remove();
        $("#MSVE_navAction_separator0").remove();
        $("#MSVE_navAction_ObliqueMapView").remove();
        //map.SetClientToken(obj.getState()["ClientToken"]);
        
        mapContainer = $(".map_container");
        mapContainer.removeClass("loading");
        
        var mainLayer = new VEShapeLayer();
        mainLayer.SetTitle("Main Layer");
        map.AddShapeLayer(mainLayer);
        
        var directionsLayer = new VEShapeLayer();
        directionsLayer.SetTitle("Directions Layer");
        map.AddShapeLayer(directionsLayer);
        directionsLayer.Hide();
        
        
        // Map Events.
        var temp = {};
        temp.clusterShape = null;
        temp.shape = null;
        temp.agencyIndex = null;
        temp.shapeID = null;
        
        
        ucSearchResultsMap.isAgencyShape = function(shape) {
            return (typeof shape.AgencyIndex !== "undefined");
        };
        
        
        ucSearchResultsMap.isCentroidShape = function(shape) {
            return (typeof shape.IsCentroid !== "undefined");
        };
        
        
        ucSearchResultsMap.isClusterShape = function(shape) {
            return (typeof shape.ClusterSpecification !== "undefined");
        };
        
        
        ucSearchResultsMap.agencyIsSelected = function() {
            return (ucSearchResultsMap.SelectedAgency !== null);
        };
        
        
        ucSearchResultsMap.clusterIsSelected = function() {
            return (ucSearchResultsMap.SelectedClusterID !== null);
        };
        
        
        ucSearchResultsMap.centroidIsSelected = function() {
			return (ucSearchResultsMap.CentroidVisible === true);
        };
        
        
        
        var mouseOverMapHandler = function(mapEvent) {
            temp.shape = map.GetShapeByID(mapEvent.elementID);
            if (!temp.shape) { return; }
            
            temp.shapeID = mapEvent.elementID;
            
            if (ucSearchResultsMap.isCentroidShape(temp.shape))
            {
                if (ucSearchResultsMap.WithholdMouseMove === true) { ucSearchResultsMap.WithholdMouseMove = false; }
                
                if (ucSearchResultsMap.agencyIsSelected())
                {
                    ucSearchResultsMap.deselectAgency();
                }
                else if (ucSearchResultsMap.clusterIsSelected())
                {
                    ucSearchResultsMap.hideClusterInfo();
                }
                
                ucSearchResultsMap.showCentroidInfo(temp.shape);
            }
            else if (ucSearchResultsMap.isClusterShape(temp.shape))
            {
                if (ucSearchResultsMap.WithholdMouseMove === true) { ucSearchResultsMap.WithholdMouseMove = false; }
                
                if (ucSearchResultsMap.agencyIsSelected())
                {
                    ucSearchResultsMap.deselectAgency();
                }
                else if (ucSearchResultsMap.clusterIsSelected())
                {
                    ucSearchResultsMap.hideClusterInfo();
                }
                else if (ucSearchResultsMap.centroidIsSelected())
                {
					ucSearchResultsMap.hideCentroidInfo();
                }
                
                ucSearchResultsMap.showClusterInfo(temp.shape);
            }
            else if (ucSearchResultsMap.isAgencyShape(temp.shape))
            {
                if (ucSearchResultsMap.WithholdMouseMove === true) { ucSearchResultsMap.WithholdMouseMove = false; }
                
                if (ucSearchResultsMap.clusterIsSelected())
                {
                    ucSearchResultsMap.hideClusterInfo();
                }
                else if (ucSearchResultsMap.centroidIsSelected())
                {
					ucSearchResultsMap.hideCentroidInfo();
                }
                
                ucSearchResultsMap.selectAgency(temp.shape.AgencyIndex);
                ucSearchResultsMap.scrollToAgency(temp.shape.AgencyIndex);
            }
            
            return true;
        };
        
        
        var mouseMoveMapHandler = function(mapEvent) {
            if (!mapEvent.elementID)
            {
                if (ucSearchResultsMap.InfoBoxIsVisible === true && ucSearchResultsMap.ShowInfoBoxFlag === false)
                {
                    if (ucSearchResultsMap.WithholdMouseMove === true)
                    {
                        if (ucSearchResultsMap.MouseLeftInfoBox === true) { return; }
                        else { ucSearchResultsMap.WithholdMouseMove = false; }
                    }
                    
                    if (ucSearchResultsMap.agencyIsSelected())
                    {
                        ucSearchResultsMap.deselectAgency();
                    }
                    else if (ucSearchResultsMap.clusterIsSelected())
                    {
                        ucSearchResultsMap.hideClusterInfo();
                    }
                    else if (ucSearchResultsMap.centroidIsSelected())
					{
						ucSearchResultsMap.hideCentroidInfo();
					}
                    else
                    {
                        ucSearchResultsMap.hideInfoBox();
                    }
                }
            }
            
            return true;
        };
        
        var deselectAgencyHandler = function(mapEvent) {
            if (mapEvent.keyCode == 27)
            {
                if (ucSearchResultsMap.WithholdMouseMove === true) { ucSearchResultsMap.WithholdMouseMove = false; }
                ucSearchResultsMap.deselectAgency();
                return true;
            }
        };
        
        var mouseUpHandler = function(mapEvent) {
            if (ucSearchResultsMap.WithholdMouseMove === true) { ucSearchResultsMap.WithholdMouseMove = false; }
            map.AttachEvent("onmousemove", mouseMoveMapHandler);
            map.AttachEvent("onmouseover", mouseOverMapHandler);
            
            mouseOverMapHandler(mapEvent);
        };
        
        var mouseDownHandler = function(mapEvent) {
            ucSearchResultsMap.hideInfoBox();
            map.DetachEvent("onmousemove", mouseMoveMapHandler);
            map.DetachEvent("onmouseover", mouseOverMapHandler);
        };
        
        var viewChangeHandler = function(mapEvent) {
            ucSearchResultsMap.detachPushpinEvents();
        };
        
        var emptyHandler = function(mapEvent) { return true; };
        
        window.ero.hide = function() { return; };
        
        
        
        // Client Token Events - no longer in use. 
        /*
        var clientTokenExpireHandler = function() {
           obj.GetNewClientToken({
                onSuccess: function(result) {
                    map.SetClientToken(result.Result);
                }
           });
        };
        
        map.AttachEvent("ontokenexpire", clientTokenExpireHandler);
        */
        
        
        
        // Functions.
        ucSearchResultsMap.attachMapEvents = function() {
            map.AttachEvent("onmousemove", mouseMoveMapHandler);
            map.AttachEvent("onmouseover", mouseOverMapHandler);
            map.AttachEvent("onmousedown", mouseDownHandler);
            map.AttachEvent("onmouseup", mouseUpHandler);
            map.AttachEvent("onkeypress", deselectAgencyHandler);
            map.AttachEvent("onchangeview", viewChangeHandler);
        };
        
        ucSearchResultsMap.attachMapEvents(); // Call the function for first load.
        
        
        ucSearchResultsMap.detachMapEvents = function() { 
            map.DetachEvent("onmousemove", mouseMoveMapHandler);
            map.DetachEvent("onmouseover", mouseOverMapHandler);
            map.DetachEvent("onmousedown", mouseDownHandler);
            map.DetachEvent("onmouseup", mouseUpHandler);
            map.DetachEvent("onkeypress", deselectAgencyHandler);
            map.DetachEvent("onchangeview", viewChangeHandler);
        };
        
        
        ucSearchResultsMap.showStartingView = function() {
            // Show view of United States when no agencies are available to load. This is the starting view of the map.
            ucSearchResultsMap.disableMap();
            map.SetCenterAndZoom(new VELatLong(39.449999928474426, -98.90799969434738), 4);
        };
        
        
        ucSearchResultsMap.clearAgencies = function() {
            mainLayer.DeleteAllShapes();
            
            ucSearchResultsMap.Agencies = [];
            ucSearchResultsMap.SelectedAgency = null;
        };
        
        
        ucSearchResultsMap.addAgencies = function(agencies, centroid) {
            if (!agencies || agencies == null) { return; }
            
            ucSearchResultsMap.Agencies = [];
            
            for (var index = 0; index < agencies.length; index++)
            {
                var agencyShape = new VEShape(VEShapeType.Pushpin, new VELatLong(agencies[index].CurrentCoordinate.Latitude, agencies[index].CurrentCoordinate.Longitude));
                agencyShape.AgencyIndex = index;
                
                agencies[index].Shape = agencyShape;
                agencies[index].Shape.DoNotSerialize = true;
                
                ucSearchResultsMap.SetUnselectedPushpin(agencyShape);
                
                mainLayer.AddShape(agencyShape);
                ucSearchResultsMap.Agencies[index] = agencies[index];
            }
            
            
            // Enable Clustering.
            var clusteringOptions = new VEClusteringOptions();
            clusteringOptions.Callback = function(clusters) { ucSearchResultsMap.clusteringCallback(clusters); };
            mainLayer.SetClusteringConfiguration(VEClusteringType.Grid, clusteringOptions);
            
            
            if (typeof centroid != "undefined" && centroid != null)
            {
                // Add the centroid pushpin.                
                var centroidShape = new VEShape(VEShapeType.Pushpin, new VELatLong(centroid.Latitude, centroid.Longitude));
                ucSearchResultsMap.SetCentroidPushpin(centroidShape);
                centroidShape.IsCentroid = {};
                
                map.AddShape(centroidShape);
                ucSearchResultsMap.CentroidShape = centroidShape;
            }
            
            
            ucSearchResultsMap.detachPushpinEvents();
        };
        
        
        ucSearchResultsMap.clusteringCallback = function(clusters) {
            for (var index = 0; index < ucSearchResultsMap.Agencies.length; index++)
            {
                // Clear this property so that when the map zooms, pushpin shapes that are 
                // no longer part of a cluster don't have info box positioned at the 
                // cluster it used to be a part of.
                delete ucSearchResultsMap.Agencies[index].Shape.ClusterSpecification;
            }
            
            
            for (var index = 0; index < clusters.length; index++)
            {
                var agencies = [];
                
                if (clusters[index].Shapes)
                {
                    for (var index2 = 0; index2 < clusters[index].Shapes.length; index2++)
                    {
                        agencies[index2] = ucSearchResultsMap.Agencies[clusters[index].Shapes[index2].AgencyIndex];
                        agencies[index2].Shape.ClusterSpecification = clusters[index];
                    }
                }
                
                
                var clusterShape = clusters[index].GetClusterShape();
                
                if (clusterShape)
                {
                    ucSearchResultsMap.SetUnselectedClusterPushpin(clusterShape);
                    ucSearchResultsMap.detachPushpinEvents(clusterShape);
                    
                    clusterShape.ClusterSpecification = clusters[index];
                    clusterShape.Agencies = agencies;
                }
            }
        };
        
        
        ucSearchResultsMap.showAllAgenciesInView = function() {
            var centroidPoint = null;
            var points = [];
            
            if (ucSearchResultsMap.CentroidShape !== null)
            {
                centroidPoint = ucSearchResultsMap.CentroidShape.GetPoints()[0];
                points[points.length] = centroidPoint;
            }
            
            for (var index = 0; index < mainLayer.GetShapeCount(); index++)
            {
                points[points.length] = mainLayer.GetShapeByIndex(index).GetPoints()[0];
            }
            
            for (var index = 0; index < mainLayer._clusterLayer.GetShapeCount(); index++)
            {
                points[points.length] = mainLayer._clusterLayer.GetShapeByIndex(index).GetPoints()[0];
            }
            
            map.SetMapView(points)
            
            
            var topLeftCoordinate = map.PixelToLatLong(new VEPixel(mapContainer.scrollTop(), mapContainer.scrollLeft()));
            var bottomRightCoordinate = map.PixelToLatLong(new VEPixel(mapContainer.scrollTop() + mapContainer.height(), mapContainer.scrollLeft() + mapContainer.width()));
            
            var foundShapeCloseToEdge = false;
            
            for (var index = 0; index < mainLayer.GetShapeCount(); index++)
            {
                var point = mainLayer.GetShapeByIndex(index).GetPoints()[0];
                
                if (topLeftCoordinate.Latitude - point.Latitude < 0.02
                        || point.Longitude - topLeftCoordinate.Longitude < 0.02
                        || point.Latitude - bottomRightCoordinate.Latitude < 0.02
                        || bottomRightCoordinate.Longitude - point.Longitude < 0.02)
                {
                    foundShapeCloseToEdge = true;
                    break;
                }
            }
            
            
            if (ucSearchResultsMap.CentroidShape !== null && centroidPoint !== null)
            {                    
                if (topLeftCoordinate.Latitude - centroidPoint.Latitude < 0.02
                        || centroidPoint.Longitude - topLeftCoordinate.Longitude < 0.02
                        || centroidPoint.Latitude - bottomRightCoordinate.Latitude < 0.02
                        || bottomRightCoordinate.Longitude - centroidPoint.Longitude < 0.02)
                {
                    foundShapeCloseToEdge = true;
                }
            }
            
            
            if(foundShapeCloseToEdge === true)
            {
                map.ZoomOut();
            }
        };
        
        
        ucSearchResultsMap.selectAgency = function(agencyIndex) {
            if (typeof agencyIndex === "undefined") { return; }
            
            var agency = ucSearchResultsMap.Agencies[agencyIndex];
            
            if (ucSearchResultsMap.SelectedAgency !== null)
            {
                ucSearchResultsMap.SelectedAgency.Shape.SetZIndex(ucSearchResultsMap.SelectedAgency.Shape.OriginalZIndex);
                ucSearchResultsMap.deselectAgency();
            }
            
            ucSearchResultsMap.SelectedAgency = agency;
            
            ucSearchResultsMap.SetSelectedPushpin(agency.Shape);
            ucSearchResultsMap.detachPushpinEvents(agency.Shape);
            
            ucSearchResultsMap.showAgencyInfo(ucSearchResultsMap.SelectedAgency);
            ucSearchResultsMap.selectAgencyInSearchResultsList(ucSearchResultsMap.SelectedAgency);
            
            ucSearchResultsMap.SelectedClusterID = null;
        };
        
        
        ucSearchResultsMap.selectAgencyInSearchResultsList = function(agency) {
            if (agency.ListItem)
            {
                agency.ListItem.addClass("selected");
            }
            else if (resultsList)
            {
                var listItems = resultsList.children("li");
                
                if (listItems.length >= agency.Shape.AgencyIndex + 1)
                {
                    $(listItems[agency.Shape.AgencyIndex]).addClass("selected");
                }
            }
        };
        
        
        ucSearchResultsMap.scrollToAgency = function(agencyIndex) {
            if (!listItems) { listItems = resultsList.find("li"); }
            var listItem = $(listItems[agencyIndex]);
            
            var scrollTop = resultsList.scrollTop();
            var itemBottom = listItem.position().top + listItem.height();
            
            if ((scrollTop + itemBottom) > (scrollTop + resultsList.height()))
            {
                resultsList.scrollTop(scrollTop + itemBottom - resultsList.height() + 16);
            }
            else if (listItem.position().top < scrollTop)
            {
                resultsList.scrollTop(scrollTop + listItem.position().top);
            }
        };
        
        
        ucSearchResultsMap.centerMapAtSelectedAgency = function() {
            if (ucSearchResultsMap.SelectedAgency != null)
            {
                map.EndContinuousPan();
                map.SetCenter(ucSearchResultsMap.SelectedAgency.Shape.GetPoints()[0]);
            }
        };
        
        
        ucSearchResultsMap.deselectAgency = function() {
            if (ucSearchResultsMap.SelectedAgency !== null)
            {
                ucSearchResultsMap.SelectedAgency.Shape.SetZIndex(ucSearchResultsMap.SelectedAgency.Shape.OriginalZIndex);
                ucSearchResultsMap.SetUnselectedPushpin(ucSearchResultsMap.SelectedAgency.Shape);
                
                if (ucSearchResultsMap.SelectedAgency.ListItem)
                {
                    ucSearchResultsMap.SelectedAgency.ListItem.removeClass("selected");
                }
                else if (resultsList)
                {
                    var selectedItem = resultsList.children("li.selected");
                    
                    if (selectedItem.length > 0)
                    {
                        selectedItem.removeClass("selected");
                    }
                }
                
                ucSearchResultsMap.SelectedAgency = null;
                ucSearchResultsMap.hideInfoBox();
            }
        };
        
        
        ucSearchResultsMap.SetUnselectedPushpin = function(shape) {
            var pushpinHtml = "<div class='pushpin'><div class='agency_index'>" + (shape.AgencyIndex + 1).toString() + "</div></div>";
            shape.SetCustomIcon(pushpinHtml);
            ucSearchResultsMap.setStandardZIndex(shape);
            shape.Pushpin = $(pushpinHtml);
        };
        
        
        ucSearchResultsMap.SetSelectedPushpin = function(shape) {
            var pushpinHtml = "<div class='pushpin_selected'><div class='agency_index'>" + (shape.AgencyIndex + 1).toString() + "</div></div>";
            shape.SetCustomIcon(pushpinHtml);
            ucSearchResultsMap.setSelectedZIndex(shape);
            shape.Pushpin = $(pushpinHtml);
        };
        
        
        ucSearchResultsMap.SetCentroidPushpin = function(shape) {
            var pushpinHtml = "<div class='pushpin_centroid'></div>";
            shape.SetCustomIcon(pushpinHtml);
            shape.SetZIndex(centroidZIndex);
            shape.Pushpin = $(pushpinHtml);
        };
        
        
        ucSearchResultsMap.SetSelectedCentroidPushpin = function(shape) {
            var pushpinHtml = "<div class='pushpin_centroid'></div>";
            shape.SetCustomIcon(pushpinHtml);
            ucSearchResultsMap.setSelectedZIndex(shape);
            shape.Pushpin = $(pushpinHtml);
        };
        
        
        ucSearchResultsMap.SetUnselectedClusterPushpin = function(shape) {
            var pushpinHtml = "<div class='pushpin_cluster'><div class='agency_index'>+</div></div>";
            shape.SetCustomIcon(pushpinHtml);
            
            if (shape.Primitives[0])
            {
                ucSearchResultsMap.setStandardZIndex(shape);
            }
            
            shape.Pushpin = $(pushpinHtml);
        };
        
        
        ucSearchResultsMap.SetSelectedClusterPushpin = function(shape) {
            var pushpinHtml = "<div class='pushpin_cluster_selected'><div class='agency_index'>+</div></div>";
            shape.SetCustomIcon(pushpinHtml);
            
            if (shape.Primitives[0])
            {
                ucSearchResultsMap.setSelectedZIndex(shape);
            }
            
            shape.Pushpin = $(pushpinHtml);
        };
        
        
        ucSearchResultsMap.setStandardZIndex = function(shape) {
            shape.OriginalZIndex = ucSearchResultsMap.UniqueShapeID++;
            shape.SetZIndex(shape.OriginalZIndex);
            if (ucSearchResultsMap.UniqueShapeID + 1 === centroidZIndex) { ucSearchResultsMap.UniqueShapeID = 1000; } // Reset the UniqueShapeID/z-index assignment value. Realistically, this should never be necessary.
        };
        
        
        ucSearchResultsMap.setSelectedZIndex = function(shape) {
            shape.SetZIndex(selectedZIndex);
        };
        
        
        ucSearchResultsMap.showCentroidInfo = function(centroidShape) {
            if (centroidShape.GetDescription().length == 0)
            {
                obj.globalUpdate("AutoOwners.AgencyLocator.ucCentroidDescription, AutoOwners.AgencyLocator", {
                    returnHtml: true,
                    onSuccess: function(results) { 
                        centroidShape.SetDescription(results.Html);
                        ucSearchResultsMap.showInfoBox(centroidShape);
                    }
                });
            }
            else
            {
                ucSearchResultsMap.showInfoBox(centroidShape);
            }
            
            ucSearchResultsMap.SetSelectedCentroidPushpin(centroidShape);
            ucSearchResultsMap.CentroidVisible = true;
            ucSearchResultsMap.SelectedClusterID = null;
        };
        
        
        ucSearchResultsMap.hideCentroidInfo = function(centroidShape) {
			ucSearchResultsMap.CentroidVisible = false;
			ucSearchResultsMap.SetCentroidPushpin(ucSearchResultsMap.CentroidShape);
        };
        
        
        ucSearchResultsMap.showAgencyInfo = function(agency) {            
            if (agency.Shape.GetDescription().length == 0)
            {
                obj.globalInvoke("AutoOwners.AgencyLocator.ucPushPinDescription, AutoOwners.AgencyLocator", "RenderPushPinDescription", {
                    params: [agency.ID],
                    returnHtml: true,
                    onSuccess: function(results) { 
                        agency.Shape.SetDescription(results.Html);
                        ucSearchResultsMap.showInfoBox(agency.Shape);
                    }
                });
            }
            else
            {
                ucSearchResultsMap.showInfoBox(agency.Shape);
            }
        };
        
        
        ucSearchResultsMap.showClusterInfo = function(clusterShape) {
            if (clusterShape.DescriptionIsSet !== true)
            {
                if (clusterShape.ClusterSpecification && clusterShape.Agencies)
                {
                    obj.globalInvoke("AutoOwners.AgencyLocator.ucClusterDescription, AutoOwners.AgencyLocator", "RenderClusterDescription", {
                        params: [clusterShape.Agencies],
                        returnHtml: true,
                        onSuccess: function(results) { 
                            $(".map_balloon li.cluster_item").unbind("click");
                                                       
                            clusterShape.SetDescription(results.Html);
                            clusterShape.DescriptionIsSet = true;
                            
                            ucSearchResultsMap.SelectedClusterID = clusterShape.GetID();
                            ucSearchResultsMap.showInfoBox(clusterShape);
                        }
                    });
                }
            }
            else
            {                
                ucSearchResultsMap.SelectedClusterID = clusterShape.GetID();
                ucSearchResultsMap.showInfoBox(clusterShape);
            }
            
            
            $(".map_balloon li.cluster_item").one("click", function(event) {
                // Handle when an agency is clicked in the cluster info box.
                
                var agencyName = $(this).find("a:first").text();
                
                if (ucSearchResultsMap.SelectedClusterID !== null)
                {
                    var clusterShape = map.GetShapeByID(ucSearchResultsMap.SelectedClusterID);
                    
                    if (clusterShape)
                    {
                        for (var index = 0; index < clusterShape.Agencies.length; index++)
                        {
                            if (clusterShape.Agencies[index].Name === agencyName)
                            {
                                if (!clusterShape.Agencies[index].Shape.ClusterSpecification)
                                {
                                    clusterShape.Agencies[index].Shape.ClusterSpecification = clusterShape.ClusterSpecification;
                                }
                                
                                ucSearchResultsMap.SelectedClusterID = clusterShape.Agencies[index].Shape.GetID();
                                ucSearchResultsMap.SelectedAgency = clusterShape.Agencies[index];
                                ucSearchResultsMap.showAgencyInfo(clusterShape.Agencies[index]);
                                ucSearchResultsMap.selectAgencyInSearchResultsList(ucSearchResultsMap.SelectedAgency);
                                ucSearchResultsMap.scrollToAgency(ucSearchResultsMap.SelectedAgency.Shape.AgencyIndex);
                                
                                ucSearchResultsMap.WithholdMouseMove = true;
                                ucSearchResultsMap.MouseLeftInfoBox = false;
                                
                                break;
                            }
                        }
                    }
                }
            });
        };
        
        
        ucSearchResultsMap.hideClusterInfo = function() {
            if (ucSearchResultsMap.SelectedClusterID !== null)
            {
                temp.clusterShape = map.GetShapeByID(ucSearchResultsMap.SelectedClusterID);
                
                if (temp.clusterShape !== null)
                {
                    ucSearchResultsMap.SetUnselectedClusterPushpin(temp.clusterShape);
                    ucSearchResultsMap.detachPushpinEvents(temp.clusterShape);
                    
                    for (var index = 0; index < temp.clusterShape.Agencies.length; index++)
                    {
                        if (temp.clusterShape.Agencies[index].ListItem)
                        {
                            temp.clusterShape.Agencies[index].ListItem.removeClass("selected");
                        }
                    }
                }
                
                ucSearchResultsMap.SelectedClusterID = null;
                ucSearchResultsMap.hideInfoBox();
            }
        };
        
        
        ucSearchResultsMap.getInfoBox = function() {
            if (infoBox == null || infoBox.length == 0)
            {
                infoBox = $(".customInfoBox-shadow").parent();
                infoBox.addClass("customInfoBox").removeClass("undefined");
                infoBox.find(".customInfoBox-actionsBackground").remove();
            }
            
            return infoBox;
        };
        
        
        ucSearchResultsMap.getInfoBox().mouseenter(function(event) { 
            event.preventDefault();
            ucSearchResultsMap.ShowInfoBoxFlag = true;
            ucSearchResultsMap.WithholdMouseMove = false;
        }).mouseleave(function(event) { 
            event.preventDefault();
            ucSearchResultsMap.ShowInfoBoxFlag = false;
            ucSearchResultsMap.MouseLeftInfoBox = true;
        });
        
        
        ucSearchResultsMap.getInfoBox().find(".customInfoBox-beak").mouseenter(function(event) {
            return true;
        }).mouseleave(function(event) { 
            return true;
        });
        
        
        ucSearchResultsMap.showInfoBox = function(shape) {
            ucSearchResultsMap.hideInfoBox();
            
            if (ucSearchResultsMap.updateInfoBoxPosition(shape))
            {
                ucSearchResultsMap.showInfoBoxUnsafe();
            }
        };
        
        
        ucSearchResultsMap.showInfoBoxUnsafe = function() {
            ucSearchResultsMap.getInfoBox()[0].style.visibility = "visible";
            ucSearchResultsMap.InfoBoxIsVisible = true;
        };
        
        
        
        ucSearchResultsMap.updateInfoBoxPosition = function(shape) {
            if (!shape) { return; }
            
            // Position the InfoBox according to the pushpin.
            var pushpinPixel = null;
            
            if (shape.ClusterSpecification)
            {
                ucSearchResultsMap.SetSelectedClusterPushpin(shape.ClusterSpecification._clusterShape);
                ucSearchResultsMap.detachPushpinEvents(shape.ClusterSpecification._clusterShape);
                
                ucSearchResultsMap.SelectedClusterID = shape.ClusterSpecification._clusterShape.GetID();
                
                pushpinPixel = map.LatLongToPixel(shape.ClusterSpecification.LatLong);
            }
            else
            {
                pushpinPixel = map.LatLongToPixel(shape.GetPoints()[0]);
            }
            
            var mapView = map.GetMapView();
            var topLeft = map.LatLongToPixel(mapView.TopLeftLatLong);
            var bottomRight = map.LatLongToPixel(mapView.BottomRightLatLong);
            
            
            if (!(pushpinPixel.x + 15 > topLeft.x && pushpinPixel.y - 45 > topLeft.y 
                    && pushpinPixel.x + 15 < bottomRight.x && pushpinPixel.y - 45 < bottomRight.y))
            {                
                ucSearchResultsMap.hideInfoBox();
            
                if (shape.ClusterSpecification)
                {
                    map.PanToLatLong(shape.ClusterSpecification.LatLong);
                }
                else
                {
                    map.PanToLatLong(shape.GetPoints()[0]);
                }
                
                map.EndContinuousPan();
                return ucSearchResultsMap.updateInfoBoxPosition(shape);
            }
            else
            {
                var infoBox = ucSearchResultsMap.getInfoBox();
                
                // I'm making use of the "style" object rather than setting the CSS values 
                // with jQuery to reduce overhead processing. This is one of the most invoked 
                // functions of the whole solution and needs to be as fast as possible.
                infoBox.find(".customInfoBox-body").html("<div class='VE_Pushpin_Popup_Body'>" + shape.GetDescription() + "</div>");
                
                var left = map.GetLeft() + pushpinPixel.x + 30;
                var shadow = $(".customInfoBox-shadow");
                
                if ((left + shadow.position().left + shadow.width() + 5 >= $("body").width()) || shape.ClusterSpecification)
                {
                    // Show the info box to the left of the map shape. This will be done for all cluster shapes.
                    infoBox[0].style.left = (map.GetLeft() + pushpinPixel.x - 24 - shadow.width()).toString() + "px";
                    infoBox.find(".customInfoBox-beak").removeClass("customInfoBox-leftBeak").addClass("customInfoBox-rightBeak");
                }
                else
                {
                    infoBox[0].style.left = (left).toString() + "px";
                    infoBox.find(".customInfoBox-beak").removeClass("customInfoBox-rightBeak").addClass("customInfoBox-leftBeak");
                }
                
                infoBox[0].style.top = (map.GetTop() + pushpinPixel.y - 45).toString() + "px";
            }
            
            
            return true;
        };
        
        
        ucSearchResultsMap.hideInfoBox = function() {
            ucSearchResultsMap.getInfoBox()[0].style.visibility = "hidden";
            ucSearchResultsMap.InfoBoxIsVisible = false;
        };
        
        
        ucSearchResultsMap.detachPushpinEvents = function(shape) {
            if (!shape)
            {
                $(".VEAPI_Pushpin").each(function(i) {
                    $(this).removeAttr("href").find("div:first").removeAttr("onmousedown");//.removeAttr("onmouseover").removeAttr("onmouseout");
                });
            }
            else
            {
                if ($(shape.GetIconElement()).hasClass("VEAPI_Pushpin")) 
                {
                    $(shape.GetIconElement()).removeAttr("href").find("div:first").removeAttr("onmousedown");//.removeAttr("onmouseover").removeAttr("onmouseout");
                }
                else
                {
                    $(shape.GetIconElement()).removeAttr("href").find("div:first").removeAttr("onmousedown");//.removeAttr("onmouseover").removeAttr("onmouseout");
                }
            }
        };
        
        
        ucSearchResultsMap.showDirections = function(directions) {
            if (directions)
            {
                if (ucSearchResultsMap.CentroidShape !== null)
                {
                    ucSearchResultsMap.CentroidShape.Hide();
                }
                
                ucSearchResultsMap.enableMap();
                
                // Hide the Main Layer that contains all of the agency points.
                mainLayer.Hide();
                
                
                // Create an array of all the points that make up the polyline of the route.
                var points = [];
                
                for (var index = 0; index < directions.Points.length; index++)
                {
                    points[index] = new VELatLong(directions.Points[index].Latitude, directions.Points[index].Longitude);
                }
                
                
                // Create the polyline shape for the route.
                var routeLine = new VEShape(VEShapeType.Polyline, points);
                routeLine.SetLineColor(new VEColor(16, 93, 162, 1.0));
                routeLine.SetLineWidth(3);
                routeLine.HideIcon();
                
                directionsLayer.DeleteAllShapes();
                directionsLayer.AddShape(routeLine);
                
                
                // Add the start and end pushpins to the map.
                var startPoint = new VEShape(VEShapeType.Pushpin, new VELatLong(directions.Route.StartingLocation.Coordinate.Latitude, directions.Route.StartingLocation.Coordinate.Longitude));
                ucSearchResultsMap.SetDirectionsStartPushpin(startPoint);
                directionsLayer.AddShape(startPoint);
                ucSearchResultsMap.detachMapEvents(startPoint);
                
                var endPoint = new VEShape(VEShapeType.Pushpin, new VELatLong(directions.Route.EndingLocation.Coordinate.Latitude, directions.Route.EndingLocation.Coordinate.Longitude));
                ucSearchResultsMap.SetDirectionsEndPushpin(endPoint);
                directionsLayer.AddShape(endPoint);
                ucSearchResultsMap.detachMapEvents(endPoint);
                
                
                // Add the step pushpins to the map.
                var stepListItems = $("#step_list li");
                
                for (var index = 0; index < directions.Route.Steps.length; index++)
                {
                    var currentStep = directions.Route.Steps[index];
                    
                    var stepPoint = new VEShape(VEShapeType.Pushpin, new VELatLong(currentStep.Coordinate.Latitude, currentStep.Coordinate.Longitude));
                    ucSearchResultsMap.SetDirectionsStepPushpin(stepPoint, index + 1);
                    directionsLayer.AddShape(stepPoint);
                    stepPoint.Hide();
                    
                    stepListItems[index].Shape = stepPoint;
                    
                    ucSearchResultsMap.detachMapEvents(stepPoint);
                }
                
                
                directionsLayer.Show();
                ucSearchResultsMap.DirectionsVisible = true;
                
                // Set the map view so that the route that was drawn is directly in view.
                map.SetMapView(points);
                
                map.DetachEvent("onmousemove", mouseMoveMapHandler);
            }
        };
        
        
        ucSearchResultsMap.resetSize = function(width, height) {
            map.Resize(width, height);
        };
        
        
        ucSearchResultsMap.centerDirections = function() {
            if (directionsLayer)
            {
                map.SetMapView(directionsLayer.GetBoundingRectangle());
            }
        };
        
        
        ucSearchResultsMap.disableMap = function() {
            map.HideDashboard();
            
            ucSearchResultsMap.detachMapEvents();
            map.AttachEvent("onmousemove", emptyHandler);
            map.AttachEvent("onmousedown", emptyHandler);
            map.AttachEvent("onmouseover", emptyHandler);
            map.AttachEvent("onmousewheel", emptyHandler);
			map.AttachEvent("ondoubleclick", emptyHandler);
            
            $(".MSVE_MapContainer *").css("cursor", "pointer");
        };
        
        
        ucSearchResultsMap.enableMap = function() {
            map.ShowDashboard();
            
            map.DetachEvent("onmousemove", emptyHandler);
            map.DetachEvent("onmousedown", emptyHandler);
            map.DetachEvent("onmouseover", emptyHandler);
            map.DetachEvent("onmousewheel", emptyHandler);
			map.DetachEvent("ondoubleclick", emptyHandler);
            ucSearchResultsMap.attachMapEvents();
            
            $(".MSVE_MapContainer").css("cursor", "url('http://ecn.dev.virtualearth.net/mapcontrol/v6.2/cursors/grab.cur'), move");
        };
        
        
        ucSearchResultsMap.removeDirections = function() {
            directionsLayer.Hide();
            mainLayer.Show();
            
            if (ucSearchResultsMap.DirectionsVisible === true)
            {
                ucSearchResultsMap.DirectionsVisible = false;
                ucSearchResultsMap.showAllAgenciesInView();
            }
            
            directionsLayer.DeleteAllShapes();
            
            map.AttachEvent("onmousemove", mouseMoveMapHandler);
            
            if (ucSearchResultsMap.CentroidShape !== null)
            {
                ucSearchResultsMap.CentroidShape.Show();
            }
        };
        
        
        ucSearchResultsMap.SetDirectionsStartPushpin = function(shape) {
            var pushpinHtml = "<div class='pushpin_directions'><img src='/images/pushpin_directions.png' alt='Start' /><span class='label'>A</span></div>";
            shape.SetCustomIcon(pushpinHtml);
            shape.Pushpin = $(pushpinHtml);
        };
        
        
        ucSearchResultsMap.SetDirectionsEndPushpin = function(shape) {
            var pushpinHtml = "<div class='pushpin_directions'><img src='/images/pushpin_directions.png' alt='End' /><span class='label'>B</span></div>";
            shape.SetCustomIcon(pushpinHtml);
            shape.Pushpin = $(pushpinHtml);
        };
        
        
        ucSearchResultsMap.SetDirectionsStepPushpin = function(shape, stepIndex) {
            var pushpinHtml = "<div class='pushpin_directions_step'><span class='label'>" + stepIndex + "</span></div>";
            shape.SetCustomIcon(pushpinHtml);
            shape.Pushpin = $(pushpinHtml);
        };
        
        
        
        // Debug Panel Functionality
        
        ucSearchResultsMap.debugPanel = $("#search_results_map_debug_panel");
        ucSearchResultsMap.debugList = ucSearchResultsMap.debugPanel.find("ul.debug_list");
        
        ucSearchResultsMap.clearDebugList = function() {
            ucSearchResultsMap.debugList.children("li").remove();
        };
        
        ucSearchResultsMap.addTextToDebugList = function(text) {
            ucSearchResultsMap.debugList.append("<li>" + text + "</li>");
        };
        
        ucSearchResultsMap.showDebugPanel = function() {
            ucSearchResultsMap.debugPanel.show();
        };
        
        ucSearchResultsMap.hideDebugPanel = function() {
            ucSearchResultsMap.debugPanel.hide();
        };
        
        
        
        // Load the 1st page of Agency points.
        if (loadAgenciesHandler)
        {
            loadAgenciesHandler();
        }
    };

})(jQuery.noConflict());
