﻿Cwo.RegisterNamespace("Cwo.Maps.Search");

Cwo.Maps.Search = function (HtmlControlID, SearchType, BingMapKey) {

    // private variables
    var cwoMapsSearch = this,
        mapProvider = null,
        map = null,
        popup = null,
        moving = false,
        htmlControlID = document.getElementById(HtmlControlID),
        searchType = SearchType,
        propertiesShapeLayer = null,
        polygonAndRadiusShapeLayer = null,
        loadingAnimationShape = null,
        latLong = null,
        currentRadius = 0,
        noPropDisplay = null,
    // Constants
        PLACE_SHAPE_LINE_COLOUR_R_COMPONENT = 0,
        PLACE_SHAPE_LINE_COLOUR_G_COMPONENT = 0,
        PLACE_SHAPE_LINE_COLOUR_B_COMPONENT = 0,
        PLACE_SHAPE_LINE_COLOUR_OPACITY = 100,
        PLACE_SHAPE_LINE_WIDTH = 2,

        PLACE_SHAPE_FILL_COLOUR_R_COMPONENT = 62,
        PLACE_SHAPE_FILL_COLOUR_G_COMPONENT = 51,
        PLACE_SHAPE_FILL_COLOUR_B_COMPONENT = 24,
        PLACE_SHAPE_FILL_COLOUR_OPACITY = 20,

        CLUSTER_POPUP_ZOOM_LEVEL_THRESHOLD = 19;

    // private methods
    function GetLatLong() {
        var latitude = null;
        var longitude = null;

        if (SearchType === "ToLet") {
            latitude = Cwo.Search.ToLet.Latitude;
            longitude = Cwo.Search.ToLet.Longitude;
        } else {
            latitude = Cwo.Search.ForSale.Latitude;
            longitude = Cwo.Search.ForSale.Longitude;
        }
        return { Latitude: latitude, Longitude: longitude };
    }


    function DrawShape(points) {
        // Create the polygon settings and then draw on the map
        var polygonSettings = {
            visible: true,
            strokeColor: map.getColor(PLACE_SHAPE_LINE_COLOUR_OPACITY, PLACE_SHAPE_LINE_COLOUR_R_COMPONENT, PLACE_SHAPE_LINE_COLOUR_G_COMPONENT, PLACE_SHAPE_LINE_COLOUR_B_COMPONENT),
            fillColor: map.getColor(PLACE_SHAPE_FILL_COLOUR_OPACITY, PLACE_SHAPE_FILL_COLOUR_R_COMPONENT, PLACE_SHAPE_FILL_COLOUR_G_COMPONENT, PLACE_SHAPE_FILL_COLOUR_B_COMPONENT),
            strokeThickness: PLACE_SHAPE_LINE_WIDTH
        }
        map.DrawPolygon(points, polygonSettings);
        //set the map to fit the points
    }


    function DrawRadius() {
        // Get the points
        //if we are drawing a radius we have no shape so the min is 1
        var radius = $('#RadiusSlider').slider('value');
        if (radius === 0) {
            radius = 1;
        }

        var points = [],
            lat1 = GetLatLong().Latitude * Math.PI / 180.0,
            lon1 = GetLatLong().Longitude * Math.PI / 180.0,
            d = radius / 3956;

        for (var x = 0; x <= 360; x += 10) {
            var tc = (x / 90) * Math.PI / 2;
            var lat = 180.0 * (Math.asin(Math.sin(lat1) * Math.cos(d) + Math.cos(lat1) * Math.sin(d) * Math.cos(tc))) / Math.PI;
            var lon;

            if (Math.cos(lat1) === 0) {
                lon = lonin;
            } else {
                lon = ((lon1 - Math.asin(Math.sin(tc) * Math.sin(d) / Math.cos(lat1)) + Math.PI) % (2 * Math.PI)) - Math.PI;
            }
            lon = 180.0 * lon / Math.PI;
            var loc = mapProvider.CreatePoint(lat, lon);
            points.push(loc);
        }
        return points;
    }

    function OnClickHandler(e) {

        if (e.targetType !== "pushpin") {
            return;
        }

        if ((e.isPrimary || e.isSecondary || $.browser.opera)) {
            if (e.target.InstructionID === undefined) { return }

            //if (!property.IsPopup) {
            var data = null;
            if (e.target.InstructionID === -1) {
                // We're dealing with a cluster of properties.                    
                var latlong = map.PixelToLatLong(e.getX(), e.getY());
                var zoomLevel = map.GetZoom();
                if (zoomLevel >= CLUSTER_POPUP_ZOOM_LEVEL_THRESHOLD) {
                    // At a certain zoom level, we need to show a pop-up that displays the details of
                    // properties in a cluster. The IDs of the properties are retrieved from the
                    // map.pointer object that represents the cluster.
                    var instructionIDs = e.target.InstructionIDs;
                    var jsonData = "{propertyInstructionIDs: " + JSON.stringify(instructionIDs.Items) + "}";
                    new Cwo.AjaxCall("/webservices/Previews.asmx/GetPropertyPreviews", jsonData, function (data) { cwoMapsSearch.ShowAccordian(data, latlong.latitude, latlong.longitude) }, null, null);
                } else {
                    map.MoveTo(latlong.latitude, latlong.longitude);
                    map.SetZoom(zoomLevel + 1)
                }
            } else {
                // Is a property pin
                data = "{InstructionID:'" + e.target.InstructionID + "'}";
                new Cwo.AjaxCall("/webservices/Previews.asmx/GetPropertyPreview", data, cwoMapsSearch.ShowPreview, null, null);
            }
        }
    }

    function DrawMap(boundrect) {
        //set up the map correctly
        var mapSettings = {
            bounds: boundrect
        }

        map = mapProvider.RenderMap(htmlControlID, mapSettings);
        map.AttachEvent("click", OnClickHandler);
        map.AttachEvent("viewchangeend", cwoMapsSearch.OnEndZoom);
    }


    // If we have a shape for the place that was searched for, then we draw it otherwise we draw a circular polygon.
    function DrawPlaceShape(Data) {

        var polygons = Data.d.ContentContainer.ShapePoints,
            polygonsCount = Data.d.ContentContainer.ShapePoints.length,
            allPoints = new Array(),
            points = new Array();

        // Add the polygon that represents the place that the user searched on, if a polygon for that
        // place has been supplied.
        if (polygonsCount > 0) {
            for (var i = 0; i < polygonsCount; i++) { // A place shape may be made up of more than one polyogn, so process each polygon. 

                var polygonPoints = polygons[i],
                    polygonPointsCount = polygonPoints.length,
                    polygonVeLatLongs = new Array();

                for (var j = 0; j < polygonPointsCount; j++) {
                    polygonVeLatLongs[j] = mapProvider.CreatePoint(polygonPoints[j].Latitude, polygonPoints[j].Longitude);
                    allPoints.push(polygonVeLatLongs[j]);
                }
                points[i] = polygonVeLatLongs;
            }
            searchHasShape = true;
        } else {
            points.push(DrawRadius());
            allPoints = points[0];
            searchHasShape = false;
        }

        if (map === null) {
            DrawMap(mapProvider.GetRectFromBounds(allPoints));
        } else {
            map.SetView(mapProvider.GetRectFromBounds(allPoints));
        }

        map.ClearPolygon();
        map.ClearMarkers();

        for (var i = 0; i < points.length; i++) {
            DrawShape(points[i]);
        }
    }

    function GetPlaceShape() {
        var radius = $('#RadiusSlider').slider('value');
        var data = "{placeID:'" + $("[id$='_placeIDHiddenField']").val() + "'" + ", bufferDistance:'" + radius + "'}";

        // Register the Call
        var AjajSequenceIndex = Cwo.Page.AjajCalls.CreateRequest("PlaceSearch");
        new Cwo.AjaxCall("/webservices/PlaceSearch.asmx/GetShape", data, function (Data) { DrawPlaceShape(Data); }, null, null);
    }

    function GetForSalePins() {

        var topLeft = map.GetTopLeft(),
            bottomRight = map.GetBottomRight(),
            zoom = map.GetZoom(),
            radius = $('#RadiusSlider').slider('value');


        if (!searchHasShape && radius === 0) {
            radius = 1;
            $('#RadiusSlider').slider("option", "value", radius);
        }

        var data = "{AskingPriceMin:'" + Cwo.Search.ForSale.Criteria.AskingPriceMin + "'"
            + ",AskingPriceMax:'" + Cwo.Search.ForSale.Criteria.AskingPriceMax + "'"
            + ",BedroomsMin:'" + Cwo.Search.ForSale.Criteria.BedroomsMin + "'"
            + ",BedroomsMax:'" + Cwo.Search.ForSale.Criteria.BedroomsMax + "'"
            + ",ReceptionsMin:'" + Cwo.Search.ForSale.Criteria.ReceptionsMin + "'"
            + ",ReceptionsMax:'" + Cwo.Search.ForSale.Criteria.ReceptionsMax + "'"
            + ",BathroomsMin:'" + Cwo.Search.ForSale.Criteria.BathroomsMin + "'"
            + ",BathroomsMax:'" + Cwo.Search.ForSale.Criteria.BathroomsMax + "'"
            + ",SearchString:'" + Cwo.Search.ForSale.Criteria.SearchString.replace(/['']/g, "\\'") + "'"
            + ",Radius:'" + $('#RadiusSlider').slider('value') + "'"
            + ",PropertyTypeID:'" + Cwo.Search.ForSale.Criteria.PropertyTypeID + "'"
            + ",PromotionID:'" + Cwo.Search.ForSale.Criteria.PromotionID + "'"
            + ",PlaceID:'" + $("[id$='_placeIDHiddenField']").val() + "'"
            + ",TopLeftVisible:{Latitude:'" + topLeft.latitude + "',Longitude:'" + topLeft.longitude + "'}"
            + ",BottomRightVisible:{Latitude:'" + bottomRight.latitude + "',Longitude:'" + bottomRight.longitude + "'}"
            + ",ZoomLevel:'" + zoom + "'}";

        // Register the Call
        var AjajSequenceIndex = Cwo.Page.AjajCalls.CreateRequest("ForSaleMapSearch");

        new Cwo.AjaxCall("/webservices/ForSaleSearch.asmx/GetMapPoints", data, function (Data) { DrawPins(Data, AjajSequenceIndex); }, null, null);
    }


    function GetToLetPins() {

        var topLeft = map.GetTopLeft(),
            bottomRight = map.GetBottomRight(),
            zoom = map.GetZoom(),
            radius = $('#RadiusSlider').slider('value');

        if (!searchHasShape && radius === 0) {
            radius = 1;
            $('#RadiusSlider').slider("option", "value", radius);
        }

        var data = "{RentalPriceMin:'" + Cwo.Search.ToLet.Criteria.RentalPriceMin + "'"
            + ",RentalPriceMax:'" + Cwo.Search.ToLet.Criteria.RentalPriceMax + "'"
            + ",BedroomsMin:'" + Cwo.Search.ToLet.Criteria.BedroomsMin + "'"
            + ",BedroomsMax:'" + Cwo.Search.ToLet.Criteria.BedroomsMax + "'"
            + ",FurnishingTypeID:'" + Cwo.Search.ToLet.Criteria.FurnishingTypeID + "'"
            + ",SearchString:'" + Cwo.Search.ToLet.Criteria.SearchString.replace(/['']/g, "\\'") + "'"
            + ",Radius:'" + $('#RadiusSlider').slider('value') + "'"
            + ",PropertyTypeID:'" + Cwo.Search.ToLet.Criteria.PropertyTypeID + "'"
            + ",TopLeftVisible:{Latitude:'" + topLeft.latitude + "',Longitude:'" + topLeft.longitude + "'}"
            + ",BottomRightVisible:{Latitude:'" + bottomRight.latitude + "',Longitude:'" + bottomRight.longitude + "'}"
            + ",ZoomLevel:'" + zoom + "'"
            + ",PlaceID:'" + $("[id$='_placeIDHiddenField']").val() + "'"
            + ",PromotionID:'" + Cwo.Search.ToLet.Criteria.PromotionID + "'}";

        // Register the Call
        var AjajSequenceIndex = Cwo.Page.AjajCalls.CreateRequest("ToLetMapSearch");
        new Cwo.AjaxCall("/webservices/ToLetSearch.asmx/GetMapPoints", data, function (Data) { DrawPins(Data, AjajSequenceIndex); }, null, null);
    }


    function DrawPins(Data, AjajSequenceIndex) {
       
        if (!Cwo.Page.AjajCalls.IsCurrentSequenceIndex(SearchType + "MapSearch", AjajSequenceIndex)) {
            return;
        }

        var points = Data.d.ContentContainer.MapPoints;
        var pointsCount = points.length;
        var numberOfProperties = "<span>" + Data.d.ContentContainer.ResultCount + "</span> " + Data.d.ContentContainer.SearchPropertyTypeText + " within <span>";
        var radius = $('#RadiusSlider').slider('value');
        var mileageDetails = '';
        var placeName = Data.d.ContentContainer.PlaceName;


        if (SearchType === "ToLet") {
            if (radius > 0) {
                mileageDetails = ((radius === 0.5) ? "1/2 mile</span> of <span>" : (radius.toString() + ((radius > 1) ? " miles</span> of <span>" : " mile</span> of <span>")));
            }
            numberOfProperties += mileageDetails + placeName + "</span>";
            // Set maplink URL
            $('#' + Cwo.Search.ToLet.ControlIDs.ResultsListButton).attr({ href: Data.d.ContentContainer.SearchURL });
            //Cwo.Search.ToLet.ShowPromotionBanner(Data.d.ContentContainer.PromotionBannerHTML);
        } else {
            if (radius > 0) {
                mileageDetails = ((radius === 0.5) ? "1/2 mile</span> of <span>" : (radius.toString() + ((radius > 1) ? " miles</span> of <span>" : " mile</span> of <span>")));
            }
            numberOfProperties += mileageDetails + placeName + "</span>";
            // Set maplink URL
            $('#' + Cwo.Search.ForSale.ControlIDs.ResultsListButton).attr({ href: Data.d.ContentContainer.SearchURL });
            Cwo.Search.ForSale.ShowPromotionBanner(Data.d.ContentContainer.PromotionBannerHTML);
        }

        $("#NumberOfProperties").html(numberOfProperties);

        for (var i = 0; i < pointsCount; i++) {
            var pointsettings, propertyInstructionId, propertyInstructionIDs;

            if (points[i].Type === 0) {
                pointsettings = { icon: "", text: points[i].ItemCount.toString(), typeName: "clusterPoint" };

                propertyInstructionId = -1;

                var zoomLevel = map.GetZoom();
                if (zoomLevel === CLUSTER_POPUP_ZOOM_LEVEL_THRESHOLD) {
                    // At a certain zoom level, we need to store the property instruction IDs of
                    // the properties associated with a clustered map point. These IDs will be used to 
                    // retrieve the details of those properties when the cluster is clicked.
                    var instructionIDs = new Cwo.Collection();
                    var point = points[i];
                    var numberOfInstructionIDs = point.ClusteredIDs.length;
                    for (var j = 0; j < numberOfInstructionIDs; j++) {
                        instructionIDs.Add(point.ClusteredIDs[j]);
                    }
                    propertyInstructionIDs = instructionIDs;
                }

            } else {
                pointsettings = { icon: "", typeName: "mapPoint" }
                propertyInstructionId = points[i].ID;
                propertyInstructionIDs = -1;
            }

            var marker = map.AddMarker(points[i].Latitude, points[i].Longitude, pointsettings);
            marker.InstructionID = propertyInstructionId;
            marker.InstructionIDs = propertyInstructionIDs;
        }

        // If there were no properties found, then we show a message to the user to indicate this.
        if (Data.d.ContentContainer.ResultCount === 0) {

            map.ClearMarkers();
            // Get the pixel details for the centre of the map so that we can manipulate the location that the message gets displayed at.            
            var centerpoint = map.GetCenter(),
                mapCentrePixel = map.LatLongToPixel(centerpoint.latitude, centerpoint.longitude),
                shapeLatLong = map.PixelToLatLong(mapCentrePixel.x - 289, mapCentrePixel.y - 130);

            var searchText = $('.InputBg input').val();

            var html = ("<div id='NoPropertiesNotification'>"
                            + "<div class='FadedBackground'>"
                                + "<div class='Header'>"
                                    + "<h6><img src='/images/icons/exclamation-mark.png' alt='No properties found' />No properties found in " + searchText + "</h6>"
                                + "</div>"
                                + "<ul>"
                                    + "<li>Please check the location entered is correct</li>"
                                    + "<li>Adjust your search filters</li>"
                                    + "<li>Try an alternative location</li>"
                                + "</ul>"
                            + "</div>"
                        + "</div>");
            noPropDisplay = map.AddInfoBox(shapeLatLong.latitude, shapeLatLong.longitude, html, {})
        }
    }

    // public methods
    this.LoadMap = function () {
        //Create the Provider but not the map yet
        mapProvider = new Cwo.MapProvider(BingMapKey);
        //Get Lat Long data
        latLong = GetLatLong();
        if (Cwo.Common.GetCookie("PropertyWideMapToken") !== "") {
            map.SetClientToken(Cwo.Common.GetCookie("PropertyWideMapToken"));
        }
        cwoMapsSearch.MapLoaded();
    };

    this.MapLoaded = function () {
        cwoMapsSearch.UpdateNew();
    };

    this.OnEndZoom = function () {
        cwoMapsSearch.UpdateNew();
    };

    this.UpdateNew = function () {
        //Check if the Radius has changed
        if (map !== null) {
            map.Remove(noPropDisplay);
        }
        var radius = $('#RadiusSlider').slider('value');
        if (map === null || currentRadius !== radius) {
            if (map !== null) {
                map.DeleteAllShapeLayers();
            }
            currentRadius = radius;
            GetPlaceShape();
        } else {
            if (map !== null) {
                map.ClearMarkers();
            }
            if (SearchType === "ToLet") {
                GetToLetPins();
            } else {
                GetForSalePins();
            }
        }
    }

    this.RadiusChanged = function () {
        var radius = $('#RadiusSlider').slider('value');
        if (currentRadius !== radius) {
            map.Remove(noPropDisplay);
            map.DeleteAllShapeLayers();
            currentRadius = radius;
            GetPlaceShape();
            if (SearchType === "ToLet") {
                GetToLetPins();
            } else {
                GetForSalePins();
            }
        }
    };

    function GetPopupPosition(latitude, longitude) {
        var mapCenter = map.GetCenter();
        var propertypixel = map.LatLongToPixel(latitude, longitude);
        var halfWidth = (map.GetWidth() / 2);
        var halfHeight = (map.GetHeight() / 2);

        if (propertypixel.x < 0) {
            if ((propertypixel.x - 300) > (halfWidth * -1)) {
                propertypixel.x = (propertypixel.x + 300)
            }
        }
        else if (propertypixel.x > 0) {
            if ((propertypixel.x + 300) > halfWidth) {
                propertypixel.x = (propertypixel.x - 300)
            }
        }

        if (propertypixel.y > 0) {
            if ((propertypixel.y + 200) > halfHeight) {
                propertypixel.y = (propertypixel.y - 200)
            }
        }
        return propertypixel;
    }


    this.ShowPreview = function (Data) {
        var property = Data.d.ContentContainer.PropertyPreviews[0];

        var html = "<ul id=\"MapSingleContainer\">";
        html += "    <li id=\"Top\">";
        html += "        <ul>";
        html += "            <li class=\"NumberOfProperties\">Property Details</li>";
        html += "            <li class=\"Close\" id=\"MapPreviewClose\">Close</li>";
        html += "        </ul>";
        html += "    </li>";
        html += "    <li id=\"Middle\">";
        html += "        <ul>";
        html += "            <li class=\"Open\">" + property.Price;
        html += "                <div class=\"Details\">";
        html += "                    <img src=\"" + property.MainPhotoUrl + "\" id=\"MapPreviewReadMoreFromPhoto\" alt=\"\" />";
        html += "                    <ul>";
        html += "                        <li class=\"PropertyType\">" + property.Summary + "</li>";
        html += "                        <li class=\"ReadMore\" id=\"MapPreviewReadMore\"><button>Read More</button></li>";
        html += "                        <li class=\"Favourites\"><button id=\"AddToFavourites\">Favourite</button></li>";
        html += "                    </ul>";
        html += "                </div>";
        html += "            </li>";
        html += "        </ul>";
        html += "    </li>";
        html += "    <li id=\"Bottom\"></li>";
        html += "</ul>";

        if (popup !== null) {
            cwoMapsSearch.ClosePreview();
        }

        var propertypixel = GetPopupPosition(property.Latitude, property.Longitude);
        var PopupPostion = map.PixelToLatLong(propertypixel.x, propertypixel.y)

        popup = map.AddInfoBox(PopupPostion.latitude, PopupPostion.longitude, html, {})
        popup.IsPopup = true;

        //We have to hack the z-index as the z-index property does not work;
        $("#MapSingleContainer").parent("div").parent("div").css("z-index", "3000");

        popup.InstructionID = property.InstructionID;
        popup.URLAliasPath = property.URLAliasPath;

        // Bind the close button
        $("#MapPreviewClose").bind("click", cwoMapsSearch.ClosePreview);
        //switch off the double click functionality
        $("#MapSingleContainer").bind("dblclick", function () { return false; });

        // Bind a Details button
        var url = property.URLAliasPath.replace("&pound;", "£");
        $("#MapPreviewReadMoreFromPhoto").bind("click", function () { Cwo.Page.NavigateWithReferrer(url); });
        $("#MapPreviewReadMore").bind("click", function () { Cwo.Page.NavigateWithReferrer(url); });

        // Bind the Add to Favourites button
        new Cwo.Favourites.FavouriteButtonHandler(property.InstructionID, "AddToFavourites", "add");
    };
    this.ClosePreview = function () {
        map.Remove(popup);
    };
    this.ShowAccordian = function (data, latitude, longitude) {

        var properties = data.d.ContentContainer.PropertyPreviews;
        var propertyCount = properties.length;

        var html = "<ul id=\"MapAccordianContainer\">";
        html += "       <li id=\"Top\">";
        html += "           <ul>";
        html += "               <li class=\"NumberOfProperties\">" + propertyCount + " Properties</li>";
        html += "               <li class=\"Close\" id=\"MapPreviewClose\">Close</li>";
        html += "           </ul>";
        html += "       </li>";
        html += "       <li id=\"Middle\">";
        html += "           <ul>";

        for (var i = 0; i < propertyCount; i++) {
            if (i === 0) {
                html += "<li class=\"Open\" id=\"MapPreviewPrice" + properties[i].InstructionID + "\"><div id=\"MapPreviewHeaderBar" + properties[i].InstructionID + "\">" + properties[i].Price + "</div>";
            } else {
                html += "<li class=\"Closed\" id=\"MapPreviewPrice" + properties[i].InstructionID + "\"><div id=\"MapPreviewHeaderBar" + properties[i].InstructionID + "\">" + properties[i].Price + "</div>";
            }

            html += "    <div class=\"Details\">";
            html += "       <img src=\"" + properties[i].MainPhotoUrl + "\" id=\"MapPreviewReadMoreFromPhoto" + properties[i].InstructionID + "\" alt=\"\" />";
            html += "       <ul>";
            html += "           <li class=\"PropertyType\">" + properties[i].Summary + "</li>";
            html += "           <li class=\"ReadMore\"><button id=\"MapPreviewReadMore" + properties[i].InstructionID + "\">Read More</button></li>";
            html += "           <li class=\"Favourites\"><button id=\"AddToFavourites" + properties[i].InstructionID + "\">Favourites</button></li>";
            html += "       </ul>";
            html += "   </div>";
            html += "</li>";
        }

        html += "           </ul>";
        html += "       </li>";
        html += "       <li id=\"Bottom\">";
        html += "       </li>";
        html += "   </ul>";

        if (popup !== null) {
            cwoMapsSearch.ClosePreview();
        }

        var propertypixel = GetPopupPosition(latitude, longitude);
        var PopupPostion = map.PixelToLatLong(propertypixel.x, propertypixel.y)

        popup = map.AddInfoBox(PopupPostion.latitude, PopupPostion.longitude, html, {})
        popup.IsPopup = true;

        $("#MapAccordianContainer").parent('div').parent('div').css("z-index", "6000");

        // Bind the close button
        $("#MapPreviewClose").bind("click", cwoMapsSearch.ClosePreview);
        //switch off the double click functionality
        $("#MapAccordianContainer").bind("dblclick", function () { return false; });

        for (var j = 0; j < propertyCount; j++) {
            cwoMapsSearch.BindPreviewButton(properties[j]);
        }
    };
    this.BindPreviewButton = function (property) {
        // Bind the Detail buttons
        $("#MapPreviewReadMore" + property.InstructionID).bind("click", function () { Cwo.Page.NavigateWithReferrer(property.URLAliasPath); });
        // Bind a Details button
        $("#MapPreviewReadMoreFromPhoto" + property.InstructionID).bind("click", function () { Cwo.Page.NavigateWithReferrer(property.URLAliasPath); });
        // Bind Expand/Collapse
        $("li #MapPreviewPrice" + property.InstructionID).bind("click", function (e) { cwoMapsSearch.ExpandCollapsePreview(property, e); });
        // Bind the Add to Favourites button
        new Cwo.Favourites.FavouriteButtonHandler(property.InstructionID, "AddToFavourites" + property.InstructionID, "add");
    };
    this.ExpandCollapsePreview = function (property, e) {

        if ($("#MapPreviewPrice" + property.InstructionID).hasClass("Open")) {
            $("#MapAccordianContainer #Middle .Open").removeClass().addClass("Closed");
        }
        else {
            $("#MapAccordianContainer #Middle .Open").removeClass().addClass("Closed");
            $("#MapPreviewPrice" + property.InstructionID).removeClass().addClass("Open");
        }
    };

    // bind the events
    $(document).ready(function () {
        Cwo.Maps.Search.Start = function () {
            cwoMapsSearch.LoadMap();
            //Cwo.Page.EventController.Subscribe("Maps.BingScriptLoaded", cwoMapsSearch.LoadMap);
            Cwo.Page.EventController.Subscribe("ForSaleFilters.CriteriaChanged", function () { cwoMapsSearch.UpdateNew(); });
            Cwo.Page.EventController.Subscribe("ToLetFilters.CriteriaChanged", function () { cwoMapsSearch.UpdateNew(); });
        };

        // Exception handling code to log exceptions to the event viewer
        if (navigator.userAgent.indexOf("MSIE") > -1) {
            Cwo.Maps.Search.Start();
            return;
        }

        Cwo.Maps.Search.Start();
    });
};

