/********************************************************
** NCSJSView.js
**
** Copyright 2008 ERDAS, Inc.
** This document contains unpublished source code of
** ERDAS, Inc. This notice does
** not indicate any intention to publish the source
** code contained herein.
**
** CREATED:  24 Feb 2005
** AUTHOR:   Simon Cope
** PURPOSE:  DHTML (HTML/JavaScript/CSS) based "kiosk" NCSView.
**			 
** EDITS:    [xx] ddMmmyy NAME COMMENTS
**           [01] 04Jul06 JX   
**                             1. Because FirFox implemention uses single precision float,
**                                so use false origin to avoid white lines when displaying 
**                                at larger scale on large images.
**                             2. Firfox uses signed short int to implement image display height and width,
**                                so limiting the maximum zoom level to avoid showing blank image tiles.
**           [02] 10Jul06 JX      Fixed non-square pixel images display problem. The fix also allows for non-square
**                                pixel on the display device (mornitor) to be corrected.
**			 [03] 04Oct06 JX   Removed the zoom checking as small changes in extents can cause significant rounding error that in term causes 
**                             display gaps or overlaps.
**           [04] 27Oct06 JX   Improved compatibility with Mac Safaris and standard rendering mode (DOCTYPE).
**                             There are still problems associated with using properties such as "offsetHeight".
**           [05] 08Nov06 JX   Fixed problems with displaying multi-layer which was introduced by previous fix.  
**           [06] 16Nov06 SC/JX   Fixed "Stack overflow at line :0" bug.
*******************************************************/

var debug_console = false;
if(!window.console) {
    if( debug_console ) {
	    var console={
	        init:function(){
	            console.bInit=true; console.d=document.createElement('div'); document.body.appendChild(console.d);
			    var a=document.createElement('a'); a.href='javascript:console.hide()'; a.innerHTML='close';
				console.d.appendChild(a); var a=document.createElement('a'); a.style.paddingLeft = "10px";
				a.href='javascript:console.clear();'; a.innerHTML='clear'; console.d.appendChild(a);
				var id='debugconsole'; if(!document.getElementById(id)){console.d.id=id;}console.hide();
        	    console.d.style.position = "absolute"; console.d.style.top = 0;	console.d.style.right = 0;
				console.d.style.width = "300px"; console.d.style.border = "1px"; console.d.style.solid = "999";
				console.d.style.background = "#eee"; console.d.style.padding = "10px";
		    },
	        hide:function(){if(!console.bInit){console.init();};console.d.style.display='none';},
	        show:function(){if(!console.bInit){console.init();};console.d.style.display='block';},
	        log:function(o){if(!console.bInit){console.init();};console.d.innerHTML+='<br/>'+o;console.show();},
	        clear:function(){if(!console.bInit){console.init();};console.d.parentNode.removeChild(console.d);
				console.init();console.show();}
	    };
	    console.bInit=false;
	} else {
	    var console={log:function(o){}};
	}
}

// 
// Helper function to implement inheritance
//
_NCSJSView_CallSuper = function(theThisBase, sFunc, args) {
		var theThis = theThisBase;
		var theSuper = theThisBase.getSuper();

		while(theThis[sFunc] == theSuper[sFunc]) {
			theThis = theSuper;
			theSuper = theThis.getSuper();
		}
		if(typeof(theSuper[sFunc]) != "undefined") {
			return(theSuper[sFunc].apply(theThisBase, args));
		}
		return(null);
	}

_NCSJSView_Extends = function(theThis, oSuper) { 
	for(sProperty in oSuper) { 
		if(typeof(theThis[sProperty]) == "undefined") {
			theThis[sProperty] = oSuper[sProperty]; 
		}
	} 	
}

//[04]
_NCSJSView_IsNot_Undefined_Nor_Function = function(funcName){//[04]
    return (funcName != "undefined")&& (funcName != "function");
    // when functions are undefined, the "typeof()" function returns "function" in Firefox /and Safaris.
}

_NCSJSView_IsLocalURL = function(sURL)
{
	//Check if URL has the same origin as the current document.
	//Two pages are considered to have the same origin if their host, port and protocol are the same.
	//The exception to this rule is if the document.domain property is set and is a suffix of the URL host. 
	var bIsLocalURL = true;
	var sDocumentHost = document.location.host;//host + port
	sDocumentHost = sDocumentHost.toLowerCase();
	var sDocumentProtocol = document.location.protocol;//e.g. http:
	sDocumentProtocol = sDocumentProtocol.toLowerCase();
	sURL = sURL.toLowerCase();
	
	var nProtocolSepIndex = sURL.indexOf("://");
	if (nProtocolSepIndex >= 0) //If "://" is not present in sURL, assume sURL represents a local path.
	{
		var sURLProtocol = sURL.substring(0, nProtocolSepIndex + 1);//Protocol includes ':' e.g. http:
		var nHostIndex = nProtocolSepIndex + 3;
		var sURLHost = sURL.substring(nHostIndex);
		
		var nSepIndex = sURLHost.indexOf("/");
		if (nSepIndex >= 0) {
			sURLHost = sURLHost.substring(0, nSepIndex);
		}
		
		// Remove the port from sURLHost is one exists
		var nSepPort = sURLHost.indexOf(":");
		if( nSepPort > 0 ) {
			sURLHost = sURLHost.substring(0, nSepPort);
		}
		
		if (document.domain && (document.domain != ""))
		{
			var sDocumentDomain = document.domain;
			sDocumentDomain = sDocumentDomain.toLowerCase();
			if ((sURLHost.indexOf(sDocumentDomain) == -1) || 
				(sURLHost.substring(sURLHost.length - sDocumentDomain.length, sURLHost.length) != sDocumentDomain))
			{
				bIsLocalURL	= false;
			}
		}
		else if ((sURLHost != sDocumentHost) || (sDocumentProtocol != sURLProtocol))
		{
			bIsLocalURL	= false;
		}				
	}
	return bIsLocalURL;
}

var _NCSJSViews = new Array();
var _NCSJSDraggedViewID = null;

//
// CLASS NCSJSViewCallbacks
//
// NCSJSView Callback class
//
function NCSJSViewCallbacks(theView, sName, callBack, bTrigger) {
	this.sName = sName;
	this.sCallBack = callBack;
	this.bTrigger = bTrigger;
	this.bIsEvaled = false;
	eval("_NCSJSView_Find(" + theView.nViewID + ")." + sName.toLowerCase() + "=" + ((callBack != null) ? callBack : "_NCSJSView_NullCB") + ";");
}

//
// CLASS NCSJSViewLayerLevel
//
// Base NCSJSViewLayer Level class 
// IMplements tiles image quadtree levels
//
function NCSJSViewLayerLevel(theLayer, level) {
	this.theLayer = theLayer;
	this.level = level;
	if(theLayer.sType == "GISOverlay"){
	    this.dWorldPerTileX = this.dWorldPerTileY = 1;
        this.nTilesWide = this.nTilesHigh = 1; 
	    
	} else {
	    this.dWorldPerTileX = theLayer.nTileSize * theLayer.dImageCellSizeX * Math.pow(2, level);
	    this.dWorldPerTileY = theLayer.nTileSize * theLayer.dImageCellSizeY * Math.pow(2, level);
	    this.nTilesWide = Math.ceil((theLayer._GetBottomRightWorldCoordinateX() - theLayer._GetTopLeftWorldCoordinateX()) / this.dWorldPerTileX);
	    this.nTilesHigh = Math.ceil((theLayer._GetBottomRightWorldCoordinateY() - theLayer._GetTopLeftWorldCoordinateY()) / this.dWorldPerTileY);
	}
	
	this.aImages = new Array();
}

NCSJSViewLayerLevel.prototype._img_onerror = function(e) {
	this.requestDone();
	//[06] this.nextRequest(); 
}

NCSJSViewLayerLevel.prototype._img_onabort = function(e) {
	var sSrc = this.src;
	this.src = null;
	this.src = sSrc;
}

NCSJSViewLayerLevel.prototype._img_draw = function(dViewTLX, dViewTLY, dPixelPerWorldX, dPixelPerWorldY, nFalseOriginX, nFalseOriginY) {
	var nLeft = Math.ceil((this.xdWorldTLX - dViewTLX) * dPixelPerWorldX) - nFalseOriginX;
	var nTop = Math.ceil((this.xdWorldTLY - dViewTLY) * dPixelPerWorldY) - nFalseOriginY;
	var nRight = Math.ceil((this.xdWorldBRX - dViewTLX) * dPixelPerWorldX) - nFalseOriginX;
	var nBottom = Math.ceil((this.xdWorldBRY - dViewTLY) * dPixelPerWorldY) - nFalseOriginY;
    if(nBottom < 0) {
		nBottom = 0;
	}
    this.style.top = nTop + "px";
	this.style.left = nLeft + "px";
	this.style.width = (nRight - nLeft) + "px";// + 1;
	this.style.height = (nBottom - nTop) + "px";// + 1;
	/* IE7 PNG bug workaround, not recommended unless absolutely necessary
	if(this.xNCSJSViewLayer.getSuper().theView.bIsIE && this.xNCSJSViewLayer.sImageType == "png") {
		this.style.width = ((nRight - nLeft) + ((nRight - nLeft) / this.xNCSJSViewLayer.nTileSize)) + "px";// + 1;
		this.style.height = ((nBottom - nTop) + ((nRight - nLeft) / this.xNCSJSViewLayer.nTileSize)) + "px";// + 1;
	} else {
		this.style.width = (nRight - nLeft) + "px";// + 1;
		this.style.height = (nBottom - nTop) + "px";// + 1;
	}
	*/
}

NCSJSViewLayerLevel.prototype._img_clearTransparency = function() {
    if(this.currentOpacity == 0.999) {
        this.style.opacity = null;
        this.style.KHTMLOpacity = null;
        this.style.MozOpacity = null;
		if (theLayer.theView.bIsIE && theLayer.theView.dIEVersion < 7 && (theLayer.sImageType == "png" || theLayer.sType == "GISOverlay") && this.xIE6AlphaImageLoader) {
			this.style.filter = this.xIE6AlphaImageLoader;
		} else {
			this.style.filter = null;
		}
        this.currentOpacity = 1.0;
    }
}

NCSJSViewLayerLevel.prototype._img_setTransparency = function(dTransparency) {
	var theLayer = this.xNCSJSViewLayer;
	
	if(!isNaN(dTransparency)) {
		var dOpacity = 1.0 - dTransparency;
		dOpacity = (dOpacity >= 0.999) ? 0.999 : dOpacity;
		this.currentOpacity = dOpacity;
	
		this.style.opacity = dOpacity;
   		this.style.KHTMLOpacity = dOpacity;
		this.style.MozOpacity = dOpacity;
		if(dOpacity == 0.999) {
			if (theLayer.theView.bIsIE && theLayer.theView.dIEVersion < 7 && (theLayer.sImageType == "png" || theLayer.sType == "GISOverlay")) {
				this.style.filter = this.xIE6AlphaImageLoader;
			} else {
				this.style.filter = null;
			}
		} else {
			if (theLayer.theView.bIsIE && theLayer.theView.dIEVersion < 7 && (theLayer.sImageType == "png" || theLayer.sType == "GISOverlay")) {
				this.xIE6Alpha = "progid:DXImageTransform.Microsoft.Alpha(opacity=" + Math.floor(100 * dOpacity) + ")";
				if (this.xIE6AlphaImageLoader) {
					this.style.filter = this.xIE6AlphaImageLoader + " " + this.xIE6Alpha;
				} else {
					this.style.filter = this.xIE6Alpha;
				}
			} else {
				this.style.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity=" + Math.floor(100 * dOpacity) + ")";
			}
		}
	}
}
		
NCSJSViewLayerLevel.prototype._img_setRequested = function(v) {
	var theLayer = this.xNCSJSViewLayer;
	if(theLayer != null) {
		if(v && !this.xInRequest) {
			this.xInRequest = true;
			theLayer.nCurrentRequests++;
		} else if(!v && this.xInRequest) {
			this.xInRequest = false;
			theLayer.nCurrentRequests--;				
		}
	}
}

NCSJSViewLayerLevel.prototype._img_nextRequest = function() {
return;//[06]
/*  
	var theLayer = this.xNCSJSViewLayer;
	if(theLayer != null) {
		while(theLayer.nCurrentRequests < theLayer.nMaxCurrentRequests && theLayer.aRequestList.length > 0) {
			var nextImg = theLayer.aRequestList[0];
			theLayer.aRequestList.remove(0);
			nextImg.xInRequestList = false;
			nextImg.setRequested(true);
			nextImg.src = nextImg.getAttribute("NCSJSViewxsrc");
		}
	}*/
}

NCSJSViewLayerLevel.prototype._img_doRequest = function() {
	var theLayer = this.xNCSJSViewLayer;
	if(theLayer != null && !this.xInRequest && !this.xInRequestList) {
		this.xTimeStamp = NCSGetTimeStampMs();
		var sSrc = this.getAttribute("NCSJSViewxsrc");
		if(theLayer.nCurrentRequests < theLayer.nMaxCurrentRequests || _NCSJSView_haveImgCached(sSrc)) {
			this.setRequested(true);
			if (theLayer.theView.bIsIE && theLayer.theView.dIEVersion < 7 && (theLayer.sImageType == "png" || theLayer.sType == "GISOverlay")) {
				this.src = "/ecwplugins/lib/bitmaps/Transparent.gif";
				this.xIE6AlphaImageLoader = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + encodeURI(sSrc) + "',sizingMethod='scale',enabled=true);";
				if (this.xIE6Alpha) {
					this.style.filter = this.xIE6AlphaImageLoader + " " + this.xIE6Alpha;
				} else {
					this.style.filter = this.xIE6AlphaImageLoader;
				}
			} else {
				this.src = sSrc;
			}
		} else if(!this.xInRequestList) {
			theLayer.aRequestList.push(this);
			this.xInRequestList = true;
		}
		//[06] this.nextRequest();
	}
}
		
NCSJSViewLayerLevel.prototype._img_requestDone = function() {
	var theLayer = this.xNCSJSViewLayer;
	if(theLayer != null) {
		this.setRequested(false);
		//[06] this.nextRequest();
	}
}

NCSJSViewLayerLevel.prototype._img_cancelRequest = function() {
	var theLayer = this.xNCSJSViewLayer;
	if(theLayer != null) {
		this.setRequested(false);
		this.src = "/ecwplugins/lib/bitmaps/Transparent.gif";
		this.style.visibility = "hidden";
		this.style.display = "none";
		theLayer.aFadeList.remove(this);
		theLayer.aRequestList.remove(this);
		this.xInRequestList = false;
		//[06] this.nextRequest();
	}
}

NCSJSViewLayerLevel.prototype._img_onload = function() {
	var theLayer = this.xNCSJSViewLayer;
	if(theLayer != null) {
		var sURL = this.src;
		if (theLayer.theView.bIsIE && theLayer.theView.dIEVersion < 7  && (theLayer.sImageType == "png" || theLayer.sType == "GISOverlay")) {
			sURL = this.getAttribute("NCSJSViewxsrc");
		}		
		_NCSJSView_addImgCached(sURL);
		theLayer.theView._Debug("_NCSJSViewEcwLayer_Progressive " + sURL);
		this.fadeState = 1.0;
		this.setTransparency(this.fadeState);					
		if(sURL.indexOf("Transparent.gif") >0) {
		} else {
			this.requestDone();
			//[06] this.nextRequest();
			this.style.display = "inline";
			this.style.visibility = "inherit";
			var nQuality = this.getAttribute("NCSJSViewxquality");

			if(theLayer.bProgressive) {
				this.setAttribute("NCSJSViewxpercent", nQuality);				
			} else {
				this.setAttribute("NCSJSViewxpercent", 100);		
				theLayer.aFadeList.remove(this);
				if(NCSGetTimeStampMs() - this.xTimeStamp >= 150 && theLayer.bFadeIn) {
					theLayer.aFadeList.push(this);
				} else {
                    var dTransparency = theLayer._GetTransparency("#");
    				if(isNaN(dTransparency)) {
    					dTransparency = 0.0;
    				}
					this.setTransparency(dTransparency);
				}
			}
			theLayer.theView.FireOnPercentComplete();
			nQuality = nQuality * 2;

			if(theLayer.bProgressive && nQuality <= 100) {
				this.setAttribute("NCSJSViewxquality", nQuality);// Next quality to load
				this.setAttribute("src", theLayer._SetSrcQuality(this.src, Math.min(100, nQuality)));
				theLayer.theView._Debug("    ->" + this.src);
			} else {
				this.onload = null;
				theLayer.theView._Debug("    ->DONE");
			}
		}
	}
}

NCSJSViewLayerLevel.prototype._img_fadeIn = function() {
	var theLayer = this.xNCSJSViewLayer;
	var dTransparency = theLayer._GetTransparency("#");
	if(isNaN(dTransparency)) {
		dTransparency = 0.0;
	}
	if(this.fadeState > dTransparency) {
		this.fadeState -= 1/16.0;
		this.fadeState = Math.max(dTransparency, this.fadeState);
		if(this.fadeState < 1/255) {
			this.fadeState = 0.0;
		} else if(this.fadeState > 1.0) {
			this.fadeState = 1.0;
		}
		this.setTransparency(this.fadeState);
		return(false);
	} else {
		return(true);
	}
}

NCSJSViewLayerLevel.prototype._img_isComplete = function() {
	if(this.currentOpacity == 1.0 && this.style.display != "none" && this.style.visibility != "hidden") {
		return(true);
	}
	return(false);
}

// Alloc an image
NCSJSViewLayerLevel.prototype._AllocImg = function(dWorldTLX, dWorldTLY, dWorldBRX, dWorldBRY, nFalseOriginX, nFalseOriginY) {
    var theLayer = this.theLayer;
    var theLevel = this;
	var img = document.createElement("img");

	img.onerror = this._img_onerror;
	img.onabort = this._img_onabort;
	img.onload = this._img_onload;

	img.xNCSJSViewLayer = this.theLayer;
	img.xNCSJSViewLevel = this;
	img.xInRequestList = false;
	img.xInRequest = false;
    
    img.clearTransparency = this._img_clearTransparency;
	img.setTransparency = this._img_setTransparency;
	img.fadeIn = this._img_fadeIn;
	img.isComplete = this._img_isComplete;

	img.draw = this._img_draw;
	
	img.setRequested = this._img_setRequested;
	//[06] img.nextRequest = this._img_nextRequest;
	img.doRequest = this._img_doRequest;
	img.requestDone = this._img_requestDone;
	img.cancelRequest = this._img_cancelRequest;
	
	this.aImages.push(img);
	
	img.border = 0;
	img.style.borderColor = "black";
    img.style.position = "absolute"; 
	img.style.visibility = "hidden";
	img.style.display = "none";
	img.xdWorldTLX = dWorldTLX;
	img.xdWorldTLY = dWorldTLY;
	img.xdWorldBRX = dWorldBRX;
	img.xdWorldBRY = dWorldBRY;
	var v = this.theLayer.theView;
	var dPixelPerWorldX = 1.0 / v.dWorldPerPixelX;
	var dPixelPerWorldY = 1.0 / v.dWorldPerPixelY;

	img.fadeState = 1.0;
	img.setTransparency(this.fadeState);
	img.draw(theLayer._GetTopLeftWorldCoordinateX(), theLayer._GetTopLeftWorldCoordinateY(), dPixelPerWorldX, dPixelPerWorldY, nFalseOriginX, nFalseOriginY);
	img.style.zIndex = -this.level;//2 * (theLayer.aLevels.length - this.level);
	theLayer.NCSJSViewDiv.appendChild(img);
	return(img);
}

var _NCSJSView_aSessionImgs = new Array();

function _NCSJSView_addImgCached(sURL) {
	if(!_NCSJSView_haveImgCached(sURL)) {
		_NCSJSView_aSessionImgs.push(sURL);
	}
}

function _NCSJSView_haveImgCached(sURL) {
	var l = _NCSJSView_aSessionImgs.length;
	var i;
	for(i = 0; i < l; i++) {
		if(_NCSJSView_aSessionImgs[i] == sURL) {
			return(true);
		}
	}
	return(false);
}

// Delete specified image
NCSJSViewLayerLevel.prototype._DeleteImg = function(img) {
    if(img) {
	    var i;
	    this.aImages.remove(img);
	    img.onload = null;
	    img.cancelRequest();

	    try {
    	    this.theLayer.NCSJSViewDiv.removeChild(img);
	    } catch(e) {}
	    
	    img.xNCSJSViewLayer = null;
		img.xNCSJSViewLevel = null;
		img.onerror = null;
		img.onabort = null;
		img.onload = null;
		img.clearTransparency = null;
		img.setTransparency = null;
		img.draw = null;
		img.setRequested = null;
		//[06] img.nextRequest = null;
		img.doRequest = null;
		img.requestDone = null;
		img.cancelRequest = null;
		img.fadeIn = null;
		img.isComplete = null;
	}
}

NCSJSViewLayerLevel.prototype._CreateTile = function(x, y, nFalseOriginX, nFalseOriginY)
{
	var theLayer = this.theLayer;
	if(theLayer.sType == "GISOverlay"){
	    this.dWorldPerTileX = theLayer._GetBottomRightWorldCoordinateX() - theLayer._GetTopLeftWorldCoordinateX();
		this.dWorldPerTileY = theLayer._GetBottomRightWorldCoordinateY() - theLayer._GetTopLeftWorldCoordinateY();
	}	
	var dWorldTLX = theLayer._GetTopLeftWorldCoordinateX() + x * this.dWorldPerTileX;
	var dWorldBRX = theLayer._GetTopLeftWorldCoordinateX() + (x + 1) * this.dWorldPerTileX;
	var dWorldTLY = theLayer._GetTopLeftWorldCoordinateY() + y * this.dWorldPerTileY;
	var dWorldBRY = theLayer._GetTopLeftWorldCoordinateY() + (y + 1) * this.dWorldPerTileY;

//	if(x < 0 || x > theLayer.nImageWidth * theLayer.dImageCellSizeX / this.dWorldPerTileX ||
//	   y < 0 || y > theLayer.nImageHeight * theLayer.dImageCellSizeY / this.dWorldPerTileY) {
	if(x < 0 || x >= theLayer._TotalTilesAtLevelX(this)||
	   y < 0 || y >= theLayer._TotalTilesAtLevelY(this)) {
		return(null);
	} else {
		var nSizeX = theLayer._GetTileSizeX();//nTileSize;
		var nSizeY = theLayer._GetTileSizeY();//nTileSize;
		
		if(dWorldBRX > theLayer._GetBottomRightWorldCoordinateX()) {
			var dX = (theLayer._GetBottomRightWorldCoordinateX() - dWorldTLX) / (dWorldBRX - dWorldTLX);
			nSizeX = Math.ceil(nSizeX * dX);
			dWorldBRX = theLayer._GetBottomRightWorldCoordinateX();			
		}
		if(theLayer.theView.bYInv) {
			if(dWorldBRY < theLayer._GetBottomRightWorldCoordinateY()) {
				var dY = (theLayer._GetBottomRightWorldCoordinateY() - dWorldTLY) / (dWorldBRY - dWorldTLY);
				nSizeY = Math.ceil(nSizeY * dY);
				dWorldBRY = theLayer._GetBottomRightWorldCoordinateY();
			}
		} else {
			if(dWorldBRY > theLayer._GetBottomRightWorldCoordinateY()) {
				var dY = (theLayer._GetBottomRightWorldCoordinateY() - dWorldTLY) / (dWorldBRY - dWorldTLY);
				nSizeY = Math.ceil(nSizeY * dY);
				dWorldBRY = theLayer._GetBottomRightWorldCoordinateY();
			}
		}

		var sSrc = theLayer._GetSrc(nSizeX, nSizeY, dWorldTLX, dWorldTLY, dWorldBRX, dWorldBRY, this.level, x, y);
		if (sSrc == "")
			return(null);
		
		var img = this._AllocImg(dWorldTLX, dWorldTLY, dWorldBRX, dWorldBRY, nFalseOriginX, nFalseOriginY);
		if(this.bProgressive) {
			img.setAttribute("NCSJSViewxquality", 25);				
		} else {
			img.setAttribute("NCSJSViewxquality", theLayer.nNonProgressiveQuality);				
		}
		img.setAttribute("NCSJSViewxpercent", 0);	
		img.setAttribute("NCSJSViewxsrc", sSrc);

		img.doRequest();
		img.width = nSizeX;
		img.height = nSizeY;
    	img.xNCSJSViewX = x;
    	img.xNCSJSViewY = y;
        return(img);
    }
}

// Delete specified image
NCSJSViewLayerLevel.prototype._DeleteTile = function(img, bRecurseUp) {
    if(img) {
        this._DeleteImg(img);
        if(bRecurseUp) {
		    this._PurgeRecurseUp(img.xNCSJSViewX, img.xNCSJSViewY);
		}
	}
}

NCSJSViewLayerLevel.prototype._FindTile = function(x, y) {
	var aImages = this.aImages;
	if(aImages != null) {
		var i;
		var len = aImages.length;
		for(i = 0; i < len; i++) {
			var img = aImages[i];
			if(img.xNCSJSViewX == x && img.xNCSJSViewY == y) {
				return(img);
			}
		}
	}
	return(null);
}
	
NCSJSViewLayerLevel.prototype._GetTileStartX = function() {
	var nStartX = Math.floor((this.theLayer.theView.dViewTLX - this.theLayer._GetTopLeftWorldCoordinateX()) / this.dWorldPerTileX);
	return(Math.max(0, Math.min(this.nTilesWide-1, nStartX)));
}

NCSJSViewLayerLevel.prototype._GetTileStartY = function() {
	var nStartY = Math.floor((this.theLayer.theView.dViewTLY - this.theLayer._GetTopLeftWorldCoordinateY()) / this.dWorldPerTileY);
	return(Math.max(0, Math.min(this.nTilesHigh-1, nStartY)));
}

NCSJSViewLayerLevel.prototype._GetTileEndX = function() {
	var nEndX = Math.ceil((this.theLayer.theView.dViewBRX - this.theLayer._GetTopLeftWorldCoordinateX()) / this.dWorldPerTileX);
	return(Math.max(0, Math.min(this.nTilesWide-1, nEndX)));
}

NCSJSViewLayerLevel.prototype._GetTileEndY = function() {
	var nEndY = Math.ceil((this.theLayer.theView.dViewBRY - this.theLayer._GetTopLeftWorldCoordinateY()) / this.dWorldPerTileY);
	return(Math.max(0, Math.min(this.nTilesHigh-1, nEndY)));
}
	
NCSJSViewLayerLevel.prototype._PurgeTiles = function(nStartX, nStartY, nEndX, nEndY, bRecurseUp) {
	if(this.aImages != null) {
		var i;
		var aImages = this.aImages;
		var nImages = aImages.length;
		for(i = nImages - 1; i >= 0; i--) {
			var img = aImages[i];
			if(img.xNCSJSViewX < nStartX || img.xNCSJSViewX > nEndX ||
			   img.xNCSJSViewY < nStartY || img.xNCSJSViewY > nEndY) {
				this._DeleteTile(img, bRecurseUp);
			}
		}
	}
	return(null);
}

NCSJSViewLayerLevel.prototype._PurgeRecurseUp = function(x, y) {
    if(this.level > 0) {
	    var levelUp = this.theLayer.aLevels[this.level - 1];
	    levelUp._DeleteTile(levelUp._FindTile(x * 2, y * 2), true);
	    levelUp._DeleteTile(levelUp._FindTile(x * 2+1, y * 2), true);
        levelUp._DeleteTile(levelUp._FindTile(x * 2, y * 2+1), true);
        levelUp._DeleteTile(levelUp._FindTile(x * 2+1, y * 2+1), true);
    }
}

//
// CLASS NCSJSViewLayer
//
// Base NCSJSView Layer class containing common method implementations
//
function NCSJSViewLayer(theView, nLayerID, layerName) {
	this.sLayerName = layerName;
	this.sLayerType = "NCSJSViewLayer";
	this.theView = theView;
	this.nLayerID = nLayerID;
	this.TransparentColors = new Array();
	this.bClip = false;
	this.bAutoCreateLevelTiles = true;
	this.nClipTLX = 0;
	this.nClipTLY = 0;
	this.nClipBRX = 0;
	this.nClipBRY = 0;
	this.nLastTileX0 = -1;
	this.nLastTileY0 = -1;
	this.nLastTileX1 = -1;
	this.nLastTileY1 = -1;
	this.nLastDivX = -1;
	this.nLastDivY = -1;
	this.nLastDivWidth = -1;
	this.nLastDivHeight = -1;
	
	//[01]
	this.bUseFalseOrigin = true;
	this.bChangeFalseOrigin = false;
	this.nFalseOriginX = 0;
	this.nFalseOriginY = 0;
	
	this.nTileSize = 256; 
	this.bMultiLevel = true;
	this.bEnableMultiLevel = true;
	this.aLevels = new Array();
	this.bFadeIn = false;
	this.aFadeList = new Array();
	this.nCurrentRequests = 0;
	this.nMaxCurrentRequests = 6;
	this.aRequestList = new Array();

	var myDIV = document.createElement("div");
	myDIV.setAttribute("id", "NCSJSViewDiv" + theView.nViewID + "_" + this.nLayerID);
	myDIV.style.position = "absolute";
	myDIV.style.left = "0px";
	myDIV.style.top = "0px";
	myDIV.style.overflow = "visible";
	myDIV.style.zIndex = nLayerID;
	myDIV.style.clip = "rect(auto auto auto auto)";
	myDIV.style.backgroundColor = "transparent";
	theView.NCSJSViewDivFrame.appendChild(myDIV);
	this.NCSJSViewDiv = myDIV;
	this.AJAX = new NCSAJAX();
	this.bRequestTimerSlowed = false;
	this.requestTimer = new NCSAJAX_Timer(10, this._doNextRequest, this, false); //[06] 
	this.requestTimer.start();//[06] 
	if( this.bFadeIn ) {
		this.fadeTimer = new NCSAJAX_Timer(1/32, this._fadeIn, this, true);
		this.fadeTimer.start();
	}
}
//[06] 

NCSJSViewLayer.prototype._doNextRequest = function(theLayer) {
	if(theLayer != null) {
		// Slow down the requestTimer if no requests pending
		if( !theLayer.bRequestTimerSlowed && (theLayer.aRequestList.length == 0) ) {
			theLayer.bRequestTimerSlowed = true;
			theLayer.requestTimer.setTimeout(500);
			return;
		} else if( theLayer.bRequestTimerSlowed && (theLayer.aRequestList.length > 0) ) {
			theLayer.bRequestTimerSlowed = false;
			theLayer.requestTimer.setTimeout(10);
			return;
		}
		while(theLayer.nCurrentRequests < theLayer.nMaxCurrentRequests && theLayer.aRequestList.length > 0) {
			var nextImg = theLayer.aRequestList[0];
			theLayer.aRequestList.remove(0);
			nextImg.xInRequestList = false;
			nextImg.setRequested(true);
			nextImg.src = nextImg.getAttribute("NCSJSViewxsrc");
		}
	}
}

//[01]
NCSJSViewLayer.prototype.GetZoomLimit = function() {
    return 32767 / this.nTileSize;
}

NCSJSViewLayer.prototype._fadeIn = function(theLayer) {
	var i;
	var a = theLayer.aFadeList;
	var nLen = a.length;
	
	for(i = 0; i < nLen; i++) {
		var img = a[i];
		if(_NCSJSView_IsNot_Undefined_Nor_Function(typeof(img))){ //[04]
			if(img.fadeIn()) {
				a.remove(img);
				if(theLayer._GetLevel() == img.xNCSJSViewLevel) {
					var theLevel = img.xNCSJSViewLevel;
					theLevel._PurgeRecurseUp(img.xNCSJSViewX, img.xNCSJSViewY);
				}
			}
		} else {
			a.remove(img);
		}
	}
	if( theLayer.bFadeIn ) {
		theLayer.fadeTimer.start();
	}
}
	
NCSJSViewLayer.prototype._Delete = function() {
	if( this.bFadeIn ) {
		this.fadeTimer.stop();
	}
	this.NCSJSViewDiv.parentNode.removeChild(this.NCSJSViewDiv);
}

NCSJSViewLayer.prototype._Post = function(sURL, sBody, sAction) {
	// If the request URL is on a different domain, send the request through the proxy.
	if (this.theView.bHaveProxy && !_NCSJSView_IsLocalURL(sURL))
		sURL = this._GetProxyURL(sURL);
	return(this.AJAX.Post(sURL, sBody, sAction));
}
NCSJSViewLayer.prototype._GetXML = function(sURL, sBody, sAction) {
	// If the request URL is on a different domain, send the request through the proxy.
	if (this.theView.bHaveProxy && !_NCSJSView_IsLocalURL(sURL))
		sURL = this._GetProxyURL(sURL);
	return(this.AJAX.GetXML(sURL, sBody, sAction));
}
NCSJSViewLayer.prototype._Get = function(sURL, sBody, sAction) {
	// If the request URL is on a different domain, send the request through the proxy.
	if (this.theView.bHaveProxy && !_NCSJSView_IsLocalURL(sURL))
		sURL = this._GetProxyURL(sURL);
	return(this.AJAX.Get(sURL, sBody, sAction));
}
NCSJSViewLayer.prototype._PostEx = function(sURL, sBody, sAction, initFunc, bAsync) {
	// If the request URL is on a different domain, send the request through the proxy.
	if (this.theView.bHaveProxy && !_NCSJSView_IsLocalURL(sURL))
		sURL = this._GetProxyURL(sURL);
	return(this.AJAX.PostEx(sURL, sBody, sAction, initFunc, this, bAsync));
}

NCSJSViewLayer.prototype._GetProxyURL = function(sURL)
{
	return((this.theView.bSSLProxy ? "https://" : "http://") + document.location.host + "/ecwp/jsviewproxy.dll?xCMD=GISOverlay&xURL=" + encodeURIComponent(sURL));
}

NCSJSViewLayer.prototype._Cancel = function() {
	this.AJAX.Cancel();
}

NCSJSViewLayer.prototype._GetLayerSourceCoordSys = function() {
	return(false);
}

NCSJSViewLayer.prototype._GetTopLeftWorldCoordinateX = function() {
	return(Number.NaN);
}

NCSJSViewLayer.prototype._GetTopLeftWorldCoordinateY = function() {
	return(Number.NaN);
}

NCSJSViewLayer.prototype._GetBottomRightWorldCoordinateX = function() {
	return(Number.NaN);
}

NCSJSViewLayer.prototype._GetBottomRightWorldCoordinateY = function() {
	return(Number.NaN);
}

NCSJSViewLayer.prototype._GetRGB = function(dX, dY) {
	return("");
}

NCSJSViewLayer.prototype._GetTransparency = function(sColors) {
	for(i = 0; i < this.TransparentColors.length; i++) {
		if(this.TransparentColors[i][0].toLowerCase() == sColors) {
			return(this.TransparentColors[i][1]);
		}
	}
	return(Number.NaN);
}

NCSJSViewLayer.prototype._SetTransparency = function(sColor, dTransparentPercent) {
	if (sColor == "")
		return;
		
	sColor = sColor.toLowerCase();
	if(sColor == "#") {
		var dTransparency = this._GetTransparency("#");
		
		// Disable multilevel support if using transparency
		if(dTransparentPercent > 0.0) {
			this.bEnableMultiLevel = false;
		} else {
			this.bEnableMultiLevel = this.bMultiLevel;
		}
		
		if(!isNaN(dTransparency) && (dTransparency == 1.0) &&
			(dTransparentPercent < 1.0))
		{
			this._Draw(false);
		}
		
		for(var l = 0; l < this.aLevels.length; l++) {
			var aImages = this.aLevels[l].aImages;
			for(var i = 0; i < aImages.length; i++) {
				aImages[i].setTransparency(dTransparentPercent);
			}
		}
	}
	
	var bGotColor = false;
	for(var i = 0; i < this.TransparentColors.length; i++) {
		if(this.TransparentColors[i][0] == sColor) {
			this.TransparentColors[i][1] = dTransparentPercent;
			bGotColor = true;
			break;
		}
	}
	if(!bGotColor) {
		this.TransparentColors[this.TransparentColors.length] =
			new Array(sColor, dTransparentPercent);
	}
}

NCSJSViewLayer.prototype._SetDivRect = function(bZoom, nLeft, nTop, nWidth, nHeight, bChangeFalseOrigin) {
	if(bZoom || bChangeFalseOrigin) {
		this.nLastDivX = Number.NaN;
		this.nLastDivY = Number.NaN;	
		this.nLastDivWidth = Number.NaN;
		this.nLastDivHeight = Number.NaN;	
	}
	nLeft = Math.floor(nLeft);
	nTop = Math.floor(nTop);
	if(this.nLastDivX != nLeft) {
		this.nLastDivX = nLeft;
		this.NCSJSViewDiv.style.left = nLeft + "px";
	}
	if(this.nLastDivY != nTop) {
		this.nLastDivY = nTop;
		this.NCSJSViewDiv.style.top = nTop + "px";
	}
	if(this.nLastDivWidth != nWidth) {
	    if(nWidth < 0) {   nWidth = 0;   } //[05]
		this.nLastDivWidth = nWidth;
		this.NCSJSViewDiv.style.width = nWidth;
	}
	if(this.nLastDivHeight != nHeight) {
	    if(nHeight < 0) {  nHeight = 0;  } //[05]
		this.nLastDivHeight = nHeight;
		this.NCSJSViewDiv.style.height = nHeight;
	}
	if(this.bClip) {
		this.NCSJSViewDiv.style.clip = "rect(" + (this.nClipTLY - nTop) + "px " + (this.nClipBRX - nLeft) + "px " + (this.nClipBRY - nTop) + "px " + (this.nClipTLX - nLeft) + "px)";
	}
}

NCSJSViewLayer.prototype._GetLevel = function()
{
	var theView = this.theView;
	var dWorldPerPixelX = theView.dWorldPerPixelX;
	var l;
	var aLevels = this.aLevels;
	var nLevels = aLevels.length;
	
	for(l = 0; l < nLevels - 1; l++) {
		if(dWorldPerPixelX * this.nTileSize < aLevels[l + 1].dWorldPerTileX) {
			break;
		}
	}
	return(aLevels[l]);
}

//[01]
NCSJSViewLayer.prototype.CalcFalseOrigin = function(dCoord, nFalseOrigin, bIsX)
{
	if(nFalseOrigin == 0) {
	    while((dCoord - nFalseOrigin) > 997999){
	        nFalseOrigin += 997999;
	    }
	    this.bChangeFalseOrigin = true;
	} else {
	    if((dCoord - nFalseOrigin) > 997999){
	        while((dCoord - nFalseOrigin) > 997999){
	            nFalseOrigin += 997999;
	        }
   	        this.bChangeFalseOrigin = true;
	    } else {
            if((dCoord - nFalseOrigin) < 0){
	            while((dCoord - nFalseOrigin) < 0){
    	            nFalseOrigin -= 997999;
	            }
   	            this.bChangeFalseOrigin = true;
   	        }
	    }	            
	}
	if(this.bChangeFalseOrigin){
	    if(bIsX){
		    this.nFalseOriginX = nFalseOrigin;	
	    } else {
		    this.nFalseOriginY = nFalseOrigin;
	    }
	}
	return this.bChangeFalseOrigin;
}

NCSJSViewLayer.prototype._Draw = function(bClear, bZoom)
{
	//var t1 = NCSGetTimeStampMs();
	var i;
	var theView = this.theView;
	var dTLX = this._GetTopLeftWorldCoordinateX();
	var dTLY = this._GetTopLeftWorldCoordinateY();
	var dPixelPerWorldX = 1.0 / theView.dWorldPerPixelX;
	var dPixelPerWorldY = 1.0 / theView.dWorldPerPixelY;
	var dViewTLX = theView.dViewTLX;
	var dViewTLY = theView.dViewTLY;
    var theLevel = this._GetLevel();
	var nThisLevel = theLevel.level;
	var aLevels = this.aLevels;
	var nLevels = aLevels.length;
	var dX = (dViewTLX - dTLX) * dPixelPerWorldX;
	var dY = (dViewTLY - dTLY) * dPixelPerWorldY;
	
	//[01]
	if(this.bUseFalseOrigin){
	    if(dX > 997999){
	       this.CalcFalseOrigin(dX, this.nFalseOriginX, true);
	       dX -= this.nFalseOriginX;
	    } else {
	        if(this.nFalseOriginX >= 997999){
	            this.nFalseOriginX = 0;
	            this.bChangeFalseOrigin = true;
	        }
	    }
	    if(dY > 997999){
	       this.CalcFalseOrigin(dY, this.nFalseOriginY, false);
	       dY -= this.nFalseOriginY;
	    } else {
	        if(this.nFalseOriginY >= 997999){
	            this.nFalseOriginY = 0;
	            this.bChangeFalseOrigin = true;
	        }
	    }
	}
    	
	this._SetDivRect(bZoom, -dX, -dY,
					  dX + theView.GetViewWidth(), 
					  dY + theView.GetViewHeight(),
					  this.bChangeFalseOrigin
					  );

	if(bClear) {
		this._Clear();
	}
	// Purge all tiles outside area
	var tmpX0 = aLevels[0]._GetTileStartX();
	var tmpX1 = aLevels[0]._GetTileEndX();
	var tmpY0 = aLevels[0]._GetTileStartY();
	var tmpY1 = aLevels[0]._GetTileEndY();
	
	if(bZoom || this.nLastTileX0 != tmpX0 || this.nLastTileY0 != tmpY0 || this.nLastTileX1 != tmpX1 || this.nLastTileY1 != tmpY1) {
		this.nLastTileX0 = tmpX0;
		this.nLastTileY0 = tmpY0;
		this.nLastTileX1 = tmpX1;
		this.nLastTileY1 = tmpY1;

		var l;
		for(l = 0; l < nLevels; l++) {
			var lev = aLevels[l];
			if(!this.bEnableMultiLevel && l != nThisLevel) {
				lev._PurgeTiles(-1,-1,-1,-1, false);
			} else {
				lev._PurgeTiles(tmpX0, tmpY0, tmpX1, tmpY1, true);
			}
			if(this.bAutoCreateLevelTiles) {
			    if((!this.bEnableMultiLevel && l == nThisLevel) || (this.bEnableMultiLevel && l >= nThisLevel)) {
				    var y;
				    // Create all tiles for current level
				    for(y = tmpY0; y <= tmpY1; y++) {
					    var x;
					    for(x = tmpX0; x <= tmpX1; x++) {
						    var img = lev._FindTile(x, y);
						    if(img == null && l == nThisLevel) {
							    img = lev._CreateTile(x, y, this.nFalseOriginX, this.nFalseOriginY);
						    }
						    if(img) {
							    img.clearTransparency();
			        		    if(l == nThisLevel) {
    							    img.style.borderColor = "yellow";
							    } else {
								    img.style.borderColor = "blue";
							    }

							    var bDone = img.getAttribute("NCSJSViewxpercent") == 100;
							    if(l == nThisLevel) {
								    if(!bDone) {
            						    img.doRequest();
    							    } else {
    								    lev._PurgeRecurseUp(img.xNCSJSViewX, img.xNCSJSViewY);
    							    }
							    } else {
								    if(!bDone && l < nLevels - 1) {
									    img.cancelRequest();
								    }
							    }
						    }
					    }
				    }
			    } else {
				    var i;
				    var aImages = lev.aImages;
				    var len = aImages.length;
				    for(i = 0; i < len; i++) {
					    var img = aImages[i];
					    img.clearTransparency();
					    if(img.getAttribute("NCSJSViewxpercent") != 100) {
						    img.cancelRequest();
					    }
				    }
			    }
			}
			tmpX0 = Math.floor(tmpX0 / 2);
			tmpY0 = Math.floor(tmpY0 / 2);
			tmpX1 = Math.floor(tmpX1 / 2);
			tmpY1 = Math.floor(tmpY1 / 2);
		}
		for(l = nLevels - 1; l > nThisLevel; l--) {
			var lev = aLevels[l];
			var y;
			var levDown = aLevels[l-1];
			for(y = tmpY0; y <= tmpY1; y++) {
				var x;
				for(x = tmpX0; x <= tmpX1; x++) {
					var img = lev._FindTile(x, y);
					if(img) {
						var i00 = levDown._FindTile(x*2, y*2);
						var i10 = levDown._FindTile(x*2+1, y*2);
						var i01 = levDown._FindTile(x*2, y*2+1);
						var i11 = levDown._FindTile(x*2+1, y*2+1);
						if(i00 != null && i00.isComplete() && 
						   i10 != null && i10.isComplete() && 
						   i01 != null && i01.isComplete() && 
						   i11 != null && i11.isComplete()) {
							lev._DeleteTile(img, false);
						}
					}		
				}
			}
		}
		if(bZoom) {
			this.nLastTileX0 = -1;
			this.nLastTileY0 = -1;
			this.nLastTileX1 = -1;
			this.nLastTileY1 = -1;
			
			var dTLX = this._GetTopLeftWorldCoordinateX();
			var dTLY = this._GetTopLeftWorldCoordinateY();
			for(l = 0; l < nLevels; l++) {
				var theLevel = aLevels[l];
				var aImages = theLevel.aImages;
				var nImages = aImages.length;
				for(i = 0; i < nImages; i++) {
					aImages[i].draw(dTLX, dTLY, dPixelPerWorldX, dPixelPerWorldY, this.nFalseOriginX, this.nFalseOriginY);
				}
			}
		}
	}
}

NCSJSViewLayer.prototype._Dump = function() { }

// Delete all images in layer
NCSJSViewLayer.prototype._Clear = function()
{
	this.nLastTileX0 = -1;
	this.nLastTileY0 = -1;
	this.nLastTileX1 = -1;
	this.nLastTileY1 = -1;

	if(this.aLevels != null) {
		var nLevels = this.aLevels.length;
		for(l = 0; l < nLevels - 1; l++) {
			if(this.aLevels[l].aImages != null) {
				while(this.aLevels[l].aImages.length) {
					this.aLevels[l]._DeleteTile(this.aLevels[l].aImages[this.aLevels[l].aImages.length-1], true);
				}
			}
		}
	}
}

NCSJSViewLayer.prototype._isVisible = function()
{
	var dTransparency = this._GetTransparency("#");	
	if(this.NCSJSViewDiv.style.visibility != "hidden" && (isNaN(dTransparency) || (!isNaN(dTransparency) && dTransparency != 1.0))) {
		return(true);
	}
	return(false);
}

NCSJSViewLayer.prototype._GetPercentComplete = function() {
	var nPercent = 100;
	try {
		var theLevel = this._GetLevel();
		var i;
		var aImages = theLevel.aImages;
		var nImages = aImages.length;
		var nTotal = 0;
	
		for(i = 0; i < nImages; i++) {
			var nQuality = aImages[i].getAttribute("NCSJSViewxpercent");
			if(nQuality != null) {
				nTotal += parseInt(nQuality);
			}
		}
		if(nImages != 0) {
			nPercent = Math.min(100, Math.ceil(nTotal / Math.max(1, nImages)));
		}
	} catch(ex) {
        //alert("Exception in _GetPercentComplete");
		// FIXME: This should not happen but it does.  So needs fixing
		// The exception is being caused by this._GetLevel() returning null. Firefox\Mozilla only.
	}
	return(nPercent);
}

NCSJSViewLayer.prototype._Dump = function() {
	var aImages = this.NCSJSViewDiv.getElementsByTagName("img");
	if(aImages) {
		var i;
		for(i = 0; i < aImages.length; i++) {
			this.theView._Debug("Tile: " + aImages[i].xNCSJSViewX + "," + aImages[i].xNCSJSViewY + ":" + aImages[i].src);
		}
	}
}

NCSJSViewLayer.prototype._SetParameter = function(pvPair) {
	var sParam = pvPair[0];
	var sValue = pvPair[1];
	switch(sParam) {
		case "url": 
				if(this.theView.Layers == null || (this.theView.Layers != null && this.theView.Layers.length == 1)) {
					this.theView.bHaveInitExtents = false;
				}
				this.sURL = sValue;
				return(true); 
			break;
		case "headers":
				this.sHeaders = encodeURI(sValue);
			break;
		case "visibility": 
				return(this.theView.SetLayerVisible(this.sLayerName, (sValue.toLowerCase() == "true") ? true : false));
			break;
		case "transparency": 
				return(this.theView.SetLayerTransparency(this.sLayerName, "#", parseFloat(sValue)));
			break;
		case "brightness": 
		case "contrast": 
		case "calchistograms":
				return(false); 
			break;
		case "tilesize": 
				this.nTileSize = parseInt(sValue);
				return(true);
			break;
		case "multilevel":
				this.bMultiLevel = (sValue.toLowerCase() == "true");
				this.bEnableMultiLevel = this.bMultiLevel;
				return(true);
			break;
		case "fadein":
				this.bFadeIn = (sValue.toLowerCase() == "true");
				if( this.bFadeIn ) {
					this.fadeTimer = new NCSAJAX_Timer(1/32, this._fadeIn, this, true);
					this.fadeTimer.start();
				}
				return(true);
			break;
		case "maxrequests":
				this.nMaxCurrentRequests = parseInt(sValue);
				return(true);
			break;
		case "imagetype":
				this.sImageType = sValue;
				return(true);
			break;
		default:
			break;
	}	
	return(false);
}

NCSJSViewLayer.prototype._GetParameter = function(paramList) {
	var sParam = paramList.split("=")[0].toLowerCase();
	switch(sParam) {
		case "url": 
				return(this.sURL); 
			break;
		case "visibility": 
				return((this.NCSJSViewDiv.style.visibility.toLowerCase() == "hidden") ? "false" : "true"); 
			break;
		case "transparency": 
				return(this._GetTransparency("#")); 
			break;
		case "freecache": 
				return("true");
			break;
		case "tilesize": 
				return(""+this.nTileSize);
			break;
		case "multilevel":
				return(this.bMultiLevel);
			break;
		case "fadein":
				return(this.bFadeIn);
			break;
		case "maxrequests":
				return(this.nMaxCurrentRequests);
			break;
		case "imagetype":
				return (this.sImageType);
			break;
		default:
			break;
	}
	return("");
}

NCSJSViewLayer.prototype._GetTileSizeX = function()
{
	return this.nTileSize;
}

NCSJSViewLayer.prototype._GetTileSizeY = function()
{
	return this.nTileSize;
}

//
// CLASS NCSJSViewEcwLayer
//
// NCSJSView ECW Layer class
//
function NCSJSViewEcwLayer(theView, nLayerID, layerName)
{
	var _super = new NCSJSViewLayer(theView, nLayerID, layerName);
	_NCSJSView_Extends(this, _super);
	this.getSuper = function() { return(_super); };
	this.sLayerType = "ecw";
	this.bInit = false;
	this.bUseImageXIndexing = true;
	this.bProgressive = false;
	this.nNonProgressiveQuality = 60;
	this.sType = "ecw";
	this.sImageType = "jpg";
	this.sImageXPath = "/ecwp/ImageX.dll";
	this.sSrcCS = "";
	this.bIsCompatibleWithCS = true;
	this.aServerAliases = new Array();
}

NCSJSViewEcwLayer.prototype._GetDSInfo = function() {
	var sCoordSys = "";
	
	if (this.theView.sTargetCoordSys != "") {
		sCoordSys = "&srs=" + this.theView.sTargetCoordSys;
	}
	if(this.sProtocol.toLowerCase() == "ecwps:" || this.sProtocol.toLowerCase() == "https:") {
		return("https://" + this.sServer + this.sImageXPath + "?dsinfo?layers=" + this.sRelPath + sCoordSys);
	} else {
		return("http://" + this.sServer + this.sImageXPath + "?dsinfo?layers=" + this.sRelPath + sCoordSys);
	}
}

NCSJSViewEcwLayer.prototype._GetSrc = function(nSizeX, nSizeY, dWorldTLX, dWorldTLY, dWorldBRX, dWorldBRY, level, tx, ty) {
	var sSrc = "";
	
	var sServer = this.sImgServer;
	var aServerAliases = this.aServerAliases;
	if (aServerAliases.length)
	{		
		var nIndex = (tx + ty * this.aLevels[level].nTilesWide) % aServerAliases.length;
		sServer = aServerAliases[nIndex];
	}		
	
	if(this.sProtocol.toLowerCase() == "ecwps:" || this.sProtocol.toLowerCase() == "https:") {
		sSrc = "https://" + sServer + this.sImageXPath + "?image?";
	} else {
		sSrc ="http://" + sServer + this.sImageXPath + "?image?";
	}
	sSrc += "cache=true&transparent=true&type=" + this.sImageType;

	if(this.bUseImageXIndexing) {
		sSrc += "&l=" + level + "&tx=" + tx + "&ty=" + ty + "&ts=" + this.nTileSize;
	} else {
		sSrc += "&sizex=" + nSizeX + "&sizey=" + nSizeY;
		sSrc += "&worldtlx=" + dWorldTLX;
		sSrc += "&worldbrx=" + dWorldBRX;
		sSrc += "&worldtly=" + dWorldTLY;
		sSrc += "&worldbry=" + dWorldBRY;
	}
	sSrc += "&fill=" + this.theView.sBGColor.replace("#","");
	if( this.sBandList != null ) {
		sSrc += "&bands=" + this.sBandList;
	}
	if(this.bProgressive) {
		sSrc += "&quality=25";
	} else {
		sSrc += "&quality=" + this.nNonProgressiveQuality;
	}
	sSrc += "&layers=" + this.sRelPath;

	if (this.theView.sTargetCoordSys != "") {
		sSrc += "&srs=" + this.theView.sTargetCoordSys;
	}
	
	return(sSrc);
}

NCSJSViewEcwLayer.prototype._SetSrcQuality = function(sSrc, nQuality) {
	var urlParts = sSrc.split("&quality=");
	return(urlParts[0] + "&quality=" + nQuality);
}

NCSJSViewEcwLayer.prototype._Open = function(bSuppressDraw) {
	if(this.sURL.length > 0) {
		var aParts = this.sURL.split("//", 2);
		this.sProtocol = aParts[0];
		this.sServer = aParts[1].split("/", 2)[0];
		this.sImgServer = this.sServer;
		this.sRelPath = aParts[1].substr(this.sServer.length);

		var dom = this._GetXML(this._GetDSInfo(), null, "GET");

		if(dom != null) {
			return(this._Init(dom, bSuppressDraw) > 0);
		}
		return(false);
	}
	return(false);
}

NCSJSViewEcwLayer.prototype._Init = function(xmlDoc, bSuppressDraw) {
 	var ecwFile = xmlDoc.getElementFromTagName("DSINFO");
	var ecwCS = xmlDoc.getElementFromTagName("COORDSPACE");
 	var ecwReg = xmlDoc.getElementFromTagName("BBOX");
	var ecwError = xmlDoc.getElementFromTagName("Error");

	if(ecwFile && ecwCS && ecwReg) {
		this.sDatum = ecwCS.getAttribute("datum");
		this.sProjection = ecwCS.getAttribute("projection");
		this.sUnits = ecwCS.getAttribute("units");
		this.sEPSG = ecwCS.getAttribute("epsg");
        
		if (!this.sEPSG) {
			this.sEPSG = "RAW";
		}
		if (this.theView.sTargetCoordSys == "") {
			this.theView.sTargetCoordSys = "EPSG:" + this.sEPSG;
		}
		
		this.nImageWidth = parseInt(ecwFile.getAttribute("width"));
		this.nImageHeight = parseInt(ecwFile.getAttribute("height"));
        
        var nTileSize = parseInt(ecwFile.getAttribute("tilesize"));
        
        if (!isNaN(nTileSize))
        {
            this.nTileSize = nTileSize;
        }
        
		var colorspace = ecwFile.getAttribute("colorspace");
		if( colorspace == "Greyscale" ) {
			this.nImageBands = 1;
		} else {
			this.nImageBands = 3;
		}
		//this.nImageBands = parseInt(ecwFile.getAttribute("numbands"));
		if(this.nImageBands >= 3) {
			this.sBandList = null;//"0,1,2";
		} else {
			this.sBandList = null;//"0";
		}
		
		//if( ecwCS.getAttribute("type") == "RAW" ) {
		this.dImageTLX = parseFloat(ecwReg.getAttribute("tlX"));
		this.dImageTLY = parseFloat(ecwReg.getAttribute("tlY"));
		this.dImageCellSizeX = parseFloat(ecwReg.getAttribute("cellsizeX"));
		this.dImageCellSizeY = parseFloat(ecwReg.getAttribute("cellsizeY"));
		this.dRotation = 0.0;//parseFloat(ecwReg.getAttribute("rotation"));
		this.bInit = true;

		var nSize = Math.min(this.nImageWidth, this.nImageHeight);
		this._Clear();
		while(this.NCSJSViewDiv.firstChild) {
			this.NCSJSViewDiv.removeChild(this.NCSJSViewDiv.firstChild);
		}
		this.aLevels.length = 0;
		if(nSize <= this.nTileSize) {
		    this.aLevels.push(new NCSJSViewLayerLevel(this, this.aLevels.length));
		} else {
		    while(nSize > this.nTileSize) {
			    this.aLevels.push(new NCSJSViewLayerLevel(this, this.aLevels.length));
			    nSize /= 2;
		    }
		}
		if(this.theView.bHaveInitExtents == false) {
			// First layer, setup extents
			var dWorldTLX = this._GetTopLeftWorldCoordinateX();
			var dWorldTLY = this._GetTopLeftWorldCoordinateY();
			var dWorldBRX = this._GetBottomRightWorldCoordinateX();
			var dWorldBRY = this._GetBottomRightWorldCoordinateY();

			this.theView.SetExtents(dWorldTLX, 
									dWorldTLY, 
									dWorldBRX,
									dWorldBRY);
			this.theView.bHaveInitExtents = true;
		} else {
			if (!bSuppressDraw)
				this.theView.Draw(false);
		}
		
		if (!this.bIsCompatibleWithCS) {
			this.theView.FireOnError(this.sLayerName, 0, "NCS_SUCCESS", "");
			this.theView.SetLayerVisible(this.sLayerName, true);
			this.bIsCompatibleWithCS = true;
		}
		return(1);
	} else if(ecwError != null) {
		var sErrorCode = ecwError.getAttribute("code");
		if(sErrorCode == "CoordinateError" || sErrorCode == "InvalidRequest") {
			if (this.theView.Layers.length > 0) {
				this.theView.FireOnError(this.sLayerName, 67, "INCOMPATIBLE_COORDINATE_SYSTEMS", ecwError.getText());
				this.theView.SetLayerVisible(this.sLayerName, false);
				this.bIsCompatibleWithCS = false;
			}
			return(-1);
		} else {
			this.theView.sErrorMsg = ecwError.getText();// + " \"" + this.sURL + "\"";
			return(-1);
		}
	} else {
		this.theView.sErrorMsg = "Failed to open " + "\"" + this.sURL + "\"";;
	}
	return(0);
}

NCSJSViewEcwLayer.prototype._GetLayerSourceCoordSys = function() {
	if (this.sSrcCS) {
		return("EPSG:" + this.sSrcCS);
	}
	var sDSInfoURL;
	
	if(this.sProtocol.toLowerCase() == "ecwps:" || this.sProtocol.toLowerCase() == "https:") {
		sDSInfoURL = "https://" + this.sServer + this.sImageXPath + "?dsinfo?layers=" + this.sRelPath;
	} else {
		sDSInfoURL = "http://" + this.sServer + this.sImageXPath + "?dsinfo?layers=" + this.sRelPath;
	}
	
	var dom = this._GetXML(sDSInfoURL, null, "GET");

	if(dom != null) {
		var ecwFile = dom.getElementFromTagName("DSINFO");
		var ecwCS = dom.getElementFromTagName("COORDSPACE");
		if(ecwFile && ecwCS) {
			this.sSrcCS = ecwCS.getAttribute("epsg");
			if (!this.sSrcCS) this.sSrcCS = "RAW";
		}
	}
	if (this.sSrcCS != "") {
		return("EPSG:" + this.sSrcCS);
	} else {
		return("EPSG:" + this.sEPSG);
	}	
}

NCSJSViewEcwLayer.prototype._GetTopLeftWorldCoordinateX = function() {
	return(this.dImageTLX);
}

NCSJSViewEcwLayer.prototype._GetTopLeftWorldCoordinateY = function() {
	return(this.dImageTLY);
}

NCSJSViewEcwLayer.prototype._GetBottomRightWorldCoordinateX = function() {
	return(this.dImageTLX + this.nImageWidth * this.dImageCellSizeX);
}

NCSJSViewEcwLayer.prototype._GetBottomRightWorldCoordinateY = function() {
	return(this.dImageTLY + this.nImageHeight * this.dImageCellSizeY);
}

NCSJSViewEcwLayer.prototype._Draw = function(bClear, bZoom)
{
	if(!this.bInit) {
		return;
	}
	_NCSJSView_CallSuper(this, "_Draw", arguments);
}

NCSJSViewEcwLayer.prototype._GetCellSizeX = function() {
	return(this.dImageCellSizeX);	
}

NCSJSViewEcwLayer.prototype._GetCellSizeY = function() {
	return(this.dImageCellSizeY);	
}

NCSJSViewEcwLayer.prototype._GetImageSizeX = function() {
	return(this.nImageWidth);	
}

NCSJSViewEcwLayer.prototype._GetImageSizeY = function() {
	return(this.nImageHeight);	
}

NCSJSViewEcwLayer.prototype._GetCellUnits = function() {
	switch(this.sUnits.toLowerCase()) {
		default: return(0); break;
		case "meters": return(1); break;
		case "degrees": return(2); break;
		case "decimal degrees": return(2); break;
		case "feet": return(3); break;
	}
	return(0);
}

NCSJSViewEcwLayer.prototype._SetParameter = function(pvPair) {
	var sParam = pvPair[0];
	var sValue = pvPair[1];
	switch(sParam) {
		case "bands": 
				this.sBandList = sValue;
				this._Draw(true, false);
				return(true);
			break;
		case "brightness": 
		case "contrast": 
		case "calchistograms":
				return(false); 
			break;
		case "progressive": 
				this.bProgressive = (sValue.toLowerCase() == "true" || sValue != "0") ? true : false;
			break;
		case "freecache":
				return(true);
			break;
		case "useimagexindexing":
				this.bUseImageXIndexing = (sValue.toLowerCase() == "true" || sValue != "0") ? true : false;
				return(this.bUseImageXIndexing);
			break;
		case "imagexpath":
		        this.sImageXPath = sValue;
		    break;
		case "serveraliases": 
			this.aServerAliases = sValue.split("|");
			break;		    
		default:
				if(sParam.indexOf("lut") == 0) {
					return(false);
				}
				_NCSJSView_CallSuper(this, "_SetParameter", arguments);
				return(true);
			break;
	}	
	return(false);
}

NCSJSViewEcwLayer.prototype._GetParameter = function(paramList) {
	var sParam = paramList.split("=")[0].toLowerCase();
	switch(sParam) {
		case "bands": 
				return(this.sBandList); 
			break;
		case "numbands": 
				return("" + this.nImageBands); 
			break;
		case "brightness": 
		case "contrast":
				return("1.0"); 
			break;
		case "calchistograms": 
				return(false); 
			break;
		case "progressive": 
				return("" + this.bProgressive);
			break;
		case "freecache": 
				return("true");
			break;
		case "useimagexindexing":
				return(""+this.bUseImageXIndexing);
			break;
		case "epsg":
		        if (!this.sEPSG || this.sEPSG == "")
				    return("none");
				else
				    return(this.sEPSG);
		    break;
		case "imagexpath":
		    return this.sImageXPath;
		    break;
		default:
				if(sParam.indexOf("histogram") == 0) {
					return(null);
				}
				return(_NCSJSView_CallSuper(this, "_GetParameter", arguments));
			break;
	}
	return("");
}

NCSJSViewEcwLayer.prototype._GetRGB = function(dX, dY) {
	if(this.theView.bHaveProxy) {
		var nLevel = this.aLevels.length - 1;//Use last level for rgb calculations
		var theLevel = this.aLevels[nLevel];

		var dTileX = (dX - this._GetTopLeftWorldCoordinateX())/theLevel.dWorldPerTileX;
		
		if(this.theView.bYInv)
			var dTileY = (dY - this._GetTopLeftWorldCoordinateY())/theLevel.dWorldPerTileY;
		else 
			var dTileY = (this._GetTopLeftWorldCoordinateY() - dY)/theLevel.dWorldPerTileY;

		if (dTileX < 0 || dTileX >= this._TotalTilesAtLevelX(theLevel) ||
			dTileY < 0 || dTileY >= this._TotalTilesAtLevelY(theLevel))
			return "";

		var nTileX = Math.floor(dTileX);
		var nTileY = Math.floor(dTileY);

		var nTilePixelX = Math.floor((dTileX - nTileX) * this.nTileSize);
		var nTilePixelY = Math.floor((dTileY - nTileY) * this.nTileSize);

		var sImageXURL = ""
		if(this.sProtocol.toLowerCase() == "ecwps:") {
			sImageXURL = "https://" + this.sImgServer + this.sImageXPath + "?image?";
		} else {
			sImageXURL ="http://" + this.sImgServer + this.sImageXPath + "?image?";
		}
		sImageXURL += "cache=true&type=png";//Use png to ensure RGB values are accurate.
		sImageXURL += "&l=" + nLevel + "&tx=" + nTileX + "&ty=" + nTileY + "&ts=" + this.nTileSize;
		
		if (this.sBandList != null)
			sImageXURL += "&bands=" + this.sBandList;

		if (this.bProgressive)
			sImageXURL += "&quality=25";
		else
			sImageXURL += "&quality=" + this.nNonProgressiveQuality;

		sImageXURL += "&layers=" + this.sRelPath;

		if (this.theView.sTargetCoordSys != "") {
			sImageXURL += "&srs=" + this.theView.sTargetCoordSys;
		}
		
		this.theView._SetWaitCursor();
		var AJAX = new NCSAJAX();
		var dom = AJAX.GetXML((this.theView.bSSLProxy ? "https://" : "http://") + document.location.host + "/ecwp/jsviewproxy.dll?xCMD=GetRGB&X=" + nTilePixelX + "&Y=" + nTilePixelY + "&xURL=" + encodeURIComponent(sImageXURL), null, "GET");
		this.theView._SetCursor(false);
		if(dom != null) {
			return(dom.getElementText("GetRGB"));
		}
	}	
	return("");
}

NCSJSViewEcwLayer.prototype._TotalTilesAtLevelX = function(LevelObj)
{
	return this.nImageWidth * this.dImageCellSizeX / LevelObj.dWorldPerTileX
}

NCSJSViewEcwLayer.prototype._TotalTilesAtLevelY = function(LevelObj)
{
	return this.nImageHeight * this.dImageCellSizeY / LevelObj.dWorldPerTileY
}

//
// CLASS NCSJSViewGISOverlayLayer
//
// NCSJSView GISOverlay Layer class
//

function NCSJSViewGISOverlayLayer(theView, nLayerID, layerName)
{
	var _super = new NCSJSViewLayer(theView, nLayerID, layerName)
	_NCSJSView_Extends(this, _super);
	this.getSuper = function() { return(_super); };
	this.dWorldTLX=0.0;
	this.dWorldTLY=0.0;
	this.dWorldBRX=0.0;
	this.dWorldBRY=0.0;
	this.bInit = false;
	this.bAutoCreateLevelTiles = false;
	this.sType = "GISOverlay";
	this.sImageSrc = "";
	this.aLevels.push(new NCSJSViewLayerLevel(this, this.aLevels.length));
}

NCSJSViewGISOverlayLayer.prototype._GetSrc = function() {	
	var sURL = (this.theView.bSSLProxy ? "https://" : "http://") + document.location.host + "/ecwp/jsviewproxy.dll?xCMD=GISOverlay";
	if(this.sHeaders) {
		sURL += "&header=" + this.sHeaders;
	}
	if(this.TransparentColors.length > 1 || (this.TransparentColors.length == 1 && this.TransparentColors[0][0] != "#")) {
		sURL += "&xTCL=";
		var i;
		for(i = 0; i < this.TransparentColors.length; i++) {
			if(this.TransparentColors[i][0] != "#") {
				sURL += this.TransparentColors[i][0].replace("#", "") + ":" + this.TransparentColors[i][1] + ";";
			}
		}
	}
	sURL += "&xURL=" + encodeURIComponent(this.sURL);
	return(sURL);
}

NCSJSViewGISOverlayLayer.prototype._OnLayerResponse = function(sResponse) {
	this.theView.FireOnLayerResponse(this.sLayerName, this.sURL, this.sBody, this.sAction, this.dNextWorldTLX, this.dNextWorldTLY, this.dNextWorldBRX, this.dNextWorldBRY, sResponse);
}

function _NCSJSViewGISOverlayLayer_OnError() {
	var theLayer = this.xNCSJSViewLayer;
	if(theLayer != null)
		theLayer._OnLayerResponse("NCS_OVERLAY_FAILURE:");
}

function _NCSJSViewGISOverlayLayer_OnLoad() {
	var theLayer = this.xNCSJSViewLayer;
	if(theLayer != null) {
		//Delete all but the last tile added.
		while( theLayer.aLevels[0].aImages.length > 1 ) {
			theLayer.aLevels[0]._DeleteTile(theLayer.aLevels[0].aImages[0], true);		
		}
		
		theLayer.dWorldTLX = theLayer.dNextWorldTLX;
		theLayer.dWorldTLY = theLayer.dNextWorldTLY;
		theLayer.dWorldBRX = theLayer.dNextWorldBRX;
		theLayer.dWorldBRY = theLayer.dNextWorldBRY;
		
		if( !isNaN( theLayer._GetTransparency("#") ) ) {
		    theLayer._SetTransparency("#", theLayer._GetTransparency("#"));
		}
		
		theLayer._Draw(true, true);
		this.style.display = "inline";
		this.style.visibility="";
		if( !theLayer.theView.bIsIE || theLayer.theView.dIEVersion > 6 ) {
			this.style.height=null;
		}

		theLayer.theView._SetCursor(false);
		theLayer._OnLayerResponse("NCS_OVERLAY_SUCCESS");
	} else {
		theLayer._OnLayerResponse("NCS_OVERLAY_FAILURE: Could not locate layer for response");	
	}
}

NCSJSViewGISOverlayLayer.prototype._PostEx = function(sURL, sBody, sAction, initFunc, bAsync, sHeaders) {
	return(this.AJAX.PostEx(sURL, sBody, sAction, initFunc, this, bAsync, sHeaders));
}

NCSJSViewGISOverlayLayer.prototype._Open = function() {
	if(this.sURL != null && this.sURL.length > 0) {
		this._Cancel();
		
		var theLayer = this;
		this.AJAX._Init = function(dom) {
			theLayer._Init(dom);
		}	
						
		this._PostEx(theLayer._GetSrc(), (theLayer.sBody ? theLayer.sBody : null), (theLayer.sAction ? theLayer.sAction : "GET"), function(dom, theLayer) {
						var sContentType = theLayer.AJAX.NCSAJAXXMLHttpRequest.getResponseHeader("Content-Type").toLowerCase();
						if (sContentType.indexOf("image") >= 0)
						{													
							//Ensure we have an image before setting img.src.
							var img = theLayer.aLevels[0]._AllocImg(theLayer.dNextWorldTLX, theLayer.dNextWorldTLY, theLayer.dNextWorldBRX, theLayer.dNextWorldBRY, theLayer.nFalseOriginX, theLayer.nFalseOriginY);
							img.onerror = _NCSJSViewGISOverlayLayer_OnError;
							img.onload = _NCSJSViewGISOverlayLayer_OnLoad;
							
							theLayer.sImageSrc = theLayer._GetSrc();
							
							// Handle PNG images for pre-IE7
							if( theLayer.theView.bIsIE && (theLayer.theView.dIEVersion < 7) ) {
								// Hack for IE - doesn't support "real" transparent PNG's, have to use a DX filter
								img.src = "/ecwplugins/lib/bitmaps/Transparent.gif";
								img.xIE6AlphaImageLoader = img.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + encodeURI(theLayer.sImageSrc) + "',sizingMethod='scale',enabled=true);";
							} else {
								img.style.filter = null;//setTransparency(0.0);
								img.src = theLayer.sImageSrc;
							}
						}
						else if (dom != null) {
							theLayer._OnLayerResponse(dom.serialize());
						} else {							
							theLayer._OnLayerResponse("NCS_OVERLAY_FAILURE:");	
						}
						return(1);
					}, true);
		
		return(true);
	}
	return(true);
}

NCSJSViewGISOverlayLayer.prototype._GetLayerSourceCoordSys = function() {
	return(false);
}

NCSJSViewGISOverlayLayer.prototype._GetTopLeftWorldCoordinateX = function() {
	return(this.dWorldTLX);
}

NCSJSViewGISOverlayLayer.prototype._GetTopLeftWorldCoordinateY = function() {
	return(this.dWorldTLY);
}

NCSJSViewGISOverlayLayer.prototype._GetBottomRightWorldCoordinateX = function() {
	return(this.dWorldBRX);
}

NCSJSViewGISOverlayLayer.prototype._GetBottomRightWorldCoordinateY = function() {
	return(this.dWorldBRY);
}

NCSJSViewGISOverlayLayer.prototype._GetPercentComplete = function() {
	return(100);
}

NCSJSViewGISOverlayLayer.prototype._isVisible = function()
{
	return(true);
}

NCSJSViewGISOverlayLayer.prototype._SetTransparency = function(sColor, dTransparency) {
	_NCSJSView_CallSuper(this, "_SetTransparency", arguments);
	var bWholeLayerTransparency = false;
	for (var i=0; i<this.TransparentColors.length; i++) {
		if (this.TransparentColors[i][0] == "#") {
			bWholeLayerTransparency = true;
			break;
		}
	}
	
	if(!bWholeLayerTransparency) {
	    dTransparency = 0.0;
	}
	
    var j;
    for(j = 0; j < this.aLevels[0].aImages.length; j++) {
	    this.aLevels[0].aImages[j].setTransparency(dTransparency);
    }

	this.theView._SetWaitCursor();
	
	if( sColor != "#" ) {
		// Reload
		this._Open();
	}
}

NCSJSViewGISOverlayLayer.prototype._SetParameter = function(pvPair) {
	var sParam = pvPair[0];
	var sValue = pvPair[1];
	switch(sParam) {
		case "body":
				this.sBody = sValue;
			break;
		case "action":
				this.sAction = sValue;
			break;
		case "worldtlx":
				this.dNextWorldTLX = parseFloat(sValue);
				if(isNaN(this.dWorldTLX)) {
					this.dWorldTLX = this.dNextWorldTLX;
				}
			break; 
		case "worldtly":
				this.dNextWorldTLY = parseFloat(sValue);
				if(isNaN(this.dWorldTLY)) {
					this.dWorldTLY = this.dNextWorldTLY;
				}
			break; 
		case "worldbrx":
				this.dNextWorldBRX = parseFloat(sValue);
				if(isNaN(this.dWorldBRX)) {
					this.dWorldBRX = this.dNextWorldBRX;
				}
			break; 
		case "worldbry":
				this.dNextWorldBRY = parseFloat(sValue);
				if(isNaN(this.dWorldBRY)) {
					this.dWorldBRY = this.dNextWorldBRY;
				}
			break; 
		default:
				_NCSJSView_CallSuper(this, "_SetParameter", arguments);
				return(true);
			break;
	}	
	return(false);
}

NCSJSViewGISOverlayLayer.prototype._GetParameter = function(paramList) {
	var sParam = paramList.split("=")[0].toLowerCase();
	switch(sParam) {
		case "body":
				return(this.sBody);
			break;
		case "action":
				return(this.sAction);
			break;
		case "worldtlx":
				return(this.dNextWorldTLX);
			break; 
		case "worldtly":
				return(this.dNextWorldTLY);
			break; 
		case "worldbrx":
				return(this.dNextWorldBRX);
			break; 
		case "worldbry":
				return(this.dNextWorldBRY);
			break; 
		default:
				if(sParam.indexOf("histogram") == 0) {
					return(null); 
				}
				return(_NCSJSView_CallSuper(this, "_GetParameter", arguments));
			break;
	}
	return("");
}

NCSJSViewGISOverlayLayer.prototype._GetRGB = function(dX, dY) {
	if(this.theView.bHaveProxy && this.sImageSrc != "") {	
		var nLevel = this.aLevels.length - 1;//Use last level for rgb calculations
		var theLevel = this.aLevels[nLevel];

        // Overlays are a single tile case
        // calculate nTilePixelX, nTilePixelY from the dX, dY
        var nWidth = this._GetTileSizeX();
        var nHeight = this._GetTileSizeY();
        var dWorldPerPixelX = nWidth / ( this._GetBottomRightWorldCoordinateX() - this._GetTopLeftWorldCoordinateX() );
        var dWorldPerPixelY = nHeight/ ( this._GetTopLeftWorldCoordinateY() - this._GetBottomRightWorldCoordinateY() );

		var nPixelX = Math.floor( (dX - this._GetTopLeftWorldCoordinateX()) * dWorldPerPixelX );
		var nPixelY = Math.floor( (this._GetTopLeftWorldCoordinateY() - dY) * dWorldPerPixelY );
		
		this.theView._SetWaitCursor();
		var AJAX = new NCSAJAX();
		var dom = AJAX.GetXML((this.theView.bSSLProxy ? "https://" : "http://") + document.location.host + "/ecwp/jsviewproxy.dll?xCMD=GetRGB&X=" + nPixelX + "&Y=" + nPixelY + "&xURL=" + encodeURIComponent(this.sImageSrc), null, "GET");
		this.theView._SetCursor(false);
		if(dom != null) {
			return(dom.getElementText("GetRGB"));
		}
	}	
	return("");
}

NCSJSViewGISOverlayLayer.prototype._TotalTilesAtLevelX = function(LevelObj)
{
	return 1;
}

NCSJSViewGISOverlayLayer.prototype._TotalTilesAtLevelY = function(LevelObj)
{
	return 1;
}


NCSJSViewGISOverlayLayer.prototype._GetTileSizeX = function()
{
	return this.theView.GetViewWidth();
}

NCSJSViewGISOverlayLayer.prototype._GetTileSizeY = function()
{
	return this.theView.GetViewHeight();
}


NCSJSViewGISOverlayLayer.prototype._GetTopLeftWorldCoordinateX = function() {
	return(this.dWorldTLX);
}

NCSJSViewGISOverlayLayer.prototype._GetTopLeftWorldCoordinateY = function() {
	return(this.dWorldTLY);
}

NCSJSViewGISOverlayLayer.prototype._GetBottomRightWorldCoordinateX = function(){
	return this.dWorldBRX;
}

NCSJSViewGISOverlayLayer.prototype._GetBottomRightWorldCoordinateY = function() {
	return this.dWorldBRY;
}


//
// CLASS NCSJSView
//
// NCSJSView DHTML/JavaScript layered view "thin-client" implementation
//
_NCSJSView_LayerBuilders = new Array();

NCSJSView_RegisterLayerType = function(sType, newFunc) {
	var i = 0;
	for(i = 0; i < _NCSJSView_LayerBuilders.length; i++) {
		if(_NCSJSView_LayerBuilders[i][0] == sType.toLowerCase()) {
			break;
		}
	}
	_NCSJSView_LayerBuilders[i] = new Array(sType.toLowerCase(), newFunc);
}

	// Register the standard layer builders
NCSJSView_RegisterLayerType("ecw", function(theView, nLayerID, sName) { return(new NCSJSViewEcwLayer(theView, nLayerID, sName)); });
NCSJSView_RegisterLayerType("gisoverlay", function(theView, nLayerID, sName) { return(new NCSJSViewGISOverlayLayer(theView, nLayerID, sName)); });

function NCSJSView(sWidth, sHeight, parentNode) {
	_NCSJSViews[_NCSJSViews.length] = this;
	this.nViewID = _NCSJSViews.length;

	var sInitialHTML = "";
	sInitialHTML += "<div id=\"NCSJSViewDivResizer" + this.nViewID + "\" style=\"position:relative;left:0px;top:0px;width:" + sWidth + "; height:" + sHeight + ";overflow:hidden;background-color:transparent;\" onresize=\"return NCSJSView_OnResize(" + this.nViewID + ");\");\">";
	if((typeof(document.addEventListener) != "undefined") && (typeof(document.addEventListener) != "function")) {
		sInitialHTML += "<div id=\"NCSJSViewDivFrame" + this.nViewID + "\" style=\"position:relative;left:0px;top:0px;width:" + sWidth + "; height:" + sHeight + ";overflow:visible;background-color:transparent;\">";
	} else {
		sInitialHTML += "<div id=\"NCSJSViewDivFrame" + this.nViewID + "\" style=\"position:relative;left:0px;top:0px;width:" + sWidth + "; height:" + sHeight + ";overflow:visible;background-color:transparent;\" onclick=\"NCSJSView_OnClick(event, " + this.nViewID + ")\" oncontextmenu=\"return(false);\" onmousedown=\"return NCSJSView_OnMouseDown(event, " + this.nViewID + ");\" onmousewheel=\"return NCSJSView_OnMouseScroll(event, " + this.nViewID + ");\">";
	}
	sInitialHTML += "<div id=\"NCSJSViewDivZoom" + this.nViewID + "\" style=\"position:absolute;left:0px;top:0px;width:100px;height:100px;visibility:hidden;z-index:100;background-color:white;filter:alpha(opacity=50);-moz-opacity:.50;opacity:.50;border: 2px red solid;\">";
	if(typeof(document.addEventListener) != "undefined" && (typeof(document.addEventListener) != "function")) {
		sInitialHTML += "<div id=\"NCSJSViewDivDrag" + this.nViewID + "\" style=\"position:relative;left:0px;top:0px;width:100%;height:100%;z-index:2000;background-color:transparent;\" onclick=\"NCSJSView_OnClick(event, " + this.nViewID + ")\" oncontextmenu=\"return(false);\" onmousedown=\"return NCSJSView_OnMouseDown(event, " + this.nViewID + ");\">&nbsp;</div>";
	}
	sInitialHTML += "</div></div></div>";

	if(arguments.length > 2) {
		parentNode.innerHTML += sInitialHTML; 
	} else {                                  
		document.write(sInitialHTML);         
	}
	
	this.NCSJSViewDivResizer = document.getElementById("NCSJSViewDivResizer" + this.nViewID);
	this.NCSJSViewDivFrame = document.getElementById("NCSJSViewDivFrame" + this.nViewID);
	this.NCSJSViewDivZoom = document.getElementById("NCSJSViewDivZoom" + this.nViewID);

	if( this.NCSJSViewDivFrame.addEventListener ) {
		this.NCSJSViewDivFrame.theView = this;
		this.NCSJSViewDivFrame.addEventListener("DOMMouseScroll", NCSJSView_OnMouseScroll, false);
	}
	
	this.Layers = new Array();
	this.AttachList = new Array();
	
	this.sWidth = sWidth;
	this.sHeight = sHeight;

	this.dViewTLX = 0.0;
	this.dViewTLY = 0.0;
	this.dViewBRX = 1.0;
	this.dViewBRY = 1.0;
	this.dWorldPerPixelX = 1.0;
	this.dWorldPerPixelY = 1.0;
	this.dZoomStep = 2.0;
	this.bStepZoom = false;
	this.bInIZoom = false;
	this.bHaveProxy = true;
	this.bSSLProxy = false;
	this.sBGColor = "ffffff";
	this.MouseMask = 0;
	this.nMouseX = 0;
	this.nMouseY = 0;
	this.nMouseStartX = 0;
	this.nMouseStartY = 0;
	this.dMouseStartWorldPerPixelX = 0.0;
	this.dMouseStartWorldPerPixelY = 0.0;
	this.PointerMode = PM_ROAM;
	this.bHaveInitExtents = false;
	this.GeolinkMode = GM_NONE;
	this.nNextLayerID = 0;
	this.bDebug = false;
	this.debugWindow = null;
	this.sErrorMsg = "No Error";
	this.dScreenAspectRatio = 1.0; //[02] = screen_pixel_width / screen_pixel_height 
	this.sTargetCoordSys = "";
	this.bPersistTargetCoordSys = false;
	
	this.bIsIE = false;
	this.bIsFF = false;
	this.dIEVersion = 5.0;
	this.dFFVersion = 1.5;
	var sUserAgent = navigator.userAgent;
	var nIndexOfMSIE = sUserAgent.indexOf("MSIE");
	var nIndexIfFF = sUserAgent.indexOf("Firefox/");
	if(nIndexOfMSIE >= 0 && sUserAgent.indexOf("Opera") < 0) {
		this.bIsIE = true;
		var nVerEnd = sUserAgent.indexOf(";", nIndexOfMSIE);
		if( nVerEnd <= nIndexOfMSIE ) nVerEnd = sUserAgent.length;
		var sVerString = sUserAgent.substring( nIndexOfMSIE+5, nVerEnd );
		this.dIEVersion = parseFloat( sVerString );
	} else if (nIndexIfFF >= 0 && sUserAgent.indexOf("Opera") < 0) {
		this.bIsFF = true;
		this.dFFVersion = parseInt(sUserAgent.substring(nIndexIfFF+8));
	}
		
	this.CallBacks = new Array(new NCSJSViewCallbacks(this, "onMouseDown", null, true),
							   new NCSJSViewCallbacks(this, "onMouseMove", null, true),
							   new NCSJSViewCallbacks(this, "onMouseUp", null, true),
							   new NCSJSViewCallbacks(this, "onExtentChange", null, true),
							   new NCSJSViewCallbacks(this, "onPointerModeChange", null, true),
							   new NCSJSViewCallbacks(this, "onGeolinkModeChange", null, true),
							   new NCSJSViewCallbacks(this, "onPercentComplete", null, true),
							   new NCSJSViewCallbacks(this, "onDrawBegin", null, true),
							   new NCSJSViewCallbacks(this, "onDrawEnd", null, true),
							   new NCSJSViewCallbacks(this, "onLoad", null, true),
							   new NCSJSViewCallbacks(this, "onLayerResponse", null, true),
							   new NCSJSViewCallbacks(this, "onError", null, true));
	
	this._SetCursor(false);
	window.setTimeout("_NCSJSView_OnLoadTrigger(" + this.nViewID + ");", 250);
	
	    // Extents change - 10x per sec
	this._FireOnExtentChangeTimer = new NCSAJAX_Timer(100, function(data) {
	        if(data && data.length == 5) {
	            var v = data[0];
	            v.onextentchange(data[1], data[2], data[3], data[4]);
                v.FireOnPercentComplete();
            }
	    }, null, true);
	    // Extents change - 5x per sec
	this._FireOnPercentCompleteTimer = new NCSAJAX_Timer(200, function(v) {
	        if(v) {
	            v.onpercentcomplete(v.GetPercentComplete());
            }
	    }, this, true);
}

NCSJSView.prototype.GetLayerSourceCoordSys = function(layerName) {
	var theLayer = this._GetLayer(layerName);
	if(theLayer != null) {
		return(theLayer._GetLayerSourceCoordSys());
	}
	return(false);
}

NCSJSView.prototype.GetTargetCoordSys = function() {
	return(this.sTargetCoordSys);
}

NCSJSView.prototype.SetTargetCoordSys = function(sCoordSys) {
	var sOldTargetCoordSys = this.sTargetCoordSys;
	var bConvertError = false;
	var aTL;
	var aBR;
	// turn off persist target coord sys
	if (sCoordSys == "") {
		this.bPersistTargetCoordSys = false;
		if (this.Layers.length == 0) {
			this.sTargetCoordSys = "";
		}
		return true;
	}
	
	if (sCoordSys.toUpperCase().indexOf("EPSG:") < 0) {
		sCoordSys = "EPSG:" + sCoordSys;
	}
	
	if (sOldTargetCoordSys == sCoordSys) {
		return true;
	}
	var sExtentsBox = this.dViewTLX + "," + this.dViewTLY + "|" + this.dViewBRX + "," + this.dViewBRY;
	var sNewExtents = this.ConvertCoordinates(sOldTargetCoordSys.substring(5), sCoordSys.substring(5), sExtentsBox);
	if (!sNewExtents) {
		bConvertError = true;
	} else {
		var aNewExtents = sNewExtents.split("|");
		if (aNewExtents.length != 2) {
			bConvertError = true;
		} else {
			var aTL = aNewExtents[0].split(",");
			var aBR = aNewExtents[1].split(",");
			if (aTL.length != 2 || aTL.length != 2) {
				bConvertError = true;
			}
		}
	}
	if (bConvertError) {
		this.FireOnError("", 67, "INCOMPATIBLE_COORDINATE_SYSTEMS", "Unable to convert from " + sOldTargetCoordSys + " to " + sCoordSys);
		return false;
	}
	
	this.sTargetCoordSys = sCoordSys;

	var bResetScale = true;
	var bAnyLayerVisible = false;
	for (var index = 0; index < this.Layers.length; index++) {
		if (this.Layers[index].sLayerType == "ecw") {
			var theLayer = this.Layers[index];
			theLayer._Open(true);
			if(bResetScale == true) {
				this.dScaleX = (theLayer._GetBottomRightWorldCoordinateX() - theLayer._GetTopLeftWorldCoordinateX()) / theLayer._GetImageSizeX();
				this.dScaleY = (theLayer._GetBottomRightWorldCoordinateY() - theLayer._GetTopLeftWorldCoordinateY()) / theLayer._GetImageSizeY();
				if(theLayer._GetBottomRightWorldCoordinateY() < theLayer._GetTopLeftWorldCoordinateY()) {
					this.bYInv = true;
				} else {
					this.bYInv = false;		
				}
				var dX = parseFloat(aBR[0]) - parseFloat(aTL[0]);
				var dY = parseFloat(aTL[1]) - parseFloat(aBR[1]);
				if(this.dScreenAspectRatio*(this.GetViewWidth() / this.GetViewHeight()) > dX / Math.abs(dY)) {
					var i = 1;
	    	        while(1){
	    	            this.dWorldPerPixelY = theLayer.dImageCellSizeY/(theLayer.GetZoomLimit() -i);
	      		        this.dWorldPerPixelX = (this.bYInv?-1:1)*this.dWorldPerPixelY * this.dScreenAspectRatio;
	    	            if(this.dWorldPerPixelX >= theLayer.dImageCellSizeX/ (theLayer.GetZoomLimit()-1)){
	        	            break;    
	    	            }
	    	            i++
	    	        }
				} else {
	    	        var i = 1;
	    	        while(1){
	                    this.dWorldPerPixelX = theLayer.dImageCellSizeX/ (theLayer.GetZoomLimit()-i);     
	                    this.dWorldPerPixelY = (this.bYInv?-1:1)*this.dWorldPerPixelX / this.dScreenAspectRatio;
	    	            if(this.dWorldPerPixelY < theLayer.dImageCellSizeY/ (theLayer.GetZoomLimit()-1)){
	        	            break;    
	    	            }
	    	            i++
	    	        }
	            }
				bResetScale = false;
			}
			if (theLayer.NCSJSViewDiv.style.visibility != "hidden") {
				bAnyLayerVisible = true;
			}
		}
	}
	if (bAnyLayerVisible) {
		this.SetExtents(parseFloat(aTL[0]), parseFloat(aTL[1]), parseFloat(aBR[0]), parseFloat(aBR[1]));
	} else {
		var sEnvelope = this._GetMaximumEnvelope(sCoordSys);
		var aEnvelope = sEnvelope.split(",");
		if (aEnvelope.length == 4) {
			if(this.bYInv) {
				this.SetExtents(parseFloat(aEnvelope[0]), parseFloat(aEnvelope[3]), parseFloat(aEnvelope[2]), parseFloat(aEnvelope[1]));
			} else {
				this.SetExtents(parseFloat(aEnvelope[0]), parseFloat(aEnvelope[1]), parseFloat(aEnvelope[2]), parseFloat(aEnvelope[3]));
			}
		} else {
			this.FireOnError("", 67, "INCOMPATIBLE_COORDINATE_SYSTEMS", "Unable to convert from " + sOldTargetCoordSys + " to " + sCoordSys);
			return false;
		}
	}
	this.bPersistTargetCoordSys = true;
	return true;
}

NCSJSView.prototype._RegisterLayerType = function(sType, newFunc) {
	NCSJSView_RegisterLayerType(sType, newFunc);
}

function _NCSJSView_NullCB() {}

NCSJSView.prototype._Debug = function(sString) {
	if(this.bDebug) {
        java.lang.System.out.println(sString);
    }
}

NCSJSView.prototype._CreateLayer = function(sType, sName) {
	var i;
	for(i = 0; i < _NCSJSView_LayerBuilders.length; i++) {
		if(_NCSJSView_LayerBuilders[i][0] == sType.toLowerCase()) {
			return(_NCSJSView_LayerBuilders[i][1](this, this.nNextLayerID++, sName));
		}
	}
	return(null);
}

NCSJSView.prototype.AddLayer = function(sLayerType, sURL, sName, paramList)
{
	if(!this.bHaveProxy && sLayerType.toUpperCase() == "GISOVERLAY") {
		this.sErrorMsg = "GISOverlay requires a server-side proxy component due to JavaScript security limitations.  Contact ERDAS for details.";
		return(-1);
	}
	if(sLayerType.toUpperCase() == "SIMPLEVECTOR") {
		this.sErrorMsg = "SIMPLEVECTOR layers are currently not supported.  Contact ERDAS for details.";
		return(-1);
	}
	var aPVPairs = this._ParseParamList(paramList);
	var theLayer = this._CreateLayer(sLayerType, sName);
	var i;
	this.Layers[this.Layers.length] = theLayer;
	theLayer._SetParameter(new Array("url", sURL));
	for(i = 0; i < aPVPairs.length; i++) {
		theLayer._SetParameter(aPVPairs[i]);
	}
	var bRet = theLayer._Open();
	this._Debug("AddLayer(" + sURL + ") == " + (this.Layers.length - 1));

	if(bRet == false) {
		this.DeleteLayer(sName);
		this.sErrorMsg = "Could not open: \"" + sURL + "\"";
		return(-1);
	}
	return(this.Layers.length - 1);
}

NCSJSView.prototype.Refresh = function() {
//alert("REFRESH");
//	this.Draw(true);
//NOP
}

NCSJSView.prototype.Draw = function(bClear, bZoom) {
	this.FireOnDrawBegin();
	var i;
	for(i = this.Layers.length - 1; i >= 0; i--) {
		var theLayer = this.Layers[i];
		if(theLayer._isVisible()) {
			theLayer._Draw(bClear, bZoom);
		} else {
			theLayer._Clear();
		}
	}
	this.FireOnDrawEnd();
}

function _NCSJSView_Find(nID) {
	return(_NCSJSViews[nID - 1]);
}

function _NCSJSView_FindLayer(nViewID, nLayerID) {
	var theView = _NCSJSView_Find(nViewID);
	var i;
	var theLayer = null;
	for(i = 0; i < theView.Layers.length; i++) {
		if(theView.Layers[i].nLayerID == nLayerID) {
			theLayer = theView.Layers[i];
			break;
		}
	}
	return(theLayer);
}

function _NCSJSView_OnLoadTrigger(nID) {
	NCSJSView_OnResize(nID);
	var theView = _NCSJSView_Find(nID);
	theView.FireOnLoad();
}

NCSJSView.prototype._GetEventX = function(e) {
	if(_NCSJSView_IsNot_Undefined_Nor_Function(typeof(e.clientX))){ //[04]
		return(document.documentElement.scrollLeft + e.clientX - this.GetScreenTLX());
	} else {
		return(document.body.scrollLeft + e.x - this.GetScreenTLX());
	}
}

NCSJSView.prototype._GetEventY = function(e) {
	if(_NCSJSView_IsNot_Undefined_Nor_Function(typeof(e.clientY))){ //[04]
		return(document.documentElement.scrollTop + e.clientY - this.GetScreenTLY());
	} else {
		return(document.body.scrollTop + e.y - this.GetScreenTLY());
	}
}

NCSJSView.prototype._GetEventWorldX = function(e, nEventX) {
	return(this.dViewTLX + nEventX * this.dWorldPerPixelX);
}

NCSJSView.prototype._GetEventWorldY = function(e, nEventY) {
	return(this.dViewTLY + (this._GetEventY(e)) * this.dWorldPerPixelY);
}

NCSJSView.prototype._GetEventMask = function(e) {
	var Mask = 0;
	if(e.ctrlKey) {
		Mask |= MVK_CONTROL;
	}
	if(e.shiftKey) {
		Mask |= MVK_SHIFT;
	}
	switch(_NCSJSView_IsNot_Undefined_Nor_Function(typeof(e.which)) ? e.which : e.button ){ //[04]

		default:
		case 0: break;
		case 1: Mask |= MVK_LBUTTON; break;
		case 2: Mask |= MVK_RBUTTON; break;
		case 3: Mask |= MVK_LBUTTON|MVK_RBUTTON; break;
		case 4: Mask |= MVK_MBUTTON; break;
		case 5: Mask |= MVK_LBUTTON|MVK_MBUTTON; break;
		case 6: Mask |= MVK_MBUTTON|MVK_RBUTTON; break;
		case 7: Mask |= MVK_LBUTTON|MVK_MBUTTON|MVK_RBUTTON; break;
	}
	return(Mask);
}

NCSJSView.prototype._GetCallbackInfo = function(name) {
	var i;
	for(i = 0; i < this.CallBacks.length; i++) {
		if(this.CallBacks[i].sName.toLowerCase() == name.toLowerCase()) {
			return(this.CallBacks[i]);
		}
	}	
	return(null);
}

NCSJSView.prototype._GetCallbackInfoById = function(id) {
	return(this.CallBacks[id]);
}

NCSJSView.prototype.FireOnMouseDown = function(Mask, ScreenX, ScreenY, dWorldX, dWorldY)
{
	if(this.GetPointerMode() == PM_POINTER) {
		if (this.onmousedown != _NCSJSView_NullCB) {	
			this.onmousedown(Mask, ScreenX, ScreenY, dWorldX, dWorldY);
		} else {
			if (this._EvalCallBackName("onMouseDown")) {
				this.onmousedown(Mask, ScreenX, ScreenY, dWorldX, dWorldY);
			}		
		}
	}
}

NCSJSView.prototype.FireOnMouseMove = function(Mask, ScreenX, ScreenY, dWorldX, dWorldY)
{
	if(this.GetPointerMode() == PM_POINTER) {
		if (this.onmousemove != _NCSJSView_NullCB) {	
			this.onmousemove(Mask, ScreenX, ScreenY, dWorldX, dWorldY);
		} else {
			if (this._EvalCallBackName("onMouseMove")) {
				this.onmousemove(Mask, ScreenX, ScreenY, dWorldX, dWorldY);
			}		
		}
	}
}

NCSJSView.prototype.FireOnMouseUp = function(Mask, ScreenX, ScreenY, dWorldX, dWorldY)
{
	if(this.GetPointerMode() == PM_POINTER) {
		if (this.onmouseup != _NCSJSView_NullCB) {	
			this.onmouseup(Mask, ScreenX, ScreenY, dWorldX, dWorldY);
		} else {
			if (this._EvalCallBackName("onMouseUp")) {
				this.onmouseup(Mask, ScreenX, ScreenY, dWorldX, dWorldY);
			}		
		}
		
	}
}

NCSJSView.prototype.FireOnExtentChange = function(dWorldTLX, dWorldTLY, dWorldBRX, dWorldBRY)
{
	if (this.onextentchange != _NCSJSView_NullCB) {	
		var t = this._FireOnExtentChangeTimer;
	    t.setData(new Array(this, dWorldTLX, dWorldTLY, dWorldBRX, dWorldBRY));
	    t.start();
	} else {
		if (this._EvalCallBackName("onExtentChange")) {
			var t = this._FireOnExtentChangeTimer;
		    t.setData(new Array(this, dWorldTLX, dWorldTLY, dWorldBRX, dWorldBRY));
		    t.start();
		}		
	}
    
}

NCSJSView.prototype.FireOnPointerModeChange = function(Mode)
{
	if (this.onpointermodechange != _NCSJSView_NullCB) {	
		this.onpointermodechange(Mode);
	} else {
		if (this._EvalCallBackName("onPointerModeChange")) {
			this.onpointermodechange(Mode);
		}		
	}
}

NCSJSView.prototype.FireOnGeolinkModeChange = function(Mode)
{
	if (this.ongeolinkmodechange != _NCSJSView_NullCB) {	
		this.ongeolinkmodechange(Mode);
	} else {
		if (this._EvalCallBackName("onGeolinkModeChange")) {
			this.ongeolinkmodechange(Mode);
		}		
	}
}

NCSJSView.prototype.FireOnPercentComplete = function()
{
	if (this.onpercentcomplete != _NCSJSView_NullCB) {	
		this._FireOnPercentCompleteTimer.start();
	} else {
		if (this._EvalCallBackName("onPercentComplete")) {
			 this._FireOnPercentCompleteTimer.start();
		}		
	}
}

NCSJSView.prototype.FireOnDrawBegin = function()
{
	if (this.ondrawbegin != _NCSJSView_NullCB) {	
		this.ondrawbegin();
	} else {
		if (this._EvalCallBackName("onDrawBegin")) {
			 this.ondrawbegin();
		}		
	}
}

NCSJSView.prototype.FireOnDrawEnd = function()
{
	if (this.ondrawend != _NCSJSView_NullCB) {	
		this.ondrawend();
	} else {
		if (this._EvalCallBackName("onDrawEnd")) {
			 this.ondrawend();
		}		
	}
}

NCSJSView.prototype.FireOnLoad = function()
{
	if (this.onload != _NCSJSView_NullCB) {	
		this.onload();
	} else {
		if (this._EvalCallBackName("onLoad")) {
			 this.onload();
		}		
	}
}

NCSJSView.prototype.FireOnError = function(layerName, num, code, desc)
{
	if (this.onerror != _NCSJSView_NullCB) {	
		this.onerror(layerName, num, code, desc);
	} else {
		if (this._EvalCallBackName("onError")) {
			 this.onerror(layerName, num, code, desc);
		}		
	}
}

NCSJSView.prototype.FireOnLayerResponse = function(sLayerName, sURL, sBody, sAction, dWorldTLX, dWorldTLY, dWorldBRX, dWorldBRY, sResponse) {
	if (this.onlayerresponse != _NCSJSView_NullCB) {	
		this.onlayerresponse(sLayerName, sURL, sBody, sAction, dWorldTLX, dWorldTLY, dWorldBRX, dWorldBRY, sResponse);
	} else {
		if (this._EvalCallBackName("onLayerResponse")) {
			 this.onlayerresponse(sLayerName, sURL, sBody, sAction, dWorldTLX, dWorldTLY, dWorldBRX, dWorldBRY, sResponse);
		}		
	}
}

function NCSJSView_OnResize(nID)
{
	var theView = _NCSJSView_Find(nID);
	var Node = theView.NCSJSViewDivFrame;
	var nWidth = theView.NCSJSViewDivFrame.offsetWidth;
	var nHeight = theView.NCSJSViewDivFrame.offsetHeight;
	
	while(nWidth <= 4 && Node.parentNode != null) {
		Node = Node.parentNode;
		nWidth = Node.offsetWidth;
	}
	Node = theView.NCSJSViewDivFrame;
	while(nHeight <= 4 && Node.parentNode != null) {
		Node = Node.parentNode;
		nHeight = Node.offsetHeight;
	}
	if(theView.sWidth.indexOf("%") >= 0) {
		var nPercent = theView.sWidth.split("%")[0];
		nWidth = nWidth * nPercent / 100.0;
		if(theView.NCSJSViewDivFrame.offsetWidth == 0) {
			theView.NCSJSViewDivFrame.style.width = nWidth + "px";
		}
	}
	if(theView.sHeight.indexOf("%") >= 0) {
		var nPercent = theView.sHeight.split("%")[0];
		nHeight = nHeight * nPercent / 100.0;
		if(theView.NCSJSViewDivFrame.offsetHeight == 0) {
			theView.NCSJSViewDivFrame.style.height = nHeight + "px";
		}
	}
}

NCSJSView.prototype.Zoom = function(x,y,delta)
{
	var nDY = parseInt(delta * 10);
	
	var dCenterX = this.dViewTLX + this.dWorldPerPixelX * x;
	var dCenterY = this.dViewTLY + this.dWorldPerPixelY * y;
	
	var dWorldPerPixelX = this.dWorldPerPixelX;
	var dWorldPerPixelY = this.dWorldPerPixelY;
	
	if(nDY > 0.0) {
		dWorldPerPixelX /= Math.pow(1.01, nDY);
		dWorldPerPixelY /= Math.pow(1.01, nDY);
	} else {
		nDY = Math.abs(nDY);
		dWorldPerPixelX *= Math.pow(1.01, nDY);
		dWorldPerPixelY *= Math.pow(1.01, nDY);			
	}
	var dNewWorldTLX = dCenterX;
	var dNewWorldTLY = dCenterY;
	var dNewWorldBRX = dCenterX;
	var dNewWorldBRY = dCenterY;

	dNewWorldTLX -= x * dWorldPerPixelX;
	dNewWorldTLY -= y * dWorldPerPixelY;
	dNewWorldBRX += (this.GetViewWidth() - x) * dWorldPerPixelX;
	dNewWorldBRY += (this.GetViewHeight() - y) * dWorldPerPixelY;
	this.SetExtents(dNewWorldTLX,
					dNewWorldTLY,
					dNewWorldBRX,
					dNewWorldBRY);	
}

function NCSJSView_OnMouseScroll(e, nID)
{
	if( nID ) { // IE
		var theView = _NCSJSView_Find(nID);
		theView._OnMouseScroll(e);
	} else if( e.rangeParent && e.rangeParent.theView ) { //firefox
		e.rangeParent.theView._OnMouseScroll(e);
	} else if ( e.currentTarget && e.currentTarget.theView ) {
		e.currentTarget.theView._OnMouseScroll(e);
	}
}

NCSJSView.prototype._OnMouseScroll = function(event)
{
	var delta = 0;
	var x=0;
	var y=0;
	if (!event) return;
	if (event.wheelDelta) { // IE/Opera/Safari
		if (navigator.userAgent.toLowerCase().indexOf('applewebkit') != -1) { // Safari
			// problem with safari, so just zoom around the centre of the
			x = this.NCSJSViewDivFrame.clientWidth/2;
			y = this.NCSJSViewDivFrame.clientHeight/2;
		} else {
			x = event.x;
			y = event.y;
		}
		
		delta = event.wheelDelta/120;
		if (window.opera) delta = -delta;
	} else if (event.detail) { // Firefox
		if (this.dFFVersion == 3) {
			x = this._GetEventX(event);
			y = this._GetEventY(event);
		} else {
		/* problem with firefox 2, so just zoom around the centre of the 
		x = event.layerX;
		y = event.layerY;
		*/
			x = this.NCSJSViewDivFrame.clientWidth/2;
			y = this.NCSJSViewDivFrame.clientHeight/2;
		}
		delta = -event.detail/3;
	}
	if (delta)
		this.Zoom(x,y,delta);
	if (event.preventDefault)
		event.preventDefault();
	event.returnValue = false;
}

function NCSJSView_OnMouseDown(e, nID)
{
	var theView = _NCSJSView_Find(nID);
	return(theView._OnMouseDown(e));
}

NCSJSView.prototype._OnMouseDown = function(e)
{
	this.nMouseX = this._GetEventX(e);
	this.nMouseY = this._GetEventY(e);
	this.nMouseStartX = this.nMouseX;
	this.nMouseStartY = this.nMouseY;
	this.nMouseStartWorldX = this._GetEventWorldX(e, this.nMouseStartX);
	this.nMouseStartWorldY = this._GetEventWorldY(e, this.nMouseStartY);
	this.dMouseStartWorldPerPixelX = this.dWorldPerPixelX;
	this.dMouseStartWorldPerPixelY = this.dWorldPerPixelY;
	this.MouseMask |= this._GetEventMask(e);
	if(_NCSJSView_IsNot_Undefined_Nor_Function(typeof(this.NCSJSViewDivFrame.setCapture))){ //[04]
		this.NCSJSViewDivFrame.setCapture(true);
	}
	this._SetCursor(true);
	this.FireOnMouseDown(this.MouseMask, this.nMouseX, this.nMouseY, this._GetEventWorldX(e, this.nMouseX), this._GetEventWorldY(e, this.nMouseY));
	if(_NCSJSDraggedViewID == null) {
		_NCSJSDraggedViewID = this.nViewID;
		if(typeof(document.addEventListener) != "undefined"){// && (typeof(document.addEventListener) != "function")) {
		    //FireFox
			document.addEventListener("mousemove", NCSJSView_OnMouseMove, false);
			document.addEventListener("mouseup", NCSJSView_OnMouseUp, false);
		} else {
		    // I.E.
			document.attachEvent("onmousemove", NCSJSView_OnMouseMove);
			document.attachEvent("onmouseup", NCSJSView_OnMouseUp);
		}
	}
	if(_NCSJSView_IsNot_Undefined_Nor_Function(typeof(e.stopPropagation))){ //[04]
		e.stopPropagation();
		e.preventDefault();
	} else {
    	e.returnValue = false;
    	e.cancelBubble = true;
    } 
	return(false);
}

function NCSJSView_OnMouseMove(e)
{
	if(_NCSJSDraggedViewID == null) { return(false); }
	var theView = _NCSJSView_Find(_NCSJSDraggedViewID);
	return(theView._OnMouseMove((typeof(e) == "undefined") ? event : e));
}

NCSJSView.prototype.MouseMoved = function()
{
    return (this.nMouseStartX != this.nMouseX) || (this.nMouseStartY != this.nMouseY);
}
NCSJSView.prototype._OnMouseMove = function(e)
{
	var nNewX = this._GetEventX(e);
	var nNewY = this._GetEventY(e);
	var eMode = this.GetPointerMode();
	var mouseMask = this.MouseMask;
	this.bInIZoom = false;
	var bRoam = false;

	if(eMode == PM_ROAM) {
		if(mouseMask & MVK_LBUTTON && !(mouseMask & MVK_RBUTTON) && !(mouseMask & MVK_SHIFT)) {
			bRoam = true;
		} else if(!this.bStepZoom && (mouseMask & MVK_LBUTTON) && (mouseMask & MVK_RBUTTON)) {
			this.bInIZoom = true;
		} else if(!this.bStepZoom && (mouseMask & MVK_LBUTTON) && (mouseMask & MVK_SHIFT)) {
			this.bInIZoom = true;
		}
	} else if (eMode == PM_ZOOM && !this.bStepZoom && mouseMask & MVK_LBUTTON) {
		if((mouseMask & MVK_SHIFT) || (mouseMask & MVK_RBUTTON)) {
			bRoam = true;
		} else {
			this.bInIZoom = true;
		}
	} else if(eMode == PM_POINTER && mouseMask & MVK_LBUTTON) {
		this.nMouseX = nNewX;
		this.nMouseY = nNewY;
		this.FireOnMouseMove(mouseMask, nNewX, nNewY, this._GetEventWorldX(e, nNewX), this._GetEventWorldY(e, nNewY));	
	} else if(eMode == PM_ZOOMBOX && mouseMask & MVK_LBUTTON) {
		this.nMouseX = nNewX;
		this.nMouseY = nNewY;
		if(this.nMouseX > this.nMouseStartX) {
		    this.NCSJSViewDivZoom.style.left = this.nMouseStartX + "px";
			this.NCSJSViewDivZoom.style.width = (this.nMouseX - this.nMouseStartX) + "px";
		} else {
			this.NCSJSViewDivZoom.style.left = this.nMouseX + "px";
			this.NCSJSViewDivZoom.style.width = (this.nMouseStartX - this.nMouseX) + "px";
		}
		if(this.nMouseY > this.nMouseStartY) {
		    this.NCSJSViewDivZoom.style.top = this.nMouseStartY + "px";
			this.NCSJSViewDivZoom.style.height = (this.nMouseY - this.nMouseStartY) + "px";
		} else {
			this.NCSJSViewDivZoom.style.top = this.nMouseY + "px";
			this.NCSJSViewDivZoom.style.height = (this.nMouseStartY - this.nMouseY) + "px";
		}
		this.NCSJSViewDivZoom.style.visibility = "visible";
		this.FireOnMouseMove(mouseMask, nNewX, nNewY, this._GetEventWorldX(e, nNewX), this._GetEventWorldY(e, nNewY));
	}
	if( bRoam ) {
		// Pan mode
		var dWorldDX = (this.nMouseX - nNewX) * this.dWorldPerPixelX;
		var dWorldDY = (this.nMouseY - nNewY) * this.dWorldPerPixelY;
		this.SetExtents(this.dViewTLX + dWorldDX,
						this.dViewTLY + dWorldDY,
						this.dViewBRX + dWorldDX,
						this.dViewBRY + dWorldDY);			
		this.nMouseX = nNewX;
		this.nMouseY = nNewY;
		this.FireOnMouseMove(mouseMask, nNewX, nNewY, this._GetEventWorldX(e, nNewX), this._GetEventWorldY(e, nNewY));
	} else if(this.bInIZoom) {
			// Izoom
		this._SetCursor(true);
		
		var nDY = nNewY - this.nMouseStartY;
		
		var dCenterX = this.nMouseStartWorldX;
		var dCenterY = this.nMouseStartWorldY;
		
		var dWorldPerPixelX = this.dMouseStartWorldPerPixelX;
		var dWorldPerPixelY = this.dMouseStartWorldPerPixelY;
		
		if(nDY > 0.0) {
			dWorldPerPixelX /= Math.pow(1.01, nDY);
			dWorldPerPixelY /= Math.pow(1.01, nDY);
		} else {
			nDY = Math.abs(nDY);
			dWorldPerPixelX *= Math.pow(1.01, nDY);
			dWorldPerPixelY *= Math.pow(1.01, nDY);			
		}
		var dNewWorldTLX = dCenterX;
		var dNewWorldTLY = dCenterY;
		var dNewWorldBRX = dCenterX;
		var dNewWorldBRY = dCenterY;

		dNewWorldTLX -= this.nMouseStartX * dWorldPerPixelX;
		dNewWorldTLY -= this.nMouseStartY * dWorldPerPixelY;
		dNewWorldBRX += (this.GetViewWidth() - this.nMouseStartX) * dWorldPerPixelX;
		dNewWorldBRY += (this.GetViewHeight() - this.nMouseStartY) * dWorldPerPixelY;
		this.SetExtents(dNewWorldTLX,
						dNewWorldTLY,
						dNewWorldBRX,
						dNewWorldBRY);	
		
		this.nMouseX = nNewX;
		this.nMouseY = nNewY;
		this.FireOnMouseMove(mouseMask, nNewX, nNewY, this._GetEventWorldX(e, nNewX), this._GetEventWorldY(e, nNewY));
	}
	if(_NCSJSView_IsNot_Undefined_Nor_Function(typeof(e.stopPropagation))){//[04]

		e.stopPropagation();
		e.preventDefault();
	} else {
    	e.returnValue = false; 
    	e.cancelBubble = true; 
    }
	return(false);
}

function NCSJSView_OnMouseUp(e)
{
	if(_NCSJSDraggedViewID == null) { return(false); }
	var theView = _NCSJSView_Find(_NCSJSDraggedViewID);
	return(theView._OnMouseUp((typeof(e) == "undefined") ? event : e));
}

NCSJSView.prototype._OnMouseUp = function(e)
{
	var nNewX = this._GetEventX(e);
	var nNewY = this._GetEventY(e);
	var mouseMask = this._GetEventMask(e);
	var eMode = this.GetPointerMode();
	this.bInIZoom = false;
	
	if((eMode == PM_ROAM || eMode == PM_ZOOM) && (mouseMask & MVK_LBUTTON || mouseMask & MVK_RBUTTON) && nNewX == this.nMouseStartX && nNewY == this.nMouseStartY) {
		var dWorldX = this._GetEventWorldX(e, nNewX);
		var dWorldY = this._GetEventWorldY(e, nNewY);
		
		var dWorldPerPixelX = this.dWorldPerPixelX;
		var dWorldPerPixelY = this.dWorldPerPixelY;
		
		var dNewWorldTLX = dWorldX;
		var dNewWorldTLY = dWorldY;
		var dNewWorldBRX = dWorldX;
		var dNewWorldBRY = dWorldY;

		var nCurrentLevel = 0;
		var nMaxLevels = 0;
		// Click-zoom
		var ecwLayer = false;
		for (var index = this.Layers.length-1; index >= 0 && !ecwLayer; index--) {
			ecwLayer = (this.Layers[index].sLayerType.toLowerCase() == "ecw") ? this.Layers[index] : false;
		}
		if (ecwLayer) {
			nMaxLevels = ecwLayer.aLevels.length-1;
			var nCurrentWorldXPerTile = this.dWorldPerPixelX * ecwLayer.nTileSize;
			var nZoomBias = (ecwLayer.sUnits.toLowerCase().indexOf("degrees") >= 0 ? 0.000000001 : 0.00001);
			for(nCurrentLevel = 0; nCurrentLevel < nMaxLevels; nCurrentLevel++) {
				if(nCurrentWorldXPerTile < ecwLayer.aLevels[nCurrentLevel+1].dWorldPerTileX) {
					break;
				}
			}
			if((mouseMask & MVK_SHIFT && mouseMask & MVK_LBUTTON) || mouseMask & MVK_RBUTTON) {		
				// Zoom Out
				if (!ecwLayer || (ecwLayer && (nCurrentLevel == nMaxLevels || (nCurrentLevel == 0 && 
					dWorldPerPixelX*this.dZoomStep*ecwLayer.nTileSize < ecwLayer.aLevels[0].dWorldPerTileX)))) {
					dWorldPerPixelX *= this.dZoomStep;
					dWorldPerPixelY *= this.dZoomStep;
				} else {
					if (nCurrentWorldXPerTile > (ecwLayer.nTileSize * ecwLayer.dImageCellSizeX * Math.pow(2, nCurrentLevel-0.5))) {
						nCurrentLevel++;
					}
					dWorldPerPixelX = (ecwLayer.aLevels[nCurrentLevel].dWorldPerTileX / ecwLayer.nTileSize)+nZoomBias;
					dWorldPerPixelY = (ecwLayer.aLevels[nCurrentLevel].dWorldPerTileY / ecwLayer.nTileSize)+nZoomBias;
				}
				
			} else {
				// Zoom In
				if (!ecwLayer || (ecwLayer && (nCurrentLevel == 0 || (nCurrentLevel == nMaxLevels && 
					dWorldPerPixelX*(1.0 / this.dZoomStep)*ecwLayer.nTileSize > ecwLayer.aLevels[nMaxLevels].dWorldPerTileX)))) {
					dWorldPerPixelX *= (1.0 / this.dZoomStep);
					dWorldPerPixelY *= (1.0 / this.dZoomStep);
				} else {
					if (nCurrentWorldXPerTile < (ecwLayer.nTileSize * ecwLayer.dImageCellSizeX * Math.pow(2, nCurrentLevel+0.5))) {
						nCurrentLevel--;
					}					
					dWorldPerPixelX = (ecwLayer.aLevels[nCurrentLevel].dWorldPerTileX / ecwLayer.nTileSize)+nZoomBias;
					dWorldPerPixelY = (ecwLayer.aLevels[nCurrentLevel].dWorldPerTileY / ecwLayer.nTileSize)+nZoomBias;
				}
			}
		}
		dNewWorldTLX -= nNewX * dWorldPerPixelX;
		dNewWorldTLY -= nNewY * dWorldPerPixelY;
		dNewWorldBRX += (this.GetViewWidth() - nNewX) * dWorldPerPixelX;
		dNewWorldBRY += (this.GetViewHeight() - nNewY) * dWorldPerPixelY;

		this.SetExtents(dNewWorldTLX,
						dNewWorldTLY,
						dNewWorldBRX,
						dNewWorldBRY);
	} else if(eMode == PM_ZOOMBOX) {
		if(mouseMask & MVK_LBUTTON && nNewX != this.nMouseStartX && nNewY != this.nMouseStartY) {
			var dWorldX = this._GetEventWorldX(e, nNewX);
			var dWorldY = this._GetEventWorldY(e, nNewY);
			
			var dNewWorldTLX, dNewWorldTLY, dNewWorldBRX, dNewWorldBRY;
			if(nNewX > this.nMouseStartX) {
				dNewWorldTLX = dWorldX - (nNewX - this.nMouseStartX) * this.dWorldPerPixelX;
				dNewWorldBRX = dWorldX;
			} else {
				dNewWorldTLX = dWorldX;
				dNewWorldBRX = dWorldX - (nNewX - this.nMouseStartX) * this.dWorldPerPixelX;
			}
			if(nNewY > this.nMouseStartY) {
				dNewWorldTLY = dWorldY - (nNewY - this.nMouseStartY) * this.dWorldPerPixelY;
				dNewWorldBRY = dWorldY;
			} else {
				dNewWorldTLY = dWorldY;
				dNewWorldBRY = dWorldY - (nNewY - this.nMouseStartY) * this.dWorldPerPixelY;
			}

			this.SetExtents(dNewWorldTLX,
							dNewWorldTLY,
							dNewWorldBRX,
							dNewWorldBRY);
		} else if((mouseMask & MVK_SHIFT && mouseMask & MVK_LBUTTON) || mouseMask & MVK_RBUTTON) {		
			// Zoom Out
			var dWorldPerPixelX = this.dWorldPerPixelX * this.dZoomStep;
			var dWorldPerPixelY = this.dWorldPerPixelY * this.dZoomStep;
			var dWorldX = this._GetEventWorldX(e, nNewX);
			var dWorldY = this._GetEventWorldY(e, nNewY);
		
			var dNewWorldTLX = dWorldX;
			var dNewWorldTLY = dWorldY;
			var dNewWorldBRX = dWorldX;
			var dNewWorldBRY = dWorldY;

			dNewWorldTLX -= nNewX * dWorldPerPixelX;
			dNewWorldTLY -= nNewY * dWorldPerPixelY;
			dNewWorldBRX += (this.GetViewWidth() - nNewX) * dWorldPerPixelX;
			dNewWorldBRY += (this.GetViewHeight() - nNewY) * dWorldPerPixelY;
			
			this.SetExtents(dNewWorldTLX,
							dNewWorldTLY,
							dNewWorldBRX,
							dNewWorldBRY);
		}
		if(mouseMask & MVK_LBUTTON) {					
			this.NCSJSViewDivZoom.style.visibility = "hidden";
		}
	}
	
	if(_NCSJSView_IsNot_Undefined_Nor_Function(typeof(this.NCSJSViewDivFrame.releaseCapture))){//[04]
		this.NCSJSViewDivFrame.releaseCapture();
	}
	this._SetCursor(false);
	//this.MouseMask &= ~mouseMask;
	this.MouseMask = 0;
	this.FireOnMouseUp(this.MouseMask, this.nMouseX, this.nMouseY, this._GetEventWorldX(e, this.nMouseX), this._GetEventWorldY(e, this.nMouseY));

//	this.nMouseX = 0;
//	this.nMouseY = 0;
//	this.nMouseStartX = 0;
//	this.nMouseStartY = 0;
	if(_NCSJSDraggedViewID != null) {
		if(typeof(document.removeEventListener) != "undefined") {
			document.removeEventListener("mousemove", NCSJSView_OnMouseMove, false);
			document.removeEventListener("mouseup", NCSJSView_OnMouseUp, false);
		} else {
			document.detachEvent("onmousemove", NCSJSView_OnMouseMove);
			document.detachEvent("onmouseup", NCSJSView_OnMouseUp);
		}
		_NCSJSDraggedViewID = null;
	}
	if(_NCSJSView_IsNot_Undefined_Nor_Function(typeof(e.stopPropagation))){//[04]
		e.stopPropagation();
		e.preventDefault();
	} else {
    	e.returnValue = false;
	    e.cancelBubble = true;
	}
	return(false);
}

function NCSJSView_OnClick(e, nID)
{
	e.returnValue = false; 
	e.cancel = true; 
	return(false);
}

NCSJSView.prototype._SetWaitCursor = function() {
	//NOTYET this.NCSJSViewDivFrame.style.cursor = "auto";
}

NCSJSView.prototype._SetCursor = function(bActive) {
	switch(this.GetPointerMode()) {
		case PM_ROAM:
				if(this.bInIZoom) {
					this.NCSJSViewDivFrame.style.cursor = "url('/ecwplugins/lib/bitmaps/cursors/zoom.cur'), move";
				} else if(bActive) {
					this.NCSJSViewDivFrame.style.cursor = "url('/ecwplugins/lib/bitmaps/cursors/roaming.cur'), move";
				} else {
					this.NCSJSViewDivFrame.style.cursor = "url('/ecwplugins/lib/bitmaps/cursors/roam.cur'), pointer";
				}
			break;
		case PM_ZOOM:
				this.NCSJSViewDivFrame.style.cursor = "url('/ecwplugins/lib/bitmaps/cursors/zoom.cur'), crosshair";
			break;
		case PM_ZOOMBOX:
				this.NCSJSViewDivFrame.style.cursor = "url('/ecwplugins/lib/bitmaps/cursors/zoombox.cur'), crosshair";
			break;
		default:
				this.NCSJSViewDivFrame.style.cursor = "auto";
			break;
	}
}

NCSJSView.prototype.SetExtents = function(dViewTLX,
										dViewTLY,
										dViewBRX,
										dViewBRY)
{
	this._SetExtentsLink(null,
							  dViewTLX,
							dViewTLY,
						    dViewBRX,
						    dViewBRY);
}


NCSJSView.prototype._SetExtentsLink = function(srcView,
												dViewTLX,
												dViewTLY,
												dViewBRX,
												dViewBRY)
{
	var bZoom = false;
	var nViewWidth = this.GetViewWidth();
	var nViewHeight = this.GetViewHeight();
	var dX = dViewBRX - dViewTLX;
	var dY = dViewBRY - dViewTLY;
	var dWorldPerPixelX = dX / nViewWidth;
	var dWorldPerPixelY = dY / nViewHeight;

	var dCurViewTLX = this.dViewTLX;
	var dCurViewTLY = this.dViewTLY;
	var dCurViewBRX = this.dViewBRX;
	var dCurViewBRY = this.dViewBRY;
	
	var dAdjViewTLX = dViewTLX;
	var dAdjViewTLY = dViewTLY;
	var dAdjViewBRX = dViewBRX;
	var dAdjViewBRY = dViewBRY;

	//if (isNaN(dViewTLX) ||  isNaN(dViewTLY) || isNaN(dViewBRX) || isNaN(dViewBRY) ) alert ("Nan passed to _SetExtentsLink");

	this._Debug("_SetExtentsLink(" + dViewTLX + "," + dViewTLY + "," + dViewBRX + "," + dViewBRY + ")");

	if(this.bHaveInitExtents == false) {
		// First setextents() call, calculate the base scale
		var i;
		for(i = 0; i < this.Layers.length; i++) {
			theLayer = this.Layers[i];
			if(theLayer.sLayerType == "ecw") {
				this.dScaleX = (theLayer._GetBottomRightWorldCoordinateX() - theLayer._GetTopLeftWorldCoordinateX()) / theLayer._GetImageSizeX();
				this.dScaleY = (theLayer._GetBottomRightWorldCoordinateY() - theLayer._GetTopLeftWorldCoordinateY()) / theLayer._GetImageSizeY();
				if(theLayer._GetBottomRightWorldCoordinateY() < theLayer._GetTopLeftWorldCoordinateY()) {
					this.bYInv = true;
				} else {
					this.bYInv = false;		
				}
				break;
			}
		}
	}
	
	if(Math.abs(Math.abs(this.dScaleX) - Math.abs(this.dScaleY)) >= 0.000001){ //[02]
	    if(this.dScreenAspectRatio*(nViewWidth / nViewHeight) > dX / Math.abs(dY)) {
		    // Aspect of window > aspect of view, recalc BRX
		    dWorldPerPixelX = (this.bYInv?-1:1)*dWorldPerPixelY * this.dScreenAspectRatio;
		    dAdjViewBRX = dAdjViewTLX + dWorldPerPixelX * nViewWidth;
	    } else {
		    dWorldPerPixelY = (this.bYInv?-1:1)*dWorldPerPixelX / this.dScreenAspectRatio;
		    dAdjViewBRY = dAdjViewTLY + dWorldPerPixelY * nViewHeight;
	    }	
	} else {
	    if(nViewWidth / nViewHeight > dX / Math.abs(dY)) {
		    // Aspect of window > aspect of view, recalc BRX
		    dWorldPerPixelX = dWorldPerPixelY * this.dScaleX / this.dScaleY;
		    dAdjViewBRX = dAdjViewTLX + dWorldPerPixelX * nViewWidth;
	    } else {
		    dWorldPerPixelY = dWorldPerPixelX * this.dScaleY / this.dScaleX;
		    dAdjViewBRY = dAdjViewTLY + dWorldPerPixelY * nViewHeight;
	    }	
	}
	var nMultiple =	0;
	if(this.bStepZoom) {
		var dZoomStep = this.dZoomStep;
		if(dWorldPerPixelX >= this.dScaleX) {	
			while(dWorldPerPixelX > 1.01 * this.dScaleX * Math.pow(dZoomStep, nMultiple)) {
				nMultiple++;
			}
			dWorldPerPixelX = this.dScaleX * Math.pow(dZoomStep, nMultiple);
			dWorldPerPixelY = this.dScaleY * Math.pow(dZoomStep, nMultiple);
		} else {
			while(dWorldPerPixelX < 0.99*this.dScaleX * Math.pow(1.0/dZoomStep, nMultiple)) {
				nMultiple++;
			}
			dWorldPerPixelX = this.dScaleX * Math.pow(1.0/dZoomStep, nMultiple);
			dWorldPerPixelY = this.dScaleY * Math.pow(1.0/dZoomStep, nMultiple);
		}
		
        if(Math.abs(Math.abs(this.dScaleX) - Math.abs(this.dScaleY)) >= 0.000001){ //[02]
            if(this.dScreenAspectRatio*(nViewWidth / nViewHeight) > dX / Math.abs(dY)) {
	            // Aspect of window > aspect of view, recalc BRX
	            dWorldPerPixelX = (this.bYInv?-1:1)*dWorldPerPixelY * this.dScreenAspectRatio;
            } else {
	            dWorldPerPixelY = (this.bYInv?-1:1)*dWorldPerPixelX / this.dScreenAspectRatio;
            }	
        }
        
		dAdjViewBRX = dAdjViewTLX + dWorldPerPixelX * nViewWidth;
		dAdjViewBRY = dAdjViewTLY + dWorldPerPixelY * nViewHeight;
	}
//[03]
	if(Math.abs(dWorldPerPixelX - this.dWorldPerPixelX) > 0.0 || Math.abs(dWorldPerPixelY - this.dWorldPerPixelY) > 0.0) {
		bZoom = true;
	}
	
	//[01]
	if(this.Layers.length > 0){
        if( ((this.Layers[0].dImageCellSizeX/dWorldPerPixelX) >= this.Layers[0].GetZoomLimit()) ||
            ((this.Layers[0].dImageCellSizeY/dWorldPerPixelY) >= this.Layers[0].GetZoomLimit())
          ){
            if(bZoom){
                if(((this.GetPointerMode() == PM_ROAM) && !(this.MouseMoved())) || this.GetPointerMode() != PM_ROAM) 
                    return;
            } else {
                if(this.bInZoom)
                    return;
            }
    	    if(this.dScreenAspectRatio*(nViewWidth / nViewHeight) > dX / Math.abs(dY)) {
    	        var i = 1;
    	        while(1){
    	            dWorldPerPixelY = this.Layers[0].dImageCellSizeY/(this.Layers[0].GetZoomLimit() -i);
      		        dWorldPerPixelX = (this.bYInv?-1:1)*dWorldPerPixelY * this.dScreenAspectRatio;
    	            if(dWorldPerPixelX >= this.Layers[0].dImageCellSizeX/ (this.Layers[0].GetZoomLimit()-1)){
        	            break;    
    	            }
    	            i++
    	        }
            } else {
    	        var i = 1;
    	        while(1){
                    dWorldPerPixelX = this.Layers[0].dImageCellSizeX/ (this.Layers[0].GetZoomLimit()-i);     
                    dWorldPerPixelY = (this.bYInv?-1:1)*dWorldPerPixelX / this.dScreenAspectRatio;
    	            if(dWorldPerPixelY < this.Layers[0].dImageCellSizeY/ (this.Layers[0].GetZoomLimit()-1)){
        	            break;    
    	            }
    	            i++
    	        }
            }
		    dAdjViewBRX = dAdjViewTLX + dWorldPerPixelX * nViewWidth;
		    dAdjViewBRY = dAdjViewTLY + dWorldPerPixelY * nViewHeight;
        }    
	} 
	
	this.dWorldPerPixelX = dWorldPerPixelX;
	this.dWorldPerPixelY = dWorldPerPixelY;
	
	this._Debug("	-> Adjusted (" + dAdjViewTLX + "," + dAdjViewTLY + "," + dAdjViewBRX + "," + dAdjViewBRY + ")");
	
	this.dViewTLX = dAdjViewTLX;
	this.dViewTLY = dAdjViewTLY;
	this.dViewBRX = dAdjViewBRX;
	this.dViewBRY = dAdjViewBRY;
	
	this.Draw(false, bZoom);

	var i;
	for(i = 0; i < this.AttachList.length; i++) {
		if(srcView != null)  {
			var j;
			var bSkip = false;
			for(j = 0; j < srcView.length; j++) {
				if(srcView[j] == this.AttachList[i]) {
					bSkip = true;
					break;
				}
			}
			if(bSkip) {
				continue;
			}
		} else {
			srcView = new Array();
		}
		srcView[srcView.length] = this;
		switch(this.GetGeolinkMode()) {
			case GM_NONE:
			default:
				break;
			case GM_WINDOW:
					this.AttachList[i]._SetExtentsLink(srcView,
												dViewTLX,
												dViewTLY,
												dViewBRX,
												dViewBRY);
				break;
			case GM_SCREEN:
					{
						var dThisTLX = dViewTLX + (this.AttachList[i].GetScreenTLX() - this.GetScreenTLX()) * this.dWorldPerPixelX;
						var dThisTLY = dViewTLY + (this.AttachList[i].GetScreenTLY() - this.GetScreenTLY()) * this.dWorldPerPixelY;
						this.AttachList[i]._SetExtentsLink(srcView,
													dThisTLX,
													dThisTLY,
													dThisTLX + this.AttachList[i].GetViewWidth() * this.dWorldPerPixelX,
													dThisTLY + this.AttachList[i].GetViewHeight() * this.dWorldPerPixelY);
					}
				break;
		}
	}
	this.FireOnExtentChange(dAdjViewTLX,
							dAdjViewTLY,
							dAdjViewBRX,
							dAdjViewBRY);
}
NCSJSView.prototype.SetExtentsAll = function()
{
	if(this.Layers.length > 0) {
		var dWorldTLX = Number.NaN;
		var dWorldTLY = Number.NaN;
		var dWorldBRX = Number.NaN;
		var dWorldBRY = Number.NaN;
		var i;
		for(i = 0; i < this.Layers.length; i++) {
			var theLayer = this._GetLayer(this.GetLayerName(i));
			if(theLayer != null && (theLayer.NCSJSViewDiv.style.visibility == "hidden" || theLayer.sLayerType != "ecw")) {
				continue;
			}
			var dLayerTLX = this.GetLayerImageTopLeftWorldCoordinateX(this.GetLayerName(i));
			var dLayerTLY = this.GetLayerImageTopLeftWorldCoordinateY(this.GetLayerName(i));
			var dLayerBRX = this.GetLayerImageBottomRightWorldCoordinateX(this.GetLayerName(i));
			var dLayerBRY = this.GetLayerImageBottomRightWorldCoordinateY(this.GetLayerName(i));
			if(!isNaN(dLayerTLX)) {
				dWorldTLX = isNaN(dWorldTLX) ? dLayerTLX : Math.min(dWorldTLX, dLayerTLX);
			}
			if(!isNaN(dLayerTLX)) {
				dWorldBRX = isNaN(dWorldBRX) ? dLayerBRX : Math.max(dWorldBRX, dLayerBRX);
			}
			if(this.bYInv) {
				if(!isNaN(dLayerTLY)) {
					dWorldTLY = isNaN(dWorldTLY) ? dLayerTLY : Math.max(dWorldTLY, dLayerTLY);
				}
				if(!isNaN(dLayerTLY)) {
					dWorldBRY = isNaN(dWorldBRY) ? dLayerBRY : Math.min(dWorldBRY, dLayerBRY);
				}
			} else {
				if(!isNaN(dLayerTLY)) {
					dWorldTLY = isNaN(dWorldTLY) ? dLayerTLY : Math.min(dWorldTLY, dLayerTLY);
				}
				if(!isNaN(dLayerTLY)) {
					dWorldBRY = isNaN(dWorldBRY) ? dLayerBRY : Math.max(dWorldBRY, dLayerBRY);
				}
			}
		}
		if (!isNaN(dWorldTLX) && !isNaN(dWorldTLY) && !isNaN(dWorldBRX) && !isNaN(dWorldBRY)) {
			this.SetExtents(dWorldTLX, 
							dWorldTLY, 
							dWorldBRX,
							dWorldBRY);	
		}
	}
}

NCSJSView.prototype._GetMaximumEnvelope = function(sCoordSys)
{
	if(this.bHaveProxy) {
		this._SetWaitCursor();
		var AJAX = new NCSAJAX();
		var dom = AJAX.GetXML((this.bSSLProxy ? "https://" : "http://") + document.location.host + "/ecwp/jsviewproxy.dll?xCMD=ENVELOPE&xSRS=" + (sCoordSys != null ? sCoordSys : this.sTargetCoordSys), null, "GET");
		this._SetCursor(false);
		if(dom != null) {
			try {
				var txt = dom.getElementText("MinX") + "," + dom.getElementText("MinY") + "," + dom.getElementText("MaxX") + "," + dom.getElementText("MaxY");
				return(txt);
			} catch( ex ) {
				return "";
			}
		}
	}
	return "";
}

NCSJSView.prototype.GetPercentComplete = function()
{
	var i;
	var avg = 0;
	for(i = 0; i < this.Layers.length; i++) {
		avg += this.Layers[i]._GetPercentComplete();
	}
	var nPercent = Math.min(100, Math.ceil(avg / Math.max(1, this.Layers.length)));
	if(this.bDebug && nPercent == 100) {
		for(i = 0; i < this.Layers.length; i++) {
			this.Layers[i]._Dump();
		}		
	}
	return(nPercent);
}

NCSJSView.prototype.GetPointerMode = function()
{
	return(this.PointerMode);
}

NCSJSView.prototype.SetPointerMode = function(Mode)
{
	this.PointerMode = Mode;
	this.FireOnPointerModeChange(this.Mode);
	this._SetCursor();
	return(true);
}

NCSJSView.prototype.GetGeolinkMode = function()
{
	return(this.GeolinkMode);
}

NCSJSView.prototype.SetGeolinkMode = function(Mode) {
	this.GeolinkMode = Mode;
	var i;
	for(i = 0; i < this.AttachList.length; i++) {
		this.AttachList[i].GeolinkMode = Mode;
	}
	this.FireOnGeolinkModeChange(this.GeolinkMode);
	this.SetExtents(this.dViewTLX, this.dViewTLY, this.dViewBRX, this.dViewBRY);
	return(true);
}

NCSJSView.prototype.ConvertCoordinates = function(nSrcEPSG, nDstEPSG, sPoints) {
	// Use the JSViewProxy to convert the coordinates
	
	// returns without doing reprojection.
	if(nSrcEPSG == nDstEPSG) {
		// No Conversion required
		return(sPoints);
	}
	
	if(this.bHaveProxy) {
		this._SetWaitCursor();
		var AJAX = new NCSAJAX();
		var dom = AJAX.GetXML((this.bSSLProxy ? "https://" : "http://") + document.location.host + "/ecwp/jsviewproxy.dll?xCMD=CVT&xS=" + nSrcEPSG + "&xD=" + nDstEPSG + "&xSl=" + sPoints, null, "GET");
		this._SetCursor(false);
		if(dom != null) {
			try {
				var txt = dom.getElementText("CVT");
				return(txt);
			} catch( ex ) {
				return "";
			}
		}
	}
	return "";
}

NCSJSView.prototype.GetTopLeftWorldCoordinateX = function() {
	return(this.dViewTLX);
}

NCSJSView.prototype.GetTopLeftWorldCoordinateY = function() {
	return(this.dViewTLY);
}

NCSJSView.prototype.GetBottomRightWorldCoordinateX = function() {
	return(this.dViewBRX);
}

NCSJSView.prototype.GetBottomRightWorldCoordinateY = function() {
	return(this.dViewBRY);
}

NCSJSView.prototype.GetVersionString = function() {
	return("NCSJSView v1.0");
}

NCSJSView.prototype.GetViewWidth = function() {
	var nWidth;
	if(_NCSJSView_IsNot_Undefined_Nor_Function(typeof(this.NCSJSViewDivResizer.offsetWidth))){//[04]
		nWidth = this.NCSJSViewDivResizer.offsetWidth;
		if(nWidth == 0) {
			nWidth = this.NCSJSViewDivResizer.parentNode.offsetWidth;
		}
	} else if(_NCSJSView_IsNot_Undefined_Nor_Function(typeof(this.NCSJSViewDivResizer.style.pixelWidth))){//[04]
		nWidth = this.NCSJSViewDivResizer.style.pixelWidth;
	} else {
		nWidth = parseInt(("" + this.NCSJSViewDivResizer.style.width).replace("px",""));
	}
	return(Math.max(1, nWidth));
}

NCSJSView.prototype.GetViewHeight = function() {
	var nHeight;
	if(_NCSJSView_IsNot_Undefined_Nor_Function(typeof(this.NCSJSViewDivResizer.offsetHeight))){//[04]
		nHeight = this.NCSJSViewDivResizer.offsetHeight;
		if(nHeight == 0) {
		nHeight = this.NCSJSViewDivResizer.offsetParent.offsetHeight; //[05]
		}
	} else if(_NCSJSView_IsNot_Undefined_Nor_Function(typeof(this.NCSJSViewDivResizer.style.pixelHeight))){//[04]
		nHeight = this.NCSJSViewDivResizer.style.pixelHeight;
	} else {
		nHeight = parseInt(("" + this.NCSJSViewDivResizer.style.height).replace("px",""));
	}
	return(Math.max(1, nHeight));
}

NCSJSView.prototype.GetLastErrorText = function()
{
	return(this.sErrorMsg);
}

NCSJSView.prototype.GetCallbackName = function(paramName) {
	var info = this._GetCallbackInfo(paramName);
	if(info != null) {
		return(info.sCallBack);
	}
	return(null);
}

function _NCSJSView_SetCallbackName_Hook(nViewID, paramName, callBack) {
	var theView = _NCSJSView_Find(nViewID);
	if(theView != null) {
		var info = theView._GetCallbackInfo(paramName);
		if(info != null) {
			info.sCallBack = callBack;
		}
	}
}

NCSJSView.prototype.SetCallbackName = function(paramName, callBack) {
	var info = this._GetCallbackInfo(paramName);
	if(info != null) {
		info.sCallBack = callBack;
		if (callBack != null && eval("typeof " + (callBack.replace("()", "").replace(";","")) + " == \"function\"")) {
			eval("_NCSJSView_Find(" + this.nViewID + ")." + paramName.toLowerCase() + "=" + ((callBack != null) ? (callBack.replace("()", "").replace(";","")) : "_NCSJSView_NullCB") + ";");
			info.bIsEvaled = true;
		} else {
			info.bIsEvaled = false;
		}
		info.bTrigger = true;
		return(true);
	}
	return(false);
}


NCSJSView.prototype._EvalCallBackName = function(name)
{
	var info = this._GetCallbackInfo(name);
	if (info && !info.bIsEvaled && info.sCallBack != null && eval("typeof " + (info.sCallBack.replace("()", "").replace(";","")) + " == \"function\"")) {
		eval("_NCSJSView_Find(" + this.nViewID + ")." + info.sName.toLowerCase() + "=" + ((info.sCallBack != null) ? (info.sCallBack.replace("()", "").replace(";","")) : "_NCSJSView_NullCB") + ";");
		info.bIsEvaled = true;
		return true;
	}
	return false;
}

NCSJSView.prototype.SetCallbackTrigger = function(paramName, bTrigger) {
	var info = this._GetCallbackInfo(paramName);
	if(info != null) {
		info.bTrigger = bTrigger;
		if(bTrigger == false) {
			eval("_NCSJSView_Find(" + this.nViewID + ")." + paramName.toLowerCase() + "=_NCSJSView_NullCB;");		
		} else {
			eval("_NCSJSView_Find(" + this.nViewID + ")." + paramName.toLowerCase() + "=" + ((info.sCallBack != null) ? info.sCallBack : "_NCSJSView_NullCB") + ";");
		}
		return(true);
	}
	return(false);
}

NCSJSView.prototype.SetBackGroundColor = function(sColor) {
	this.sBGColor = sColor;
	this.NCSJSViewDivFrame.style.backgroundColor = sColor;
}

NCSJSView.prototype.GetScreenTLX = function() {
	var node = this.NCSJSViewDivResizer;
	var nLeft = 0;
	while(node != null) {
		if(typeof(node.offsetLeft) == "number") {
			nLeft += node.offsetLeft;
		}
		node = node.offsetParent;
	}	
	return(nLeft);
}

NCSJSView.prototype.GetScreenTLY = function() {
	var node = this.NCSJSViewDivResizer;
	var nTop = 0;
	while(node != null) {
		if(typeof(node.offsetTop) == "number") {
			nTop += node.offsetTop;
		}
		node = node.offsetParent;
	}	
	return(nTop);
}

NCSJSView.prototype.GetAttachPoint = function() {
	return(this);
}

NCSJSView.prototype.Attach = function(theView) {
	if(theView != this) {
		var i;
		
		for(i = 0; i < this.AttachList.length; i++) {
			if(this.AttachList[i] == theView) {
				break;
			}
		}
		this.AttachList[i] = theView;
		for(i = 0; i < theView.AttachList.length; i++) {
			if(theView.AttachList[i] == this) {
				break;
			}
		}
		theView.AttachList[i] = this;
		
		for(i = 0; i < theView.AttachList.length; i++) {
			theView.AttachList[i].SetGeolinkMode(this.GetGeolinkMode());
		}
		
	}
}

NCSJSView.prototype.Detach = function() {
	var i;
	for(i = 0; i < this.AttachList.length; i++) {
		var j;
		for(j = 0; j < this.AttachList[i].AttachList.length; j++) {
			if(this.AttachList[i].AttachList[j] == this) {
				while(j < this.AttachList[i].AttachList.length - 1) {
					this.AttachList[i].AttachList[j] = this.AttachList[i].AttachList[j+1];
					j++;
				}
				this.AttachList[i].AttachList.length--;
				break;
			}
		}
		this.AttachList.length = 0;
	}
	return(this);
}

NCSJSView.prototype.SetParameters = function(parameters) {
	var aPVPairs = this._ParseParamList(parameters);
	var i;
	for(i = 0; i < aPVPairs.length; i++) {
		switch(aPVPairs[i][0].toLowerCase()) {
			case "zoomstep": this.dZoomStep = parseFloat(aPVPairs[i][1]); break;
			case "onmousedown": 
			case "onmousemove": 
			case "onmouseup": 
			case "onextentchange": 
			case "onpointermodechange": 
			case "ongeolinkmodechange": 
			case "onpercentcomplete": 
			case "ondrawbegin": 
			case "ondrawend": 
			case "onload": 
			case "onlayerresponse":
			case "onerror":
					this.SetCallbackName(aPVPairs[i][0], aPVPairs[i][1]);
				break;
		}
	}
	return(true);
}

NCSJSView.prototype.GetParameter = function(paramName) {
	switch(paramName.toLowerCase()) {
		case "zoomstep": return(""+this.dZoomStep); break;
	}
	return(null);
}

NCSJSView.prototype.CaptureView = function(fileName) {
	return(null);
}

NCSJSView.prototype.GetLayerIndex = function(layerName) {
	var i;
	for(i = 0; i < this.Layers.length; i++) {
		if(this.Layers[i].sLayerName == layerName) {
			return(i);
		}
	}
	return(-1);
}

NCSJSView.prototype.GetLayerName = function(layerIndex) {
	if(layerIndex < this.Layers.length && layerIndex >= 0) {
		return(this.Layers[layerIndex].sLayerName);
	}
	return(null);
}

NCSJSView.prototype._GetLayer = function(layerName) {
	var i;
	for(i = 0; i < this.Layers.length; i++) {
		if(this.Layers[i].sLayerName == layerName) {
			return(this.Layers[i]);
		}
	}
	return(null);
}

NCSJSView.prototype.GetLayerImageTopLeftWorldCoordinateX = function(layerName) {
	var theLayer = this._GetLayer(layerName);
	if(theLayer != null) {
		return(theLayer._GetTopLeftWorldCoordinateX());
	}
	return(0.0);
}

NCSJSView.prototype.GetLayerImageTopLeftWorldCoordinateY = function(layerName) {
	var theLayer = this._GetLayer(layerName);
	if(theLayer != null) {
		return(theLayer._GetTopLeftWorldCoordinateY());
	}
	return(0.0);
}

NCSJSView.prototype.GetLayerImageBottomRightWorldCoordinateX = function(layerName) {
	var theLayer = this._GetLayer(layerName);
	if(theLayer != null) {
		return(theLayer._GetBottomRightWorldCoordinateX());
	}
	return(0.0);
}

NCSJSView.prototype.GetLayerImageBottomRightWorldCoordinateY = function(layerName) {
	var theLayer = this._GetLayer(layerName);
	if(theLayer != null) {
		return(theLayer._GetBottomRightWorldCoordinateY());
	}
	return(0.0);
}
					
NCSJSView.prototype.GetLayerType = function(layerName) {
	var theLayer = this._GetLayer(layerName);
	if(theLayer != null) {
		return(theLayer.sType);
	}
	return(null);
}

NCSJSView.prototype.DeleteLayer = function(layerName) {
	var i;
	for(i = 0; i < this.Layers.length; i++) {
		var theLayer = this.Layers[i];
		if(theLayer.sLayerName == layerName) {
			theLayer._Delete();
			
			var j;
			for(j = i + 1; j < this.Layers.length; j++) {
				this.Layers[j - 1] = this.Layers[j];
			}
			this.Layers.length--;
			if(this.Layers.length == 0) {
				this.bHaveInitExtents = false;
				if (!this.bPersistTargetCoordSys) {
					this.sTargetCoordSys = "";
				}
			}
			return(true);
		}
	}
	return(false);
}

NCSJSView.prototype.DeleteAllLayers = function() {
	while(this.Layers.length > 0) {
		this.DeleteLayer(this.Layers[0].sLayerName);
	}
	if (!this.bPersistTargetCoordSys) {
		this.sTargetCoordSys = "";
	}
}

NCSJSView.prototype.GetNumberLayers = function() {
	return(this.Layers.length);
}

NCSJSView.prototype.MoveLayer = function(nSrcLayerIndex, nDestLayerIndex) {
	if(nSrcLayerIndex < 0 || nSrcLayerIndex >= this.Layers.length || nDestLayerIndex < 0) {
		return(false);
	}
	if(nSrcLayerIndex == nDestLayerIndex) {
		return(true);
	}
	var theLayer = this.Layers[nSrcLayerIndex];
	var newLayers = new Array();
	var i, j;
	for(i = 0, j = 0; i < this.Layers.length; i++) {
		if(i == nDestLayerIndex) {
			newLayers[newLayers.length] = theLayer;
			theLayer = null;
		} else {
			if(j == nSrcLayerIndex) {
				j++;
			}
			newLayers[newLayers.length] = this.Layers[j];
			j++
		}
	}
	if(theLayer != null) {
		newLayers[newLayers.length] = theLayer;
	}
	this.Layers = newLayers;
	for(i = 0; i < this.Layers.length; i++) {
		this.Layers[i].NCSJSViewDiv.style.zIndex = i+1;
	}
	return(true);
}

NCSJSView.prototype.GetLayerFileName = function(layerName) {
	var theLayer = this._GetLayer(layerName);
	if(theLayer != null) {
		return(theLayer.sURL);
	}
	return(null);
}

NCSJSView.prototype.GetLayerProjection = function(layerName) {
	var theLayer = this._GetLayer(layerName);
	if(theLayer != null) {
		return(theLayer.sProjection);
	}
	return(null);
}

NCSJSView.prototype.GetLayerDatum = function(layerName) {
	var theLayer = this._GetLayer(layerName);
	if(theLayer != null) {
		return(theLayer.sDatum);
	}
	return(null);
}

NCSJSView.prototype.SetLayerTransparency = function(layerName, sColor, dTransparentPercent) {
	var theLayer = this._GetLayer(layerName);
	if(theLayer != null) {
		var ret = theLayer._SetTransparency(sColor, 1.0-dTransparentPercent);
		if(dTransparentPercent != 1.0) {
	//		theLayer._Draw(false);
		} else {
	//		theLayer._Clear();
		}
		return(ret);
	}
	return(false);
}

NCSJSView.prototype.GetLayerTransparency = function(layerName, sColors) {
	var theLayer = this._GetLayer(layerName);
	if(theLayer != null) {
		return(theLayer._GetTransparency(sColors));
	}
	return(Number.NaN);
}

NCSJSView.prototype.GetLayerRGB = function(layerName, dX, dY) {
	var theLayer = this._GetLayer(layerName);
	if(theLayer != null)
		return(theLayer._GetRGB(dX, dY));
	return("");
}

NCSJSView.prototype.SetLayerGDTDataDownloading = function(layerName, bUseOnDemand) {
	return;
}

NCSJSView.prototype.SetLayerVisible = function(layerName, bValue) {
	var theLayer = this._GetLayer(layerName);
	if(theLayer != null) {
		if(bValue) {
			theLayer.NCSJSViewDiv.style.visibility = "visible";
			theLayer._Draw(false, false);		
		} else {
			theLayer.NCSJSViewDiv.style.visibility = "hidden";
			theLayer._Clear();
		}
	}
}

NCSJSView.prototype.SetLayerClipRect = function(layerName, nTLX, nTLY, nBRX, nBRY) {
	var theLayer = this._GetLayer(layerName);
	if(theLayer != null) {
		theLayer.nClipTLX = nTLX;
		theLayer.nClipTLY = nTLY;
		theLayer.nClipBRX = nBRX;
		theLayer.nClipBRY = nBRY;
	}
}

NCSJSView.prototype.SetLayerClip = function(layerName, bValue) {
	var theLayer = this._GetLayer(layerName);
	if(theLayer != null) {	
		theLayer.bClip = bValue;
		if(!theLayer.bClip) {
			theLayer.NCSJSViewDiv.style.clip = "rect(auto auto auto auto)";
		}
		theLayer._Draw(false, false);		
	}
}

NCSJSView.prototype.GetLayerCellSizeX = function(layerName) {
	var theLayer = this._GetLayer(layerName);
	if(theLayer != null) {
		return(theLayer._GetCellSizeX());	
	}
	return(Number.NaN);
}

NCSJSView.prototype.GetLayerCellSizeY = function(layerName) {
	var theLayer = this._GetLayer(layerName);
	if(theLayer != null) {
		return(theLayer._GetCellSizeY());	
	}
	return(Number.NaN);
}

NCSJSView.prototype.GetLayerImageSizeX = function(layerName) {
	var theLayer = this._GetLayer(layerName);
	if(theLayer != null) {
		return(theLayer._GetImageSizeX());	
	}
	return(0);
}

NCSJSView.prototype.GetLayerImageSizeY = function(layerName) {
	var theLayer = this._GetLayer(layerName);
	if(theLayer != null) {
		return(theLayer._GetImageSizeY());	
	}
	return(0);
}

NCSJSView.prototype.GetLayerCellUnits = function(layerName) {
	var theLayer = this._GetLayer(layerName);
	if(theLayer != null) {
		return(theLayer._GetCellUnits());	
	}
	return(0);
}

NCSJSView.prototype.GetLayerVisibleImageTopLeftWorldCoordinateX = function(layerName) {
	var theLayer = this._GetLayer(layerName);
	if(theLayer != null) {
		var dLayerTLX = theLayer._GetTopLeftWorldCoordinateX();	
		var dLayerTLY = theLayer._GetTopLeftWorldCoordinateY();	
		var dLayerBRX = theLayer._GetBottomRightWorldCoordinateX();	
		var dLayerBRY = theLayer._GetBottomRightWorldCoordinateY();	
		
		if(dLayerTLX >= this.dViewBRX || dLayerBRX <= this.dViewTLX ||
		   dLayerTLY <= this.dViewBRY || dLayerBRY >= this.dViewTLY) {
			return(0.0);   
		}
		return(Math.max(dLayerTLX, this.dViewTLX));
	}
	return(Number.NaN);	
}

NCSJSView.prototype.GetLayerVisibleImageTopLeftWorldCoordinateY = function(layerName) {
	var theLayer = this._GetLayer(layerName);
	if(theLayer != null) {
		var dLayerTLX = theLayer._GetTopLeftWorldCoordinateX();	
		var dLayerTLY = theLayer._GetTopLeftWorldCoordinateY();	
		var dLayerBRX = theLayer._GetBottomRightWorldCoordinateX();	
		var dLayerBRY = theLayer._GetBottomRightWorldCoordinateY();	
		
		if(dLayerTLX >= this.dViewBRX || dLayerBRX <= this.dViewTLX ||
		   dLayerTLY <= this.dViewBRY || dLayerBRY >= this.dViewTLY) {
			return(0.0);   
		}
		return(Math.min(dLayerTLY, this.dViewTLY));
	}
	return(Number.NaN);	
}

NCSJSView.prototype.GetLayerVisibleImageBottomRightWorldCoordinateX = function(layerName) {
	var theLayer = this._GetLayer(layerName);
	if(theLayer != null) {
		var dLayerTLX = theLayer._GetTopLeftWorldCoordinateX();	
		var dLayerTLY = theLayer._GetTopLeftWorldCoordinateY();	
		var dLayerBRX = theLayer._GetBottomRightWorldCoordinateX();	
		var dLayerBRY = theLayer._GetBottomRightWorldCoordinateY();	
		
		if(dLayerTLX >= this.dViewBRX || dLayerBRX <= this.dViewTLX ||
		   dLayerTLY <= this.dViewBRY || dLayerBRY >= this.dViewTLY) {
			return(0.0);   
		}
		return(Math.min(dLayerBRX, this.dViewBRX));
	}
	return(Number.NaN);	
}

NCSJSView.prototype.GetLayerVisibleImageBottomRightWorldCoordinateY = function(layerName) {
	var theLayer = this._GetLayer(layerName);
	if(theLayer != null) {
		var dLayerTLX = theLayer._GetTopLeftWorldCoordinateX();	
		var dLayerTLY = theLayer._GetTopLeftWorldCoordinateY();	
		var dLayerBRX = theLayer._GetBottomRightWorldCoordinateX();	
		var dLayerBRY = theLayer._GetBottomRightWorldCoordinateY();	
		
		if(dLayerTLX >= this.dViewBRX || dLayerBRX <= this.dViewTLX ||
		   dLayerTLY <= this.dViewBRY || dLayerBRY >= this.dViewTLY) {
			return(0.0);   
		}
		return(Math.max(dLayerBRY, this.dViewBRY));
	}
	return(Number.NaN);	
}

NCSJSView.prototype._ConvertCoords = function(sD, sP, sXY, dD, dP) {
	//[03] returns without doing reprojection.
	if(sD == dD && sP == dP) {
		// No Conversion required
		return(sXY);
	}
	if(this.bHaveProxy) {
		this._SetWaitCursor();
		var AJAX = new NCSAJAX();
		var dom = AJAX.GetXML((this.bSSLProxy ? "https://" : "http://") + document.location.host + "/ecwp/jsviewproxy.dll?xCMD=CVT&xSD=" + sD + "&xSP=" + sP + "&xDD=" + dD + "&xDP=" + dP + "&xSX=" + sXY[0] + "&xSY=" + sXY[1], null, "GET");
		this._SetCursor(false);
		if(dom != null) {
			var txt = dom.getElementText("CVT").split(",");
			return(new Array(parseFloat(txt[0]), parseFloat(txt[1])));
		}
	}
	return(null);
}

NCSJSView.prototype._GetCoordLatLon = function(dX, dY) {
	for(i = 0; i < this.Layers.length; i++) {
		var theLayer = this.Layers[i];
		if(theLayer.sDatum && theLayer.sDatum.length > 0 && 
		   theLayer.sProjection && theLayer.sProjection.length > 0) {
			var a = this._ConvertCoords(theLayer.sDatum, theLayer.sProjection, 
										new Array(dX, dY), 
										"WGS84", "GEODETIC");
			if(a && a.length == 2) {
				return(a);
			}
			return(null);
		}
	}
	return(null);
}

NCSJSView.prototype.GetCoordLatitude = function(dX, dY) {
	var a = this._GetCoordLatLon(dX, dY);
	if(a) {
		return(a[1]);
	}
	return(Number.NaN);
}

NCSJSView.prototype.GetCoordLongitude = function(dX, dY) {
	var a = this._GetCoordLatLon(dX, dY);
	if(a) {
		return(a[0]);
	}
	return(Number.NaN);
}

NCSJSView.prototype._GetCoordEN = function(dX, dY) {
	for(i = 0; i < this.Layers.length; i++) {
		var theLayer = this.Layers[i];
		if(theLayer.sDatum && theLayer.sDatum.length > 0 && 
		   theLayer.sProjection && theLayer.sProjection.length > 0) {
			var a = this._ConvertCoords("WGS84", "GEODETIC", 
										new Array(dX, dY), 
										theLayer.sDatum, theLayer.sProjection);
			if(a && a.length == 2) {
				return(a);
			}
			return(null);
		}
	}
	return(null);
}

NCSJSView.prototype.GetCoordEasting = function(dLat, dLong) {
	var a = this._GetCoordEN(dLong, dLat);
	if(a) {
		return(a[0]);
	}
	return(Number.NaN);
}

NCSJSView.prototype.GetCoordNorthing = function(dLat, dLong) {
	var a = this._GetCoordEN(dLong, dLat);
	if(a) {
		return(a[1]);
	}
	return(Number.NaN);
}

NCSJSView.prototype._GetParamFromPVPairs = function(aPVPairs, sName) { 
	var i;
	sName = sName.toLowerCase();
	for(i = 0; i < aPVPairs.length; i++) {
		if(aPVPairs[i][0] == sName) {
			return(aPVPairs[i][1]);
		}
	}
	return(null);
}

NCSJSView.prototype._ParseParamList = function (paramList) {
	var aParts = paramList.split(";");
	var i;
	var aPVPairs = new Array();
	
	for(i = 0; i < aParts.length; i++) {
		var iIndex = aParts[i].indexOf("=");
		aPVPairs[aPVPairs.length] = new Array(aParts[i].substr(0, iIndex).toLowerCase(), aParts[i].substr(iIndex + 1));
	}
	return(aPVPairs);
}

NCSJSView.prototype.SetLayerParameter = function(layerName, paramList) {
	var bRet = true;
	var theLayer = this._GetLayer(layerName);
	if(theLayer != null) {
		var aPVPairs = this._ParseParamList(paramList);
		var i;
		var bURL = false;
		for(i = 0; i < aPVPairs.length; i++) {
			if(aPVPairs[i][0].toLowerCase() == "url") {
				bURL = true;
			}
			bRet &= theLayer._SetParameter(aPVPairs[i]);
		}
		if(bURL) {
			bRet &= theLayer._Open();
		}
	}
	return(bRet);
}

NCSJSView.prototype.GetLayerParameter = function(layerName, paramName) {
	var theLayer = this._GetLayer(layerName);
	if(theLayer != null) {
		return(theLayer._GetParameter(paramName));
	}
	return("");
}
