﻿
Type.registerNamespace("Internova");

Internova.Map = function(identifier, 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._identifier = identifier;
    this._Active = false
  
    this._map = null;
    this._pinID = 0;
    this._zoomlevel = 0;
    this._layer = null;
    this._recordableItemID = 0;
    this._year = 0;
    
    //Additional Layers
    this._CPBRCLayerVisible = false;
    this._CPBRCLayer = null;
    this._CambsLayerVisible = false;
    this._CambsLayer = null;
    this._POILayerVisible = false;
    this._POILayer = null;
        
    //popup specific
    this._PopupPrefix = "POPUP";
    this._currentpin = null;
    this._currentindex = 0;   
    
    //Birdseye - fix due to not lat/long data available
    this._MapBEyeCentre;  
    this._latoffset = 0.0; //0.005;
    this._lonoffset = 0.0; //0.01;    
    
    this.GetPinDataDelegate = null;
    this.PinHoverDelegate = null;
    this.MouseDownDelegate = null;
    this.PanFromDelegate = null;
    this.ZoomFromDelegate = null
    
    this._mapInstance = null;
    this.initCompleted = false;
    
    this._page = 1;
    
    this._init();
}

Internova.Map.prototype = {

    _init: function() {
        /// <summary>
        ///   Initialises the Map.
        /// </summary>       
        
        //setup map
        this._map = new VEMap(this._mapArgs.DivID);    
		this._map.SetDashboardSize(VEDashboardSize.Tiny);
        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._layer = new VEShapeLayer();         
        
        for(x = 0; x < categoryIDs.length; x++) {
            this._map.AddShapeLayer(eval('category_' + categoryIDs[x]));
            
            if (!document.getElementById('chkCategory_' + categoryIDs[x]).checked)
            {
				eval("category_" + categoryIDs[x]).Hide();
            }
        }
        
        //setup the function to get new data whenever the map changes
        this.GetPinDataDelegate = Function.createDelegate(this, this._GetPinData);
        this._map.AttachEvent("onchangeview", this.GetPinDataDelegate);
        
        //turn off the standard popup and attach our custom handler
        this.PinHoverDelegate = Function.createDelegate(this, this._PinActivate);
        this._map.AttachEvent("onmouseover", this.PinHoverDelegate);
        //attached empty onmouseout event so that the state of the push pin is reset and onmouseover fires correctly
        this._map.AttachEvent("onmouseout", function (e) { return; });
        this._map.AttachEvent("onclick", this.PinHoverDelegate);
        
        //Prevent the zoom from exceeding the set level
        this.CheckZoomLevel = Function.createDelegate(this, this._CheckZoomLevel);
        this._map.AttachEvent("onendzoom", this.CheckZoomLevel);

        //Setup additional storage for shapes
        VEShape.prototype.Bounds = "";  
	    VEShape.prototype.Drawn = false;    
	    VEShape.prototype.Match = false;

        //get the data for the default view
        this._GetPinData();
        
        this.initCompleted = true;
    },  

    _GetPinData: function() {  
        /// <summary>
        ///   Get the latest map data from the webservice.
        /// </summary>
        
        if (this.initCompleted)
        {
            var advertDiv = document.getElementById('POI_advert');
            advertDiv.style.visibility='hidden'; 
            advertDiv.style.display='none';
        }
        
        //encode the current map bounds
        var points = new Array();
        var zoom;
        
        if (this._map.GetMapStyle() == VEMapStyle.Birdseye) {    
            //set zoomlevel      
            zoom = 19;
            points.push(new VELatLong(this._MapBEyeCentre.Latitude + this._latoffset, this._MapBEyeCentre.Longitude - this._lonoffset));
            points.push(new VELatLong(this._MapBEyeCentre.Latitude - this._latoffset, this._MapBEyeCentre.Longitude + this._lonoffset));
        }else {
            var view = this._map.GetMapView();
            points.push(view.TopLeftLatLong);
            points.push(view.BottomRightLatLong);
            
            //get zoomlevel
            zoom = this._map.GetZoomLevel();

            //to try to support Birsdeye we store the centre as currently there is no way to get the lat/long in birdseye :(
            this._MapBEyeCentre = this._map.GetCenter();

        }
        var bounds = Utility.createEncodings(points);
        if (this._zoomlevel != zoom) {
            //clear existing pins
            for(x = 0; x < categoryIDs.length; x++) {
                eval('category_' + categoryIDs[x]).DeleteAllShapes();
            }

            this._zoomlevel = zoom;
        }
        
        this._page = 1;
        
        //call webservice	
        this._service.GetClusteredMapData(bounds, zoom, Function.createDelegate(this, this._OnMapDataSucceeded), Utility.OnFailed);
        this._GetTextResults();
        
    },
    
    //user for refreshing the text search reszults only
    _GetTextResults: function() {
    
       
        //encode the current map bounds
        var points = new Array();
        var zoom;
        
        if (this._map.GetMapStyle() == VEMapStyle.Birdseye) {    
            //set zoomlevel      
            zoom = 19;
            points.push(new VELatLong(this._MapBEyeCentre.Latitude + this._latoffset, this._MapBEyeCentre.Longitude - this._lonoffset));
            points.push(new VELatLong(this._MapBEyeCentre.Latitude - this._latoffset, this._MapBEyeCentre.Longitude + this._lonoffset));
        }else {
            var view = this._map.GetMapView();
            points.push(view.TopLeftLatLong);
            points.push(view.BottomRightLatLong);
            
            //get zoomlevel
            zoom = this._map.GetZoomLevel();

            //to try to support Birsdeye we store the centre as currently there is no way to get the lat/long in birdseye :(
            this._MapBEyeCentre = this._map.GetCenter();

        }
        var bounds = Utility.createEncodings(points);
        
        var selectedCategoryIDs = "";
        for(i = 0; i < categoryIDs.length; i++) 
        {   
            if (document.getElementById('chkCategory_' + categoryIDs[i]).checked)
            {
				selectedCategoryIDs += categoryIDs[i] + ',';
            }
        }
        
        
        //call webservice
        this._service.GetPagedTextResults(bounds, zoom, this._page, selectedCategoryIDs, Function.createDelegate(this, this._OnTextResultsSucceeded), Utility.OnFailed);
    },
    
     
    _OnTextResultsSucceeded: function(results) {
		//alert(results);
		document.getElementById('POI_text_results').innerHTML = results;

    },

    _OnMapDataSucceeded: function(results) {
        /// <summary>
        ///   Receive data for map.
        /// </summary>  
        /// <param name="result">The webservice result object - Optomised CSV string</param>  
            
        //decode pins
		if (results != "~~~")
		{

			var result=results.split(",")
			var filters = result[0].split("~~~~")[1].split(":")
			var locs = Utility.decodeLine(result[0].split("~~~~")[0]);
	        
			//add new pins
			for(x = 0; x < locs.length; x++) {
				var loc = locs[x];
				var bounds = result[x+1];
				var layerID = filters[x];
				var drawn = false;

				//see if it is in the current drawn pins
				for(i = 0; i < totalpins; i++) {
				   var currentshape = eval('category_' + i + '.GetShapeByIndex(i)');
					if (currentshape.Bounds == bounds && currentShape.layerID == layerID) {
						drawn = true;
						currentshape.Match = true;
						break; //shortcut loop
					}
				}            
	            
				if (!drawn) {
					var newShape = new VEShape(VEShapeType.Pushpin, loc); 
					newShape.Bounds = bounds; 
					newShape.LayerID = layerID;         
					newShape.Drawn = drawn;
					newShape.Match = true;
	                
					// Show the right icon here
					var iconIndex;
	                
	//                if(!Array.indexOf){
                		for(var i=0; i<categoryIDs.length; i++)
                		{
							if(categoryIDs[i]==filters[x]){
								iconIndex = i;
							}
						}
	//                }
	//                else
	//                {
	//                      Why does IE still not support indexOf ???????
	//                    iconIndex = categoryIDs.indexOf(filters[x]);
	//                }
	                
	                
	                
	                
	                var iconHeight;
	                
	                if (this._zoomlevel < 6)
	                {
						iconHeight = 36;
					}
					else if (this._zoomlevel == 6)
					{
						iconHeight = 52;
					}
					else
					{
						iconHeight = 72;
					}				
	                
	                
					newShape.IconUrl =  "/Handlers/ResizeImage.ashx?path=/images/icons/" + categoryIcons[iconIndex] + "&height=" + iconHeight; 
	                
					/////////////TODO put it on the right layer here???
					eval('category_' + filters[x] + '.AddShape(newShape)');
					
				}          
			}
		}
        
        //remove all existing pins on matches from the screen
        for(y = 1; y <= 14; y++)
        {
            var totalpins = this._layer.GetShapeCount();
            for(x = (totalpins-1); x >=0; x--) {
                var currentshape = eval('category_' + y + '.GetShapeByIndex(x)');
                if (!currentshape.Match) {
                    eval('category_' + y + '.DeleteShape(currentshape)');
                }
                //set match back to false for next time we pan the map.
                currentshape.Match = false;
            }
        }
    },
    _AddDisplayPin: function(lat, lon, pinID) {
		
		this._pinID = pinID;
		
		var bounds = new VELatLong(lat, lon);
		var boundsArray = new Array(bounds, bounds);


		var displayPin = new VEShape(VEShapeType.Pushpin, bounds); 
		
		displayPin.Bounds = Utility.createEncodings(boundsArray);	
		displayPin.IconUrl =  "/Images/ClearPixel.gif"; 
		
		this._map.AddShape(displayPin);
		
		this._currentpin = displayPin;	
		this._currentpin.SetDescription("Loading...");
		this._currentpin.SetTitle("");
				
		this._service.GetPushPin(this._currentpin.Bounds, 0, Function.createDelegate(this, this._OnDisplayPinSucceeded), Utility.OnFailed, this._currentpin.GetID());	
		
		event.cancelBubble=true;
		event.returnValue=false;
    },
       
     _OnDisplayPinSucceeded: function(result, ID) { 

        if (ID==this._currentpin.GetID()) 
        { 
            this._currentpin.SetDescription("<span class=\"VEPushPin_Title\">" + result.Name + "</span><br />" + 
                "<img id=\"photo_" + result.PointID + "\" src=\"/images/points/" + result.PointID + ".jpg\" class=\"pinPopup_image\" " +
                "onerror=\"this.style.visibility='hidden';this.style.display='none';\" />" +
                "<div class=\"pinPopup_text\">" + result.Desc + "</div>" + 
                "<div class=\"pinPopup_url\">" + 
                (result.PhoneNumber ? "Tel: " + result.PhoneNumber + "<br />" : "") +
                (result.Url ? "<br /><a href=\"" + result.Url + "\" target=\"_blank\">" + (result.urlTitle ? result.UrlTitle : result.Url) + "</a>" : "") +
                (result.SecondaryUrl ? "<br /><a href=\"" + result.SecondaryUrl + "\" target=\"_blank\">" + (result.SecondaryUrlTitle ? result.SecondaryUrlTitle : result.SecondaryUrl) + "</a>" : "") +
                "<div class=\"logos\"><a href=\"http://www.courierexchange.co.uk/\" target=\"_blank\"><img src=\"images/logo-cx.gif\" alt=\"Courier Exchange\" /></a>" +
                "&nbsp;<a href=\"http://www.haulageexchange.co.uk/\" target=\"_blank\"><img src=\"images/logo-hx.gif\" alt=\"Haulage Exchange\" /></a></div>" +
                "</div>");

        }
        
        this._map.ShowInfoBox(this._currentpin);		
    },    
    
    
    _RemoveDisplayPin: function(pinID) {
    
		VEHideVEShapeERO(false);
		this._map.HideInfoBox(this._currentpin);
		this._map.DeleteShape(this._currentpin);
		  
    },
    _PinActivate: function(e) {
        /// <summary>
        ///   Receives any mouse of event from VE
        /// </summary>  
        /// <param name="e">The MapEvent object</param>
        if (e.elementID)
        {
            if (e.elementID != null)
            {
                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("");
                }
                e.cancelBubble=true;e.returnValue=false;
            }
        }

    },   
    
    
    _getAJAXContent: function() {
        /// <summary>
        ///   Request content for popup.
        /// </summary>  


        //call the web service
        //document.getElementById('debug').innerHTML  = document.getElementById('debug').innerHTML + this._currentpin.Bounds + '<br>';
        if(this._currentpin.Bounds != '')
        {
            this._service.GetPushPin(this._currentpin.Bounds, this._currentindex, 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(result.Title);
                this._currentpin.SetDescription(result.Details);
            }else {
                //create the content element
                var el = document.createElement("div");
                
                el.innerHTML = "<span class=\"VEPushPin_Title\">" + result.Name + "</span><br />" + 
                    "<img id=\"photo_" + result.PointID + "\" src=\"/images/points/" + result.PointID + ".jpg\" class=\"pinPopup_image\" " +
                    "onerror=\"this.style.visibility='hidden';this.style.display='none';\" />" +
                    "<div class=\"pinPopup_text\">" + result.Desc + "</div>" + 
                    "<div class=\"pinPopup_url\">" + 
                    (result.PhoneNumber ? "Tel: " + result.PhoneNumber + "<br />" : "") +
                    (result.Url ? "<br /><a href=\"" + result.Url + "\" target=\"_blank\">" + (result.urlTitle ? result.UrlTitle : result.Url) + "</a>" : "") +
                    (result.SecondaryUrl ? "<br /><a href=\"" + result.SecondaryUrl + "\" target=\"_blank\">" + (result.SecondaryUrlTitle ? result.SecondaryUrlTitle : result.SecondaryUrl) + "</a>" : "") +
                    "<div class=\"logos\"><a href=\"http://www.courierexchange.co.uk/\" target=\"_blank\"><img src=\"images/logo-cx.gif\" alt=\"Courier Exchange\" /></a>" +
                    "&nbsp;<a href=\"http://www.haulageexchange.co.uk/\" target=\"_blank\"><img src=\"images/logo-hx.gif\" alt=\"Haulage Exchange\" /></a></div>" +
                    "</div>";

//        pin.SetTitle("M1 Junction 24 Truck Stop");
//        pin.SetDescription("<div class=\"pinPopup_image\"><img src=\"/images/photo2.jpg\"/></div>" + 
//            "<div class=\"pinPopup_text\">Lorem ipsum dolor sit amet consectataur. Lorem ipsum consectataur sit amet dolor. Lorem ipsum dolor. Lorem ipsum consectataur.</div>" + 
//            "<div class=\"pinPopup_url\"><a href=\"http://www.internova.co.uk\" />View website</a></div>"
//            );

                //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 pagerResults = document.createElement("div");
                    pagerResults.innerHTML = (this._currentindex + 1) + " of " + result.TotalRecords;
                    el.appendChild(pagerResults);
                    Sys.UI.DomElement.addCssClass(pagerResults, "VEPushPin_pageResults");
                    
                    var prevButton = document.createElement("div");
                    prevButton.innerHTML = "Previous";
                    el.appendChild(prevButton);
                    Sys.UI.DomElement.addCssClass(prevButton, "ActionButton");
                    Sys.UI.DomElement.addCssClass(prevButton, "Previous");
                    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");
                    Sys.UI.DomElement.addCssClass(nextButton, "Next");
                    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();
    },             

    _CheckZoomLevel: function() {
    
        if (this.initCompleted)
        {
            var advertDiv = document.getElementById('POI_advert');
            advertDiv.style.visibility='hidden'; 
        }
        
        if (this._map.GetZoomLevel() <= 5)
        {
            this._map.SetZoomLevel(5);
            return false;
        }
        else
        {
            return true;
        }
    },
    

     _AddPOILayer: function()
    {   
        this._POILayer = new VEShapeLayer();
        this._POILayer.SetTitle("Points Of Interest");
        this._map.AddShapeLayer(this._POILayer);
        
        var points = new Array(
            new VELatLong(52.4990857124,-0.1794647216),
            new VELatLong(52.4795635292,-0.1782659912),
            new VELatLong(52.4750636445,-0.139901123),
            new VELatLong(52.4950636445,-0.139901123)
        )
            
        shape = new VEShape(VEShapeType.Polygon, points);
        
        // Add the shape to the map.
        this._POILayer.AddShape(shape);
        this._POILayerVisible = true;
        // as GETPInDAta
    },
        
    _ShowHideLayer: function(layer)
    {
        switch(layer)
        {
            case "CPBRC":
                if (this._CPBRCLayerVisible)
                {
                    this._CPBRCLayer.Hide();
                }
                else
                {
                    this._CPBRCLayer.Show();
                }
                this._CPBRCLayerVisible = ! this._CPBRCLayerVisible;
                
                document.getElementById("chkCPBRCLayer_" + this._identifier).checked = this._CPBRCLayerVisible;
                break;
            case "CAMBS":
                if (this._CambsLayerVisible)
                {
                    this._CambsLayer.Hide();
                }
                else
                {
                    this._CambsLayer.Show();
                }
                this._CambsLayerVisible = ! this._CambsLayerVisible;
                
                document.getElementById("chkCambsLayer_" + this._identifier).checked = this._CambsLayerVisible;
                break;
            case "POI":
                if (this._POILayerVisible)
                {
                    this._POILayer.Hide();
                }
                else
                {
                    this._POILayer.Show();
                }
                this._POILayerVisible = ! this._POILayerVisible;
                
                document.getElementById("chkPOILayer_" + this._identifier).checked = this._POILayerVisible;
                break;                                
        }
    },
    
    _GetData: function() {
        var ddlSpecies = document.getElementById("ddlSpecies_" + this._identifier)
        var ddlYear = document.getElementById("ddlYear_" + this._identifier)
        document.getElementById("mapHeader_" + this._identifier).innerHTML = ddlSpecies.options[ddlSpecies.selectedIndex].text + ' : ' + ddlYear.options[ddlYear.selectedIndex].text        
  
        mapDiv = document.getElementById("myMap_" + this._identifier);
        mapDiv.style.visibility = "visible";
        mapDiv.style.left = "0px";
        
        document.getElementById("mapFilter_" + this._identifier).style.visibility = "visible";
        
        document.getElementById("mapSelector_" + this._identifier).style.visibility = "hidden";
                
        this._recordableItemID = document.getElementById("ddlSpecies_" + this._identifier).value;
        this._year = document.getElementById("ddlYear_" + this._identifier).value;
        this._GetPinData();
    },
    
    _SelectData: function() {
        document.getElementById("mapHeader_" + this._identifier).innerHTML = "Create a Single Species Map";
        
        mapDiv = document.getElementById("myMap_" + this._identifier);
        mapDiv.style.visibility = "hidden";
        mapDiv.style.left = "-1000px";

        document.getElementById("mapFilter_" + this._identifier).style.visibility = "hidden";
       
        document.getElementById("mapSelector_" + this._identifier).style.visibility = "visible";
    },
    
    Dispose: function() {
        /// <summary>
        ///   cleans up all objects. Detaches all events.
        /// </summary>
        if (this._map != null) {
            this._map.DetachEvent("onchangeview", this.GetPinDataDelegate);
            this._map.DetachEvent("onmouseover", this.PinHoverDelegate);
            this._map.DetachEvent("onclick", this.PinHoverDelegate);  
            if (this._dualmode)
            {
                this._map.DetachEvent("onmousedown", this.MouseDownDelegate);   
                this._map.DetachEvent("onmousewheel", this.MouseDownDelegate);   
                this._map.DetachEvent("onendpan", this.PanFromDelegate);  
                this._map.DetachEvent("onendzoom", this.ZoomFromDelegate);   
            } 
            this._map.Dispose();
        }    
        this._service = null;
        this._mapArgs = null;
        this._identifier = null;
        this._dualmode = null;
        this._Active = null
    
        this._map = null;
        this._pinID = 0;
        this._zoomlevel = 0;
        this._layer = null;
        this._recordableItemID = 0;
        this._year = 0;
        
        // Additional Layers
        this._CPBRCLayerVisible = false;
        this._CPBRCLayer = null;
        this._CambsLayerVisible = false;
        this._CambsLayer = null;
        this._POILayerVisible = false;
        this._POILayer = null;
                    
        //popup specific
        this._PopupPrefix = null;
        this._currentpin = null;
        this._currentindex = null;   
        
        //Birdseye
        this._MapBEyeCentre = null;  
        this._latoffset = null;
        this._lonoffset = null;    
        
        this.GetPinDataDelegate = null;
        this.PinHoverDelegate = null;  
        this.MouseDownDelegate = null;
        this.PanFromDelegate = null;
        this.ZoomFromDelegate = null
    }    
}

Internova.Map.registerClass('Internova.Map', null, Sys.IDisposable);

if (typeof(Sys) !== "undefined") Sys.Application.notifyScriptLoaded();

