﻿
Type.registerNamespace("Renters");

Renters.Map = function(service, mapArgs) {
    /// <summary>
    ///   The VE Map.
    ///   Supports load on demand
    /// </summary>
    /// <param name="service">The webservice to call for the map data.</param>
    /// <param name="mapArgs">The map initalisation data.</param>

    this._service = service;
    this._mapArgs = mapArgs;

    this._map = null;
    this._layer = null;
    this._layerHidden = null;
    this._layerRegion = null
    this._layerHelp = null
    this._layerRegionLabels = null;
    this._layerLoading = null
    this._display = null;

    //popup specific
    this._PopupPrefix = "POPUP";
    this._currentpin = null;
    this._currentindex = 0;

    this._OnMapChangeDelegate = null;

    this._init();
};

Renters.Map.prototype = {

    varSearchTerm: "",
    varLocationCode: "",
    varPropertyType: "",
    varAmenities: "",
    varCloseBy: "",
    varRegion: "",
    varBedrooms: "",
    varBathrooms: "",
    varMaxPrice: -1,
    varMinPrice: -1,
    varUtilities: "",
    varFeatures: "",
    varFirstSearch: 0,
    varLocationID: "",
    varAdCode: "",
    varRadius: 2,
    varRefresh: false,
    varCurrentPage: 1,
    varItemsPerPage: 6,
    varTotalPinResults: 0,
    varPinDisplay: "",
    varPinLocations: "",
    varProduct: "",
    varPublication: "",

    _init: function() {
        /// <summary>
        ///   Initialises the Map.
        /// </summary>       

        //setup map
        this._map = new VEMap(this._mapArgs.DivID);
        //this._map.AttachEvent("oncredentialserror", this._MyHandleCredentialsError);
        //this._map.AttachEvent("oncredentialsvalid", this._MyHandleCredentialsValid);
        this._map.SetCredentials(this._mapArgs.key);
        //load map parameters - divID, center, zoomlevel, style, fixed, mode, scale, showSwitch, display
        this._map.LoadMap(this._mapArgs.Center, this._mapArgs.Zoomlevel, this._mapArgs.Style, this._mapArgs.Fixed, this._mapArgs.Mode, this._mapArgs.ShowSwitch);

        //clear the infobox style
        this._map.ClearInfoBoxStyles();

        this._map.SetScaleBarDistanceUnit(this._mapArgs.Scale);

        //region labels Layer
        this._layerRegionLabels = new VEShapeLayer();
        this._map.AddShapeLayer(this._layerRegionLabels);

        //displayable layer for results in boundary
        this._layer = new VEShapeLayer();
        this._map.AddShapeLayer(this._layer);
        //displayable region mapping
        this._layerRegion = new VEShapeLayer();
        this._map.AddShapeLayer(this._layerRegion);
        //displayable how to use map
        this._layerHelp = new VEShapeLayer();
        this._map.AddShapeLayer(this._layerHelp);
        //displayable loading animated image
        //        this._layerLoading = new VEShapeLayer();
        //        this._map.AddShapeLayer(this._layerLoading);
        //non-displayable all search results layer
        this._layerHidden = new VEShapeLayer();
        this._map.AddShapeLayer(this._layerHidden);
        this._layerHidden.Hide();

        //setup the function to get new data whenever the map changes
        this._OnMapChangeDelegate = Function.createDelegate(this, this._GetSearchData);
        this._map.AttachEvent("onchangeview", this._OnMapChangeDelegate);

        //turn off the standard popup and attach our custom handler
        this.PinHoverDelegate = Function.createDelegate(this, this._PinActivate);
        this._map.AttachEvent("onmouseover", this.PinHoverDelegate);
        this._map.AttachEvent("onclick", this.PinHoverDelegate);

        //this._DisplayLoading();
        this._DisplayRegions();
        this._DisplayHelp();
    },

    _MyHandleCredentialsError: function() {
        alert("The credentials are invalid.");
    },

    _MyHandleCredentialsValid: function() {
        alert("The credentials are valid.");
    },

    _ClearSearchVars: function() {
        this.varSearchTerm = "";
        this.varLocationCode = "";
        this.varPropertyType = "";
        this.varAmenities = "";
        this.varCloseBy = "";
        this.varRegion = "";
        this.varBedrooms = "";
        this.varBathrooms = "";
        this.varMaxPrice = -1;
        this.varMinPrice = -1;
        this.varUtilities = "";
        this.varFeatures = "";
        this.varRadius = 2;
        this.varProduct = "";
        this.varPublication = "";
    },

    _DisplayHelp: function() {
        var mainCentre; //= new VELatLong(43.764152, -79.564539);

        switch (this._mapArgs.Publication.toLowerCase()) {
            case "cgy":
            case "c":
                //Cgy
                mainCentre = new VELatLong(51.024848, -114.107312);
                break;
            case "edm":
            case "e":
                //Edm
                mainCentre = new VELatLong(53.546018, -113.495636);
                break;
            default:
                //GTA
                mainCentre = new VELatLong(43.764152, -79.564539);
                break;
        }

        var textOffset = new VEPixel(80, 105); // (17, 4) default text size setting
        var imgOffset = new VEPixel(75, 100); // default image offset from anchor setting (horz,vert)

        //Create VECustomeIcon just for text display
        var customIcon = new VECustomIconSpecification();
        customIcon.TextContent = "<p style=\"font-weight:bold;white-space:no-wrap;width:177px;height:129px\">To search by map,<br />double click on the area<br />of interest to zoom in.</p>";
        customIcon.Image = "http://rentersclassified.ca/userfiles/image/Green_Map_overlay.png";
        customIcon.ImageOffset = imgOffset;
        var textColor = new VEColor(0, 0, 0, 1.0); //black
        customIcon.ForeColor = textColor;
        customIcon.TextBold = true;
        customIcon.TextFont = "helvetica";
        customIcon.TextOffset = textOffset;
        customIcon.TextSize = 10;

        //Create VEShape objects, set parameters, and add to the map
        var details = "<p style=\"text-align:left;margin:0,0,0,0;\">To search by map, double click on the area of interest to zoom in. Once zoomed in, points will appear that " +
            "represent individual or multiple rental locations in the current maps boundary. A listing view of the results will also appear " +
            "on the right side for you to page through if desired. You may also mouse over the points to view the available locations in " +
            "a listed view.<br />Click on the building image to launch a details page on the location.</p>";
        var title = "Renters Classified Map How To";
        var help = new VEShape(VEShapeType.Pushpin, mainCentre);
        help.SetCustomIcon(customIcon);
        help.SetDescription(details);
        help.SetTitle(title);
        help.ShowIcon();
        this._layerHelp.AddShape(help);
    },

    _GetMapBoundaries: function() {
        /// <summary>
        ///   Get the latest map data from the webservice.
        /// Updated: D.A. - 2010-05-04
        /// With SQL Server 2008, spatial data order have changed. Originally it was Lat/Long but has been swiched to Long/Lat for WKT 
        /// coordinate pairs. So commenting out code below and swapping positions so Long/Lat
        /// </summary>

        var WKTBoundsEast = "";
        var WKTBoundsWest = "";
        var viewrect;

        if (this._map.GetMapStyle() == VEMapStyle.Birdseye) {
            var be = this._map.GetBirdseyeScene();
            viewrect = be.GetBoundingRectangle();
        } else {
            viewrect = this._map.GetMapView();
        }
        if (this._map.GetMapMode() == VEMapMode.Mode3D) {
            //we have four corners to use, to support view greater then half earth we would need to impliment logic as per 2D.
            WKTBoundsEast = "POLYGON((" + viewrect.TopLeftLatLong.Longitude + " " + viewrect.TopLeftLatLong.Latitude + ", " + viewrect.BottomLeftLatLong.Longitude + " " + viewrect.BottomLeftLatLong.Latitude + ", " + viewrect.BottomRightLatLong.Longitude + " " + viewrect.BottomRightLatLong.Latitude + ", " + viewrect.TopRightLatLong.Longitude + " " + viewrect.TopRightLatLong.Latitude + ", " + viewrect.TopLeftLatLong.Longitude + " " + viewrect.TopLeftLatLong.Latitude + "))";
        } else {
            //only have two points to use. Need to break into polygon no greater then half the Earth.
            if (viewrect.TopLeftLatLong.Longitude < 0) {
                if (viewrect.BottomRightLatLong.Longitude < 0) {
                    WKTBoundsWest = "POLYGON((" + viewrect.TopLeftLatLong.Longitude + " " + viewrect.TopLeftLatLong.Latitude + ", " + viewrect.TopLeftLatLong.Longitude + " " + viewrect.BottomRightLatLong.Latitude + ", " + viewrect.BottomRightLatLong.Longitude + " " + viewrect.BottomRightLatLong.Latitude + ", " + viewrect.BottomRightLatLong.Longitude + " " + viewrect.TopLeftLatLong.Latitude + ", " + viewrect.TopLeftLatLong.Longitude + " " + viewrect.TopLeftLatLong.Latitude + "))";
                } else {
                    WKTBoundsWest = "POLYGON((" + viewrect.TopLeftLatLong.Longitude + " " + viewrect.TopLeftLatLong.Latitude + ", " + viewrect.TopLeftLatLong.Longitude + " " + viewrect.BottomRightLatLong.Latitude + ", " + 0 + " " + viewrect.BottomRightLatLong.Latitude + ", " + 0 + " " + viewrect.TopLeftLatLong.Latitude + ", " + viewrect.TopLeftLatLong.Longitude + " " + viewrect.TopLeftLatLong.Latitude + "))";
                }
            }
            if (viewrect.BottomRightLatLong.Longitude > 0) {
                if (viewrect.TopLeftLatLong.Longitude > 0) {
                    WKTBoundsEast = "POLYGON((" + viewrect.TopLeftLatLong.Longitude + " " + viewrect.TopLeftLatLong.Latitude + ", " + viewrect.TopLeftLatLong.Longitude + " " + viewrect.BottomRightLatLong.Latitude + ", " + viewrect.BottomRightLatLong.Longitude + " " + viewrect.BottomRightLatLong.Latitude + ", " + viewrect.BottomRightLatLong.Longitude + " " + viewrect.TopLeftLatLong.Latitude + ", " + viewrect.TopLeftLatLong.Longitude + " " + viewrect.TopLeftLatLong.Latitude + "))";
                } else {
                    WKTBoundsEast = "POLYGON((" + 0 + " " + viewrect.TopLeftLatLong.Latitude + ", " + 0 + " " + viewrect.BottomRightLatLong.Latitude + ", " + viewrect.BottomRightLatLong.Longitude + " " + viewrect.BottomRightLatLong.Latitude + ", " + viewrect.BottomRightLatLong.Longitude + " " + viewrect.TopLeftLatLong.Latitude + ", " + 0 + " " + viewrect.TopLeftLatLong.Latitude + "))";
                }
            }
        }
        return WKTBoundsWest; //+WKTBoundsEast;
    },

    //Region Defined Region Information ************************************************************************************

    _DisplayRegions1: function(Category) {
        /// <summary>
        ///   Display the regions on the Map.
        /// </summary>

        //call webservice
        this._service.GetMapRegions(Category, Function.createDelegate(this, this._OnMapRegionDataSucceeded), Function.createDelegate(this, this._OnFailed));
    },

    _DisplayRegions: function() {
        /// <summary>
        ///   Display the regions on the Map.
        /// </summary>
        switch (this._mapArgs.Publication.toLowerCase()) {
            case "cgy":
            case "c":
                //Cgy
                this._service.GetMapRegions("region_ab_cgy_NE", Function.createDelegate(this, this._OnMapRegionDataSucceeded), Function.createDelegate(this, this._OnFailed));
                this._service.GetMapRegions("region_ab_cgy_NW", Function.createDelegate(this, this._OnMapRegionDataSucceeded), Function.createDelegate(this, this._OnFailed));
                this._service.GetMapRegions("region_ab_cgy_SE", Function.createDelegate(this, this._OnMapRegionDataSucceeded), Function.createDelegate(this, this._OnFailed));
                this._service.GetMapRegions("region_ab_cgy_SW", Function.createDelegate(this, this._OnMapRegionDataSucceeded), Function.createDelegate(this, this._OnFailed));
                this._service.GetMapRegions("region_ab_cgy_CN", Function.createDelegate(this, this._OnMapRegionDataSucceeded), Function.createDelegate(this, this._OnFailed));
                break;
            case "edm":
            case "e":
                //Edm
                this._service.GetMapRegions("region_ab_edm_NE", Function.createDelegate(this, this._OnMapRegionDataSucceeded), Function.createDelegate(this, this._OnFailed));
                this._service.GetMapRegions("region_ab_edm_NW", Function.createDelegate(this, this._OnMapRegionDataSucceeded), Function.createDelegate(this, this._OnFailed));
                this._service.GetMapRegions("region_ab_edm_SE", Function.createDelegate(this, this._OnMapRegionDataSucceeded), Function.createDelegate(this, this._OnFailed));
                this._service.GetMapRegions("region_ab_edm_SW", Function.createDelegate(this, this._OnMapRegionDataSucceeded), Function.createDelegate(this, this._OnFailed));
                this._service.GetMapRegions("region_ab_edm_CN", Function.createDelegate(this, this._OnMapRegionDataSucceeded), Function.createDelegate(this, this._OnFailed));
                break;
            default:
                //GTA
                this._service.GetMapRegions("region_on_Central", Function.createDelegate(this, this._OnMapRegionDataSucceeded), Function.createDelegate(this, this._OnFailed));
                this._service.GetMapRegions("region_on_East", Function.createDelegate(this, this._OnMapRegionDataSucceeded), Function.createDelegate(this, this._OnFailed));
                this._service.GetMapRegions("region_on_West", Function.createDelegate(this, this._OnMapRegionDataSucceeded), Function.createDelegate(this, this._OnFailed));
                this._service.GetMapRegions("region_on_North", Function.createDelegate(this, this._OnMapRegionDataSucceeded), Function.createDelegate(this, this._OnFailed));
                this._service.GetMapRegions("region_on_Hamilton", Function.createDelegate(this, this._OnMapRegionDataSucceeded), Function.createDelegate(this, this._OnFailed));
                break;
        }
    },

    _OnMapRegionDataSucceeded: function(results) {
        /// <summary>
        ///   Receive data for map.
        /// </summary>  
        /// <param name="result">The webservice result object - JSON</param>  

        //delete old data
        //this._layer.DeleteAllShapes();

        //add new pins
        var _title;
        var newShapes = new Array();
        for (x = 0; x < results.length; x++) {
            var newShape = new VELatLong(results[x].Latitude, results[x].Longitude);
            _title = results[x].Title;
            newShapes.push(newShape);
        }

        var outlineColor;
        var fillColor;
        var id = _title;
        var outlineWidth = 0;
        var textOffset;
        var imgOffset;
        var textColor;
        var iconPath;
        switch (_title.toLowerCase()) {
            case "central":
                outlineColor = new VEColor(71, 43, 128, 1); //71|43|128
                fillColor = new VEColor(71, 43, 128, 0.2); //71|43|128
                textColor = new VEColor(71, 43, 128, 1.0);
                textOffset = new VEPixel(22, -7); // (13, 4) default text size setting
                imgOffset = new VEPixel(15, -10); // default image offset from anchor setting
                iconPath = "http://rentersclassified.ca/userfiles/image/oval.png";
                break;
            case "east":
                outlineColor = new VEColor(83, 147, 215, 1); //83|147|215
                fillColor = new VEColor(83, 147, 215, 0.2); //83|147|215
                textColor = new VEColor(83, 147, 215, 1.0);
                textOffset = new VEPixel(175, -108); // (17, 4) default text size setting
                imgOffset = new VEPixel(160, -110); // default image offset from anchor setting
                iconPath = "http://rentersclassified.ca/userfiles/image/oval.png";
                break;
            case "west":
                outlineColor = new VEColor(192, 30, 57, 1); //192|30|157
                fillColor = new VEColor(192, 30, 57, 0.2); //192|30|157
                textColor = new VEColor(192, 30, 57, 1.0);
                textOffset = new VEPixel(-80, -50); // (17, 4) default text size setting
                imgOffset = new VEPixel(-95, -53); // default image offset from anchor setting
                iconPath = "http://rentersclassified.ca/userfiles/image/oval.png";
                break;
            case "north":
                outlineColor = new VEColor(72, 127, 67, 1); //72|127|157
                fillColor = new VEColor(72, 127, 67, 0.2); //72|127|157
                textColor = new VEColor(72, 127, 67, 1.0);
                textOffset = new VEPixel(11, -120); // (16, 4) default text size setting
                imgOffset = new VEPixel(0, -123); // default image offset from anchor setting
                iconPath = "http://rentersclassified.ca/userfiles/image/oval.png";
                break;
            case "hamilton":
                outlineColor = new VEColor(20, 19, 0, 1); //205|92|92
                fillColor = new VEColor(20, 19, 0, 0.2); //205|92|92
                textColor = new VEColor(20, 19, 0, 1.0);
                textOffset = new VEPixel(-120, 100); // (16, 4) default text size setting
                imgOffset = new VEPixel(-120, 98); // default image offset from anchor setting
                iconPath = "http://rentersclassified.ca/userfiles/image/oval.png";
                break;
            case "cgy_ne":
                outlineColor = new VEColor(83, 147, 215, 1); //83|147|215
                fillColor = new VEColor(83, 147, 215, 0.2); //83|147|215
                textColor = new VEColor(71, 43, 128, 1.0);
                textOffset = new VEPixel(-85, -125); // (16, 4) default text size setting
                imgOffset = new VEPixel(-95, -132); // default image offset from anchor setting
                _title = "North West";
                iconPath = "http://rentersclassified.ca/userfiles/image/ovalbig.png";
                break;
            case "cgy_nw":
                outlineColor = new VEColor(71, 43, 128, 1); //71|43|128
                fillColor = new VEColor(71, 43, 128, 0.2); //71|43|128
                textColor = new VEColor(83, 147, 215, 1.0);
                textOffset = new VEPixel(85, -93); // (16, 4) default text size setting
                imgOffset = new VEPixel(80, -100); // default image offset from anchor setting
                _title = "North East";
                iconPath = "http://rentersclassified.ca/userfiles/image/ovalbig.png";
                break;
            case "cgy_cn":
                outlineColor = new VEColor(192, 30, 57, 1); //192|30|157
                fillColor = new VEColor(192, 30, 57, 0.2); //192|30|157
                textColor = new VEColor(192, 30, 57, 1.0);
                textOffset = new VEPixel(23, 6); // (13, 4) default text size setting
                imgOffset = new VEPixel(10, 0); // default image offset from anchor setting
                _title = "Central";
                iconPath = "http://rentersclassified.ca/userfiles/image/ovalbig.png";
                break;
            case "cgy_sw":
                outlineColor = new VEColor(72, 127, 67, 1); //72|127|157
                fillColor = new VEColor(72, 127, 67, 0.2); //72|127|157
                textColor = new VEColor(72, 127, 67, 1.0);
                textOffset = new VEPixel(-77, 116); // (16, 4) default text size setting
                imgOffset = new VEPixel(-80, 110); // default image offset from anchor setting
                _title = "South West";
                iconPath = "http://rentersclassified.ca/userfiles/image/ovalbig.png";
                break;
            case "cgy_se":
                outlineColor = new VEColor(20, 19, 0, 1); //205|92|92
                fillColor = new VEColor(20, 19, 0, 0.2); //205|92|92
                textColor = new VEColor(20, 19, 0, 1.0);
                textOffset = new VEPixel(85, 75); // (16, 4) default text size setting
                imgOffset = new VEPixel(80, 70); // default image offset from anchor setting
                _title = "South East";
                iconPath = "http://rentersclassified.ca/userfiles/image/ovalbig.png";
                break;
            case "edm_ne":
                outlineColor = new VEColor(83, 147, 215, 1); //83|147|215
                fillColor = new VEColor(83, 147, 215, 0.2); //83|147|215
                textColor = new VEColor(83, 147, 215, 1.0);
                textOffset = new VEPixel(-85, -75); // (16, 4) default text size setting
                imgOffset = new VEPixel(-95, -80); // default image offset from anchor setting
                _title = "North West";
                iconPath = "http://rentersclassified.ca/userfiles/image/ovalbig.png";
                break;
            case "edm_nw":
                outlineColor = new VEColor(71, 43, 128, 1); //71|43|128
                fillColor = new VEColor(71, 43, 128, 0.2); //71|43|128
                textColor = new VEColor(71, 43, 128, 1.0);
                textOffset = new VEPixel(85, -95); // (16, 4) default text size setting
                imgOffset = new VEPixel(80, -100); // default image offset from anchor setting
                _title = "North East";
                iconPath = "http://rentersclassified.ca/userfiles/image/ovalbig.png";
                break;
            case "edm_cn":
                outlineColor = new VEColor(192, 30, 57, 1); //192|30|157
                fillColor = new VEColor(192, 30, 57, 0.2); //192|30|157
                textColor = new VEColor(192, 30, 57, 1.0);
                textOffset = new VEPixel(-10, 25); // (17, 4) default text size setting
                imgOffset = new VEPixel(-25, 20); // default image offset from anchor setting
                _title = "Central";
                iconPath = "http://rentersclassified.ca/userfiles/image/ovalbig.png";
                break;
            case "edm_sw":
                outlineColor = new VEColor(72, 127, 67, 1); //72|127|157
                fillColor = new VEColor(72, 127, 67, 0.2); //72|127|157
                textColor = new VEColor(72, 127, 67, 1.0);
                textOffset = new VEPixel(-87, 87); // (16, 4) default text size setting
                imgOffset = new VEPixel(-90, 80); // default image offset from anchor setting
                _title = "South West";
                iconPath = "http://rentersclassified.ca/userfiles/image/ovalbig.png";
                break;
            case "edm_se":
                outlineColor = new VEColor(20, 19, 0, 1); //205|92|92
                fillColor = new VEColor(20, 19, 0, 0.2); //205|92|92
                textColor = new VEColor(20, 19, 0, 1.0);
                textOffset = new VEPixel(87, 76); // (16, 4) default text size setting
                imgOffset = new VEPixel(80, 70); // default image offset from anchor setting
                _title = "South East";
                iconPath = "http://rentersclassified.ca/userfiles/image/ovalbig.png";
                break;
        }

        //Create VECustomeIcon just for text display
        var customIcon = new VECustomIconSpecification();
        customIcon.TextContent = "<div style='white-space: nowrap'>" + _title + "</div>";
        customIcon.Image = iconPath;  //"http://rentersclassified.ca/userfiles/image/oval.png";
        customIcon.ImageOffset = imgOffset;
        //var textColor = new VEColor(0, 0, 0, 1.0); //black
        customIcon.ForeColor = textColor;
        customIcon.TextBold = true;
        customIcon.TextFont = "helvetica";
        customIcon.TextOffset = textOffset;
        customIcon.TextSize = 10;

        var label = new VEShape(VEShapeType.Pushpin, this._mapArgs.Center);
        label.SetCustomIcon(customIcon);
        //label.SetTitle(_title);
        //label.ShowIcon();
        this._layerRegionLabels.AddShape(label);

        //Create VEShape objects, set parameters, and add to the map
        var poly = new VEShape(VEShapeType.Polygon, newShapes);
        poly.SetLineWidth(1);
        poly.SetLineColor(outlineColor);
        poly.SetFillColor(fillColor);
        poly.SetPoints(newShapes);
        //poly.SetCustomIcon(customIcon);
        //poly.ShowIcon();
        poly.HideIcon();
        this._layerRegion.AddShape(poly);
    },

    //Get Pins bound by defined area in map Information ************************************************************************************

    _GetPinData: function() {
        /// <summary>
        ///   Get the latest map data from the webservice.
        /// Updated: D.A. - 2010-05-04
        /// With SQL Server 2008, spatial data order have changed. Originally it was Lat/Long but has been swiched to Long/Lat for WKT 
        /// coordinate pairs. So commenting out code below and swapping positions so Long/Lat
        /// </summary>

        var WKTBounds = "";
        WKTBounds = this._GetMapBoundaries();
        this._service.GetMapData(WKTBounds, Function.createDelegate(this, this._OnMapDataSucceeded), Function.createDelegate(this, this._OnFailed));
    },


    _GetFirstSearchData: function() {
        this.varFirstSearch = 1;
        this._GetSearchData();
    },

    _GetSearchData: function() {
        //_GetSearchData: function(varSearchTerm, varLocationCode, varPropertyType, varAmenities, varCloseBy,
        //       varRegion, varBedrooms, varBathrooms, varMaxPrice, varMinPrice, varUtilities, varFeatures) {
        /// <summary>
        ///   Get the latest map data from the webservice.
        /// Updated: D.A. - 2010-05-04
        /// With SQL Server 2008, spatial data order have changed. Originally it was Lat/Long but has been swiched to Long/Lat for WKT 
        /// coordinate pairs. So commenting out code below and swapping positions so Long/Lat
        /// </summary>

        //hide help layer
        if (this._layerHelp.IsVisible()) {
            this._layerHelp.Hide();
        }
        if (this._layerRegionLabels.IsVisible()) {
            this._layerRegionLabels.Hide();
        }

        //setup the function to get new data whenever the map changes
        this._map.DetachEvent("onchangeview", this._OnMapChangeDelegate);
        this._OnMapChangeDelegate = Function.createDelegate(this, this._GetSearchData);
        this._map.AttachEvent("onchangeview", this._OnMapChangeDelegate);

        var WKTBounds = "";
        WKTBounds = this._GetMapBoundaries();

        //added for filtering for Renters Edm and Cgy
        var docProduct = document.getElementById("defproduct");
        var docPublication = readValue("defpublication");
        if (docProduct.value != "") { this.varProduct = docProduct.value; }
        if (docPublication.value != "") {
            var _pub;
            switch (docPublication.value.toLowerCase()) {
                case "c":
                case "cgy":
                    _pub = "calgary";
                    break;
                case "E":
                case "edm":
                    _pub = "edmonton";
                    break;
                default:
                    _pub = "toronto";
                    break;
            }
            this.varPublication = _pub;
        }

        //call webservice
        this._service.GetMapSearch(this.varSearchTerm, this.varLocationCode, this.varPropertyType, this.varAmenities, this.varCloseBy,
            this.varRegion, this.varBedrooms, this.varBathrooms, this.varMaxPrice, this.varMinPrice, this.varUtilities, this.varFeatures,
            WKTBounds, this.varRadius, brwsr, ContID, locationImagePath, -1, -1, this.varProduct, this.varPublication,
            Function.createDelegate(this, this._OnMapDataSucceeded), Function.createDelegate(this, this._OnFailed));
    },

    _GetAllData: function() {
        //function to load hidden layer with all results
        var WKTBounds = "";

        //call webservice 
        this._service.GetMapSearch(this.varSearchTerm, this.varLocationCode, this.varPropertyType, this.varAmenities, this.varCloseBy,
            this.varRegion, this.varBedrooms, this.varBathrooms, this.varMaxPrice, this.varMinPrice, this.varUtilities, this.varFeatures,
            WKTBounds, this.varRadius, brwsr, ContID, locationImagePath, -1, -1, this.varProduct, this.varPublication,
            Function.createDelegate(this, this._OnMapDataSucceeded), Function.createDelegate(this, this._OnFailed));
    },

    _OnMapDataSucceeded: function(results) {
        /// <summary>
        ///   Receive data for map.
        /// </summary>  
        /// <param name="result">The webservice result object - JSON</param>

        //delete old cache data
        searchCache.clear();
        pinCache.clear();
        displayCache.clear();

        //setup search results display
        this._layer.DeleteAllShapes();

        var shape;

        this.varTotalPinResults = results.length;
        var totResults = this.varTotalPinResults
        if (totResults > 0) {
            //add new pins
            var newShapes = new Array();
            for (x = 0; x < totResults; x++) {
                var newShape = new VEShape(VEShapeType.Pushpin, new VELatLong(results[x].Latitude, results[x].Longitude));
                newShape.SetCustomIcon("<img id='" + results[x].LocationID + "' src='http://www.rentersclassified.ca/Userfiles/image/pin.png' alt='pin' />"); //pin.png
                //collect shapes to use to "center" map
                newShapes.push(newShape);
            }
            this._layer.AddShape(newShapes);

            //set clustering of pins
            var options = new VEClusteringOptions();
            options.Callback = this._ClusteringCallback;

            this._layer.SetClusteringConfiguration(VEClusteringType.Grid, options);

            //set the view based on the shapes added
            if (this.varFirstSearch == 1) {
                this._map.SetMapView(newShapes);
                this.varFirstSearch = 0;
            }

            //set zoom level if only 1 result so not zoomed all the way in
            this.varCurrentPage = 1;
            this._GetSearchDisplayData();
        } else {
            this._display = window.document.getElementById(this._mapArgs.Display);
            this._display.innerHTML = DisplayNoResults();
        }

        //hide loading layer
        //        if (this._layerLoading.IsVisible()) {
        //            this._layerLoading.Hide();
        //        }
    },

    _ClusteringCallback: function(clusters) {
        var _Desc = "";
        var _ShapeID = "";
        var shape;
        var shapeIDs;
        for (var i = 0; i < clusters.length; ++i) {
            var cluster = clusters[i];
            _Desc = "";
            _ShapeID = "";
            for (var j = 0; j < cluster.Shapes.length; j++) {
                //get description infor for the popup

                _ShapeID = _ShapeID + cluster.Shapes[j].GetID() + "," + parseImgLocID(cluster.Shapes[j].GetCustomIcon()) + "|";
            }
            if (_ShapeID.length > 0) { _ShapeID = "|" + _ShapeID; } //_ShapeID = _ShapeID.substr(0, _ShapeID.length - 1); }
            var _ClustShapeIcon = new VECustomIconSpecification();
            var pinName = cluster.Shapes.length.toString();
            if (cluster.Shapes.length > 20) {
                pinName = "20_plus";
            }

            // added in hidden input to collect the shape id's belonging to cluster so can loop through all pins on map on mouseover of display search
            // to get correct clustering pin id to hightlight
            _ClustShapeIcon.CustomHTML = "<input type=\"hidden\" id=\"hdn_cluster_idx" + i.toString() + "\" value=\"" + _ShapeID + "\" /><img src='http://www.rentersclassified.ca/Userfiles/image/pin" + pinName + ".png' alt='pin" + cluster.Shapes.length.toString() + "' />";

            var clusterShape = cluster.GetClusterShape();
            //added in the hidden value to pass on the associated shape ids that belong to the cluster
            clusterShape.SetCustomIcon(_ClustShapeIcon);
        }
    },

    //Get Right hand side display Information ************************************************************************************

    _SearchResultPage: function(PageNumber) {
        this.varCurrentPage = PageNumber;
        //check if result in cache
        //get the display from pin display cache if exists
        var display = displayCache.getItem(this.varCurrentPage.toString());
        if (display !== null && typeof (display) !== "undefined" && display != "") {
            this._display.innerHTML = display;
        } else {
            this._GetSearchDisplayData();
        }
    },

    _GetSearchDisplayData: function() {
        var WKTBounds = "";
        WKTBounds = this._GetMapBoundaries();

        //call webservice 
        this._service.GetMapSearch(this.varSearchTerm, this.varLocationCode, this.varPropertyType, this.varAmenities, this.varCloseBy,
            this.varRegion, this.varBedrooms, this.varBathrooms, this.varMaxPrice, this.varMinPrice, this.varUtilities, this.varFeatures,
            WKTBounds, this.varRadius, brwsr, ContID, locationImagePath, this.varCurrentPage, itemsOnPage, this.varProduct, this.varPublication,
            Function.createDelegate(this, this._OnMapDataDisplaySucceeded), Function.createDelegate(this, this._OnFailed));
    },

    _OnMapDataDisplaySucceeded: function(results) {
        /// <summary>
        ///   Receive data for Right hand side display.
        /// </summary>  
        /// <param name="result">The webservice result object - JSON</param>

        //setup search results display
        this._display = window.document.getElementById(this._mapArgs.Display);
        this._display.innerHTML = "";

        //initialize buffer
        var bufResults = new Renters.StringBuffer();
        //add display items to an array
        //var arrShapeIDs = new Array();
        var shape;
        var cacheKey;
        var _shapeDisplay;
        var totResults = this.varTotalPinResults;
        var found = false;

        //set maxPages and itemsOnPage set in Default.aspx.js
        if (totResults <= itemsOnPage) {
            maxPages = 1;
        } else if (totResults % itemsOnPage === 0) {
            maxPages = Math.floor(totResults / itemsOnPage);
        } else {
            maxPages = Math.floor(totResults / itemsOnPage) + 1;
        }

        for (x = 0; x < results.length; x++) {
            found = false;
            //get the shapes id from cache based on location id
            shapeID = searchCache.getItem(results[x].LocationID);

            if (shapeID === null || typeof (shapeID) === "undefined" || shapeID == "") {
                //Not in cache so check clustered items first, get the cluster layer
                var clusteredShapes = map._layer._clusterLayer;
                //loop through the "clustered" shapes in the cluster layer
                for (var y = 0; y < clusteredShapes.GetShapeCount(); y++) {
                    //get the cluster shape
                    var clusterShape = clusteredShapes.GetShapeByIndex(y);
                    //get the cluster shape id
                    var id = clusterShape.GetID();
                    //get the clustered shapes icon info
                    var custIcon = clusterShape.GetCustomIcon();
                    icon = custIcon.CustomHTML;
                    //since included a hidden input
                    if (icon.indexOf(results[x].LocationID) >= 0) {
                        shapeID = id;
                        searchCache.setItem(results[x].LocationID.toString(), shapeID.toString(), { expirationAbsolute: null,
                            expirationSliding: 3600,
                            priority: CachePriority.Low,
                            callback: null
                        });
                        found = true;
                        break;
                    }
                }

                if (!found) {
                    //have to look through each shape in the map
                    for (var z = 0; z < this._layer.GetShapeCount(); z++) {
                        var shp = this._layer.GetShapeByIndex(z);
                        //get location id from image id value
                        var locId = parseImgLocID(shp.GetCustomIcon());
                        if (locId == results[x].LocationID) {
                            //found shape associated with location id 
                            shapeID = shp.GetID();
                            //add item to cache
                            searchCache.setItem(results[x].LocationID.toString(), shapeID.toString(), { expirationAbsolute: null,
                                expirationSliding: 3600,
                                priority: CachePriority.Low,
                                callback: null
                            });
                            found = true;
                            break;
                        }
                    }
                }
            }

            //DisplaySearchData can be found in Userfiles\image\Formatting.js
            _shapeDisplay = DisplaySearchData(results[x].Price, results[x].PropertyType, results[x].FullAddress, results[x].PropertyManager,
                results[x].LocationCode, results[x].LocationID, shapeID, results[x].AdCode, results[x].IsAd);
            //            _shapeDisplay = _shapeDisplay.replace(/'##SHAPEID##'/g, shapeID);
            //_shapeDisplay = results[x].BuildingDisplay.replace(/'##SHAPEID##'/g, shapeID);
            bufResults.append(_shapeDisplay);

            //if number hits max items per page, cache and clear buffer. (x + 1) comes from need to adjust count which is started from 0 vs. 1
            if ((x + 1) % itemsOnPage === 0) {
                //set search results header and nav
                bufResults.addToFront("<div class=\"tab_back\"><h3 class=\"tab\">Results</h3></div>" + DisplaySearchNavigation(this.varCurrentPage.toString(), maxPages, totResults));
                //add item to cache
                displayCache.setItem(this.varCurrentPage.toString(), bufResults.toString(), { expirationAbsolute: null,
                    expirationSliding: 3600,
                    priority: CachePriority.Low,
                    callback: null
                });
                bufResults.clear();
            }
        }

        //add rest of items to cache and clear buffer. Removed (x + 1)
        if (x % itemsOnPage !== 0) {
            //set search results header and nav
            bufResults.addToFront("<div class=\"tab_back\"><h3 class=\"tab\">Results</h3></div>" + DisplaySearchNavigation(this.varCurrentPage.toString(), maxPages, totResults));
            //add item to cache
            displayCache.setItem(this.varCurrentPage.toString(), bufResults.toString(), { expirationAbsolute: null,
                expirationSliding: 3600,
                priority: CachePriority.Low,
                callback: null
            });
            bufResults.clear();
        }

        this._display.innerHTML = displayCache.getItem(this.varCurrentPage.toString()); //bufResults.toString();
    },

    //Get pin mouseover display Information ************************************************************************************

    _PinActivate: function(e) {
        /// <summary>
        ///   Receives any mouse of event from VE
        /// </summary>  
        /// <param name="e">The MapEvent object</param>         
        if (e.elementID) {
            var popupShape = this._map.GetShapeByID(e.elementID)
            if (popupShape) {
                if (popupShape.Type != "Polygon") {
                    if (popupShape.Title == "Renters Classified Map How To") {
                        //set current pin
                        this._currentpin = popupShape;
                        this._currentindex = 0;
                        this._currentpin.SetDescription(popupShape.Notes);
                    } else {
                        //set current pin
                        this._currentpin = popupShape;
                        this._currentindex = 0;
                        //var tmp = this._currentpin._customIcon;

                        this._currentpin.SetDescription("<div id='" + this._PopupPrefix + this._currentpin.GetID() + "'>Loading...</div>");
                        //get the content for the pin.
                        this._GetPinDisplay();
                        //this._currentpin.SetTitle("Opened");
                    }
                }
            }
        }
    },

    _GetPinDisplay: function() {
        var locations = "";
        var loc = "";
        var ID = this._currentpin.GetID();
        //check if result in cache
        //get the display from pin display cache if exists
        //get info for the cluster, get all the shapeids from the shapes contained within the cluster
        var icon = this._currentpin._customIcon;
        var shapelist = parseHiddenInput(icon);
        if (shapelist !== null && typeof (shapelist) !== "undefined" && shapelist != "") {
            //cluster so process it as such
            var arrShapeIDs = shapelist.split("|");
            for (var z = 0; z < arrShapeIDs.length; z++) {
                //pull the location ids for those shapes
                if (arrShapeIDs[z] !== null && typeof (arrShapeIDs[z]) !== "undefined" && arrShapeIDs[z] != "") {
                    //use the values set in clustering based upon |<shapeid>,<locationid>|
                    var ShpLoc = arrShapeIDs[z].toString().split(","); //get [0]=shapeid, [1] = locationid
                    locations = locations + ShpLoc[1] + ",";
                }
            }
        } else {
            //non cluster so process as such
            loc = parseImgLocID(icon);
            if (loc !== null && typeof (loc) !== "undefined" && loc !== "") {
                locations = locations + loc + ",";
                searchCache.setItem(loc.toString(), this._currentpin.GetID(), { expirationAbsolute: null,
                    expirationSliding: 3600,
                    priority: CachePriority.Low,
                    callback: null
                });
            }
        }

        if (locations !== null && locations != "" && typeof (locations) !== "undefined" && locations.length > 0) {
            //locations exist so go through process of pulling info from cache/db
            this.varPinLocations = locations.substr(0, locations.length - 1);
            this._GetPinDisplayData();
            //            }
        } else {
            // no location info so display error message
            //create the content element
            var e2 = document.createElement("div");
            e2.setAttribute("style", "max-height:225px;overflow:auto;")
            e2.innerHTML = "Sorry, Location information not available";
            //clear loading and attach the content
            $get(this._PopupPrefix + ID).innerHTML = "";
            $get(this._PopupPrefix + ID).appendChild(e2);
        }
    },

    _GetPinDisplayData: function() {
        //call webservice
        this._service.GetPinDisplay(this.varPinLocations, brwsr, ContID, locationImagePath,
            Function.createDelegate(this, this._OnMapDataPinDisplaySucceeded), Function.createDelegate(this, this._OnFailed), this._currentpin.GetID());
    },

    _OnMapDataPinDisplaySucceeded: function(results, ID) {
        /// <summary>
        ///   Receive data for Pin popup display.
        /// </summary>  
        /// <param name="result">The webservice result object - JSON</param>

        //initialize buffer
        var bufResults = new Renters.StringBuffer();
        var totResults = results.length;
        for (var x = 0; x < totResults; x++) {
            //DisplaySearchData can be found in Userfiles\image\Formatting.js
            var _shapeDisplay = DisplaySearchData(results[x].Price, results[x].PropertyType, results[x].FullAddress, results[x].PropertyManager,
                results[x].LocationCode, results[x].LocationID, ID, results[x].AdCode, results[x].IsAd);
            bufResults.append(_shapeDisplay);
        }

        //verify this is the data for the current popup.
        if (ID == this._currentpin.GetID()) {
            if (this._map.GetMapMode() == VEMapMode.Mode3D) {
                //3D mode fails to be able to retrieve the div we placed earlier so resort to setting the title and description only
                //this._currentpin.SetTitle(result.Title);
                this._currentpin.SetDescription(bufResults.toString());
            } else {
                var el = document.createElement("div");
                if (totResults > 1) {
                    el.setAttribute("style", "max-height:225px;overflow:auto;");
                }
                el.innerHTML = bufResults.toString();
                //clear loading and attach the content
                $get(this._PopupPrefix + ID).innerHTML = "";
                $get(this._PopupPrefix + ID).appendChild(el);
            }
        }
        //add info to cache
        pinCache.setItem(this.varPinLocations.toString(), bufResults.toString(), { expirationAbsolute: null,
            expirationSliding: 3600,
            priority: CachePriority.Low,
            callback: null
        });
    },


    _OnMapDataPinDisplaySucceeded1: function(results, ID) {
        /// <summary>
        ///   Receive data for Pin popup display.
        /// </summary>  
        /// <param name="result">The webservice result object - JSON</param>

        results = results.toString().replace(/'##SHAPEID##'/g, "'" + ID + "'");
        //verify this is the data for the current popup.
        if (ID == this._currentpin.GetID()) {
            if (this._map.GetMapMode() == VEMapMode.Mode3D) {
                //3D mode fails to be able to retrieve the div we placed earlier so resort to setting the title and description only
                //this._currentpin.SetTitle(result.Title);
                this._currentpin.SetDescription(results.toString());
            } else {
                var el = document.createElement("div");
                el.setAttribute("style", "max-height:225px;overflow:auto;");
                el.innerHTML = results.toString();
                //clear loading and attach the content
                $get(this._PopupPrefix + ID).innerHTML = "";
                $get(this._PopupPrefix + ID).appendChild(el);
            }
        }
        //add info to cache
        pinCache.setItem(this.varPinLocations.toString(), results.toString(), { expirationAbsolute: null,
            expirationSliding: 3600,
            priority: CachePriority.Low,
            callback: null
        });
    },

    _CheckIsSearch: function() {
        if (this.varSearchTerm != "" || this.varLocationCode != "" || this.varPropertyType != "" || this.varAmenities != "" || this.varCloseBy != "" ||
                this.varRegion != "" || this.varBedrooms != "" || this.varBathrooms != "" || this.varMaxPrice >= 0 || this.varMinPrice >= 0 ||
                this.varUtilities != "" || this.varFeatures != "")
        { return true; }
        else {
            return false;
        }
    },

    _onFeedLoad: function(layer) {
        var numShapes = layer.GetShapeCount();
        var shape;
        var sidebar = document.getElementById('sidebar');
        for (var i = 0; i < numShapes; ++i) {
            shape = layer.GetShapeByIndex(i);
            sidebar.innerHTML += '<div class="title">' + '<a href="" onmouseout="map.HideInfoBox();" onmouseover="Highlight(\'' + shape.GetID() + '\');">' + shape.GetTitle() + '</a>' + '</div>';
            sidebar.innerHTML += '<div class="description">' + shape.GetDescription() + '</div>';
        }
    },

    _OnFailed: function(error) {
        /// <summary>
        ///     This is the failed callback function for all webservices.
        /// </summary>  
        /// <param name="error">The error object from the webservice</param>          

        var stackTrace = error.get_stackTrace();
        var message = error.get_message();
        var statusCode = error.get_statusCode();
        var exceptionType = error.get_exceptionType();
        var timedout = error.get_timedOut();

        // Display the error.    
        var RsltElem =
            "Stack Trace: " + stackTrace + "<br/>" +
            "Service Error: " + message + "<br/>" +
            "Status Code: " + statusCode + "<br/>" +
            "Exception Type: " + exceptionType + "<br/>" +
            "Timedout: " + timedout;

        alert(RsltElem);
    },

    Dispose: function() {
        /// <summary>
        ///   cleans up all objects. Detaches all events.
        /// </summary>
        if (this._map !== null) {
            this._map.DetachEvent("onchangeview", this._OnMapChangeDelegate);
            this._map.Dispose();
        }
        this._service = null;
        this._mapArgs = null;

        this._map = null;
        this._layer = null;

        this._OnMapChangeDelegate = null;
    }
};

Renters.Map.registerClass('Renters.Map');

if (typeof (Sys) !== "undefined") { Sys.Application.notifyScriptLoaded(); }


