// Copyright (c) 2008 Anna Putrino and Stanislav Chachkov (http://www.hikr.org), All rights reserved 
QuadWorld.prototype=new GridBounds
QuadWorld.prototype.constructor=QuadWorld
function QuadWorld(url,opts,m){
	GridBounds.call(this,m)
	this.url=url
	this.world_listener=null
	this.old_bounds=null
	this.root=null
	this.max_zoom=14;
	this.opts=opts
	if(!this.opts.zoom_increment)this.opts.zoom_increment=2
}
	
	QuadWorld.prototype.remove=function(){
		if(this.world_listener)GEvent.removeListener(this.world_listener)
		if(this.root)this.root.rm(this.map)
	}
	
	QuadWorld.prototype.insert=function(marker){
		this.root.insert(marker.getLatLng(),marker,17)
	}
	QuadWorld.prototype.load=function(){
		var me=this
		
		r4displayBlock('loading_map')
		//if(document.getElementById('selector_count'))r4showHTML('selector_count','')
		
		//if(opt) this.map_opt=opt
		//var url=r4_root+"load_pizs.php"+this.

		loadXMLDoc(this.url, function (req){
		
		if (req.readyState == 4){

			var xmlDoc=req.responseXML
			if(xmlDoc){
				var p = xmlDoc.getElementsByTagName("piz");
				if(p.length>0){
					//if(document.getElementById('selector_count'))r4showHTML('selector_count','('+p.length+')')
					me.root=new Quad2()
	
					//console.profile()
					for(var i=0;i<p.length;i++){
						//marker=new GMarker(p,{"icon":icons[type].yellow,"title":name})
						var marker=me.opts.createmarker(p[i])
						me.root.insert(marker.getLatLng(),marker,17)
						//GEvent.addListener(marker, "click", onclick(id))
					}
					//console.profileEnd()
	
					me.showTiles()

					me.world_listener=GEvent.addListener(me.map, "moveend", function(){
						me.showTiles()
					})
				}
				
				
			}
			r4displayNone('loading_map')
			if(me.opts.onloadend) me.opts.onloadend(p.length)
		}	
			
		})
	} 	
	

	QuadWorld.prototype.showTiles=function(){
		var me=this
		var zoom=me.map.getZoom()+this.opts.zoom_increment
		if(zoom>this.max_zoom) zoom=this.max_zoom	
		var bounds= me.getGridBounds_(me.map.getBounds(), zoom,new GSize(0,0),new GSize(0,0));
		
		var z=bounds.z
		
		if(!this.old_bounds){
		  for (var x = bounds.minX; x <= bounds.maxX; x++) {
			for (var y = bounds.minY; y <= bounds.maxY; y++) {
				this.root.fire(x,y,bounds.z,function(quad){quad.show(me.map)})			
			}
		  }		
		  
		}else if(this.old_bounds.z ==z){
			
			me.rectangleDiffCoords(this.old_bounds,bounds,function(x,y){
				me.root.fire(x,y,z,function(quad){quad.hide()})
			})	
			
			me.rectangleDiffCoords(bounds,this.old_bounds,function(x,y){
				me.root.fire(x,y,z,function(quad){quad.show(me.map)})
			})
		
		}else{
			
		  for (var x = this.old_bounds.minX; x <= this.old_bounds.maxX; x++) {
			for (var y = this.old_bounds.minY; y <= this.old_bounds.maxY; y++) {
				this.root.fire(x,y,this.old_bounds.z,function(quad){quad.hide()})
			}
		  }		
			
		  for (var x = bounds.minX; x <= bounds.maxX; x++) {
			for (var y = bounds.minY; y <= bounds.maxY; y++) {
				this.root.fire(x,y,bounds.z,function(quad){quad.show(me.map)})			
			}
		  }		
		}
	
		this.old_bounds=bounds
	}	
	
	function Quad2(){
	}
	
	Quad2.prototype.rm=function(map){
		if(this.obj.qadded){
			map.removeOverlay(this.obj)
			this.obj.quadded=false
			this.obj=null
		}
		if(this.more){
			for(var i=0;i<this.more.length;i++){
				if(this.more[i].qadded)map.removeOverlay(this.more[i])
				this.more[i].qadded=false
			}
			this.more=null
		}
		if(this.children){			
			if(this.children[0])this.children[0].rm(map)
			if(this.children[1])this.children[1].rm(map)
			if(this.children[2])this.children[2].rm(map)
			if(this.children[3])this.children[3].rm(map)
			this.children=null
		}
	}

	Quad2.prototype.hide=function(){

		if(this.obj.qadded){
		
			this.obj.hide()
			if(this.more){
				for(var i=0;i<this.more.length;i++){
					if(this.more[i].qadded)this.more[i].hide()
				}
			}
		
		}
	}
	
	Quad2.prototype.show=function(map){
		if(!this.obj.qadded){
			map.addOverlay(this.obj)
			this.obj.qadded=true
		}else{
		
			this.obj.show()
		}	
		if(this.more){
			for(var i=0;i<this.more.length;i++){
				if(!this.more[i].qadded){
					map.addOverlay(this.more[i])
					this.more[i].qadded=true

				}else{
					this.more[i].show(map)
				}
			}
		}
	}

	Quad2.prototype.insertLatLng=function (latlng,obj,z){
		  var point=this.wgs2pix(latlng,z);
		  this.insert(point.x,point.y,obj,z);
	}	
  
   Quad2.prototype.wgs2pix=function(latlng,zoom){
	  var d=1<<(zoom-1);
	  var sin_lat=Math.sin( latlng.lat() *Math.PI  / 180.0);
	  if(sin_lat>0.9999){
		  sin_lat=0.9999;
	  }else if(sin_lat < -0.9999){
		  sin_lat=-0.9999;
	  }
	  x=Math.floor( ( 180.0 + latlng.lng() ) *d /180.0);
	  y=Math.floor( d * ( ( 1.0 - ( 0.5/Math.PI )  * Math.log( ( 1.0 + sin_lat)  / ( 1.0 - sin_lat) ) ) ) );
	  
	  return {"x":x,"y":y};
	  
  }

  Quad2.prototype.insert=function (latlng,obj, z) {
	  var d=1<<(z-1);
	  var sin_lat=Math.sin( latlng.lat() *Math.PI  / 180.0);
	  if(sin_lat>0.9999){
		  sin_lat=0.9999;
	  }else if(sin_lat < -0.9999){
		  sin_lat=-0.9999;
	  }
	  var x=Math.floor( ( 180.0 + latlng.lng() ) *d /180.0);
	  var y=Math.floor( d * ( ( 1.0 - ( 0.5/Math.PI )  * Math.log( ( 1.0 + sin_lat)  / ( 1.0 - sin_lat) ) ) ) );
		
	 var me=this
	 
	 while(1){
		 if(!(me.obj)){ 
	
			me.obj = obj
			continue
			
		}else if(z>3){
			var z1=z-1
			var cid= (((1<<z1)&x)>>z1) | (((1<<z1)&y)>>(z1-1))
			
			//var cid=this.getChildId(x,y,z-1);
			if(!me.children) me.children=new Array(4)
			if(!me.children[cid]) me.children[cid]=new Quad2	
			me=me.children[cid]
			z--
			continue
		}else if(me.obj!=obj){
			if(!me.more)me.more=[]
			me.more.push(obj)
		}
		return
	 }
  }

  Quad2.prototype.getChildId=function (x,y,z){
		  return (z>0)?((((1<<z)&x)>>z) | (((1<<z)&y)>>(z-1))):((1&x) | ((1&y)<<1))
  }
  
  Quad2.prototype.fire= function(x,y,z,callback){
		var me=this

		while(z>0){
			var z1=z-1
			var cid= (z1>0)?((((1<<z1)&x)>>z1) | (((1<<z1)&y)>>(z1-1))):((1&x) | ((1&y)<<1))
			if(me.children && me.children[cid]){
				me=me.children[cid]
				z--
			}else{
				return
			}
	  }
		callback(me)  
  }
  


