
function KMLManager( map ,type, enabled ) {
  this.map = map;
  this.enabled = enabled;
  this.type = type;
  this.path = 'http://www.seero.com/kml/';
  this.zoomSpacing = new Array();
  for (x= -13; x < 6;x++) { this.zoomSpacing[x+10] = 1.2*Math.pow(2,x);}
  
  this.nWide = 6;
  this.nHigh = 4;
  this.curKMLs = new Array();
  this.curList = new Array();
  this.newList = new Array();
  this.allKMLs = new Array();
  this.allList = new Array();
  this.lastZoom = this.map.getZoom();
  this.loading = 0;
  
  GEvent.bind(this.map,'moveend', this, this.updateGMap );
}


KMLManager.prototype.isNotIn = function(str,arr) {
  var i = 0;
  if (arr) {
    for (i=0;i< arr.length;i++) {
      if (str == arr[i]) {return false;}
    }
  }
  return true;
}
  
KMLManager.prototype.point2tileURL = function(lat,lng,zoom) {
  var fac = this.zoomSpacing[16-zoom];
  var tlat = Math.round(Math.pow(10,10)*(Math.round( Math.round((lat/fac)) /this.nHigh)))/Math.pow(10,10);
  var tlng = Math.round(Math.pow(10,10)*(Math.round( Math.round((lng/fac)) /this.nWide)))/Math.pow(10,10);
  return this.path+this.type+'_z'+zoom+'_'+tlat+'_'+tlng+'.kml';
} 
  
KMLManager.prototype.myUniq = function(arr) {
  var newarr = new Array();
  var i = 0;
  var n = arr.length;
  for (i=0; i < n ;i=i+1) { 
    if (this.isNotIn(arr[i], newarr)) {
      newarr.push(arr[i]);
    }
  }
  return newarr;
}
  
  
KMLManager.prototype.loadTiles = function(bounds,zoom) {
  var sw = bounds.getSouthWest();
  var ne = bounds.getNorthEast();
  
  this.newList = new Array();
  
  if (this.type == 'vod') {
    d=3.0;
  } else if (this.type == 'bchome') {
    d=8.0;
  } else {
    d=4.0;
  }
  dlat = (ne.lat() - sw.lat())/d;
  if ( ne.lng() > sw.lng() ) {
    dlng = (ne.lng() - sw.lng())/d;
  } else {
    dlng = (360-sw.lng() + ne.lng())/d;
  }

  for ( x=0 ; x<=d ; x++ ) {        
    var plng = sw.lng()+(x*dlng);
    if (plng > 180) {
      plng = plng-360;
    }
    for (y=0 ;y <= d ; y++ ) {
      this.newList.push(this.point2tileURL(sw.lat()+(y*dlat),plng,zoom));
    }
  }

  this.newList = this.myUniq(this.newList);
  this.clearTiles(zoom);
  var ind =0;
  
  //add a no cache query string
  var d = new Date();
  var nocache = '?'+d.getTime().toString().substring(0,8);
  for(ind=0 ; ind < this.newList.length ; ind=ind+1) {
    if (this.isNotIn(this.newList[ind], this.allList)) {
      this.allKMLs[this.newList[ind]]=new GGeoXml(this.newList[ind]+nocache);
      this.allList.push(this.newList[ind]);
    }
    this.curKMLs[ind] = this.allKMLs[this.newList[ind]];
    if (this.isNotIn(this.newList[ind], this.curList)) {
      this.map.addOverlay(this.allKMLs[this.newList[ind]]);
    }
  }
  this.curList = this.newList;
}
  
KMLManager.prototype.clearTiles = function(zoom) {
  if (this.curKMLs) {
    var ind = 0;
    var tmpKMLs = new Array();
    if (zoom == this.lastZoom) {
      var n = this.curKMLs.length;
      for(ind=0; ind < n ; ind=ind+1) {
        if (this.isNotIn(this.curList[ind],this.newList)) {
          this.map.removeOverlay(this.curKMLs[ind]);
        }
      }
    } else {
      this.map.closeInfoWindow();
      var n = this.curKMLs.length;
      for(ind=0; ind < n ; ind=ind+1) {
          this.map.removeOverlay(this.curKMLs.pop());
      }
      this.lastZoom = zoom;
    }
    delete(this.curKMLs);
    this.curKMLs= new Array();
  }
}
 
KMLManager.prototype.updateGMap = function () {
  if ( this.enabled ) {
    this.loadTiles(map.getBounds(),map.getZoom());
  }
}

KMLManager.prototype.disable = function() {
  this.enabled=false;
  this.map.closeInfoWindow();
  var n = this.curKMLs.length;
  for( ind=0; ind < n ; ind=ind+1 ) {
    this.map.removeOverlay(this.curKMLs.pop());
  }
  delete(this.curKMLs);
  this.curKMLs= new Array();
  delete(this.curList);
  this.curList= new Array();
  this.lastZoom = -1;
}

KMLManager.prototype.enable = function() {
  this.enabled = true;
  this.loadTiles(map.getBounds(), map.getZoom() );
}