﻿
var KFS_Map;
var KFS_regions;
var KFS_cities; 
var KFS_suburbs;
var KFS_listings;
var KFS_debug = false;

function KFS_diagnostic(){
    alert("diagnostic");
    GLog.write("diagnostic");
}

function KFS_LoadMapFromControls(){
   
   var lat = parseFloat(document.getElementById("KFSLatCtrl").value);
   var lng = parseFloat(document.getElementById("KFSLngCtrl").value);
   var zoom = parseFloat(document.getElementById("KFSZoomCtrl").value);
   KFS_LoadMap(lat,lng,zoom,null);
}

function KFS_LoadMap(lat,lng,zoom,mapOptions)
{
    //GLog.write('loading' + lat + ',' + lng + ',' + zoom);
    if (GBrowserIsCompatible())
   {
       KFS_Map = new GMap2(document.getElementById("KFSMap"));
       KFS_Map.addControl(new GMapTypeControl());
       KFS_Map.addControl(new GLargeMapControl());
       GEvent.addListener(KFS_Map,"zoomend",function(){this.closeInfoWindow();}) 
       KFS_Map.setCenter(new GLatLng( lat,lng), zoom);
   }
   else
   {
        document.getElementById("KFSMap").style.display = "none";
        document.getElementById("KFSMapNotWorking").style.display = "block";
   }
}

function KFS_loadCache(){

    KFS_regions = new KFS_AreaCache('Regions',KFS_Map,null,6,7,'/listingLocation.axd?type=region',KFS_AreaCache_regionsCallBack,10,0.15);
    KFS_cities = new KFS_AreaCache('Cities',KFS_Map,null,8,10,'/listingLocation.axd?type=city',KFS_AreaCache_citiesCallBack,2,0.15);
    KFS_suburbs = new KFS_AreaCache('Suburbs',KFS_Map,null,11,13,'/listingLocation.axd?type=suburb',KFS_AreaCache_suburbsCallBack,0.5,0.15);
    KFS_listings = new KFS_AreaCache('Listings',KFS_Map,null,14,17,'/listingLocation.axd?type=listing',KFS_AreaCache_listingsCallBack,0.125,0.2);
    
    KFS_listings.receiveListings = KFS_AreaCache_receiveListings;
    
    KFS_regions.mapViewChange();
    KFS_cities.mapViewChange();
    KFS_suburbs.mapViewChange();
    KFS_listings.mapViewChange();
}

function KFS_clearCache(){
    
    KFS_regions.clear();
    KFS_cities.clear();
    KFS_suburbs.clear(); 
    KFS_listings.clear();
    
}

function KFS_listingTypeSelectionChanged(listingTypeName, selected){
    KFS_Map["KFSShow" + listingTypeName] = selected;
    KFS_regions.refreshDisplay()
}

         
function KFS_DisplayMarkerWithTabs(lat,lng,tabs)
{
   //GLog.write(tabs)
   //alert (tabs);
   var m = new GMarker(new GLatLng(lat,lng));
   var markertabs = new Array();
   //KFS_Map.addOverlay(m);
   for(x in tabs)
   {
        markertabs[x] = new GInfoWindowTab(tabs[x][0],tabs[x][1]);
   }
   
   m.markertabs = markertabs
   
   GEvent.addListener(m, "mouseover", function() {this.openInfoWindowTabsHtml(this.markertabs);});
   
   KFS_Map.addOverlay(m);
  //GLog.write("end")

   
}



function KFS_DisplayMarker(lat,lng,html,drag,updating){
    
    var m = new GMarker(new GLatLng(lat,lng),{draggable: drag});
    
    if (html){
        m.html = html;
        GEvent.addListener(m, "mouseover", function() {this.openInfoWindowHtml(this.html);});
    }
    
    if (updating == true){
    
        GEvent.addListener(m, "dragend", function() {
        
               
                if (document.getElementById("KFSLatCtrl")){
                    document.getElementById("KFSLatCtrl").value = this.getPoint().lat();
                }
                if (document.getElementById("KFSLngCtrl")){
                    document.getElementById("KFSLngCtrl").value = this.getPoint().lng();
                }
                
                if (m.html){
                    this.openInfoWindowHtml(this.html);
                }
                
            } //end anon function
        ) //end addListener
    } //end if
   
   
    KFS_Map.addOverlay(m);

}

function KFS_displayMarkerFromControls(html,drag,updating){
    
    
    var lat = parseFloat(document.getElementById("KFSLatCtrl").value);
    var lng = parseFloat(document.getElementById("KFSLngCtrl").value);
    
    if (lat & lng){
        KFS_DisplayMarker(lat,lng,html,drag,updating);
    }
    
    
    
}

function KFS_displayLocation(lat,lng,zoom){
   
    if (KFS_Map){
        KFS_Map.closeInfoWindow();
        KFS_Map.setCenter(new GLatLng(lat,lng),zoom);
    }
}


    //assign shared variables to the area cache
    KFS_AreaCache.prototype.requestCacheTimeLimit = 10000;
    
   //assign functions to the area cache object
    KFS_AreaCache.prototype.reclaim = KFS_AreaCache_reclaim;
    KFS_AreaCache.prototype.receiveAreas = KFS_AreaCache_receiveAreas;
    KFS_AreaCache.prototype.getAreas = KFS_AreaCache_getAreas
    KFS_AreaCache.prototype.mapViewChange = KFS_AreaCache_mapViewChange;
    KFS_AreaCache.prototype.clear = KFS_AreaCache_clear;
    KFS_AreaCache.prototype.clearExpiredRequests = KFS_AreaCache_clearExpiredRequests;
    KFS_AreaCache.prototype.refreshDisplay = KFS_AreaCache_refreshDisplay;
    KFS_AreaCache.prototype.isInActiveZoomRange = KFS_AreaCache_isInActiveZoomRange;
    KFS_AreaCache.prototype.isMarkerInSelectionRange = KFS_AreaCache_isMarkerInSelectionRange;
    KFS_AreaCache.prototype.isMarkerInZoomRange = KFS_AreaCache_isMarkerInZoomRange;
    
    //extend google GLatLng object
    GLatLng.prototype.getCachingName = KFS_GLatLng_getCachingName;
    GLatLng.prototype.getBounds = KFS_GLatLng_getBounds;
   
    //extend google GLatLngBounds object
    GLatLngBounds.prototype.display = KFS_displayBounds;
    GLatLngBounds.prototype.toPointArray = KFS_GLatLngBounds_toPointArray;
    GLatLngBounds.prototype.getBounds = KFS_GLatLngBounds_getBounds;
    
    //extend GMarker object
    GMarker.prototype.isOnMap = false;
    GMarker.prototype.isAffectedBySelectionRange = false;
    GMarker.prototype.isRestaurant = false;
    GMarker.prototype.isCafe = false;
    GMarker.prototype.isBar = false;
    GMarker.prototype.isWinery = false;
    GMarker.prototype.isBakery = false;
    GMarker.prototype.isTakeaway = false;
    

    //extend GMap object
    GMap2.prototype.showRestaurant = true;
    GMap2.prototype.showCafe = true;
    GMap2.prototype.showBar = true;
    GMap2.prototype.showWinery = true;
    GMap2.prototype.showBakery = true;
    GMap2.prototype.showTakeaway = true;
    
    
    function KFS_AreaCache_isInActiveZoomRange(){
        
        if((this.zoomMaxBound >= this.map.getZoom()) && (this.zoomMinBound <= this.map.getZoom())){
            return true;
        }
        else {
            return false;
        }
    }
    
    function KFS_AreaCache_isMarkerInSelectionRange(marker){
    
        
        if(marker == null){return false;}
        
        if(marker.isAffectedBySelectionRange == false){return true;}
        //GLog.write(this.map.showRestaurant + ";" + this.map.showCafe + ";" +  this.map.showBar + ";" + this.map.showWinery + ";" + this.map.showBakery );
        //GLog.write("isRestaurant" + marker.isRestaurant + "; showrestat" + this.map.showRestaurant); 
        if(this.map.showRestaurant == true && marker.isRestaurant == true){return true;}
        if(this.map.showCafe == true && marker.isCafe == true){return true;}
        if(this.map.showBar == true && marker.isBar == true){return true;}
        if(this.map.showWinery == true && marker.isWinery == true){return true;}
        if(this.map.showBakery == true && marker.isBakery == true){return true;}
        if(this.map.showTakeaway == true && marker.isTakeaway == true){return true;}
        
        return false;
    }
    
    function KFS_AreaCache_isMarkerInZoomRange(marker){
        //GLog.write("inZoom; currentzoom=" + this.map.getZoom());
        //GLog.write("maxzoom=" + marker.KFS_maxZoom + "   minzoom" + marker.KFS_minZoom );
        if(marker == null){return false;}
        
        if((marker.KFS_maxZoom >= this.map.getZoom()) && (marker.KFS_minZoom <= this.map.getZoom())){
           return true;
        }
        else {
            return false;
        }
        
    }
    
    function KFS_AreaCache_refreshDisplay() {
        //GLog.write("refresh display()","#00aa00");
        this.map.closeInfoWindow();
        
        for (x in this.downloadCache){
            
            var markers = this.downloadCache[x];
            
            if(markers == null){continue;}
            
            for (y in markers){
                
                //GLog.write(this.cacheName + "; inzoomrange=" + this.isMarkerInZoomRange(markers[y]) + ";  inselectionreange=" + this.isMarkerInSelectionRange(markers[y]));
                if(this.isMarkerInZoomRange(markers[y]) && this.isMarkerInSelectionRange(markers[y])){
                    
                    if (markers[y].isOnMap == false){
                        this.map.addOverlay(markers[y]);
                        markers[y].isOnMap = true;
                    }
                    
                }
                else{
                    this.map.removeOverlay(markers[y]);
                    markers[y].isOnMap = false;
                }
            }
        }
    }
    
    function KFS_GLatLngBounds_getBounds (rounding,proximityBuffer){
        
        var ne = this.getNorthEast().getBounds(rounding,proximityBuffer).getNorthEast();
        var sw = this.getSouthWest().getBounds(rounding,proximityBuffer).getSouthWest();
        return new GLatLngBounds(sw,ne);
    } 
    
    function KFS_GLatLng_getCachingName(rounding){
        
        //GLog.write("getCacheName(); point= " + this);
        var point = this.getBounds(rounding).getSouthWest()
        //GLog.write("southwestpoint of containing bounds =" + point);
        
        
        var decimalPlaces = 0;
        var index = rounding.toString().indexOf(".");
        if (index != -1) {
             decimalPlaces = rounding.toString().substr(index + 1).length;
        }
        
        var roundTo = Math.pow(10,decimalPlaces);
        //(decimalPlaces == 0) ? roundTo = 1 : roundTo = ;
        //GLog.write("decimal Places= " + decimalPlaces + "  roundTO= " + roundTo);
        //GLog.write("this= " + this)
        return (Math.round(point.lat()* roundTo)) / roundTo + "_" + (Math.round(point.lng()* roundTo)) / roundTo;
    }
    
    function KFS_GLatLngBounds_toPointArray(rounding){

       //GLog.write("KFS_GLatLngBounds_toPointArray for: " + this);
        
        var latSteps = (Math.abs(this.getNorthEast().lat() - this.getSouthWest().lat())) /rounding;
        var lngSteps;
        
        //crossing anti-meridian
        if (this.getNorthEast().lng() < this.getSouthWest().lng()){
            lngSteps = (Math.abs(180 - this.getSouthWest().lng())) / rounding;
            lngSteps += (Math.abs(this.getNorthEast().lng() + 180)) / rounding;
        }
        else{
            lngSteps = (Math.abs(this.getNorthEast().lng() - this.getSouthWest().lng())) / rounding;
        }
        
        lngSteps = Math.round(lngSteps);
        latSteps = Math.round(latSteps);
         
        var points = new Array();
        var count = 0;
        
        var originLat = this.getSouthWest().lat()
        var originLng = this.getSouthWest().lng()
        //GLog.write("lat=" + originLat + " lng = " + originLng + "rnd=" + rounding + " latSteps=" + latSteps + " lngsteps" + lngSteps);
        
        for (stepLat = 0 ; stepLat < latSteps; stepLat++){
            
            for (stepLng = 0 ; stepLng < lngSteps; stepLng++){
                
                
                points[count] = new GLatLng(originLat + (stepLat * rounding),originLng + (stepLng * rounding));
                count++
            }
        
        }  
        //GLog.write(points);
        return points;
        
        
    }
    
    function KFS_GLatLng_getBounds(rounding,proximityBuffer){

        var swLat;
        var swLng;
        var neLat;
        var neLng;
        
        if (this.lat() % rounding == 0){
            swLat = this.lat();
        }
        else if (this.lat() < 0){
            swLat = (this.lat() - (rounding - Math.abs(this.lat() % rounding)))
        }
        else{
            swLat = (this.lat() -  Math.abs(this.lat() % rounding));
        }
        
        if (this.lng() % rounding == 0){
            swLng = this.lng();
        }
        else if (this.lng() < 0){
            swLng = (this.lng() - (rounding - Math.abs(this.lng() % rounding)))
        }
        else{
            swLng = (this.lng() -  Math.abs(this.lng() % rounding));
        }
        
        neLat = swLat + rounding;
        neLng = swLng + rounding;
        
        //GLog.write("calculating bounds for point=" + this);
        //GLog.write("swLat=" + swLat + " , " + "swLng=" + swLng + " , " + "neLat=" + neLat + " , " + "neLng=" + neLng );
        var calculatedBounds = new GLatLngBounds(new GLatLng(swLat,swLng),new GLatLng(neLat, neLng));
        
        //GLog.write("sw="+ calculatedBounds.getSouthWest() +" ;ne=" + calculatedBounds.getNorthEast());
        //GLog.write("immediateBounds bounds =" + calculatedBounds);
        //calculatedBounds.display();
        
        //if a proximity buffer was specified then calculate for that
        if(proximityBuffer != null){
            
            var boundsWidth = Math.abs(calculatedBounds.getNorthEast().lng() - calculatedBounds.getSouthWest().lng());
            var boundsHeight = Math.abs(calculatedBounds.getNorthEast().lat() - calculatedBounds.getSouthWest().lat());
            var distNth = Math.abs(calculatedBounds.getNorthEast().lat() - this.lat());
            var distEst = Math.abs(calculatedBounds.getNorthEast().lng() - this.lng());
            var distSth = Math.abs(calculatedBounds.getSouthWest().lat() - this.lat());
            var distWst = Math.abs(calculatedBounds.getSouthWest().lng() - this.lng());
            
            //GLog.write("h" + boundsWidth + ", w" + boundsHeight + ", n" + distNth + ", e" + distEst + ", s" + distSth + ", w" + distWst + ", ");
            //GLog.write("nth prox=" + distNthboundsHeight);
            if ((distNth / boundsHeight) < proximityBuffer == true){
                neLat += rounding;
                //GLog.write("extending","#ff0000");
                
            }
            //GLog.write("est prox=" + distEst / boundsWidth);
            if ((distEst / boundsWidth) < proximityBuffer == true){
                //GLog.write("extending","#ff0000");
                neLng += rounding;
            }
            //GLog.write("sth prox=" + distSth / boundsHeight);
            if ((distSth / boundsHeight) < proximityBuffer == true){
                swLat -= rounding;
                //GLog.write("extending","#ff0000");
                
            }
            //GLog.write("wth prox=" + distWst / boundsHeight);
            if ((distWst / boundsHeight) < proximityBuffer == true){
                swLng -= rounding;
                //GLog.write("extending","#ff0000");
            }

            //redined the bounds again based on the updated values
            calculatedBounds = new GLatLngBounds(new GLatLng(swLat,swLng),new GLatLng(neLat, neLng));
        
        }
        
        if (document.getElementById("chkPoint")){
            if (document.getElementById("chkPoint").checked == true){
                calculatedBounds.display("#ff0000");
            }
        }
        
        return calculatedBounds;    
        
    }
    
    function KFS_displayBounds(x){
        
        displayColor = x || "#010101";
        var lat1 = this.getSouthWest().lat();
        var lng1 = this.getSouthWest().lng();
        var lat2 = this.getNorthEast().lat();
        var lng2 = this.getNorthEast().lng();
        var polygon = new GPolygon([new GLatLng(lat1,lng1),new GLatLng(lat1,lng2),new GLatLng(lat2,lng2),new GLatLng(lat2,lng1),new GLatLng(lat1,lng1)],displayColor,2);
        this.map.addOverlay(polygon);
    }
    
    function KFS_AreaCache (_cacheName, _map, _cacheSize, _zoomMinBound,_zoomMaxBound,_dataSourceURL,_callBack,_rounding,_proximityBuffer){
        
        
        
        this.cacheName =_cacheName;
        this.map = _map;
        this.cacheSize = _cacheSize || 10;
        this.proximityBuffer = _proximityBuffer;
        this.zoomMaxBound = _zoomMaxBound ;
        this.zoomMinBound = _zoomMinBound ;
        this.dataSourceURL = _dataSourceURL;
        this.dataCallBack = _callBack;
        this.rounding = _rounding;
        this.proximityBuffer = _proximityBuffer;
        
        this.downloadCache = new Array();
        this.requestCache = new Array();
        
        GEvent.bind (this.map,'moveend',this,this.mapViewChange);
        //GLog.write(this.cacheName + " ; " + this.map.showRestaurant + ";" + this.map.showCafe + ";" +  this.map.showBar + ";" + this.map.showWinery + ";" + this.map.showBakery );
        //GLog.write("cachetime=" + this.map);
    }
    
 
    //depreciated
    //KFS_AreaCache.prototype.dataCallBack = KFS_AreaCache_regionsCallBack;
    
    function KFS_AreaCache_regionsCallBack(data,response){KFS_regions.receiveAreas(data,response);}
    function KFS_AreaCache_citiesCallBack(data,response){KFS_cities.receiveAreas(data,response);}
    function KFS_AreaCache_suburbsCallBack(data,response){KFS_suburbs.receiveAreas(data,response);}
    function KFS_AreaCache_listingsCallBack(data,response){KFS_listings.receiveListings(data,response);}
    
    
    function KFS_AreaCache_receiveListings(data, responseCode){
        
        
        //GLog.write(this.cacheName + " KFS_AreaCache_receiveListings");
        
        var xml = GXml.parse(data);
        //GLog.write(data);
        var cells = xml.documentElement.getElementsByTagName("cell");
        //GLog.write("returnd cells= " + cells.length);
        if (cells.length == 0){
            return;
        }
        
        for (var i = 0; i < cells.length; i++){
            
            var cellName = cells[i].getAttribute("name");
            //GLog.write("server returned cell" + cellName);
            if(this.downloadCache[cellName] == null){
                 
                 //create a new cell in the download cache 
                 //GLog.write("creating new cell " + cellName);
                 this.downloadCache[cellName] = new Array();
                 this.requestCache[cellName] = null;
            }
        }
        
        
        var listings = xml.documentElement.getElementsByTagName("listing");
        
        var id = 0;
        var listing;
        var count = 0;
        for (var i = 0; i < listings.length; i++){
            
            listing = listings[i];
            //GLog.write("received " + listing.getAttribute("name"));
            var lat = parseFloat(listing.getAttribute("lat"));
            var lng = parseFloat(listing.getAttribute("lng"));
            var point = new GLatLng(lat,lng);
            var marker = new GMarker(point);
            marker.isAffectedBySelectionRange = true;
            //GLog.write("downloaded point " + point);
            var cell = point.getCachingName(this.rounding);
            //GLog.write("point cache name=" + cell);
            id = listing.getAttribute("id")
            //GLog.write("currentId = " + id);
            //if the download cache already contains the cell
           
           
           if (this.downloadCache[cell] == null ){
                //GLog.write('returned point not in cell' + id);
                continue;
            } 
              
                
            //if the cell already contains the marker then move to next listing 
            if (this.downloadCache[cell][id]){
                //GLog.write('listing already exists:' + id);
                continue;
            } 
            else{
                //GLog.write('adding point ' + point + " to cell " + cell);
                this.downloadCache[cell][id] = marker;
            }
            
            
            //specify types
            var types = listing.getElementsByTagName("type");
            //GLog.write(types);
            for (var t = 0; t < types.length; t++){
                //GLog.write(id + "; type= " + types[t].firstChild.data);
                switch(types[t].firstChild.data)
                    {
                    case "res":
                      marker.isRestaurant = true;
                      break    
                    case "caf":
                      marker.isCafe = true;
                      break
                    case "bar":
                      marker.isBar = true;
                      break
                    case "win":
                      marker.isWinery = true;
                      break
                    case "bak":
                      marker.isBakery = true;
                      break
                    case "tak":
                      marker.isTakeaway = true;
                      break
                      
                    }//end switch
            } //end for
            
           
            
            marker.html = listing.getAttribute("html");
            //GLog.write("html=" +  marker.html);
            
            GEvent.addListener(marker, "mouseover", function() {this.openInfoWindowHtml(this.html);});
            //GEvent.addListener(marker, "mouseout", function(){alert(this.html); this.closeInfoWindowHtml();});
            
             var minZoom;
             var maxZoom;
            (listing.getAttribute("min") != "") ? minZoom = parseInt(listing.getAttribute("min"),10) : minZoom = this.zoomMinBound;
            (listing.getAttribute("max") != "") ? maxZoom = parseInt(listing.getAttribute("max"),10) : maxZoom = this.zoomMaxBound;

            //GLog.write (id + " " +  listing.getAttribute("min") + ' ' + listing.getAttribute("max"));
            marker.KFS_minZoom = minZoom;
            marker.KFS_maxZoom = maxZoom;
            
            
            //this.markerManager.addMarker(marker,minZoom,maxZoom);
            //GLog.write("marker added to manager");
            count++;
            //GLog.write("count=" + count);
           
        
        }//end for loop
        
        var loading = document.getElementById ('KFSLoadingInfo');
                if(loading){loading.style.visibility = 'hidden';}
        
        this.refreshDisplay();
        //this.markerManager.refresh();
        //GLog.write (count + "items added"); 
        
        
    }
    
    function KFS_AreaCache_receiveAreas(data, responseCode){
        
        if(KFS_debug)
            GLog.write(this.cacheName + " KFS_AreaCache_receiveAreas");
        
        
        var xml = GXml.parse(data);
        //GLog.write(data);
        var cells = xml.documentElement.getElementsByTagName("cell");
        //GLog.write("returnd cells= " + cells.length);
        if (cells.length == 0){
            return;
        }
        
        for (var i = 0; i < cells.length; i++){
            
            var cellName = cells[i].getAttribute("name");
            //GLog.write("server returned cell" + cellName);
            if(this.downloadCache[cellName] == null){
                 
                 //create a new cell in the download cache 
                 //GLog.write("creating new cell " + cellName);
                 this.downloadCache[cellName] = new Array();
                 this.requestCache[cellName] = null;
            }
        }
        
        
        
        var areas = xml.documentElement.getElementsByTagName("area");
        
        var id = 0;
        var area;
        var count = 0;
        for (var i = 0; i < areas.length; i++){
            
            area = areas[i];
            //GLog.write("received " + area.getAttribute("name"));
            var lat = parseFloat(area.getAttribute("lat"));
            var lng = parseFloat(area.getAttribute("lng"));
            var point = new GLatLng(lat,lng);
            var marker = new GMarker(point);
            //GLog.write("downloaded point " + point);
            var cell = point.getCachingName(this.rounding);
            //GLog.write("point cache name=" + cell);
            id = area.getAttribute("id")
            //GLog.write("currentId = " + id);
            //if the download cache already contains the cell
           
           
           if (this.downloadCache[cell] == null ){
                //GLog.write('returned point not in cell' + id);
                continue;
            } 
              
                
            //if the cell already contains the marker then move to next area 
            if (this.downloadCache[cell][id]){
                //GLog.write('area already exists:' + id);
                continue;
            } 
            else{
                //GLog.write('adding point ' + point + " to cell " + cell);
                this.downloadCache[cell][id] = marker;
            }
            
            marker.html = area.getAttribute("html");
            GEvent.addListener(marker, "mouseover", function() {this.openInfoWindowHtml(this.html);});
            //GEvent.addListener(marker, "mouseout", function(){alert(this.html); this.closeInfoWindowHtml();});
            
             var minZoom;
             var maxZoom;
            (area.getAttribute("min") != "") ? minZoom = parseInt(area.getAttribute("min"),10) : minZoom = this.zoomMinBound;
            (area.getAttribute("max") != "") ? maxZoom = parseInt(area.getAttribute("max"),10) : maxZoom = this.zoomMaxBound;

            //GLog.write (id + " " +  area.getAttribute("min") + ' ' + area.getAttribute("max"));
            marker.KFS_minZoom = minZoom;
            marker.KFS_maxZoom = maxZoom;
            
            
            //this.markerManager.addMarker(marker,minZoom,maxZoom);
            //GLog.write("marker added to manager");
            count++;
            //GLog.write("count=" + count);
           
        
        }//end for loop
        
        var loading = document.getElementById ('KFSLoadingInfo');
                if(loading){loading.style.visibility = 'hidden';}
                
        this.refreshDisplay();
        //this.markerManager.refresh();
        if(KFS_debug)
            GLog.write (count + "items added"); 
        
    
    } //end KFS_AreaCache_receiveAreas ()
    
    

////          GLog.write("adding cities");
////          
////          
////          
////          
////          
////          marker.html += "</br><a href='javascript:navigate(" + lat.toString() + "," + lng.toString() + ",11)'>View</
////          GEvent.addListener(marker, "click", function(){navigate(this.getPoint().y,this.getPoint().x);});
////          
////          
////          
////          //regionCache[regionCache.length] = marker;
////          areaManager.addMarker(marker,7,10);
////          GLog.write("city added");
////          
////        }//end for loop
//        
////    } //end KFS_AreaCache_receiveAreas ()
//    
    
    //handles the map changing viewport
    function KFS_AreaCache_clear(){
        
        if(KFS_debug)
            GLog.write("clearing cache" + this.cacheName);
        
        for(x in this.downloadCache){
//            GLog.write(
            if (this.downloadCache[x] == null){
                //GLog.write("continue");
                continue;
            }
            //GLog.write("getting points");
            //GLog.write("getting points");
            var points = this.downloadCache[x];
            
            for(y in points){
                //GLog.write("removing point " + points[y].getPoint());
                this.map.removeOverlay(points[y]);
            }
        }
//        GLog.write("preFail");
//        this.map.removeOverLay(this.markerManager);
//        GLog.write("postFail");
        
        this.markerManager = null;
        this.markerManager = new GMarkerManager(this.map);
        this.requestCache = null;
        this.requestCache = new Array();
        this.downLoadCache = null;
        this.downloadCache = new Array();
        
    }
    
    function KFS_AreaCache_mapViewChange(){
        
        //ensure that when moving out of zoom range that all markers are removed
        this.refreshDisplay();
       
        //check that map current view is within zoom area
        if (this.isInActiveZoomRange() == false){
            return;
        }
       
        if (document.getElementById("chkViewPort")){
            if (document.getElementById("chkViewPort").checked == true){
                this.map.getBounds().display("#00ff00");
            }
        }
         
        var totalRequiredBounds = this.map.getBounds().getBounds(this.rounding,this.proximityBuffer)
        
        //instruct this cache to download the areas associated with the current viewport bounds and surrounds
        this.getAreas(totalRequiredBounds);
        
    }
    
    
    function KFS_AreaCache_clearExpiredRequests(){
        
        
        var requestedTime;
        var currentTime = new Date().getTime();
        
        //GLog.write("KFS_AreaCache_clearExpiredRequests();  timeLimit= " + this.requestCacheTimeLimit + " current time=" + currentTime);
        for (x in this.requestCache){
            
            if(this.requestCache[x] == null){
                continue;
            }
            var diff = currentTime - this.requestCache[x].getTime();
            //GLog.write("diff=" + diff);
            if (diff > this.requestCacheTimeLimit){
                this.requestCache[x] = null;
                //GLog.write(currentTime - this.requestCache[x].getTime());
                //GLog.write("Clearing request cache; " + x + "  " + this.requestCache[x]);
            }
        }
    }
    
    function KFS_AreaCache_getAreas(requestedBounds){
        
        this.clearExpiredRequests ();
        
        //GLog.write(this.cacheName + " KFS_AreaCache_getAreas()");
        //GLog.write("requested bounds=" + requestedBounds);
        var points = requestedBounds.toPointArray(this.rounding);
        //GLog.write("totalPoints= " + points.length);
        var queryString = "&rounding=" + this.rounding + "&cells="
        var requireDownload = false; 
        for(x in points){
        
            if (document.getElementById("chkRequired")){
                if (document.getElementById("chkRequired").checked == true){
                        var dump = new GLatLngBounds(points[x],new GLatLng(points[x].lat() + this.rounding,points[x].lng() + this.rounding))
                        dump.display();
                        
                }
            }
        
            //GLog.write(points[x].getCachingName(this.rounding));
            var name = points[x].getCachingName(this.rounding);
            //GLog.write(name);
            
//            
            if (this.requestCache[name] != null){
                //GLog.write(this.cacheName +  " cell in request cache " + points[x].getCachingName(this.rounding),"#ff6633");
                continue;
            }
//            
            if (this.downloadCache[name] != null){
                //GLog.write(this.cacheName +  " cell in download cache " + points[x].getCachingName(this.rounding),"#99ff99");
                continue;
            }
         
            if((this.downloadCache[name] == null) & (this.requestCache[name] == null)){
                requireDownload = true;
                
                //mark request cache as requested by setting the value of the cell to the current time
                this.requestCache[points[x].getCachingName(this.rounding)] = new Date();
                //GLog.write("requested point=" + points[x] + " cacheName =" + points[x].getCachingName(this.rounding));
                //GLog.write(this.cacheName +  " requesting download " + points[x].getCachingName(this.rounding) + " time=" + new Date(),"#ff0000");
                queryString += points[x].getCachingName(this.rounding) + "$"
                
            }
            
            
            
            
         } //end for loop
         
         if (requireDownload == true){
                
                if(KFS_debug)
                    GLog.write("downloading " + this.dataSourceURL + queryString)
                
                GDownloadUrl(this.dataSourceURL + queryString ,this.dataCallBack);
                
                var loading = document.getElementById ('KFSLoadingInfo');
                if(loading){loading.style.visibility = 'visible';}
          }

    }//end KFS_AreaCache_getAreas()
    
    function KFS_AreaCache_reclaim (){
        //GLog.write(this.cacheName + ' reclaim');
    }
