// miscelanious functions
function isMSIE(){return !!(window.attachEvent&&!window.opera);}
function isOpera(){return !!window.opera;}
function Trim(s) { return s.replace(/(^\s+)|(\s+$)/g,"") }

function roundTo(inputNum, precision){
	var guide=Math.pow(10,precision);var inputnum=(Math.round(inputNum*guide)/guide);var numString=inputNum+"";
	if(numString.search(/./)<0) {numString+=".";for(var j=0;j<precision;j++)numString+="0";}
	var afterDecimal=numString.substring(numString.search(/\./)+1);
	if(afterDecimal.length>precision){return numString.substring(0,numString.search(/\./)+1+precision);}
	while(afterDecimal.length<precision){afterDecimal+="0";numString+="0";}return (numString);
}
// smth that is used in zoom control
function y_offs() { return self.pageYOffset||(document.documentElement&&document.documentElement.scrollTop)||(document.body&&document.body.scrollTop);}
function getBounds(element) {
	if (element==null) { return(null) }
	var left=element.offsetLeft; var top=element.offsetTop;
	for(var parent=element.offsetParent;parent;parent=parent.offsetParent) {
		left+=parent.offsetLeft-parent.scrollLeft; top+=parent.offsetTop-parent.scrollTop
	}
	return {left:left,top:top,width:element.offsetWidth,height:element.offsetHeight}
}

var HALFPI=1.5707963267948966;
var M_PI=HALFPI*2;
var EPS10=1.e-10;
var EARTH_RADIUS=6378137;
var EARTH_E=0.081819190842621;

// - - 
// class MercPoint
MercPoint.prototype.x=null;
MercPoint.prototype.y=null;
MercPoint.prototype.getX=function(){return(this.x)};
MercPoint.prototype.getY=function(){return(this.y)};
MercPoint.prototype.ToString=function(){return "(x="+roundTo(this.x,2)+",y="+roundTo(this.y,2)+")"; }
MercPoint.prototype.ToWgs84=function(){return new Wgs84Point(this.x*180./(EARTH_RADIUS*M_PI),this._p(Math.exp(-this.y/EARTH_RADIUS),EARTH_E)*180./M_PI);}
MercPoint.prototype.InBounds=function(){return(this.x>=MAP_COORD.W&&this.x<=MAP_COORD.E&&this.y>=MAP_COORD.S&&this.y<=MAP_COORD.N);}
function MercPoint(z,w){this.x=z;this.y=w;return(this);}
MercPoint.prototype._p=function(ts,e){var eccnth=.5*e;var Phi=HALFPI-2.*Math.atan(ts);i=15;do{con=e*Math.sin(Phi);dphi=HALFPI-2.*Math.atan(ts*Math.pow((1.-con)/(1.+con),eccnth))-Phi;Phi+=dphi;}while(Math.abs(dphi)>EPS10&&--i);if(i<=0)return 0.;return Phi;}

// - - 
// class Wgs84Point
Wgs84Point.prototype.la=null;
Wgs84Point.prototype.lo=null;
Wgs84Point.prototype.getLatitude=function(){return(this.la);}
Wgs84Point.prototype.getLongitude=function(){return(this.lo);}
Wgs84Point.prototype.ToString=function(){return "(lon="+roundTo(this.lo,6)+",lat="+roundTo(this.la,6)+")";}
Wgs84Point.prototype.ToMerc=function(){return new MercPoint(EARTH_RADIUS*this.lo*M_PI/180.,-EARTH_RADIUS*Math.log(this._t(this.la*M_PI/180.,Math.sin(this.la*M_PI/180.),EARTH_E)));}
Wgs84Point.prototype.InBounds=function(){return this.ToMerc().InBounds();}
function Wgs84Point(a,b){this.lo=a;this.la=b;return(this);}
Wgs84Point.prototype._t=function(phi,sinphi,e){sinphi*=e;return(Math.tan(.5*(HALFPI-phi))/Math.pow((1.-sinphi)/(1.+sinphi),.5*e));}



// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// class MapBounds
MercBounds.prototype.Y=null;MercBounds.prototype.Z=null;
MercBounds.prototype.getMin=function(){return(this.Y)};
MercBounds.prototype.getMax=function(){return(this.Z)};
function MercBounds(pMin,pMax){this.Y=pMin;this.Z=pMax;return(this);}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// class ZoomItem
ZoomItem.prototype.O;  // div-container
ZoomItem.prototype.P;  // image of ruler item
ZoomItem.prototype.Ap; // zoom index
function ZoomItem(left,top,index) {
	this.G=left; this.F=top;this.Ap=index;
	this.O=document.createElement("div");
	this.O.id="ruller_div_"+index;this.O.className="shadow";this.O.style.position="absolute";
	this.O.style.left=left+"px";this.O.style.top=top+"px";this.O.style.width="17px";this.O.style.height="14px";
	this.O.style.zIndex="100";this.O.style.cursor="pointer";
	this.P=document.createElement("img");
	this.P.id="ruller_"+index;this.P.className="shadow";this.P.style.position="absolute";
	this.P.style.left="0px";this.P.style.top="0px";this.P.style.width="17px";this.P.style.height="14px";
	this.P.style.zIndex="100";this.P.style.background="none";this.P.style.cursor="pointer"; 
	this.O.appendChild(this.P);return this
}
ZoomItem.prototype.onMouseMove=function(e) {} // if(!MapiAG.AN){return}
ZoomItem.prototype.getDOMElement=function(){return(this.O)};
ZoomItem.prototype.CK=function(source){this.P.src=source};
ZoomItem.prototype.onMouseDown=function(e){
	var old_zoom = MAPi.getZoomIndex();
	MapiAG.setCurrentIndex(this.Ap); // -- zoom control
	MAPi.setZoomIndex(this.Ap);
	MAPi.showMap();
	if ( MAPi.onZoom ) MAPi.onZoom( old_zoom,this.Ap );
	MapiAG.Ap=this.Ap // -- zoom control
};
        

// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// class ZoomControl
var KIO=17;   // distance from top
var A$=14;    // height of smthuing
var Ch=17;
var B6=17;
var RUNNER_WIDTH=17;
var RUNNER_HEIGHT=16;
ZoomControl.prototype.G;
ZoomControl.prototype.F;
ZoomControl.prototype.Au; // number of zoom levels
ZoomControl.prototype.AN=false;
ZoomControl.prototype.Ap;
ZoomControl.prototype.AQ; // zoom-in button
ZoomControl.prototype.AR; // zoom-out button
ZoomControl.prototype.B7=null;
ZoomControl.prototype.AM=null;
ZoomControl.prototype._ruler_div=null;
ZoomControl.prototype.setCurrentIndex=function(index) { this.Ap=index };

function ZoomControl(left,top,length) {
	this.G=left; this.F=top; this.Au=length; this.B7=new Array(); var _this=this;
	this.AQ=document.createElement("img");
	this.AQ.id="button_zoom_in";
	this.AQ.src=IMAGE_ROOT+"/zoom-in.gif";
	this.AQ.className="shadow";
	this.AQ.style.position="absolute"; this.AQ.style.left=left+"px"; this.AQ.style.top=top+"px"; this.AQ.style.width=Ch+"px";
	this.AQ.style.height=B6+"px"; this.AQ.style.zIndex="102"; this.AQ.style.background="none"; this.AQ.style.cursor="pointer";
	this.AQ.onmousedown=function(e) {MAPi.zoomIn()};

        var AC=document.createElement("div"); //AC=zoom-in button
	this._ruler_div=AC;
	AC.style.position="absolute";AC.style.left=left+"px";AC.style.top=(top+KIO)+"px";
	AC.style.width=KIO+"px";AC.style.height=(this.Au*A$)+"px";AC.style.zIndex="107";
	AC.style.cursor="pointer";
        AC.onmousedown=function(e) {
		if(!e) { e=window.event }
		_this.AN=true;
		if(isMSIE()){var F=e.clientY+y_offs()}else {F=e.pageY}
		var bounds=getBounds(AC);
		if(bounds!=null) {
			var index=_this.Au-Math.floor((F-bounds.top)/A$)-1;
			if(index<0) { index=0; }
			if(index>(_this.Au-1)) { index=_this.Au-1 }
			_this.B7[_this.Au-1-index].onMouseDown(e)
		}
		if(e.stopPropagation) { e.stopPropagation() } else { e.cancelBubble=true }
		if(e.preventDefault) { e.preventDefault() } else { e.returnValue=false }
	};
	AC.onmouseup=function(e) { MapiAG.AN=false };
	AC.onmousemove=function(e) { if(!MapiAG.AN) { return } 
		var Aa;
		if(e==undefined){e=window.event; Aa=e.button }else { Aa=e.which }
		if(Aa!=1){return}
		AC.style.cursor="pointer";
		if(isMSIE()) {var F=e.clientY+y_offs()}else{F=e.pageY}
		var bounds=getBounds(AC);
		var index=_this.Au-Math.floor((F-bounds.top)/A$)-1;
		if(index<0) { index=0 }
		if(index>(_this.Au-1)) { index=_this.Au-1 }
		if(MapiAG.Ap!=index) { _this.B7[ _this.Au-1-index ].onMouseDown(e) }
		if(e.stopPropagation) { e.stopPropagation() } else { e.cancelBubble=true }
		if(e.preventDefault) { e.preventDefault() } else { e.returnValue=false }
	};
	MAPi.getViewport().appendChild(AC); // zoom-in button was added

	var begin=0;
	for(var C=0;C<this.Au;C++) {
		var Bj=new ZoomItem(0,begin,C); this.B7[C]=Bj;
		if(C==this.Au-1) { Bj.CK(IMAGE_ROOT+"/ruler-bottom.gif" ) } else { 
			if(C==0) {Bj.CK(IMAGE_ROOT+"/ruler-top.gif")} 
			else { Bj.CK(IMAGE_ROOT+"/ruler-middle.gif") }
		}
		AC.appendChild(Bj.getDOMElement()); begin+=A$
	}

	this.AR=document.createElement("img"); // AR=zoom out
	this.AR.id="button_zoom_out"; this.AR.src=IMAGE_ROOT+"/zoom-out.gif"; this.AR.className="shadow";
	this.AR.style.position="absolute"; this.AR.style.left=left+"px"; this.AR.style.top=(begin+this.F+KIO)+"px";
	this.AR.style.width=Ch+"px"; this.AR.style.height=B6+"px"; this.AR.style.zIndex="102"; this.AR.style.cursor="pointer";
	this.AR.onmousedown=function(e) { MAPi.zoomOut(); };

	MAPi.getViewport().appendChild(this.AQ); // zoom ruler items added
	MAPi.getViewport().appendChild(this.AR); // zoom out button added
	MapiAG=this;return(this)
}

ZoomControl.prototype.onMouseMove=function(e) {
	if(!MapiAG.Dw){return}var Aa;
	if(e==undefined){e=window.event;Aa=e.button}else{Aa=e.which}
	if(Aa!=1){return}
	var index=BB-Math.round(e.pageY-getBounds(AC).top/A$);MapiAG.B7[index].onMouseDown(e)
};
ZoomControl.prototype.SelectZoom=function(index) { // zoom level visual selection
	if(this.AM==null) {
		this.AM=document.createElement("img");
		this.AM.id="runner"; this.AM.src=IMAGE_ROOT+"/runner.gif";
		this.AM.style.position="absolute"; this.AM.style.left="0px"; this.AM.style.top="0px";
		this.AM.style.width=RUNNER_WIDTH+"px"; this.AM.style.height=RUNNER_HEIGHT+"px"; this.AM.style.zIndex="107";
		this.AM.style.background="none"; this.AM.style.cursor="pointer";
		var _this=this; this.AM.onmouseup=function(e) { _this.AN=false };
		MAPi.getViewport().appendChild(this.AM)
	}
	this.Ap=index;
	try { this.B7[this.Ap].getDOMElement().removeChild(this.AM) } catch(At) {}
	this.B7[index].getDOMElement().appendChild(this.AM)
};
ZoomControl.prototype.showRuler=function() { MAPi.getViewport().appendChild(AC) };
ZoomControl.prototype.hideRuler=function() { try { MAPi.getViewport().removeChild(AC) } catch(At){}};
ZoomControl.prototype.showZoomButtons=function(){};
ZoomControl.prototype.hideZoomButtons=function(){};


// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// class MapCell
// AD= Map Cell
var c=256; var T=256; var Da=null; var DW=null;
function MapCell(x,y,a) {
	this.K=parseInt(x); this.N=parseInt(y); 
	this.G=this.K*c;//  this.F=(a.getHeight()-T)-this.N*T; 
	this.F=this.N*T;//
	this.q=a; return(this)
}
MapCell.prototype.q; // Map Level Pointer
MapCell.prototype.K; // _x
MapCell.prototype.N; // _y
MapCell.prototype.G; // _x*256 pixels
MapCell.prototype.F; // top?
MapCell.prototype.J=null;  // DOM element
MapCell.prototype.R=false; // visibility
MapCell.prototype.getX=function() { return(this.K) };
MapCell.prototype.getY=function() { return(this.N) };
MapCell.prototype.getLeft=function() { return(this.G) };
MapCell.prototype.getTop=function() { return(this.F) };
MapCell.prototype.isVisible=function() { return(this.R) };
MapCell.prototype.getDOMElement=function() { return(this.J) };
MapCell.prototype.show=function(x,y) {
	if(this.J==null) {
		this.J=document.createElement("div");
		this.J.id="t_"+ this.q._zoom_index + "_ " + this.K+"_"+this.N;
		this.J.style.left= x+"px";
		this.J.style.top= y+"px";
		this.J.style.width=c;
		this.J.style.height=T;
		this.J.style.overflow="hidden";
		this.J.style.position="absolute";
		this.J.style.border="0px";
		this.J.style.zIndex="10";
		this.J.style.background="url(" + this.q.getBaseURL()+"/"+this.N+"/"+this.K+".png) no-repeat";
	}
	this.q.getDOMElement().appendChild(this.J);
	this.R=true
};
MapCell.prototype.repaint=function() {
	if(this.J==null) { return }
	this.J.style.left=this.q.getLeft()+this.G+c+"px";
	this.J.style.top=this.q.getTop()+this.F+T+"px"
};
MapCell.prototype.hide=function() { try { this.q.getDOMElement().removeChild(this.J) } catch(At) {} this.R=false };


// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// class MapLevel
// V=width, Q=height (in pixels) _zoom_index (G,F) - level center
MapLevel.prototype.Z; // div of a level
MapLevel.prototype.G;
MapLevel.prototype.F;
MapLevel.prototype.V;
MapLevel.prototype.Q;
MapLevel.prototype._CX; // saved center
MapLevel.prototype._CY;
MapLevel.prototype._MX; // saved drag point during start
MapLevel.prototype._MY;
MapLevel.prototype.dd;
MapLevel.prototype._zoom_index;
MapLevel.prototype._units_per_pixel;
MapLevel.prototype.BP;
MapLevel.prototype.C$;
MapLevel.prototype.AV=Array();  // array of cells (divs?)
MapLevel.prototype.Di=null;
MapLevel.prototype._objects_index=Array();
MapLevel.prototype.A4=null;
MapLevel.prototype.As=null;
MapLevel.prototype.A6=null;
MapLevel.prototype.An=null;
MapLevel.prototype.Ac;
MapLevel.prototype.AX;
function MapLevel(width,height,AP) {
	this.V=width;
	this.Q=height;
	this._zoom_index=AP;
	this.BP=Math.round(this.V/c);
	this.C$=Math.round(this.Q/T);
	this.G=0 // Math.round((VIEWPORT_WIDTH-this.V)/2);
	this.F=0 // Math.round((VIEWPORT_HEIGHT-this.Q)/2);
	this.Z=document.createElement("div");
	this.Z.id="maplvl_"+AP;
	this.Z.style.overflow="hidden";
	this.Z.style.position="absolute";
	this.Z.style.left="0px";
	this.Z.style.top="0px";
	this.Z.style.width=width+"px";
	this.Z.style.height=height+"px";
	this.Z.style.zIndex="20";
	this.Z.style.cursor='url("'+IMAGE_ROOT+'/openhand.cur.ico"), default';
	this.Z.style.backgroundColor="#80b080";
	this.Z.style.border="2px #000000 solid";
	var _this=this;
	var C4=0;
	var C2=0;
	window.onmousewheel=this.onMouseWheel;
	try{ document.onmousewheel=this.onMouseWheel; } catch(e) {}
	this.Z.oncontextmenu=function(e) {};
	this.Z.onmouseover=function(e) { MapiAG.AN=false; MAPi.Ab=true };
	this.Z.onmouseout=function(e)  { MAPi.Ab=false;  };
	this.Z.onclick=function(e) { 
		if(!e) { e=window.event } 
	};
	this.Z.ondblclick=function(e){
		if(!e){e=window.event} MAPi.dragging=true;
	};
	this.Z.onmousedown=function(e) {
		if(!e) {e=window.event }
		if(!MAPi.Ab) { e.returnValue=true; return; }
		BX=true; MAPi.dragging=true;
		_this._CX=MAPi.CX;_this._CY=MAPi.CY;_this._MX=e.clientX;_this._MY=e.clientY;
		if(isOpera()) {_this.Z.style.cursor="move"}
		else { _this.Z.style.cursor='url("'+IMAGE_ROOT+'/closedhand.cur.ico"), move' }
		if(e.stopPropagation) { e.stopPropagation() } else { e.cancelBubble=true }
		if(e.preventDefault)  { e.preventDefault() } else { e.returnValue=false }

		if ( MAPi.onStartDrag ) MAPi.onStartDrag(MercPoint(MAPi.CX,MAPi.CY));
		//MAPi.fireEvent("startdrag");
	};
	this.Z.onmouseup=function(e) {
		if(!e) { e=window.event }
		BX=false;MAPi.dragging=false;MAPi.Ab=true;
		if(MAPi.ggg!=null) {MAPi.ggg.onMouseUp(e) }
		if (isOpera()) {_this.Z.style.cursor="default";}
		else {_this.Z.style.cursor='url("'+IMAGE_ROOT+'/openhand.cur.ico"), default' }
		if(e.stopPropagation) {e.stopPropagation()} else {e.cancelBubble=true}
		if(e.preventDefault)  {e.preventDefault()} else {e.returnValue=false}

		if ( MAPi.onStopDrag ) MAPi.onStopDrag(MercPoint(MAPi.CX,MAPi.CY));
		//MAPi.fireEvent("enddrag");
	};
	this.Z.onmousemove=function(e) {
		var Aa;
		if(e==undefined) { e=window.event; Aa=e.button } else { Aa=e.which }
		if (MAPi.dragging) {
			offsx=_this._CX+(e.clientX-_this._MX);
			offsy=_this._CY+(e.clientY-_this._MY);
			MAPi.setCenterXY( offsx, offsy );
			_this.repaintMap()
		}
		if(e.stopPropagation) { e.stopPropagation() } else { e.cancelBubble=true }
		if(e.preventDefault) { e.preventDefault() } else { e.returnValue=false }
	};
	return(this)
}
MapLevel.prototype.getDOMElement=function() { return(this.Z) };
MapLevel.prototype.getLeft=function() { return(this.G) };
MapLevel.prototype.getTop=function() {  return(this.F) };
MapLevel.prototype.getWidth=function() { return(this.V) };
MapLevel.prototype.getHeight=function() { return(this.Q) };
MapLevel.prototype.setBaseURL=function(baseURL) { this.dd=baseURL };
MapLevel.prototype.getBaseURL=function() { return(this.dd) };
MapLevel.prototype.setZoomIndex=function(index) { this._zoom_index=index };
MapLevel.prototype.getZoomIndex=function() { return(this._zoom_index) };
MapLevel.prototype.hide=function() {
	for(var C=this.A4;C<=this.A6;C++) {
		if(this.AV[C]==null) { continue }
		for(var M=this.As;M<=this.An;M++) { var Ak=this.AV[C][M]; if(Ak!=null) { Ak.hide() } }
	}
	MAPi._vp.removeChild(this.Z)
};
MapLevel.prototype.hidelevel=function() {
	try{ MAPi._vp.removeChild(this.Z) } catch(e){}
}
MapLevel.prototype.repaintMap=function()  {
	total=0; 
	var cx=parseInt( (this.getWidth() - MAPi.CX)/256 ); // center in cells
	var cy=parseInt( (this.getHeight() - MAPi.CY)/256 ); // center in cells
	var wh2=parseInt( (VIEWPORT_WIDTH / 256 + 4) / 2);
	var hh2=parseInt( (VIEWPORT_HEIGHT / 256 + 4) / 2);
	var max_x=this.getWidth() / 256;
	var max_y=this.getHeight() / 256;
	for ( y=cy - hh2; y<= cy + hh2; y ++ ) {
		if ( y >= 0 && y <= max_y && y < MAPi.getMaxCell() ) 
		for ( x=cx-wh2; x <= cx + wh2; x ++ ) 
			if ( x >= 0 && x <= max_x && x < MAPi.getMaxCell() ) {
				var cell=new MapCell( x, y, this );
				cell.show( x*256, y*256 ); total ++;
			}
	}
	var _left=VIEWPORT_WIDTH/2 - (this.getWidth() - MAPi.CX);
	var _top=VIEWPORT_HEIGHT/2 - (this.getHeight() - MAPi.CY);
	this.Z.style.left=_left + "px";
	this.Z.style.top=_top + "px";
	this.Z.style.width =this.getWidth();
	this.Z.style.height=this.getHeight();
	//MAPi.message( "CENTER: " + MAPi.CX + "x" + MAPi.CY 
	//	+ "<BR />MAX: " + max_x + "x" + max_y 
	//	+ ", X=" + (cx-wh2) + ".." + (cx+wh2) + "("+cx+")"
	//	+ ", Y=" + (cy-hh2) + ".." + (cy+hh2) + "("+cy+")"
	//)
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// class MapEngine
MapEngine.prototype.AS // array of zooms
MapEngine.prototype.D  // current zoom properties..
MapEngine.prototype.CX=null; // in pixels
MapEngine.prototype.CY=null; // in pixels
MapEngine.prototype.D=null;
MapEngine.prototype.dragging=false;
MapEngine.prototype._zi;
MapEngine.prototype._vp;
MapEngine.prototype._zinum;
MapEngine.prototype._zc=null;
MapEngine.prototype._c=null;

MapEngine.prototype.onStartDrag=null;
MapEngine.prototype.onStopDrag=null;
MapEngine.prototype.onZoom=null;

MapEngine.prototype.getZoomControl=function() { return this._zc; }
MapEngine.prototype.getZoomIndex=function() { return this._zi; }
MapEngine.prototype.setZoomIndex=function(z) { 
	var old_lvl=this.AS[ this._zi ];
	old_lvl.hidelevel();
	var new_lvl=this.AS[ z ];
	nCX=new_lvl.getWidth()/2; nCY=new_lvl.getHeight()/2;
	if( this.CX != null && this.CY != null )  {
		var _px=this.CX / old_lvl.getWidth();
		var _py=this.CY / old_lvl.getHeight();
                this.setCenterXY(parseInt(_px*new_lvl.getWidth()),parseInt(_py*new_lvl.getHeight()));
	} else {
		this.setCenterXY(new_lvl.getWidth()/2, new_lvl.getHeight()/2);
	}
	this._zi=z;  
}
MapEngine.prototype.terminateLoading=function() {
	// clear current map level
	try {
		this.AS[ this._zi ].Z.innerHTML = "";
	} catch (e) {alert(e);}
}

MapEngine.prototype.getViewport=function() {return this._vp; }
MapEngine.prototype.zoomIn=function() {	if ( this._zi > 0 ) { 
	this.terminateLoading();
	this.setZoomIndex( this._zi-1); this.showMap(); 
	if ( this.onZoom ) this.onZoom( this._zi+1, this._zi );
} }
MapEngine.prototype.zoomOut=function() { if ( this._zi < this._zinum-1 ) { 
	this.terminateLoading();
	this.setZoomIndex( this._zi+1); this.showMap(); 
	if ( this.onZoom ) this.onZoom( this._zi-1, this._zi );
} }
MapEngine.prototype.zoom=function(index) { if ( index > 0 && index < this._zinum-1) { 
	this.terminateLoading();
	this.setZoomIndex( index ); this.showMap(); 
	if ( this.onZoom ) this.onZoom( this._zi, index );
} }

MapEngine.prototype.getCenterX=function(){return parseInt(this.CX);}
MapEngine.prototype.getCenterY=function(){return parseInt(this.CY);}
MapEngine.prototype.getGeoLevel=function(){ return MAP_ZOOM_LIST[this._zi].L; }
MapEngine.prototype.getMaxCell=function(){ return MAP_ZOOM_LIST[this._zi].G; }
MapEngine.prototype.getAreaSize=function(){ return MAP_ZOOM_LIST[this._zi].G*256; }
MapEngine.prototype.getCenterCoordX=function(){return Math.round( MAP_COORD.E - this.CX*(MAP_COORD.E - MAP_COORD.W)/this.AS[ this._zi ].getWidth());}
MapEngine.prototype.getCenterCoordY=function(){return Math.round( MAP_COORD.S + this.CY*(MAP_COORD.N - MAP_COORD.S)/this.AS[ this._zi ].getHeight());}
MapEngine.prototype.getCenterViewSize=function(){ 
	return Math.round( MAP_ZOOM_LIST[this._zi].M*712/31); 
}

MapEngine.prototype.setCenterXY=function(x,y){this.CX=x;this.CY=y;return true;}
MapEngine.prototype.setCenter=function(p) {
	var dx=this.getAreaSize();
	if(p instanceof Wgs84Point){
		var w=p.ToMerc();
		if(!w.InBounds()) return false;
		return this.setCenterXY((MAP_COORD.E-w.getX())*dx/(MAP_COORD.E-MAP_COORD.W),(w.getY()-MAP_COORD.S)*dx/(MAP_COORD.N-MAP_COORD.S));
	} else if (p instanceof MercPoint) {
		return this.setCenterXY((MAP_COORD.E-p.getX())*dx/(MAP_COORD.E-MAP_COORD.W),(p.getY()-MAP_COORD.S)*dx/(MAP_COORD.N-MAP_COORD.S));
	}
	return false;
};
MapEngine.prototype.messageHide=function(x){ this._mei.style.visibility="hidden"; }
MapEngine.prototype.message=function(x){ /*this._mei.innerHTML=x; this._mei.style.visibility="visible"; clearTimeout(); setTimeout("MAPi.messageHide()",2000)*/ }
MapEngine.prototype.error=function(x){ this._mei.innerHTML="<span style='font-family:arial;color:darkred'>"+x+"</span>"; this._mei.style.visibility="visible"; clearTimeout(); setTimeout("MAPi.messageHide()",3000) }
function MapEngine( div ) {
	this._zi 	= MAP_ZOOM_DEFAULT;
	this._zinum 	= MAP_ZOOM_LIST.length;
	this._vp  	= div;
	this._vp.style.position="absolute";
	this._vp.style.overflow="hidden";
	this._vp.style.display="block";
	this._vp.style.backgroundColor="#a0ffa0";
	this._vp.style.zIndex=1;
	var p=this._vp.parentNode;
	this._vp.style.width=(p.clientWidth - 3) + "px";
	this._vp.style.height=(p.offsetHeight - 3) + "px";
	VIEWPORT_WIDTH=p.clientWidth - 3;
	VIEWPORT_HEIGHT=p.offsetHeight - 3;
	// adding message box
	this._mei 	= document.createElement("div");
	this._mei.style.position="absolute"; this._mei.style.left="80px"; this._mei.style.top="10px";
	this._mei.style.width="480px"; this._mei.style.zIndex="107";
	this._mei.style.backgroundColor="yellow"; 
	this._mei.style.textAlign="center"; this._mei.style.fontSize="10px"; 
	this._mei.style.border="2px darkred dashed"; 
	this._mei.style.padding="5px 5px 5px 5px"; 

	this.messageHide()
	div.appendChild(this._mei)
	this.AS =new Array( MAP_ZOOM_LIST.length )
	for ( level=0; level < MAP_ZOOM_LIST.length; level++ ) {
		var zi=MAP_ZOOM_LIST[level].Z;
		var szx=MAP_ZOOM_LIST[level].G * c;
		var szy=MAP_ZOOM_LIST[level].G * T;
		var map=new MapLevel(szx,szy,level);
		map.setBaseURL( MAP_ROOT + zi); // set base url for that zoom level
		map.scale=MAP_ZOOM_LIST[level].M; // meters per inch
		map.cells=MAP_ZOOM_LIST[level].G;
		this.AS[ level ]=map;
		if ( this.CX == null && this.CY == null && level == this._zi ) {
			this.setCenterXY( szx/2, szy/2 );
		}
	} 
	this._c=document.createElement("img");
	this._c.style.left= parseInt(VIEWPORT_WIDTH/2 - 8 ) +"px";
	this._c.style.top= parseInt(VIEWPORT_HEIGHT/2 - 8 )+"px";
	this._c.style.overflow="hidden";
	this._c.style.position="absolute";
	this._c.style.zIndex="501";
	this._c.src=IMAGE_ROOT + "/cross16x16.png";
	div.appendChild( this._c );
	MAPi=this;
	window.onresize=onMapEngineResize;
}
MapEngine.prototype.repaintMap=function() {
	lvl=this.AS[this._zi];this.D=lvl;this._vp.appendChild( lvl.Z );
	lvl.repaintMap();
}
MapEngine.prototype.showMap=function() {
	this._zc.SelectZoom( this._zi );
	lvl=this.AS[ this._zi ];
	this.repaintMap();
}
function onMapEngineResize( e ) {
	var p=MAPi._vp.parentNode;
	MAPi._vp.style.width=(p.clientWidth - 3) + "px";
	MAPi._vp.style.height=(p.offsetHeight - 3) + "px";
    	VIEWPORT_LEFT=0;VIEWPORT_TOP=0;VIEWPORT_WIDTH=p.clientWidth-3;
	VIEWPORT_HEIGHT=p.offsetHeight-3;
	MAPi._c.style.left= parseInt(VIEWPORT_WIDTH/2 - 8 ) +"px";
	MAPi._c.style.top= parseInt(VIEWPORT_HEIGHT/2 - 8 )+"px";
}
MapEngine.prototype.initialize=function(){
	// document.write( "1 initializing...<BR />" );
	this._zc=new ZoomControl(10, 35, this._zinum );
	this.showMap();
}


MapImgObject.prototype.PX=0;
MapImgObject.prototype.PY=0;
MapImgObject.prototype._x=0;
MapImgObject.prototype._y=0;
MapImgObject.prototype.Src="";
MapImgObject.prototype.J=new Array( MAP_ZOOM_LIST.length );
function MapImgObject( point, ptx, pty, path ) {
	if( point instanceof Wgs84Point) {
		this.Src=path;
		this._x=ptx; this._y=pty; // pointer coords on image
		if ( !point.InBounds() ) {
			MAPi.error( "Latitude or Longitude is out of map bounds" ); 
		} else {
		        var p = point.ToMerc();
			var pcx=(p.getX() - MAP_COORD.W) / (MAP_COORD.E - MAP_COORD.W);
			var pcy=(MAP_COORD.N - p.getY() ) / (MAP_COORD.N - MAP_COORD.S);
		
			for ( level=0; level < MAP_ZOOM_LIST.length; level++ ) {		
                        x=pcx*MAPi.AS[ level ].getWidth() ;  // + this.PX; // define local pixel
			y=pcy*MAPi.AS[ level ].getHeight() ; // this.PY;
                        var im=document.createElement("img");
			im.style.left= (x - this._x)+"px";
			im.style.top= (y - this._y)+"px";
			im.style.overflow="hidden";
			im.style.position="absolute";
			im.style.zIndex="500";
			im.src=this.Src
			MAPi.AS[ level ].Z.appendChild( im );
			this.J[level]=im;
			}
		}
	}
}
MapImgObject.prototype.remove=function() {
	// exception here is normal
	try{
	for(level=0;level<MAP_ZOOM_LIST.length;level++){		
		MAPi.AS[level].Z.removeChild(this.J[level]);this.J[level]=null;
	}
	}catch(e){}
}


