﻿  var ImageDirectory='/images';
   
    
    var isIE = navigator.platform == 'Win32' &&
               /MSIE (5\.5|[6-9])/.test( navigator.userAgent );
 

function MyPoint(x,y) 
{
  this.x=x;
  this.y=y;
}

MyPoint.prototype.toString=function() 
{
  return"("+this.x+", "+this.y+")"
};

MyPoint.prototype.equals=function(ia) 
{
  if(!ia)
  {
    return false;
  }
  return this.x==ia.x&&this.y==ia.y
};

MyPoint.prototype.distanceFrom=function(ia) 
{
  var La=this.x-ia.x;
  var Pa=this.y-ia.y;

  return Math.sqrt(La*La+Pa*Pa)
};

MyPoint.prototype.approxEquals=function(ia) 
{
  if(!ia)
    return false;
  return jd(this.x,ia.x)&&jd(this.y,ia.y)
};





function TileManager(gmap,baseUrl) 
    {
    
    this.zoomLevel=-999;
	this.area;
	this.baseUrl=baseUrl;
	this.gmap=gmap;
    var me=this;
    this.dataTiles=new Array();
   
    this.toAddress =function(x,y, zoom)
    {
     //  x=((longitude+180)* Math.pow(2,zoom))/360
     //   y=((-latitude+90)* Math.pow(2,zoom))/180
        x=Math.floor(x);
        y=Math.floor(y);
         out = '';
        m=new Array(2)
        m[0]=new Array(2);
        m[1]=new Array(2);
        
        m[0][0]='q';
        m[0][1]='t';
        m[1][0]='r';
        m[1][1]='s';
       for( i=0;i<zoom;i++)
        {
           rx=x%2;
            x= x/2;
            ry=y%2;
            y=y/2;
              x=Math.floor(x);
            y=Math.floor(y);
      
            out= m[Math.floor(rx)][Math.floor(ry)]+out;
            
        }
        return 't'+out;
    }
    this.getTileCoordinate = function(lat,lon,zoom,d) 
    {
	    if(!d)
		    d=new MyPoint(0,0);
    		
    	
	    var duhX=Math.floor( ((lon+180.0)* GetTileXCount(zoom))/360.0  );
	    var duhY=Math.floor( ((-lat+90.0)* GetTileYCount(zoom))/180.0  );
	    d.x=duhX;
	    d.y=duhY;
	    return d;
    	
    };
   
   this.SetBaseUrl=function(newUrl)
   {
        if(newUrl!=me.baseUrl)
        {
            me.baseUrl=newUrl;
            me.CleanHouse();
            // SynchData(me.area,me.zoomLevel);
        }
       
   }
    
    
    ///////////////////////////////////////////
     this.IsDataTileCached=function(zoom,x,y)
    {
        for(i= 0;i<me.dataTiles.length;i++)
        { 
             if(me.dataTiles[i].tileX==x  && me.dataTiles[i].tileY==y)
             {
                 return true;
             }
             return false;
         }
    };
  
    
   
    this.RequestDataTile=function(zoom,x,y)
    {
        
        var url=baseUrl+me.toAddress(x,y,zoom);   //me.baseUrl+zoom+"/"+x+"/"+y;

         
         GDownloadUrl(url, function(data, responseCode) {
            
              var xml = GXml.parse(data);
              var newDataTile=new DataTile(zoom,x,y,xml);
              me.DataTileRecieved(newDataTile);
            });
    };
    this.RemoveDataTile=function(tileIndex)
    {
        var newTile=me.dataTiles[tileIndex];
       
        for(i=0;i<newTile.GetPoints().length;i++)
        {
            var dataPoint=newTile.GetPoints()   [i];
                me.gmap.removeOverlay(dataPoint.overlay);											
		    
        }
        
        this.dataTiles.splice(tileIndex,1);
    };
    this.DataTileRecieved=function(newTile)
    {
        me.dataTiles.push(newTile);
        for(i=0;i<newTile.GetPoints().length;i++)
        {
            var dataPoint=newTile.GetPoints()[i];
           
            me.AddDataPoint(dataPoint);
        }

    } ;
    this.AddDataPoint=function(dataPoint)
    {
        if(dataPoint.Location.x<-600 || dataPoint.Location.x>600)return;
        if(dataPoint.Location.y<-600 || dataPoint.Location.y>600)return;
    var icon=new GIcon();                         
            icon.iconSize = new GSize(dataPoint.iconWidth, dataPoint.iconHeight);
            
          
              icon.image=dataPoint.iconUrl;
              
            
            
            icon.iconAnchor = new GPoint(dataPoint.iconWidth/2, dataPoint.iconHeight/2);
            icon.infoWindowAnchor = new GPoint(dataPoint.iconWidth/2, dataPoint.iconHeight/4);
	
            var overlay= new GMarker(
                                new GPoint(dataPoint.Location.x,dataPoint.Location.y),
                                    {
                                icon: icon,
                                title:dataPoint.title});
                                
       
            dataPoint.overlay=overlay;
            overlay.dataPoint=dataPoint;
                              

           
						   
            me.gmap.addOverlay(overlay);
            
              GEvent.addListener(overlay, "click", function() 
					    {
					        var sss=dataPoint.abbreviatedContent;
					       
		                     dataPoint.overlay.openInfoWindowHtml("<div class=\"infoWindow\">"+
                            sss
                            +"<br/></div>");
						}
					);
    }
    
    this.GetTileRange=function(area,zoom,lowerLeft,upperRight)
    {
        me.getTileCoordinate(area.getSouthWest().lat(),area.getSouthWest().lng(),zoom,lowerLeft);
        me.getTileCoordinate(area.getNorthEast().lat(),area.getNorthEast().lng(),zoom,upperRight);
        if(lowerLeft.x>upperRight.x)
        {
            upperRight.x+=GetTileXCount(zoom);
        }
         if(lowerLeft.y>upperRight.y)
        {
            var temp=upperRight.y;
            upperRight.y=lowerLeft.y
            lowerLeft.y=temp
            
            upperRight.x+=GetTileXCount(zoom);
        }
    }
    this.ClipHiddenDataTiles=function(area,zoom)
    {
        var lowerLeft=new MyPoint(0,0);
        var upperRight=new MyPoint(0,0);
        me.GetTileRange(area,zoom,lowerLeft,upperRight);
       
       
        var newDataTiles=new  Array();
        for(i= me.dataTiles.length-1;i>=0;i--)
        {    
            if(  
                me.dataTiles[i].x>=lowerLeft.x-1  ||
                me.dataTiles[i].x<=upperRight.x+1 ||
                me.dataTiles[i].y<=lowerLeft.y+1  ||
                me.dataTiles[i].y>=upperRight.y-1  
            
            )
            {

                newDataTiles.push(me.dataTiles[i]);
            }    
           
        }
        me.dataTiles=newDataTiles;
    };
    //area should be a GLatLngBounds
    this.RequestMissingDataTiles=function(area,zoom)
    {
        var lowerLeft=new MyPoint(0,0);
        var upperRight=new MyPoint(0,0);
        
        me.GetTileRange(area,zoom,lowerLeft,upperRight);
 
        for(x=lowerLeft.x;x<=upperRight.x;x++)
        {
            for(y=lowerLeft.y;y<=upperRight.y;y++)
            {
            
                if(!me.IsDataTileCached(zoom,x,y))
                {
                    me.RequestDataTile(zoom,x,y);
                }
                else
                {
                   // alert("cached");
                }
            }
        }
    };
    this.CleanHouse=function()
    {
        for(tileIndex=0;tileIndex< me.dataTiles.length;tileIndex++)
        {    

            for(i=0;i<me.dataTiles[tileIndex].GetPoints().length;i++)
            {
                var dataPoint=me.dataTiles[tileIndex].GetPoints()[i];
                    me.gmap.removeOverlay(dataPoint.overlay);											
                
            }
        }
        me.dataTiles=new Array();
    };
   this.SynchData=function(area,zoom)
   {
       
        if(zoom!=me.zoomLevel)
        {
           me.CleanHouse();
        }
        this.area=area;
        me.zoomLevel=zoom;
        
        me.ClipHiddenDataTiles(area,zoom);      
        me.RequestMissingDataTiles(area,zoom);
  
   } ;
   
    ///////////////////////////////
    
   
}


function DataPoint(xmlData)
{
    
    this.Location = new MyPoint(
                            parseFloat(xmlData.getAttribute("longitude")),
                            parseFloat(xmlData.getAttribute("latitude"))
                            );
    this.title=xmlData.getAttribute("title");
    this.abbreviatedContent=xmlData.getAttribute("abbreviatedContent");
    this.guid=xmlData.getAttribute("guid");
    this.url=xmlData.getAttribute("url");
    this.iconUrl=xmlData.getAttribute("iconUrl");
    this.iconWidth=xmlData.getAttribute("iconWidth");
    this.iconHeight=xmlData.getAttribute("iconHeight");
    
    
    this.zoomLevel=xmlData.getAttribute("zoomLevel");
    
    this.tileX=xmlData.getAttribute("tileX");
    
    this.tileY=xmlData.getAttribute("tileY");
  /*  this.iconWidth=xmlData.getAttribute("iconWidth");
    this.iconWidth=xmlData.getAttribute("iconHeight");
    this.iconUrl=xmlData.getAttribute("iconUrl");
    this.iconAnchor=new MyPoint(
                            xmlData.getAttribute("iconAnchorX"), 
                            xmlData.getAttribute("iconAnchorY")
                            );
                            */
}



function DataTile(zoom,x,y,xml)
{
    var me=this;
    me.xml=xml;
    me.zoom=zoom;
    me.x=x;
    me.y=y;
    me.dataPoints=new Array();
    me.dataElements = xml.documentElement.getElementsByTagName("dataPoint");

      for (var i = 0; i < me.dataElements.length; i++) 
      {
        var newPoint=new DataPoint(me.dataElements[i])
        me.dataPoints.push(newPoint);
       
      }
   this.GetPoints=function()
   {
        return me.dataPoints;
   }
}





function GetTileXCount(zoom)
{
    return Math.pow(2,zoom+1);
}

function GetTileYCount(zoom)
{
	return Math.pow(2,zoom);

}   

 
    

function GCMap(a_mapDivId)
{

    var me=this;

    this.mapDivId=a_mapDivId;
    this.toolTipHoverStyle;
    this.toolTipStyle;
    this.MarkerStyle;
    this.IndexStyle;
    this.GeoDataType;
    this.NodeSource;
    this.NodeSourceId;
    this.gmap=null;
    this.markers=new Array();
    this.icon=null;
    this.selectItemGUID;
    this.mapIsReady=false;
    this.howManyToShow=16;
    this.moveListeners=new Array();
    this.moveEndListeners=new Array();
   // this.overviewMapControl=new GOverviewMapControl();
    this.mapControl=null;//new GLargeMapControl();
    this.scaleControl=null;//=new GScaleControl()
    this.mapTypeControl=null;//=new GScaleControl()
    this.IsDraggable=true;
    this.clickAction;
    this.tileManager;
    this.AddMapMoveListener=function AddMapMoveListener(listener)
    { 
        me.moveListeners.push(listener);
        
    };
    this.AddMapMoveEndListener=function AddMapMoveEndListener(listener)
    {
        me.moveEndListeners.push(listener);
    }  
   


    
    this.FetchManager= function(markerStyle,indexStyle,geoDataType,nodeSource,nodeSourceId)
    {
        me.MarkerStyle=markerStyle;
        me.IndexStyle=indexStyle;
        me.GeoDataType=geoDataType;
        me.NodeSource=nodeSource;
        me.NodeSourceId=nodeSourceId;
      
    }

   

   
    this.MakeMapActionLink =function ( text,action)
    {
   
      var link=document.createElement('a');
        var linkText=document.createTextNode(text);
        link.appendChild(linkText);
        link.href='javascript:void(0);';
        addEvent( link,'click',action);
        return link;
    }
    this.MakeZoomLink =function (text, mappableSummary)
    {
    
       return me.MakeMapActionLink(text,
                       function(){  me.ZoomOnItem(mappableSummary.Guid);}
                                );
       
    }
      this.MakeZoomALittleLink =function (text, mappableSummary)
    {
    
       return me.MakeMapActionLink(text,
                       function(){  
                       var selected=me.GetMarker( mappableSummary.Guid);
        
                       me.ZoomMap(selected.lng,selected.lat,me.gmap.getZoom()+1);
                          
                       
                       }
                                );
       
    }
    this.MakePopupLink =function ( mappableSummary)
    {
       return me.MakeMapActionLink('focus',
                       function(){  me.Popup(mappableSummary.Guid);}
                                );
   
    }
    this.MakeOpenLink =function ( text,mappableSummary)
    {
        var link=document.createElement('a');
        var linkText=document.createTextNode(text);
        link.appendChild(linkText);
        link.href=mappableSummary.Url;
        return link;
   
    }
    this.CreateMap =function ()
    {
        me.gmap = new GMap2(document.getElementById(me.mapDivId));
         if(mapDataType!=null)
                {
                
                    url="tiles/"+mapDataType+"/byscore/";
                }
                else
                {
                    url="tiles/places/byscore/";
                }
        me.tileManager=new TileManager(me.gmap, url);
       // if(me.overviewMapControl!=null)
       // {
	   //     me.gmap.addControl(me.overviewMapControl);
	   // }
        if(!me.IsDraggable)
        {
            me.gmap.disableDragging();
        }
        if(me.mapControl!=null)
        {
            me.gmap.addControl(me.mapControl);
        }
        if(me.scaleControl!=null)
        {
            me.gmap.addControl(me.scaleControl);
        }
        if(me.mapTypeControl!=null)
        {
            me.gmap.addControl(me.mapTypeControl);
        }
      
    		/*
        GEvent.addListener(me.gmap, "move", function() 
                {
                 
                   for(i= 0;i<me.moveListeners.length;i++)
                    {
                  
                        var listener= me.moveListeners[i];
                        listener(me.gmap);
                    }
                }
                 );
                */
       
	    me.mapIsReady=true;
    }
    this.StartFetching=function()
    {

      GEvent.addListener(me.gmap, "moveend", function() 
        {
            
            me.UpdateCookies();
         
           for(i= 0;i<me.moveEndListeners.length;i++)
            {          
                var listener= me.moveEndListeners[i];
               listener(me.gmap);
             }


            if(me.gmap==null)return;    
            if(!me.mapIsReady)return;
                     
                me.FetchMarkers();
           
          
        });
        me.FetchMarkers();
    }
    this.UpdateCookies=function () 
    { 
        var center = me.gmap.getCenter();
	    setCookie("mapX",""+center.lng());
	    setCookie("mapY",""+center.lat());
	    setCookie("mapZ",""+me.gmap.getZoom());
	    setCookie("mapBBOX",me.gmap.getBounds());
    }
    this.FetchMarkers=function ()
    {
         if(me.tileManager!=null)
        {  
            me.tileManager.SynchData(me.gmap.getBounds(),me.gmap.getZoom()-1);
        }
    }
   
    this.CreateOverlayIfNew=function ( newMarker)
    {
        for(var oldMarker in me.markers)
	    {
		    if(oldMarker.guid==newMarker.guid)
		    {
			    return;
		    }
	    }
	    me.markers.push(newMarker);
	    me.CreateOverlay(newMarker);
    }

    this.CleanupMarkers=function ()
    {
	    var tempSelectedMarker;
	    while(me.markers.length>0)
	    {
		    var markerToRemove=me.markers.shift();
    		
		    if(markerToRemove.guid!=me.selectItemGUID)
		    {
			    me.gmap.removeOverlay(markerToRemove.overlay);											
		    }
		    else
		    {	
			    tempSelectedMarker=markerToRemove;
		    }
	    }
	    if(tempSelectedMarker!=null)
	    {
		    me.markers.unshift(tempSelectedMarker);
    			
	    }
    }
    this.CreateOverlay=function (marker)
    {
    	
		
    		
        marker.Icon.image+='#guid'+marker.guid;
        //var thisIcon=new GIcon(marker.Icon);


        var overlay= new GMarker(marker.point,marker.Icon);
        marker.overlay=overlay;
        overlay.marker=marker;
        overlay.markerGUID=marker.guid;
        //thisIcon.image += '#' + escape( marker.title );
        
        GEvent.addListener(overlay, "click", function() 
					    {
					      
					       
						        overlay.openInfoWindowHtml("<div class=\"infoWindow\">"+overlay.marker.abbreviatedContent+"<br/></div>");
						      
                           
					   
					    });
    					

        me.gmap.addOverlay(overlay);
        return overlay;
    }
    this.FetchMarkersTimeOut=function ()
    {
    

    }

    this.InitMap=function (x,y,zoom,autosize,mapType) 
    {
        me.CreateMap() 
        me.gmap.setCenter(new GLatLng( y,x,true), zoom);
    }
    this.InitMapFromCookie=function (ajax,autosize,mapType) 
    {
    	
	    var x=getCookie("mapX");
	    var y=getCookie("mapY");
	    var z=getCookie("mapZ");
    	
    	
    	
	    if(x!=null)
	    {
		    var xx=parseFloat(x);
		    var yy=parseFloat(y);
		    var zz=parseInt(z);		
		    me.InitMap(xx, yy, zz,autosize,mapType);
	    }
    	
    	
    }


    this.FixMapSize=function (theMap)
    {

        var bounds=me.gmap.getBounds();
        var center=me.gmap.getCenter();
	    var frameWidth;
	    var frameHeight
	    if (self.innerWidth)
	    {
		    frameWidth = self.innerWidth;
		    frameHeight = self.innerHeight;
	    }
	    else if (document.documentElement && document.documentElement.clientWidth)
	    {
		    frameWidth = document.documentElement.clientWidth;
		    frameHeight = document.documentElement.clientHeight;
	    }
	    else if (document.body)
	    {
		    frameWidth = document.body.clientWidth;
		    frameHeight = document.body.clientHeight;
	    }
	    var newWidth=frameWidth-180;
	    var newHeight=frameHeight;
	    if(!isIE)
	    {
	        newHeight-=90;
	        
	    }
	    me.howManyToShow=Math.floor((newHeight*newWidth)/(10000));
	    if(theMap.style.width!=newWidth+"px"   || theMap.style.height!=newHeight+"px")
	    {
	        var zoomAdjust=newWidth/me.gmap.getSize().width;
	        theMap.style.width=newWidth+"px";
            theMap.style.height=newHeight+"px";
             if(zoomAdjust>=1.5)
	        {
	            me.gmap.zoomIn();
	        }
            if(zoomAdjust>=3.2)
	        {
	            me.gmap.zoomIn();
	        }
	        
            me.gmap.checkResize();
            me.gmap.setCenter(center);
            /*
            if(me.overviewMapControl!=null)
            {
                me.gmap.removeControl(me.overviewMapControl);
                me.overviewMapControl=new GOverviewMapControl();
                me.gmap.addControl(me.overviewMapControl,new GControlPosition(G_ANCHOR_BOTTOM_RIGHT, new GSize(10,10)));
            }
            */
	    }
    }
   
  


    this.ZoomOnItem=function (markerGUID)
    {
        var selected=me.GetMarker( markerGUID);
        selectItemGUID=markerGUID;	
        var zoomLevel=me.CalcZoomLevel(selected.BoundingRect);
        me.ZoomMap(selected.lng,selected.lat,zoomLevel);
        return false;
    }		
        
    this.ZoomMap=function (lng,lat,zoomLevel)
    {
	    var point = new GLatLng(lat,lng);
	    if(zoomLevel<1)zoomLevel=1;
	    me.gmap.setCenter(point,zoomLevel);
	    return false;	
    }

    this.Popup=function (markerGUID)
    {
	    var selMarker=me.GetMarker( markerGUID);	
	    if(selMarker!=null)
	    {
		    selMarker.overlay.openInfoWindowHtml("<div class=\"infoWindow\">"+selMarker.abbreviatedContent+"<br/></div>");
	    }
	    return false;
    }


    this.FocusOnItem=function (markerGUID)
    {
	    me.selectItemGUID=markerGUID;
	    me.Popup(markerGUID);		
	    return false;
    }		


    this.CenterMap=function (lng,lat)
    {
	    var point = new GLatLng(lat,lng,true);
	    me.gmap.panTo(point);
	    return false;	
    }
    this.GetMarker=function (markerGUID)
    {
        for(i=0;i<me.markers.length;i++)
	    {
		    if(me.markers[i].guid==markerGUID)
		    {
			    return me.markers[i];
		    }
	    }
	    return null;
    }
    this.GetBounds=function()
    {
        return me.gmap.getBounds();
    }

    this.CalcZoomLevel=function(rect)
    {
        return 17-Math.max(
        LogBase2( (rect.Right-rect.Left) * 15000),
        LogBase2( (rect.Top-rect.Bottom) * 15000)+1
        );
    }
    
}
 function LogBase2(value)
        {
            var ret=1;
            while(value>1)
            {
                value=value/2;
                ret=ret+1;
            }
            return ret;
        }
        
       
function CGeoLocation(lng,lat)
{
    this.Latitude=lat;
    this.Longitude=lng;
    
}
    
function CGeoRect(lowerLeft,upperRight)
{
    this.LowerLeft=lowerLeft;
    this.UpperRight=upperRight;
    this.Left=function()
    {
        return lowerLeft.Longitude;
    }
    this.Bottom=function()
    {
        return lowerLeft.Latitude;
    }
    this.Right=function()
    {
        return UpperRight.Longitude;
    }
    this.Top=function()
    {
        return UpperRight.Latitude;
    }
   
    
}

function MyMarker(nodeSummary)
{
    
    this.Location=nodeSummary.Location;
    this.lng=nodeSummary.Location.Longitude;
	this.lat=nodeSummary.Location.Latitude;
	this.point = new GPoint(this.lng,this.lat);
	this.title=nodeSummary.Title;
	this.abbreviatedContent=nodeSummary.AbbreviatedContent;
	this.guid=nodeSummary.Guid;
	this.BoundingRect=nodeSummary.BoundingRect;
	this.Icon=new GIcon();
	this.Url=nodeSummary.Url;
	if(nodeSummary.IconWidth>0)
	{
        this.Icon.iconSize = new GSize(nodeSummary.IconWidth, nodeSummary.IconHeight);
    }
    this.Icon.image=nodeSummary.IconUrl;
	this.Icon.iconAnchor = new GPoint(3, 3);
	this.Icon.infoWindowAnchor = new GPoint(3, 3);
		   
      
}

function addEvent(obj, evType, fn)
{
    if (obj.addEventListener)
    {
        obj.addEventListener(evType, fn, true);
        return true;
    }
    else if (obj.attachEvent)
    {
        var r = obj.attachEvent("on"+evType, fn);
        return r;
    }
    else
    {
        return false;
    }
}






     function onWebMethodError(fault)
{

    
 }
 