﻿
Type.registerNamespace("Rhc.Mapping");

Rhc.Mapping.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._pinID = 0;
    this._zoomlevel = 0;
    this._layer = null;
    
    //popup specific
    this._PopupPrefix = "POPUP";
    this._currentpin = null;
    this._currentindex = 0;   
    
    this.GetPinDataDelegate = null;
    this.PinHoverDelegate = null;
    this.ChangeMapStyle = null;
    
    this._minPrice = "0";
    this._maxPrice = "0";
    this._beds = -1;
    this._baths = -1;
    this._type = 0;
    this._listedIn = 0;
    this._features = "";
    
    this._init();
}

Rhc.Mapping.Map.prototype = {

    _init: function() {
        /// <summary>
        ///   Initialises the Map.
        /// </summary>       
        
        //setup map
        this._map = new VEMap(this._mapArgs.DivID);    
        this._map.LoadMap(this._mapArgs.Center,this._mapArgs.Zoomlevel,this._mapArgs.Style,this._mapArgs.Fixed,this._mapArgs.Mode); 
        this._map.SetScaleBarDistanceUnit(this._mapArgs.Scale);
        
        this._map.SetMouseWheelZoomToCenter(false);
        
        this._layer = new VEShapeLayer();         
        this._map.AddShapeLayer(this._layer);
        
        //setup the function to get new data whenever the map changes
        this.GetPinDataDelegate = Function.createDelegate(this, this._GetPinData);
        this._map.AttachEvent("onchangeview", this.GetPinDataDelegate);
        
        //setup the function to set the map style when it changes
        this.ChangeMapStyle = Function.createDelegate(this, this._ChangeMapStyle);
        this._map.AttachEvent("onchangemapstyle", this.ChangeMapStyle);
        
        //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);
        
        //Setup additional storage for shapes
        VEShape.prototype.Bounds = "";  

        //get the data for the default view
        this._GetPinData();
    },  
    
    setMinPrice: function(value) {
        this._minPrice = value;
    },

    setMaxPrice: function(value) {
        this._maxPrice = value;
    },
    
    setBeds: function(value) {
        this._beds = value;
    },
    
    setBaths: function(value) {
        this._baths = value;
    },
    
    setType: function(value) {
        this._type = value;
    },

    setListedIn: function(value) {
        this._listedIn = value;
    },

    setFeatures: function(value) {
        this._features = value;
    },
    
    Find: function(value) {
        
        this._map.Find(null, value, null, null, null, null, false, false, null, null, this._LocationFindCallback);
        
        
    },
    
    SetZoomLevel: function(value) {
        this._map.SetZoomLevel(value);
    },

    _LocationFindCallback: function(shape, results, places, hasmore)
    {
        
        if(places == null)
        {
            alert('Place not found.\nPlease try again.');
        }
        
        map.SetZoomLevel(13);
    },

    _ChangeMapStyle: function(event) {
        // if the map style is set to road, force back to Shaded.        
        switch(event.mapStyle)
        {
            case VEMapStyle.Road:
                this._map.SetMapStyle(VEMapStyle.Shaded);
                break;
        }
    },


    _GetPinData: function() {  
        /// <summary>
        ///   Get the latest map data from the webservice.
        /// </summary>
            
        //encode the current map bounds
        var points = new Array();
        var zoom;
        
        switch(this._map.GetMapStyle())
        {
            case VEMapStyle.Road:
            case VEMapStyle.Shaded:
            case VEMapStyle.Aerial:
            case VEMapStyle.Hybrid:
                var view = this._map.GetMapView();
                points.push(view.TopLeftLatLong);
                points.push(view.BottomRightLatLong);
                
                //get zoomlevel
                zoom = this._map.GetZoomLevel();
                break;
                
            case VEMapStyle.Oblique:
            case VEMapStyle.Birdseye:
            case VEMapStyle.BirdseyeHybrid:
                //set zoomlevel      
                zoom = 19;
                var be = this._map.GetBirdseyeScene();
                var rect = be.GetBoundingRectangle();
                points.push(rect.TopLeftLatLong);
                points.push(rect.BottomRightLatLong);
                break;
        }
        
        
        var bounds = Utility.createEncodings(points);
        if (this._zoomlevel != zoom) {
            //clear existing pins
            this._layer.DeleteAllShapes();
            this._zoomlevel = zoom;
        }
      
        //call webservice
        this._service.GetClusteredMapData(bounds, zoom, this._minPrice, this._maxPrice, this._beds, this._baths, this._type, this._listedIn, this._features, Function.createDelegate(this, this._OnMapDataSucceeded), Utility.OnFailed);
        
        var rssPath = "webservices/GeoRSS.aspx?Bounds=" + bounds;
        rssPath += "&minPrice=" + this._minPrice;
        rssPath += "&maxPrice" + this._maxPrice;
        rssPath += "&beds" + this._beds;
        rssPath += "&baths" + this._baths;
        rssPath += "&type" + this._type;
        rssPath += "&listedIn" + this._listedIn;
        rssPath += "&features" + this._features;
        
        
        document.getElementById('rssLink').href = rssPath;
        
        
    },

    _OnMapDataSucceeded: function(results) {
        /// <summary>
        ///   Receive data for map.
        /// </summary>  
        /// <param name="result">The webservice result object - Optomised CSV string</param>  
            
        //decode pins
        var result=results.split(",")
        var locs = Utility.decodeLine(result[0]);
        var newShapes = new Array();
        
        //clear existing pins
        this._layer.DeleteAllShapes();
               
        //add new pins
        for(x = 0; x < locs.length; x++) {
            var loc = locs[x];
            var bounds = result[x+1];

            var newShape = new VEShape(VEShapeType.Pushpin, loc); 
            newShape.Bounds = bounds;         
            //set custom png pin, IE6 will require a PNG fix.
            if(Sys.Browser.agent==Sys.Browser.InternetExplorer&&Sys.Browser.version==6){
                newShape.SetCustomIcon("<div class='myPushpinIE6'></div>");
            }else {  
                newShape.SetCustomIcon("<div class='myPushpin'></div>");
            }
            
            newShapes.push(newShape);
   
        }       
        this._layer.AddShape(newShapes);           
    },
    
    _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)
            {
                //set current pin
                this._currentpin = popupShape;
                this._currentindex = 0;
                
                //get the content for the pin.
                this._getAJAXContent();
                this._currentpin.SetDescription("<div id='" + this._PopupPrefix + this._currentpin.GetID() + "'>Loading...</div>");
                this._currentpin.SetTitle("");
            }
        }
    },   
    
    _getAJAXContent: function() {
        /// <summary>
        ///   Request content for popup.
        /// </summary>  
        
        //call the web service
        this._service.GetPushPin(this._currentpin.Bounds, this._currentindex, this._minPrice, this._maxPrice, this._beds, this._baths, this._type, this._listedIn, this._features, Function.createDelegate(this, this._OnContentSucceeded), Utility.OnFailed, this._currentpin.GetID());
    }, 
    
    _OnContentSucceeded: function(result, ID) { 
        /// <summary>
        ///   Receive content for popup.
        /// </summary>  
        /// <param name="result">The webservice result object - JSON PinData</param>  
        /// <param name="ID">The popup ID associated with this call</param>  
            
        //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("Property: #" + result.Title);
                var content = result.Details + "</br>";
                content += "<div class='ActionButton' onClick='SelectProperty(" + result.Title + ")'>View</div>";
                this._currentpin.SetDescription(content);
            }else {
                //create the content element
                var el = document.createElement("div");
                
                var content = "<table width='295' border='0'><tr valign='top'><td height='75'>";
                
                content += "<div class='pinTitle'>Property: #" + result.Title + "</div>" +  result.Details + "<br/>";
                content += "<div class='ActionButton' onClick='SelectProperty(" + result.Title + ")'>View</div>";
                content += "</td><td width='75'>" + "<img style='float:right' src='" + result.Thumb + "'/></td></tr>";
                content += "<tr><td>" + (this._currentindex + 1) + "/" + result.TotalRecords + "</td><td></td></tr></table>"
                
                el.innerHTML = content;
                //clear loading and attach the content
                $get(this._PopupPrefix + ID).innerHTML = "";
                $get(this._PopupPrefix + ID).appendChild(el);
                
                if (result.TotalRecords > 1) {
                    //prev / next functionlaity
                    var prevButton = document.createElement("div");
                    prevButton.innerHTML = "Previous";
                    el.appendChild(prevButton);
                    
                    Sys.UI.DomElement.addCssClass(prevButton, "ActionButton");
                    if (this._currentindex > 0) {  
                        $addHandler(prevButton,"click",Function.createDelegate(this, this._PreviousRecord));      
                    }else {
                        Sys.UI.DomElement.addCssClass(prevButton, "ButtonDisabled");
                    }
                    
                    var nextButton = document.createElement("div");
                    nextButton.innerHTML = "Next";
                    el.appendChild(nextButton);  
                    
                    Sys.UI.DomElement.addCssClass(nextButton, "ActionButton");
                    if (this._currentindex < (result.TotalRecords-1)) {  
                        $addHandler(nextButton,"click",Function.createDelegate(this, this._NextRecord));                         
                    }else {
                        Sys.UI.DomElement.addCssClass(nextButton, "ButtonDisabled");
                    }
                }
                
                
                
                              
            }
        }
    },    
    
    _PreviousRecord: function() {
        /// <summary>
        ///   Request the previous record.
        /// </summary>  
        this._currentindex--;
        $get(this._PopupPrefix + this._currentpin.GetID()).innerHTML = "Loading...";
        this._getAJAXContent();
    },
    
    _NextRecord: function() {
        /// <summary>
        ///   Request the next record.
        /// </summary>      
        this._currentindex++;
        $get(this._PopupPrefix + this._currentpin.GetID()).innerHTML = "Loading...";
        this._getAJAXContent();
    },             

    Dispose: function() {
        /// <summary>
        ///   cleans up all objects. Detaches all events.
        /// </summary>
        if (this._map != null) {
            this._map.DetachEvent("onchangeview", this.GetPinDataDelegate);
            this._map.DetachEvent("onchangemapstyle", this.ChangeMapStyle);
            this._map.DetachEvent("onmouseover", this.PinHoverDelegate);
            this._map.DetachEvent("onclick", this.PinHoverDelegate);                
            this._map.Dispose();
        }    
        this._service = null;
        this._mapArgs = null;
        
        this._map = null;
        this._pinID = null;
        this._zoomlevel = null;
        this._layer = null;
        
        //popup specific
        this._PopupPrefix = null;
        this._currentpin = null;
        this._currentindex = null;   

        this.GetPinDataDelegate = null;
        this.ChangeMapStyle = null;
        this.PinHoverDelegate = null;   
    }    
}



Rhc.Mapping.Map.registerClass('Rhc.Mapping.Map', null, Sys.IDisposable);

if (typeof(Sys) !== "undefined") Sys.Application.notifyScriptLoaded();


