
Type.registerNamespace("VEPlus");

                        
VEPlus.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._layers = null;
    
    //popup specific
    this._PopupPrefix = "POPUP";
    this._currentpin = null;
    this._currentindex = 0;   
    this._currentLatLon = null;
    
    this.GetPinDataDelegate = null;
    this.PinHoverDelegate = null;
    this.PinClickDelegate = null;
    this.MapStyleChangedDelegate = null;
    
// scale factor array

    this._scaleFactors = new Array(.0005,     
                             30, 20, 10, 
                             5, 2.5, 1, 
                             .7, .3, .2, 
                             .1, .05, .03, 
                             .01, .005, .003, 
                             .0015, .0007, 
                             .0004, .0002, .0002);                                                         
    
    
    this._init();

    this.GetMap = function() 
    {
        return this._map;
    }
    
}

VEPlus.Map.prototype = {

    _init: function() {
        /// <summary>
        ///   Initialises the Map.
        /// </summary>       
        //map.LoadMap(SpaceNeedle, 16, VEMapStyle.Aerial, false, VEMapMode.Mode3D, true, null);
        //setup map
        this._map = new VEMap(this._mapArgs.DivID);    
        this._map.LoadMap(this._mapArgs.Center,this._mapArgs.Zoomlevel,this._mapArgs.Style,this._mapArgs.Fixed,VEMapMode.Mode2D,true,null); 
        this._map.SetScaleBarDistanceUnit(this._mapArgs.Scale);
        
        this._layers = new Array();
        
        //setup the function to get new data whenever the map changes
        this.GetPinDataDelegate = Function.createDelegate(this, this._GetPinData);
        this._map.AttachEvent("onchangeview", this.GetPinDataDelegate);
        
        this.MapStyleChangedDelegate = Function.createDelegate(this, this._MapStyleChanged);
        this._map.AttachEvent("onchangemapstyle", this.MapStyleChangedDelegate);
        
        //turn off the standard popup and attach our custom handler
        this.PinHoverDelegate = Function.createDelegate(this, this._PinActivate);
        this.PinClickDelegate = Function.createDelegate(this, this._PinClicked);
        this._map.AttachEvent("onmouseover", this.PinHoverDelegate);

        this._map.AttachEvent("onclick", this.PinClickDelegate);

        //Setup additional storage for shapes
        VEShape.prototype.Bounds = "";  
        VEShapeLayer.prototype.LayerSource = "";
        VEShapeLayer.prototype.IconUrl = "";
        VEShapeLayer.prototype.ClusteredIconUrl = "";
        VEShapeLayer.prototype.IsExpansion = false;

    VEShape.prototype.IsClustered  = false;     // is a clustered pin flag
    VEShape.prototype.IsExpanded = false;       // is an expanded pin flag
    VEShape.prototype.Pins = null;              // array containing clusterd pins
    VEShape.prototype.ExpandedLayer = null;     // a map layer object containing the expanded pins 

    },  

_MapStyleChanged: function(mapevent) {  

//If user changes map style turn off imagery layer
var sLayerId = 30; //Street Directory
  if(document.getElementById( sLayerId + "_chkLayerButton" + sLayerId ).checked)
  {
    document.getElementById( sLayerId + "_chkLayerButton" + sLayerId ).checked = false;
    document.getElementById( sLayerId + "_chkLayerButton" + sLayerId ).onclick();
    }

},

    _GetPinData: function() {  
        /// <summary>
        ///   Get the latest map data from the webservice.
        /// </summary>
            
        //encode the current map bounds
        var points = new Array();
        var zoom;
        
        if (this._map.GetMapStyle() == VEMapStyle.Birdseye || this._map.GetMapStyle() == "b") {    
            //set zoomlevel      
            zoom = 19;
            var be = this._map.GetBirdseyeScene();
            var rect = be.GetBoundingRectangle();
            points.push(rect.TopLeftLatLong);
            points.push(rect.BottomRightLatLong);

        }else {
            var view = this._map.GetMapView();
            points.push(view.TopLeftLatLong);
            points.push(view.BottomRightLatLong);
            
            //get zoomlevel
            zoom = this._map.GetZoomLevel();

        }
        var bounds = Utility.createEncodings(points);
        if (this._zoomlevel != zoom) {
            //clear existing pins
            for (x in this._layers)
            {
                if(this._layers[x].IsVisible())
                {
                    this._layers[x].DeleteAllShapes();
                }
            }           
        
            this._zoomlevel = zoom;
        }
      
        //call webservice
        for (x in this._layers)
        {
            if(this._layers[x].IsVisible() && this._layers[x].IsExpansion == false )
            {
                this._service.GetClusteredMapDataString(this._layers[x].LayerSource,bounds, zoom, Function.createDelegate(this, this._OnMapDataSucceeded), Utility.OnFailed,x);
            }
            else if(this._layers[x].IsVisible() && this._layers[x].IsExpansion == true )
            {
                this._layers[x].DeleteAllShapes();
            }
        }
    },

    _OnMapDataSucceeded: function(results, layerID) {
        /// <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
        if(this._layers[layerID])
            this._layers[layerID].DeleteAllShapes();
        else
            return; //The Layer doesn't exist, we could try and load it again??
               
        //add new pins
        for(x = 0; x < locs.length; x++) {
            var loc = locs[x];
            var bounds = result[x+1];
            var pinCount = result[x+locs.length+1];
            var boundsLocs = Utility.decodeLine(bounds);

if(boundsLocs && boundsLocs.length > 0)
{

            var newShape = new VEShape(VEShapeType.Pushpin, loc); 
            newShape.Bounds = bounds;         
            newShape.Pins = pinCount;
            //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 {  
            
                var a=new VECustomIconSpecification();
         
                //newShape.SetCustomIcon("<div class='myPushpin'></div>");
                if(boundsLocs[0].Latitude != boundsLocs[1].Latitude || boundsLocs[0].Longitude != boundsLocs[1].Longitude)
                {
                    //newShape.SetCustomIcon("<img src='" + this._layers[layerID].ClusteredIconUrl + "'></img>"); //Need to define these in the database
                    a.Image = this._layers[layerID].ClusteredIconUrl;
                    newShape.IsClustered = true;
                    newShape.IsExpanded = false;
                }
                else
                {
                    //newShape.SetCustomIcon("<img src='" + this._layers[layerID].IconUrl + "'></img>"); //Need to define these in the database
                    a.Image = this._layers[layerID].IconUrl;
                    newShape.IsClustered = false;
                    newShape.IsExpanded = false;
                }
                
                newShape.SetCustomIcon(a);            
            //}
            
            newShapes.push(newShape);
   }
        }       
        
        if(this._layers[layerID])
            this._layers[layerID].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);
            var bFound = false;    
            
            if(popupShape && popupShape.GetType() == "Point")
            {
                var layerId = popupShape.GetShapeLayer().GetId();
                
                for (x in this._layers)
                {
                    if(this._layers[x].IsVisible())
                    {
                        if(this._layers[x].GetId() == layerId)
                        {
                            bFound = true;
                            break;
                        }
                    }
                }
            }
            
            if (popupShape && bFound)
            {
                //set current pin
                this._currentpin = popupShape;
                this._currentindex = 0;
                
                //get the content for the pin.
                this._getAJAXContent();
                this._currentpin.SetDescription("");
                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
        if(this._currentpin && this._currentpin.GetShapeLayer())
        {
        	var layerSource = this._currentpin.GetShapeLayer().LayerSource;
	        this._service.GetPushPin(layerSource,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.Pins);
                //this._currentpin.SetDescription(result.Details);
                if(this._currentpin.Pins > 1 && this._currentpin.GetShapeLayer().IsExpansion)
                {
                    this._currentpin.SetDescription("<div align='right' id='" + this._PopupPrefix + this._currentpin.GetID() + "'>Too many ("+ this._currentpin.Pins + "). Zoom in further.</div>");
                    this._currentpin.SetTitle("");
                }
                else if(this._currentpin.Pins > 1 && this._currentpin.GetShapeLayer().IsExpansion == false)
                {
                    this._currentpin.SetDescription("<div align='right' id='" + this._PopupPrefix + this._currentpin.GetID() + "'>Click to Expand</div>");
                    this._currentpin.SetTitle("");
                }
                else
                {
                    this._currentpin.SetTitle(result.Title);
                    this._currentpin.SetDescription(result.Details);
                }
                
            }else {
                //create the content element
                var el = document.createElement("div");
                Sys.UI.DomElement.addCssClass(el, "PopupArea");
                
                var TitleDiv = document.createElement("div");
                var ZoomDiv = document.createElement("div");
                var DetailsDiv = document.createElement("div");
                ZoomDiv.setAttribute("title", "Re-centre on this address");
                
                TitleDiv.innerHTML = "<b>" + result.Title + "</b>";
                Sys.UI.DomElement.addCssClass(TitleDiv, "TitleArea");
                ZoomDiv.innerHTML = "";
                Sys.UI.DomElement.addCssClass(ZoomDiv, "ZoomArea");
                DetailsDiv.innerHTML = "<br /><br />" + result.Details + "<br />";
                
                el.appendChild(TitleDiv);
                el.appendChild(ZoomDiv);
                el.appendChild(DetailsDiv);
                
                //Store current lat lon in case user wants to zoom to it
                this._currentLatLon = new VELatLong(result.Lat, result.Lon);
                
                $addHandler(ZoomDiv,"click",Function.createDelegate(this, this._ZoomRecord));      

                //clear loading and attach the content
                $get(this._PopupPrefix + ID).innerHTML = "";
                $get(this._PopupPrefix + ID).appendChild(el);
                
                //abc2.innerHTML = "";
                //abc2.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));      
                        prevButton.setAttribute("title", "Show previous address");
                    }else {
                        Sys.UI.DomElement.addCssClass(prevButton, "ButtonDisabled");
                    }
                    var nextButton = document.createElement("div");
                    nextButton.innerHTML = "&nbsp; Next";
                    el.appendChild(nextButton);  
                    Sys.UI.DomElement.addCssClass(nextButton, "ActionButton");
                    if (this._currentindex < (result.TotalRecords-1)) {  
                        $addHandler(nextButton,"click",Function.createDelegate(this, this._NextRecord));                         
                        nextButton.setAttribute("title", "Show next address");
                    }else {
                        Sys.UI.DomElement.addCssClass(nextButton, "ButtonDisabled");
                    }
                    
                    var pageCount = document.createElement("div");
                    pageCount.innerHTML = "&nbsp; &nbsp;" + (this._currentindex + 1) + " of " + result.TotalRecords + " Records";
                    el.appendChild(pageCount);
                    Sys.UI.DomElement.addCssClass(pageCount, "PageCount");
                }      
                
                //If this is the first time the popup is shown see if it is off screen
                if(this._currentindex == 0)
                {
                    //Parent Popup DIV
                    //This is making a big assumption on the layout of VE Popup
                    var parentDiv = el.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode;
                    
                    if (!isNaN(parseInt(parentDiv.style.left)))
                    {
                        var beak = parentDiv.childNodes[1];
                    
                        if(parseInt(parentDiv.style.left) < -1)  //The amount of overlap before we change the class
                        {
                            var origLeft = parseInt(parentDiv.style.left);
                            origLeft = origLeft * -1; // Change to a positive number (absolute)
                            origLeft = origLeft - 20; // How far the beak is offset from the side
                            parentDiv.style.left="10px"; //How far we want it to sit inside the left hand side
                            
                            if(origLeft<24)
                            {
                                //Make sure the beak sits on the div
                                parentDiv.style.left= (origLeft * -1) + 34 + "px";
                                origLeft = 24;
                            }
                            
                            if(parseInt(parentDiv.style.top) < parentDiv.clientHeight)
                            {
                                //Too close to the top, put the div below the pin
                                if(parseInt(beak.style.top) == parseInt(parentDiv.style.top))
                                    parentDiv.style.top = parseInt(parentDiv.style.top) + 44 + "px"; //lower the div
                                else
                                    parentDiv.style.top = parseInt(parentDiv.style.top) + 80 + "px"; //lower the div
                                
                                if(parentDiv.className.indexOf('noBeak') == -1)
                                {
                                    beak.style.top = "-20px"; //put the beak above the top of the div
                                
                                    if(parentDiv.className.indexOf('ero-leftBeak') > -1)
                                    {
                                        //beak will appear to the top left
                                        beak.style.left = origLeft + "px";
                                        beak.style.right = "";
                                     }   
                                    else
                                    {
                                        //beak will appear to the top right
                                        beak.style.right = origLeft + "px";
                                        beak.style.left = "";
                                    }
                                    
                                    //Change the image to the top one
                                    beak.className = "erotopBeak";
                                }
                                
                                    
                            }
                            else
                            {
                                //put the div above the pin
                                parentDiv.style.top = parseInt(parentDiv.style.top) - (parentDiv.clientHeight - 20) + "px"; //raise the div
                                
                                if(parentDiv.className.indexOf('noBeak') == -1)
                                {
                                    beak.style.top = parentDiv.clientHeight - 4;  //put the beak below the bottom of the div
                                    
                                    if(parentDiv.className.indexOf('ero-leftBeak') > -1)
                                    {
                                        //beak will appear to the bottom left
                                        beak.style.left = origLeft + "px";
                                        beak.style.right = "";
                                     }   
                                    else
                                    {
                                        //beak will appear to the bottom right
                                        beak.style.right = origLeft + "px";
                                        beak.style.left = "";
                                    }
                                    
                                    //Change the image to the bottom one
                                    beak.className = "erobottomBeak";
                                }
                                
                            }
                        }
                        else
                        {
                        
                            if(parentDiv.className.indexOf('noBeak') == -1)
                            {
                    
                                //Reset Class back to normal left or right
                                if(parentDiv.className.indexOf('ero-leftBeak') > -1)
                                {
                                    //beak.style.top = ""; //This is set by VE
                                    beak.style.right = "";
                                    beak.style.left = "";
                                    beak.className = "eroleftBeak";
                                }
                                else
                                {
                                    //beak.style.top = ""; //This is set by VE
                                    beak.style.right = "";
                                    beak.style.left = "";
                                    beak.className = "erorightBeak";
                                }
                            }
                            
                        }
                    }
                }
            }
        }
    },    
    
    _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();
    },             

    _ZoomRecord: function() {
        /// <summary>
        ///   Zoom to the current record.
        /// </summary>      
        
        this._map.SetCenterAndZoom(this._currentLatLon, 15);
    },             
    
    loadClusteredLayer: function(layerURL,layerID,iconUrl,clusteredIconUrl) {
    
        if(this._layers[layerID])
        {
            this._layers[layerID].Show();
            this._GetPinData();
            }
        else
        {
            var layer = new VEShapeLayer();
            layer.LayerSource = layerURL;
            layer.IconUrl = iconUrl;
            layer.ClusteredIconUrl = clusteredIconUrl;
            this._layers[layerID] = layer; //Keep track of layer so we can turn it on and off
            this._map.AddShapeLayer(this._layers[layerID]);
            //var veLayerSpec = new VEShapeSourceSpecification(VEDataType.GeoRSS, layerURL, layer);
            //map.GetMap().ImportShapeLayerData(veLayerSpec, onFeedLoad, true);
            this._GetPinData();
        }
    
    },

    hideClusteredLayer: function(layerID) {
    
        if(this._layers[layerID])
            this._layers[layerID].Hide();
    
    },

    _PinClicked: function(e) {

if (this._map.GetMapMode() != VEMapMode.Mode3D) {        
return;
}

        if (e.elementID)
        {
            var pin = this._map.GetShapeByID(e.elementID);
            var bFound = false;    
            var layer = null;
            
            if(pin)
            {
                var layerId = pin.GetShapeLayer().GetId();
                
                for (x in this._layers)
                {
                    if(this._layers[x].IsVisible())
                    {
                        if(this._layers[x].GetId() == layerId)
                        {
                            layer = this._layers[x];
                            bFound = true;
                            break;
                        }
                    }
                }
            }
            
            if (pin && bFound)
            {
                
                var pin = this._map.GetShapeByID(e.elementID);
                
                // Clicked on a clustered Pushpin
                if(pin.GetType() == "Point" && pin.IsClustered )
                {
                    // if pin is expanded - collapse it
			        if(pin.IsExpanded)
     	            {
                        this._CollapsePin(pin);
				        return;
                    }
                 	
                 	//if(pin.Pins > 10) //Can't have too many in the circle
                 	//{
                 	    //Get subset of data using tight cluster
                        //this._service.GetUnClusteredMapData(layer.LayerSource,pin.Bounds, this._map.GetZoomLevel(), Function.createDelegate(this, this._ExpandPin), Utility.OnFailed,pin);
                        if(pin.Pins > 1 && pin.GetShapeLayer().IsExpansion == false)
                            this._service.GetClusteredMapData(layer.LayerSource,pin.Bounds, this._map.GetZoomLevel() + 1, Function.createDelegate(this, this._ExpandPin), Utility.OnFailed,pin);
                    //}
                    //else
                    //    this._ExpandPin(null,pin); // otherwise expand the pin
                }
            }
        }    
        
    },
    
    _ExpandPin: function(results,pin)
    {
        //if(results)
            //var locs = Utility.decodeLine(results);
            
        var result=results.split(",")
        var locs = Utility.decodeLine(result[0]);
            
        pin.SetDescription("Click icon to collapse");
        //pin.SetCustomIcon("<img src='expanded.png' />");

        // create a new shape layer
        var expandLayer = new VEShapeLayer();
        pin.ExpandedLayer = expandLayer;
        
        // get count of pins
        var pinCount = locs.length;
        var zoom = this._map.GetZoomLevel();
        var centerPoint = pin.GetPoints();
        var scalefactor = this._scaleFactors[zoom];

	    // adjust the zoom factor for 'oblique' view
        if( this._map.GetMapStyle() == 'o' )
        {
            scalefactor = this._scaleFactors[0];
            if( zoom == 2 )
            {
                scalefactor = this._scaleFactors[20];
            }
        }

        var deg = 360 / pinCount;
        var totalDegree = 0;

	    // hack code when a clustered pin represents
	    // just 2 pins
        if( deg > 120 )
        {
            deg = 120;
            totalDegree = -150;
        }

        // loop to create individual pins
        for(var i = 0; i < pinCount; i++)
        {
            
		    // calculate an X and Y point for the new pin
            var y = Math.cos(totalDegree * Math.PI/180);
            var x = Math.sin(totalDegree * Math.PI/180 );
            totalDegree += deg;
    		
		    // create new latlong for the new pin based on X and Y poins and zoom scale factor
            var newLatLon = new VELatLong(centerPoint[0].Latitude + ( x * scalefactor), 
									      centerPoint[0].Longitude + ( y * scalefactor));
            var newPin = new VEShape(VEShapeType.Pushpin, newLatLon );
    		
		    // add a polyline
            var newpoly = new VEShape(VEShapeType.Polyline, 
								      [new VELatLong(centerPoint[0].Latitude, 
								                     centerPoint[0].Longitude),
								       newLatLon]);

            newpoly.HideIcon();
    		
		    // set some of the pins properties
		    newPin.SetTitle("Loading....");
            //newPin.SetDescription(pin.Pins[i]);
            
            //var loc = locs[i];
            //var points = new Array();

            //points.push(loc);
            //points.push(loc);
            
            //var bounds = Utility.createEncodings(points);            
            //newPin.Bounds = bounds;
            
            //var a=new VECustomIconSpecification();
            //a.Image = pin.GetShapeLayer().IconUrl;
            //newPin.SetCustomIcon(a);
            
            var loc = locs[i];
            var bounds = result[i+1];
            var newpinCount = result[i+locs.length+1];
            var boundsLocs = Utility.decodeLine(bounds);
            
            newPin.Bounds = bounds;
            newPin.Pins = newpinCount;
            
          if(Sys.Browser.agent==Sys.Browser.InternetExplorer&&Sys.Browser.version==6){
                newPin.SetCustomIcon("<div class='myPushpinIE6'></div>");
            }else {  
            
                var a=new VECustomIconSpecification();
         
                //newShape.SetCustomIcon("<div class='myPushpin'></div>");
                if(boundsLocs[0].Latitude != boundsLocs[1].Latitude || boundsLocs[0].Longitude != boundsLocs[1].Longitude)
                {
                    //newShape.SetCustomIcon("<img src='" + this._layers[layerID].ClusteredIconUrl + "'></img>"); //Need to define these in the database
                    a.Image = pin.GetShapeLayer().ClusteredIconUrl;
                    newPin.IsClustered = true;
                    newPin.IsExpanded = false;
                }
                else
                {
                    //newShape.SetCustomIcon("<img src='" + this._layers[layerID].IconUrl + "'></img>"); //Need to define these in the database
                    a.Image = pin.GetShapeLayer().IconUrl;
                    newPin.IsClustered = false;
                    newPin.IsExpanded = false;
                }
                
                newPin.SetCustomIcon(a);            
            }            
    		
		    // add new pin and polyline to the new shapelayer
            expandLayer.AddShape(newPin);	
            expandLayer.AddShape(newpoly);  				
        }
        
        expandLayer.LayerSource = pin.GetShapeLayer().LayerSource;
        expandLayer.IconUrl = pin.GetShapeLayer().IconUrl;
        expandLayer.ClusteredIconUrl = pin.GetShapeLayer().ClusteredIconUrl;
        this._layers[pin.GetId()+'_exp'] = expandLayer; //Keep track of layer so we can turn it on and off
        expandLayer.IsExpansion = true;
    
        this._map.AddShapeLayer(expandLayer);        
            
	    pin.IsExpanded = true;
    },

    _CollapsePin: function(pin)
    {
        // get the expanded layer and remove/delete it
        this._map.DeleteShapeLayer(pin.ExpandedLayer);
        
	    // set the pins properties
        pin.SetDescription("This Clusterd Pin Represents " + pin.Pins.length + 
		           " Pins <br /><br />Click the pin to expand");
        //pin.SetCustomIcon("<img src='cluster.png' />");
        
            var a=new VECustomIconSpecification();
            a.Image = pin.GetShapeLayer().ClusteredIconUrl;
            pin.SetCustomIcon(a);
        
	    pin.ExpandedLayer = null;
        pin.IsExpanded = false;
    },
    
    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);                
            this._map.DetachEvent("onchangemapstyle", this.MapStyleChangedDelegate);                
            this._map.Dispose();
        }    
        this._service = null;
        this._mapArgs = null;
        
        this._map = null;
        this._pinID = null;
        this._zoomlevel = null;
        //agd this._layer = null;
        this._layers = null;
        
        //popup specific
        this._PopupPrefix = null;
        this._currentpin = null;
        this._currentindex = null;   
        this._currentLatLon = null;

        this.GetPinDataDelegate = null;
        this.PinHoverDelegate = null;   
        this.MapStyleChangedDelegate = null;
    }    
}

VEPlus.Map.registerClass('VEPlus.Map', null, Sys.IDisposable);

if (typeof(Sys) !== "undefined") Sys.Application.notifyScriptLoaded();

