/* the code from the NCSAJAX.js and NCSJSView.js files is copied in here in entirety
   because the hard-coded pages for the atlases does not include them, and they are 
   needed for non-plugin viewing.  */

// There is a major bug in Mozilla where the onLoad event for the body gets called before the
// plugins on the page are loaded, this seems to work around it.
var tOnLoadTimer = null;
var vectorMode = "polygon";
var ECWVectorLayer = null;
var clickmapbuilder = false;

var ImageLinkPrefix = '../';
var ImageLinkSuffix = '.htm';

var sFilename2 = "";
var sFilename3 = "";

var ECWNoPluginUrl = "/ecwplugins/download.htm";

var nResult;
nResult = ECWCheck();	

if (nResult <= 0) 
{
	/*
	if( document.images )
		location = ECWNoPluginUrl;
	else
		location.href = ECWNoPluginUrl;
	*/
	setCookie("NCSPluginInstallMethod", "HTML");
} 
else if (nResult == 6) 
{
	setCookie("NCSPluginInstallMethod", "HTML");
}


function SetExtentsFitWidth() {

	var TLX = document.ECWView1.GetLayerImageTopLeftWorldCoordinateX("RasterLayer");
	var TLY = document.ECWView1.GetLayerImageTopLeftWorldCoordinateY("RasterLayer");
	var BRX = document.ECWView1.GetLayerImageBottomRightWorldCoordinateX("RasterLayer");
	var BRY = document.ECWView1.GetLayerImageBottomRightWorldCoordinateY("RasterLayer");
	
	if (sFilename2 != "") {
	
		TLX = Math.min(TLX, document.ECWView1.GetLayerImageTopLeftWorldCoordinateX("RasterLayer2"));
		TLY = Math.min(TLY, document.ECWView1.GetLayerImageTopLeftWorldCoordinateY("RasterLayer2"));
		BRX = Math.max(BRX, document.ECWView1.GetLayerImageBottomRightWorldCoordinateX("RasterLayer2"));
		BRY = Math.max(BRY, document.ECWView1.GetLayerImageBottomRightWorldCoordinateY("RasterLayer2"));
		
	}

	if (sFilename3 != "") {
	
		TLX = Math.min(TLX, document.ECWView1.GetLayerImageTopLeftWorldCoordinateX("RasterLayer3"));
		TLY = Math.min(TLY, document.ECWView1.GetLayerImageTopLeftWorldCoordinateY("RasterLayer3"));
		BRX = Math.max(BRX, document.ECWView1.GetLayerImageBottomRightWorldCoordinateX("RasterLayer3"));
		BRY = Math.max(BRY, document.ECWView1.GetLayerImageBottomRightWorldCoordinateY("RasterLayer3"));
		
	}

	var w = document.ECWView1.GetViewWidth();
	var h = document.ECWView1.GetViewHeight();

	var y = (h/w)*(BRX-TLX) + TLY;
	
	document.ECWView1.SetExtents(TLX, TLY, BRX, y);

}

function SetExtentsFitAll() {

	var TLX = document.ECWView1.GetLayerImageTopLeftWorldCoordinateX("RasterLayer");
	var TLY = document.ECWView1.GetLayerImageTopLeftWorldCoordinateY("RasterLayer");
	var BRX = document.ECWView1.GetLayerImageBottomRightWorldCoordinateX("RasterLayer");
	var BRY = document.ECWView1.GetLayerImageBottomRightWorldCoordinateY("RasterLayer");
	
	if (sFilename2 != "") {
	
		TLX = Math.min(TLX, document.ECWView1.GetLayerImageTopLeftWorldCoordinateX("RasterLayer2"));
		TLY = Math.min(TLY, document.ECWView1.GetLayerImageTopLeftWorldCoordinateY("RasterLayer2"));
		BRX = Math.max(BRX, document.ECWView1.GetLayerImageBottomRightWorldCoordinateX("RasterLayer2"));
		BRY = Math.max(BRY, document.ECWView1.GetLayerImageBottomRightWorldCoordinateY("RasterLayer2"));
		
	}

	if (sFilename3 != "") {
	
		TLX = Math.min(TLX, document.ECWView1.GetLayerImageTopLeftWorldCoordinateX("RasterLayer3"));
		TLY = Math.min(TLY, document.ECWView1.GetLayerImageTopLeftWorldCoordinateY("RasterLayer3"));
		BRX = Math.max(BRX, document.ECWView1.GetLayerImageBottomRightWorldCoordinateX("RasterLayer3"));
		BRY = Math.max(BRY, document.ECWView1.GetLayerImageBottomRightWorldCoordinateY("RasterLayer3"));
		
	}

	var w = document.ECWView1.GetViewWidth();
	var h = document.ECWView1.GetViewHeight();
	
	var y = (h/w)*(BRX-TLX) + TLY;
	document.ECWView1.SetExtents(TLX, TLY, BRX, BRY);

}

function LoadHandler() {
	clearTimeout(tOnLoadTimer);
	ECWToolbar1.setCurrentItem("UID_VIEW_PAN");
	
	//alert(sFilename);

	if (document.ECWView1.AddLayer("ECW", sFilename, "RasterLayer", "") < 0 ) {
	   //alert(document.ECWView1.GetLastErrorText());
	   //document.ECWView1.AddLayer("ECW", "ecwp://#servername#/ecwplugins/ecw_logo.ecw", "RasterLayer", "");
	   alert("Error opening ECW high-resolution image.  The image is not available.");
	   }
	
	if (clickmapbuilder == true) {
		alert("Image 1 width = " + document.ECWView1.GetLayerImageSizeX("RasterLayer"));
	}

	if (sFilename2 != "") {
		if (document.ECWView1.AddLayer("ECW", sFilename2, "RasterLayer2", "") < 0 ) {
		   alert(document.ECWView1.GetLastErrorText());
		   //document.ECWView1.AddLayer("ECW", "ecwp://#servername#/ecwplugins/ecw_logo.ecw", "RasterLayer", "");
		   alert("Error opening ECW high-resolution image.  The image is not available.");
		   }
		}

	if (sFilename3 != "") {
		if (document.ECWView1.AddLayer("ECW", sFilename3, "RasterLayer3", "") < 0 ) {
		   alert(document.ECWView1.GetLastErrorText());
		   //document.ECWView1.AddLayer("ECW", "ecwp://#servername#/ecwplugins/ecw_logo.ecw", "RasterLayer", "");
		   alert("Error opening ECW high-resolution image.  The image is not available.");
		   }
		}

	//alert("NCSPluginInstallMethod = " + getPluginInstallMethod("NCSPluginInstallMethod"));

	if (getPluginInstallMethod("NCSPluginInstallMethod") != "HTML") {

		// Add the clickmap builder simple vector overlay
		if (document.ECWView1.AddLayer("simplevector", "", "VectorOverlay", ";") < 0) {
			alert(document.ECWView1.GetLastErrorText());
		}
		else {
			ECWVectorLayer = new NCSVectorLayer(document.ECWView1, "VectorOverlay");
		}
		
		// Add the click areas
		if (LinkCount + LinkPolyCount > 0)
		{
			document.ECWView1.AddLayer("simplevector", "", "ClickAreaPoly", ";");
			document.ECWView1.AddLayer("simplevector", "", "ClickArea", ";");
			
			document.ECWView1.SetLayerParameter("ClickArea", "color=#FF0000;linewidth=3");
			document.ECWView1.SetLayerTransparency("ClickArea", "#", 0.5);
	
			document.ECWView1.SetLayerParameter("ClickAreaPoly", "color=#FF0000;linewidth=3");
			document.ECWView1.SetLayerTransparency("ClickAreaPoly", "#", 0.5);
	
			for (var i = 0; i < LinkCount; i++)
			{
				points = LinkTLX[i] + "," + LinkTLY[i] + "|" + LinkBRX[i] + "," + LinkTLY[i] + "|";
				points = points + LinkBRX[i] + "," + LinkBRY[i] + "|" + LinkTLX[i] + "," + LinkBRY[i];
				document.ECWView1.SetLayerParameter("ClickArea", "polygon" + (i+1) + "=" + points);
			}
	
			for (var i = 0; i < LinkPolyCount; i++)
			{
				var points = "";
				for (var j = 0; j < LinkPolyXs[i].length; j++)
				{
					if (j > 0)
					{
						points = points + "|";
					}
					points = points + LinkPolyXs[i][j] + "," + LinkPolyYs[i][j];
				}
				document.ECWView1.SetLayerParameter("ClickAreaPoly", "polygon" + (i+1) + "=" + points);
			}
		}
	}

	document.ECWView1.SetBackGroundColor("#DDDDDD");
	//document.ECWView1.SetExtentsAll();
	SetExtentsFitAll();
}				

function ECWToolbarCB(uid, value)
{
	if (uid == "UID_VIEW_PAN")
	{
		document.ECWView1.SetPointerMode(0);
	}
	else if (uid == "UID_VIEW_ZOOM")
	{
		document.ECWView1.SetPointerMode(1);
	}
	else if (uid == "UID_VIEW_ZOOMBOX")
	{
		document.ECWView1.SetPointerMode(3);
	}
	else if (uid == "UID_VIEW_POINTER")
	{
		vectorMode = "none";
		document.ECWView1.SetPointerMode(2);
	}
	else if (uid == "UID_ANNOT_SQUARE")
	{
		vectorMode = "rectangle";
		document.ECWView1.SetPointerMode(2);
	}
	else if (uid == "UID_ANNOT_POLYGON")
	{
		vectorMode = "polygon";
		// ECWVectorLayer.objectNumPoints = 0;
		document.ECWView1.SetPointerMode(2);
	}
	else if (uid == "UID_ANNOT_CIRCLE")
	{
		vectorMode = "circle";
		document.ECWView1.SetPointerMode(2);
	}
	else if (uid == "UID_VIEW_CUT")
	{
		ECWVectorLayer.clear();
	}
	else if (uid == "UID_VIEW_WIDTH")
	{
		SetExtentsFitWidth();
	}
	else if (uid == "UID_VIEW_RESET")
	{
		SetExtentsFitAll();
		//document.ECWView1.SetExtentsAll();
	}
	else if (uid == "UID_IMAGE_COMBO")
	{
		document.ECWView1.DeleteAllLayers();
		if (document.ECWView1.AddLayer("ECW", value, "RasterLayer", "") < 0 ) {
			alert(document.ECWView1.GetLastErrorText());
		}
	}
	else if (uid == "UID_PRINT")
	{
		printWindow();
	}
}

function clickMap(worldX, worldY) {
	for (var i = 0; i < LinkCount; i++) {
		if (worldX <= LinkBRX[i] && worldX >= LinkTLX[i] && worldY <= LinkBRY[i] && worldY >= LinkTLY[i]) {
			document.location.href = ImageLinkPrefix + LinkImageId[i] + ImageLinkSuffix;
			return;
		}
	}
	for (var i = 0; i < LinkPolyCount; i++) {
		if (pointInPoly(LinkPolyXs[i], LinkPolyYs[i], worldX, worldY) == 1) 
		{
			document.location.href = ImageLinkPrefix + LinkPolyImageId[i] + ImageLinkSuffix;
			return;
		}
	}
}

/*
Point in Polygon function
Copyright (c) 1970-2003, Wm. Randolph Franklin 
http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html

Permission is hereby granted, free of charge, to any person obtaining a copy 
of this software and associated documentation files (the "Software"), to deal 
in the Software without restriction, including without limitation the rights 
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
copies of the Software, and to permit persons to whom the Software is 
furnished to do so, subject to the following conditions: 

1. Redistributions of source code must retain the above copyright notice, this 
list of conditions and the following disclaimers. 

2. Redistributions in binary form must reproduce the above copyright notice in 
the documentation and/or other materials provided with the distribution. 

3. The name of W. Randolph Franklin may not be used to endorse or promote 
products derived from this Software without specific prior written permission.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
*/

function pointInPoly(xp, yp, x, y) {

	var i = 0;
	var j = 0;
	var c = 0;
	var npol = xp.length;
	
	for (j = npol - 1; i < npol; j = i++) {
        if ((((yp[i]<=y) && (y<yp[j])) ||
             ((yp[j]<=y) && (y<yp[i]))) &&
            (x < (xp[j] - xp[i]) * (y - yp[i]) / (yp[j] - yp[i]) + xp[i])) {
          if (c == 0) 
		  	c = 1;
		  else 
		    c = 0;
		}
	}
	return c;
}

// ---------------------- MOUSE FUNCTIONS ---------------------------

function ECWMouseDown(buttonMask, dScreenX, dScreenY , worldx, worldy)
{
	if (vectorMode != "none")
	{
    	var filled = false;
    	ECWVectorLayer.setMode((filled ? "filled" : "") + vectorMode);
        ECWVectorLayer.mouseDown(worldx, worldy);
    }
}

function ECWMouseUp(buttonMask, dScreenX, dScreenY , worldx, worldy)
{
	if (vectorMode != "none")
	{
		ECWVectorLayer.mouseUp(worldx, worldy);

		if (clickmapbuilder == true)
		{
			//update the fields with the points
			imgdata.points.value = ECWVectorLayer.objectPointsX + "; " + ECWVectorLayer.objectPointsY;
	
			var r = imgdata.points.createTextRange();
			r.select();
			r.execCommand('copy');
	
		}
    }
	else
	{
		clickMap(worldx, worldy);
	}
	
}

function ECWMouseMove(buttonMask, dScreenX, dScreenY , worldx, worldy)
{
	if (vectorMode != "none")
	{
	   ECWVectorLayer.mouseMove(worldx, worldy);
    }
}

function ECWVectorSetLineWidth(value)
{
    ECWVectorLayer.lineThickness = value;
    ECWVectorLayer.redraw();
}

function ECWVectorSetPenColor(value)
{
    ECWVectorLayer.penColor = value;
    ECWVectorLayer.redraw();
}

function ECWVectorSetFillColor(value)
{
    ECWVectorLayer.fillColor = value;
    ECWVectorLayer.redraw();
}


function onLoadCB() {
	tOnLoadTimer = setTimeout("LoadHandler()", 500);
}

function close_image()
{
	//document.ECWView1.Close(true); 
}

function prep_filename(sFile)
{
/*
	var sBase = window.location.href.substr(0, window.location.href.lastIndexOf("/"));
	sBase = sBase.substr(0, sBase.lastIndexOf("/"));
	sBase = sBase.replace("file:///", "");
	sBase = sBase.replace("file://", "//");
	var sFilename = sBase + sFile;
	sFilename = sFilename.replace(/\//g, "\\");
	sFilename = sFilename.replace(/%20/g, " ");
*/
	if (sFile.indexOf('HGSv') != -1) {
		sFile = sFile.replace(/\/ecw\//, '/');
		return 'ecwp://' + location.host + '/pab-images/original/FLP/HGS' + sFile;
	} else {
		return 'ecwp://' + location.host + '/rdic-images' + sFile;
	}
}
function printWindow() {

	//ECWToolbar1.setCurrentItem('UID_VIEW_PAN');

	//mb = document.getElementById('menubar');
	//t1 = document.getElementById('temp1');

	//mb.swapNode(t1);

	factory.printing.portrait = false;
	factory.printing.header = '';
	factory.printing.footer = '';
	factory.printing.leftMargin = 0.25;
	factory.printing.topMargin = 0.25;
	factory.printing.rightMargin = 0.25;
	factory.printing.bottomMargin = 0.25;
	factory.printing.Print(true);
	
	//mb.swapNode(t1);
}


/********************************************************
** NCSJSView.js
**
** Copyright 2005 Earth Resource Mapping Ltd.
** This document contains unpublished source code of
** Earth Resource Mapping Pty Ltd. 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;
	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;
        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) {
			this.style.filter = null;
		} 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);
			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;
		_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._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 "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";
}

NCSJSViewEcwLayer.prototype._GetDSInfo = function() {
	if(this.sProtocol.toLowerCase() == "ecwps:") {
		return("https://" + this.sServer + this.sImageXPath + "?dsinfo?layers=" + this.sRelPath);
	} else {
		return("http://" + this.sServer + this.sImageXPath + "?dsinfo?layers=" + this.sRelPath);
	}
}

NCSJSViewEcwLayer.prototype._GetSrc = function(nSizeX, nSizeY, dWorldTLX, dWorldTLY, dWorldBRX, dWorldBRY, level, tx, ty) {
	var sSrc = "";
	if(this.sProtocol.toLowerCase() == "ecwps:") {
		sSrc = "https://" + this.sImgServer + this.sImageXPath + "?image?";
	} else {
		sSrc ="http://" + this.sImgServer + 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;

	return(sSrc);
}

NCSJSViewEcwLayer.prototype._SetSrcQuality = function(sSrc, nQuality) {
	var urlParts = sSrc.split("&quality=");
	return(urlParts[0] + "&quality=" + nQuality);
}

NCSJSViewEcwLayer.prototype._Open = function() {
	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) > 0);
		}
		return(false);
	}
	return(false);
}

NCSJSViewEcwLayer.prototype._Init = function(xmlDoc) {
 	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");
        
		this.nImageWidth = parseInt(ecwFile.getAttribute("width"));
		this.nImageHeight = parseInt(ecwFile.getAttribute("height"));
		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();
		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 {
			this.theView.Draw(false);
		}
		return(1);
	} else if(ecwError != null) {
		this.theView.sErrorMsg = ecwError.getText();// + " \"" + this.sURL + "\"";
		return(-1);
	} else {
		this.theView.sErrorMsg = "Failed to open " + "\"" + this.sURL + "\"";;
	}
	return(0);
}

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;
		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;
		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;

		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.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="";
		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) {
	return(this.AJAX.PostEx(sURL, sBody, sAction, initFunc, this, bAsync));
}

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.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + encodeURI(theLayer.sImageSrc) + "',sizingMethod='scale',enabled=true);";
								//this.onload = null;
								img.src = "/ecwplugins/lib/bitmaps/Transparent.gif";
							} 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._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) {	
		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.bIsIE = false;
	this.dIEVersion = 5.0;
	var sUserAgent = navigator.userAgent;
	var nIndexOfMSIE = sUserAgent.indexOf("MSIE");
	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 );
	}
		
	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));
	
	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._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 Leica Geosystems for details.";
		return(-1);
	}
	if(sLayerType.toUpperCase() == "SIMPLEVECTOR") {
		this.sErrorMsg = "SIMPLEVECTOR layers are currently not supported.  Contact Leica Geosystems 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) {
		this.onmousedown(Mask, ScreenX, ScreenY, dWorldX, dWorldY);
	}
}

NCSJSView.prototype.FireOnMouseMove = function(Mask, ScreenX, ScreenY, dWorldX, dWorldY)
{
	if(this.GetPointerMode() == PM_POINTER) {
		this.onmousemove(Mask, ScreenX, ScreenY, dWorldX, dWorldY);
	}
}

NCSJSView.prototype.FireOnMouseUp = function(Mask, ScreenX, ScreenY, dWorldX, dWorldY)
{
	if(this.GetPointerMode() == PM_POINTER) {
		this.onmouseup(Mask, ScreenX, ScreenY, dWorldX, dWorldY);
	}
}

NCSJSView.prototype.FireOnExtentChange = function(dWorldTLX, dWorldTLY, dWorldBRX, dWorldBRY)
{
    var t = this._FireOnExtentChangeTimer;
    t.setData(new Array(this, dWorldTLX, dWorldTLY, dWorldBRX, dWorldBRY));
    t.start();
}

NCSJSView.prototype.FireOnPointerModeChange = function(Mode)
{
	this.onpointermodechange(Mode);
}

NCSJSView.prototype.FireOnGeolinkModeChange = function(Mode)
{
	this.ongeolinkmodechange(Mode);
}

NCSJSView.prototype.FireOnPercentComplete = function()
{
    this._FireOnPercentCompleteTimer.start();
}

NCSJSView.prototype.FireOnDrawBegin = function()
{
	this.ondrawbegin();
}

NCSJSView.prototype.FireOnDrawEnd = function()
{
	this.ondrawend();
}

NCSJSView.prototype.FireOnLoad = function()
{
	this.onload();
}

NCSJSView.prototype.FireOnLayerResponse = function(sLayerName, sURL, sBody, sAction, dWorldTLX, dWorldTLY, dWorldBRX, dWorldBRY, sResponse) {
	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);
	}
}

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
		/* problem with firefox, 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;
			this.NCSJSViewDivZoom.style.width = this.nMouseX - this.nMouseStartX;
		} else {
			this.NCSJSViewDivZoom.style.left = this.nMouseX;
			this.NCSJSViewDivZoom.style.width = this.nMouseStartX - this.nMouseX;
		}
		if(this.nMouseY > this.nMouseStartY) {
		    this.NCSJSViewDivZoom.style.top = this.nMouseStartY;
			this.NCSJSViewDivZoom.style.height = this.nMouseY - this.nMouseStartY;
		} else {
			this.NCSJSViewDivZoom.style.top = this.nMouseY;
			this.NCSJSViewDivZoom.style.height = this.nMouseStartY - this.nMouseY;
		}
		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 dNewWorldTLX = dWorldX;
		var dNewWorldTLY = dWorldY;
		var dNewWorldBRX = dWorldX;
		var dNewWorldBRY = dWorldY;

		// Click-zoom
		if((mouseMask & MVK_SHIFT && mouseMask & MVK_LBUTTON) || mouseMask & MVK_RBUTTON) {		
			// Zoom Out
			var dWorldPerPixelX = this.dWorldPerPixelX * this.dZoomStep;
			var dWorldPerPixelY = this.dWorldPerPixelY * this.dZoomStep;
			dNewWorldTLX -= nNewX * dWorldPerPixelX;
			dNewWorldTLY -= nNewY * dWorldPerPixelY;
			dNewWorldBRX += (this.GetViewWidth() - nNewX) * dWorldPerPixelX;
			dNewWorldBRY += (this.GetViewHeight() - nNewY) * dWorldPerPixelY;
		} else {
			// Zoom In
			var dWorldPerPixelX = this.dWorldPerPixelX * 1.0 / this.dZoomStep;
			var dWorldPerPixelY = this.dWorldPerPixelY * 1.0 / this.dZoomStep;
			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 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);
				}
			}
		}
		this.SetExtents(dWorldTLX, 
						dWorldTLY, 
						dWorldBRX,
						dWorldBRY);
	}
}

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;
		eval("_NCSJSView_Find(" + this.nViewID + ")." + paramName.toLowerCase() + "=" + ((callBack != null) ? (callBack.replace("()", "").replace(";","")) : "_NCSJSView_NullCB") + ";");
		info.bTrigger = 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":
					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;
			}
			return(true);
		}
	}
	return(false);
}

NCSJSView.prototype.DeleteAllLayers = function() {
	while(this.Layers.length > 0) {
		this.DeleteLayer(this.Layers[0].sLayerName);
	}
}

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("");
}

/********************************************************
** NCSAJAX.js
**
** Copyright 2005 Earth Resource Mapping Ltd.
** This document contains unpublished source code of
** Earth Resource Mapping Pty Ltd. This notice does
** not indicate any intention to publish the source
** code contained herein.
**
** CREATED:  01 Sep 2005
** AUTHOR:   Simon Cope
** PURPOSE:  AJAX and DOM JS objects.
**
** EDITS:    [xx] ddMmmyy NAME COMMENTS
*******************************************************/

Array.prototype.remove = function(i) {
	var res = null;
	if(typeof(i) == "number") {
		if(i < this.length) {
		    if(typeof(this.splice) == "function") {
		        res = this.splice(i, 1);
		    } else if(i == 0) {
				this.reverse();
				res = this.pop();
				this.reverse();
			} else if(i == this.length - 1) {
				res = this.pop();
			} else {
				var aLeft = (i > 0) ? this.slice(0, i) : new Array();
				var aRight = (i < this.length - 1) ? this.slice(i + 1, this.length) : new Array();
				res = this.slice(i, 1)[0];
				while(this.length) {
					this.pop();
				}
				aLeft = aLeft.concat(aRight);
				aLeft.reverse();
				while(aLeft.length) {
					this.push(aLeft.pop());
				}
			}
		}
	} else {
		var j;
		for(j = this.length-1; j >= 0; j--) {
			if(this[j] == i) {
				res = this.remove(j);
				//break;
			}
		}
	}
	return(res);
}

Array.prototype.endIterate = function() {
	this.bEndIterate = true;
}

Array.prototype.iterate = function() {
	var rVal = true;
	var a = arguments;
	var func = a[0];
	this.bEndIterate = false;
	var i;
	var len = this.length;
	switch(a.length) {
		case 0:
				for(i = 0; i < len && !this.bEndIterate; i++) {
					rVal |= func(this, this[i]);
				}
			break;
		case 1:
				for(i = 0; i < len && !this.bEndIterate; i++) {
					rVal |= func(this, this[i], a[1]);
				}
			break;
		case 2:
				for(i = 0; i < len && !this.bEndIterate; i++) {
					rVal |= func(this, this[i], a[1], a[2]);
				}
			break;
		case 3:
				for(i = 0; i < len && !this.bEndIterate; i++) {
					rVal |= func(this, this[i], a[1], a[2], a[3]);
				}
			break;
		case 4:
				for(i = 0; i < len && !this.bEndIterate; i++) {
					rVal |= func(this, this[i], a[1], a[2], a[3], a[4]);
				}
			break;
		case 5:
				for(i = 0; i < len && !this.bEndIterate; i++) {
					rVal |= func(this, this[i], a[1], a[2], a[3], a[4], a[5]);
				}
			break;
		default:
				alert("ERROR: can't iterate with " + a.length + " arguments");
				rVal = false;
			break;
	}
	return(rVal);
}

//
// Static method to build a string - faster than s=s1+s2+s3...
//
String.build = function() {
	var len = arguments.length;
	var s = new Array(len);
	for(i = 0; i < len; i++) {
		s[i] = arguments[i];
	}
	return(s.join(""));
}
//
// CLASS NCSAJAXDOMElement
//
// NCSAJAXDOMElement class used by NCSAJAXDOM class to assist parsing XML server responses.
//
// These classes use the DOM XML parser if available, else cheap and dirty string manipulation
//
function NCSAJAXDOMElement(sElement, theElement) {
	this.theElement = theElement;
	this.tagName = sElement;
	this.nodeType = theElement.nodeType;
	this.ownerDocument = theElement.ownerDocument;
	this.bDOM = (typeof(this.theElement) != "string");
	if(this.bDOM) {
		NCSAJAXDOMElement.prototype.getElement = function(sElement) {
				var aEls = this.theElement.getElementsByTagName(sElement);
				if(aEls != null && aEls.length > 0)	{
					return(new NCSAJAXDOMElement(sElement, aEls[0]));
				}
				return(null);
			};
		NCSAJAXDOMElement.prototype.getElements = function() {
				var aEls = new Array();
				var i;
				var node = this.theElement.firstChild;
				while(node) {
					if(node.nodeType == 1) {
						aEls.push(new NCSAJAXDOMElement(node.tagName, node));
					}
					node = node.nextSibling;
				}
				if(aEls.length > 0) {
					return(aEls);
				}
				return(null);
			};
		NCSAJAXDOMElement.prototype.getText = function() {
				if(typeof(this.innerHTML) != "undefined") {
					return(this.innerHTML);
				} else {
   					var nodes = this.theElement.childNodes;
   					var len = nodes.length;
   					if(len == 1 && nodes[0].nodeType == 3) {
						return(nodes[0].data);
					} else {
						var s = "";
						for(var i=0; i < len; i++){
							var node = nodes[i];
							if(node.nodeType == 3){
								s += node.data;
							}
						}
						return(s);
					}
				}
				return(null);
			};
		NCSAJAXDOMElement.prototype.getElementText = function(sElement) {
				var el = this.getElement(sElement);
				if(el != null) {
					return(el.getText());
				}
				return(null);
			};
		NCSAJAXDOMElement.prototype.getAttribute = function(sAttribute) {
			return(this.theElement.getAttribute(sAttribute));
		}
	} else {
		NCSAJAXDOMElement.prototype.getElement = function(sElement) {
			var aEls = this.theElement.split(sElement + ">");
			if(aEls != null && aEls.length > 0)	{
				return(new NCSAJAXDOMElement(sElement, aEls[0]));
			}
			return(null);
		}

		NCSAJAXDOMElement.prototype.getElementText = function(sElement) {
			var el = this.getElement(sElement);
			if(el != null) {
				return(el.getText());
			}
			return(null);
		}

		NCSAJAXDOMElement.prototype.getText = function() {
			return(this.theElement.split("</")[0]);
		}

		NCSAJAXDOMElement.prototype.getAttribute = function(sAttribute) {
			if(this.theElement.split(sAttribute + "=\"").length > 1) {
				return(this.theElement.split(sAttribute + "=\"")[1].split("\"")[0]);
			} else if(this.theElement.split(sAttribute + "=").length > 1) {
				if(this.theElement.split(sAttribute + "=")[1].split(" ").length > 1) {
					return(this.theElement.split(sAttribute + "=")[1].split(" ")[0]);
				} else {
					return(this.theElement.split(sAttribute + "=")[1].split(">")[0]);
				}
			} else {
				return(null);
			}
		}

	}
}


//
// CLASS NCSAJAXDOM
//
// NCSAJAXDOM class to assist parsing XML server responses.
//
function NCSAJAXDOM(theResponse) {
	var res = theResponse;
	this.theResponse = res;
	this.bDOM = (typeof(this.theResponse) != "string");

	if(this.bDOM) {
		var dom = this;
		this.getElementsByTagName = function(sElement) {
				var aEls = null;
				aEls = this.theResponse.getElementsByTagName(sElement);
				if(aEls != null && aEls.length > 0) {
					var aVEls = new Array();
					var i;
					var len = aEls.length;
					for(i = 0; i < len; i++) {
						aVEls.push(new NCSAJAXDOMElement(sElement, aEls[i]));
					}
					return(aVEls);
				}
				return(null);
			}
	} else {
		this.getElementsByTagName = function(sElement) {
				var aEls = aEls = this.theResponse.split("<" + sElement);
				if(aEls != null && aEls.length) {
					var aVEls = new Array();
					aEls.remove(0);
					aEls.iterate(function(a, r) {
								var l = r.indexOf("/>");
								//if(l >= 0) l += ("/>").length;
								var l2 = r.indexOf("</" + sElement + ">");
								//if(l2 >= 0) l2 += ("</" + sElement + ">").length;
								if(l == -1) {
									l = l2;
								} else if(l2 >= 0) {
									l = Math.min(l, l2);
								}
								if(l == -1) {
									l = r.length;
								}
								//alert(r.substring(0, l));
								aVEls.push(new NCSAJAXDOMElement(sElement, r.substring(0, l)));
							});
					return(aVEls);
				}
				return(null);
			};
	}
}
/*
NCSAJAXDOM.prototype.getElementsByTagName = function(sElement) {
	var aEls = null;
	if(!this.bDOM) {
		aEls = this.theResponse.split("<" + sElement);
	} else {
		aEls = this.theResponse.getElementsByTagName(sElement);
	}
	if(aEls != null) {
		var aVEls = new Array();
		var i;
		for(i = 0; i < aEls.length; i++) {
			aVEls[aVEls.length] = new NCSAJAXDOMElement(sElement, aEls[i]);
		}
		return(aVEls);
	}
	return(null);
}*/

NCSAJAXDOM.prototype.getElementFromTagName = function(sElement) {
	var aEls = this.getElementsByTagName(sElement);
	if(aEls != null && aEls.length) {
		return(aEls[0]);
	}
	return(null);
}

NCSAJAXDOM.prototype.getElementText = function(sElement) {
	var el = this.getElementFromTagName(sElement);
	if(el != null) {
		return(el.getText());
	}
	return(null);
}

NCSAJAXDOM.prototype.serialize = function() {
//alert(typeof(XMLSerializer));//this.theResponse.childNodes[0].innerHTML);//.childNodes[0].tagName);
	if(!this.bDOM) {
		return(this.theResponse);
	} else if(this.theResponse.xml) {
		return(this.theResponse.xml);
	} else if(this.getElementFromTagName("BODY")) {
		return(this.getElementFromTagName("BODY").getText());
//	} else if(this.theResponse.childNodes && this.theResponse.childNodes.length > 0 && this.theResponse.childNodes[0].innerHTML) {
//		return(this.theResponse.childNodes[0].innerHTML);
	} else {
		try {
			// create serializer object
			var xmlSerializer = new XMLSerializer();
			// serialize
			var markup = xmlSerializer.serializeToString(this.theResponse);
			return(markup);
		} catch(e) {
			//debugger; //alert("Unknown response from server, type \"" + typeof(this.theResponse) + "\"");
		}
	}
}

//
// NCSAJAX_Timer class
//
var _NCSAJAX_Timers = new Array();
var _NCSAJAX_Timers_NextID = 0;

function NCSGetTimeStampMs() {
    var d = new Date();
    return(d.getTime());
}

function _NCSAJAX_TimerCB(nID) {
	var i;
	var len = _NCSAJAX_Timers.length;
	for(i = 0; i < len; i++) {
		var t = _NCSAJAX_Timers[i];

		if(t.nID == nID) {
			if(t.bOneShot) {
		        t.timerID = -1;
		    }
		    t.nLastTimeout = NCSGetTimeStampMs();
			t.func(t.data);
			break;
		}
	}
}

NCSAJAX_Timer = function(nTimeout, func, data, bOneShot) {
	this.nID = _NCSAJAX_Timers_NextID++;
	this.func = func;
	this.data = data;
	this.bOneShot = bOneShot;
	this.nTimeout = nTimeout;
	this.nLastTimeout = NCSGetTimeStampMs();
	this.timerID = -1;
	_NCSAJAX_Timers.push(this);
/*
	if(bOneShot) {
		this.timerID = window.setTimeout("_NCSAJAX_TimerCB(" + this.nID + ");", nTimeout);
	} else {
		this.timerID = window.setInterval("_NCSAJAX_TimerCB(" + this.nID + ");", nTimeout);
	}*/
}

NCSAJAX_Timer.prototype.setTimeout = function(nTimeout) {
	var bRunning = false;
	if(this.timerID != -1) {
		bRunning = true;
	}
	this.cancel();
    this.nTimeout = nTimeout;
	if( bRunning ) {
		this.start();
	}
}

NCSAJAX_Timer.prototype.setFunc = function(func) {
    this.func = func;
}

NCSAJAX_Timer.prototype.setData = function(data) {
    this.data = data;
}

// Cancel current timeout
NCSAJAX_Timer.prototype.cancel = function() {
    if(this.timerID != -1) {
	    window.clearTimeout(this.timerID);
	    this.timerID = -1;
	}
}

// Cancel current timeout and delete timer
NCSAJAX_Timer.prototype.stop = function() {
    this.cancel();
	_NCSAJAX_Timers.remove(this);
}

// Start timer if not currently started.
NCSAJAX_Timer.prototype.start = function() {
    if(this.timerID == -1) {
        if(this.bOneShot) {
	        this.timerID = window.setTimeout("_NCSAJAX_TimerCB(" + this.nID + ");", this.nTimeout);
        } else {
            this.timerID = window.setInterval("_NCSAJAX_TimerCB(" + this.nID + ");", this.nTimeout);
        }
    } else {
        var tsNow = NCSGetTimeStampMs();
        if(tsNow - this.nLastTimeout > this.nTimeout) {
            if(this.bOneShot) {
                window.clearTimeout(this.timerID);
		        this.timerID = -1;
		    }
		    this.nLastTimeout = tsNow;
			this.func(this.data);
        }
    }
}

// Restart (cancel/start) timer
NCSAJAX_Timer.prototype.restart = function() {
    this.cancel();
    this.start();
}

//
// NCSAJAX - Asynchronous Javascript and XML object
//
// Uses HTTPRequest
//
var _NCSAJAXs = new Array();

function _NCSAJAX_Find(nID) {
	var i;
	for(i = 0; i < _NCSAJAXs.length; i++) {
		if(_NCSAJAXs[i].nID == nID) {
			return(_NCSAJAXs[i]);
			break;
		}
	}
	return(null);
}

function NCSAJAX() {
	_NCSAJAXs[_NCSAJAXs.length] = this;
	this.nID = _NCSAJAXs.length;

	this.NCSAJAXXMLHttpRequest = null;
	this.initFunc = null;
	this.initData = null;
	this.bAsync = true;
}

// Post something to sURL
NCSAJAX.prototype.Post = function(sURL, sBody, sAction) {
	return(this.PostEx(sURL, sBody, sAction, null, null, true));
}

NCSAJAX.prototype.GetXML = function(sURL, sBody, sAction) {
	if(this.PostEx(sURL, sBody, sAction, function(dom, theAJAX) { theAJAX.m_GetXMLHookDOM = dom; return(1);	}, this, false)) {
		return(this.m_GetXMLHookDOM);
	}
	return(null);
}

NCSAJAX.prototype.Get = function(sURL, sBody, sAction) {
	var dom = this.GetXML(sURL, sBody, sAction);
	if(dom) {
		return(dom.serialize());
	}
	return(null);
}

NCSAJAX.prototype.PostEx = function(sURL, sBody, sAction, initFunc, initData, bAsync) {
//window.open(sURL);
	this.Cancel();

	try {
		var xmlDoc = null;
		if(typeof window.ActiveXObject != 'undefined' ) {
			xmlDoc = new ActiveXObject("Microsoft.XMLHTTP");
		} else if(typeof(XMLHttpRequest) != "undefined") {
			xmlDoc = new XMLHttpRequest();
		}
		if(xmlDoc != null) {
			this.NCSAJAXXMLHttpRequest = xmlDoc;
			
			if(bAsync) {
				xmlDoc.onreadystatechange = function() {
					try {
						if(xmlDoc.readyState==4 && xmlDoc.status==200) {
							if(initFunc != null) {
								//When the response MIME type is "text/xml", "application/xml" or "*/*+xml",
								//it should be parsed into xmlDoc.responseXML.  Otherwise, the response
								//will be in xmlDoc.responseText.
								var sContentType = xmlDoc.getResponseHeader("Content-Type");
								if (sContentType.indexOf("image") >= 0)
									initFunc(null, initData);
								else if (xmlDoc.responseXML && (xmlDoc.responseXML.xml != ""))
									initFunc(new NCSAJAXDOM(xmlDoc.responseXML), initData);
								else
									initFunc(new NCSAJAXDOM(xmlDoc.responseText), initData);
							}
						}
					} catch(ex) {
						// Firefox triggers an exception if NCSAJAX.prototype.Cancel is called while a request is pending.
					}
				};
			}
			//alert(xmlDoc.onreadystatechange);
			xmlDoc.open(sAction, sURL, bAsync);
			try {
				// Firefox does not correctly set the referer HTTP header, so we must do it manually
				xmlDoc.setRequestHeader('Referer', document.location);
			} catch(ex) { };
			xmlDoc.send(sBody);
			if(!bAsync && xmlDoc.readyState==4 && xmlDoc.status==200) {
				
				if(initFunc != null) {
					//When the response MIME type is "text/xml", "application/xml" or "*/*+xml",
					//it should be parsed into xmlDoc.responseXML.  Otherwise, the response
					//will be in xmlDoc.responseText.
					var sContentType = xmlDoc.getResponseHeader("Content-Type");
					if (sContentType.indexOf("image") >= 0)
						initFunc(null, initData);
					else if (xmlDoc.responseXML && (xmlDoc.responseXML.xml != ""))
						initFunc(new NCSAJAXDOM(xmlDoc.responseXML), initData);
					else
						initFunc(new NCSAJAXDOM(xmlDoc.responseText), initData);
				}
			} 
		}
	} catch(ex) {
		// When the resource cannot be located (Error number -2146697211) return that the post failed
		// and leave the alert to be processed higher up.
		if(ex.number != -2146697211)
		{
			alert("Post failed: " + ex.message);
		}
		return(false);
	}
	return(true);
}

NCSAJAX.prototype.Cancel = function() {
	if(this.NCSAJAXXMLHttpRequest != null) {
		switch(this.NCSAJAXXMLHttpRequest.readyState) {
			case 1://Loading
			case 2://Loaded
			case 3://Interactive	
				this.NCSAJAXXMLHttpRequest.abort();
				break;
			default://0 (Uninitialized) or 4 (Complete)
				break;
		}
		this.NCSAJAXXMLHttpRequest = null;
	}
}
