// display_map.js
/*
COPYRIGHT 1995-2005 ESRI

TRADE SECRETS: ESRI PROPRIETARY AND CONFIDENTIAL
Unpublished material - all rights reserved under the 
Copyright Laws of the United States.

For additional information, contact:
Environmental Systems Research Institute, Inc.
Attn: Contracts Dept
380 New York Street
Redlands, California, USA 92373

email: contracts@esri.com
*/

var mapMoveIncrement = 3;
if (isNav) mapMoveIncrement *=2;
var navDir = "";
var nav_active = false;
var nx = 0;
var ny = 0;
var tempToolMode = "MapZoomIn";
var nav_active = false;
var nav_dir = "";
var xDir = 0;
var yDir = 0;
var mouseDirection = "";
var panStartLeft = 0;
var panStartTop = 0;
var panStartCenterX = 0;
var panStartCenterY = 0;
var reloadTimer;
var m_fadeInterval;
var cacheUpdateDelay = 500;
var dynamicUpdateDelay = 1000;
var vectortoolbar = "VectorToolbar";
var mouseWheelAwayZoomIn = true;
var mapUseZoomAnimation = true;
var mapUseKeyboardNavigation = true;
var mapDefaultResourceId = "webTierBlendingOfAllResources";
var mapDefaultZoomInMode = "esriDefaultMapShiftDrag";
var mapDefaultZoomOutMode = "esriDefaultMapAltDrag";
var mapDefaultZoomInAction = "DragRectangle";
var mapDefaultZoomOutAction = "DragRectangle"
var mapDefaultZoomInCursor= "crosshair";
var mapDefaultZoomOutCursor = "crosshair";

var esriJavaScriptDecimalDelimiter = ((("theChar is" + (10/100)).indexOf("."))==-1) ? "," : "."; // get decimal delimiter used by JavaScript on user machine


var esriDirectToCacheURL = true;

function MapObject(controlName, viewWidth, viewHeight, tileWidth, tileHeight, totalLevels, startColumns, startRows, tileServerUrl) {
	inheritsFrom(new ControlObject(controlName, "Map", 0, 0, viewWidth, viewHeight), this);
	this.index = 0;
	this.mapType = "tile";
	this.name = controlName;
	this.divId = "MapDiv_" + controlName;
	this.divId2 = "MapDiv2_" + controlName;
	this.divScaleId2 = "MapDiv2Table_" + controlName;
	this.imageId = "MapImage_" + controlName;
	this.imageId2 = "MapImage2_" + controlName;
	this.vectorDivId = "LineDiv_" + controlName;
	this.snapCircleId = "SnapCircle_" + controlName;
	this.containerDivId = "MapControlDiv_" + this.controlName;
	this.maptipDivId = "MapTipLayerDiv_" + this.controlName;
	this.overlayDivId = "MapOverlayDiv_" + this.controlName;
	this.mozillaLinkId = "MapMozillaLink_" + this.controlName;
	this.parentId = null;
	this.dragBoxColor = "Black";
	this.dragLineWidth = 3;
	this.imageSizeFactor = 1;	
	this.lastWidth = viewWidth;
	this.lastHeight = viewHeight;

	this.containerLeft = 0;
	this.containerTop = 0;

	this.backColor = "White";

	this.imgUrl = "";
	this.cursor = "pointer";
	this.mapMoveIncrement = mapMoveIncrement;
	this.panBuffer = 0;
	
	this.navigationEnabled = true;
	// action flags
	this.drawBox = false;
	this.dragImage = false;
	this.drawShape = false;
	this.showLoading = false;
	
	this.actionType = "DragImage";
	this.clientAction = "DragImage";
	this.mode = "MapPan";
	// holders for mouse/key combo events
	this.tempMode = "MapPan";
	this.tempCursor = "move";
	this.tempAction = "DragAction";
	// mouse/key combo events
	    // shift.... mousedown/move/up ... default is MapZoomIn ... requires Map control has MapZoomIn/DragRectangle Tool Item
	this.shiftMode = mapDefaultZoomInMode;
	this.shiftAction = mapDefaultZoomInAction;
	this.shiftCursor = mapDefaultZoomInCursor;
	this.defaultShiftMode = mapDefaultZoomInMode;
	this.defaultShiftAction = mapDefaultZoomInAction;
	    // ctrl .... mousedown only... click ... no default
	this.ctrlMode = "";
	this.ctrlAction = "Point";
	this.ctrlCurosr = "pointer";
	this.ctrlFunction = ""; // function to handle after mousedown
	    // alt .... mousedown/move/up ... default is MapZoomOut ... requires Map control has MapZoomOut/DragRectangle Tool Item
	this.altMode = mapDefaultZoomOutMode;
	this.altAction = mapDefaultZoomOutAction;
	this.altCursor = mapDefaultZoomOutCursor;
	this.defaultAltMode = mapDefaultZoomOutMode;
	this.defaultAltAction = mapDefaultZoomOutAction;
	
	this.moveFunction = null;
	this.tempMoveFunction = null;
	this.preModeExecFunction = null;
	this.windowObject = mapWindow;
	
	// .NET ClientPostback properties
	this.pageID = "";
	this.forcePostBackEvent = "";
	
	// associated objects
	this.divObject = null;
	this.divObject2 = null;
	this.divScaleObject2 = null;
	this.imageObject = null;
	this.imageObject2 = null;
	this.vectorObject = null;
	this.snapCircleObject = null;
	this.loadingObject = null;
	this.containerObject = null;
	this.maptipObject = null;
	this.overlayObject = null;
//	this.backObject = null;
	this.mozillaLinkObject = null;
	
    this.callBackFunctionString = "";
    this.tileCallbackFunctionString = "";
    this.identifyCallbackFunctionString = "";
    this.vectorCallbackFunctionString = "";
	
   this.mapType = "tile";
   this.tileRequestType = "single"; // single or multiple
   this.viewWidth = viewWidth;
   this.viewHeight = viewHeight;
   this.viewLeft = 0;
   this.viewTop = 0;
   this.tileWidth = tileWidth;
   this.tileHeight = tileHeight;
   this.lastTileWidth = 0;
   this.lastTileHeight = 0;
   this.totalLevels = totalLevels;
   this.startColumns = startColumns;
   this.startRows = startRows;
   this.level = 0;
   this.columns = startColumns;
   this.rows = startRows
   this.continuousCallback = false;
   this.viewNumbers = new Array();
   
   this.columnsPerView = Math.ceil(viewWidth/tileWidth);
   this.rowsPerView = Math.ceil(viewHeight/tileHeight);
   this.lastColumnsPerView = 0;
   this.lastRowsPerView = 0;
   
   this.startColumn = 0;
   this.startRow = 0;
   this.startLeftOffset = 0;
   this.startTopOffset = 0;
   this.currentLeftColumn = 0;
   this.currentTopRow = 0;
   this.currentRightColumn = 0;
   this.currentBottomRow = 0;
   this.bufferLeftColumn = 0;
   this.bufferTopRow = 0;
   this.bufferRightColumn = 0;
   this.bufferBottomRow = 0;
   this.leftOffset = 0;
   this.topOffset = 0;
   this.gridWidth = 0;
   this.gridHeight = 0;
   
   this.useScrollWheel = true;
   
    this.currentLeftColumnBuffer = -9999999;
    this.currentTopRowBuffer = -9999999;
    this.currentRightColumnBuffer = -9999999;
    this.currentBottomRowBuffer = -9999999;
    this.currentXOffset = 0;
    this.currentYOffset = 0;
    this.lastLeftColumn = -9999999;
    this.lastTopRow = -9999999;   			
    this.lastRightColumn = -9999999;
    this.lastBottomRow = -9999999; 
    this.lastLeftColumnBuffer = -9999999;
    this.lastTopRowBuffer = -9999999;   			
    this.lastRightColumnBuffer = -9999999;
    this.lastBottomRowBuffer = -9999999; 
    
    this.baseTileColumn = 0;
    this.baseTileRow = 0;
    this.baseTileXOffset = 0;
    this.baseTileYOffset = 0;
    this.gridXOffset = 0;
    this.gridYOffset = 0;
   
   this.navDivId = "MapNavDiv_" + this.controlName;
   this.navDivObject = null;
   
   this.displayedTiles = new Array();
   this.requestedMapTipTiles = new Array();
   this.keyFocus = true;
//   this.TilesToGet = new Array();
//   this.TilesToClear = new Array();
//   this.TilesToHold = new Array();
   
   this.enableResizeEvent = false;
   this.widthSizeFactor = 1.0;
   this.heightSizeFactor = 1.0
   
   this.resizeExtent = false;
   this.lastViewBox = null;
   
   this.blankImagePath = esriBlankImagePath;
   this.blankImageObject = new Image();
   this.mapDiv2UpdateDelay = 1000;
   
   this.mapUnits = "Degrees";
   this.measureUnits = "Miles";
   this.clearDrawnVectors = true;
   this.currentVectorToolbarState = "hidden"; 
 	
	this.tileServerUrl = tileServerUrl;
	this.enableTileCaching = true;
	
	this.decimalDelimiter = esriSystemDecimalDelimiter;
	this.useZoomAnimation = true;	
	//this.ie6AlphaDisplayType = "AlphaImageLoader"; // type of alpha display used on IE6... AlphaImageLoader or VML
	this.forcePngAlphaOnBase = false; // force IE6 alpha loader on png images on base animation later? False will speed in transparency is not needed
	
   this.startUp = true;
   this.clearLevelGridCount = 0;
   this.changeLevelGridCount = -1;
    
   this.createDivs = function(mapContainer, startResourceList, returnString) {
        var containerDiv = null;
        var vWidth1 = this.viewWidth + "px";
        var vHeight1 = this.viewHeight + "px";
   	    if (mapContainer!=null && mapContainer!="") 
		        containerDiv = document.getElementById(mapContainer);
        
        if (returnString==null) returnString = false;
        if (startResourceList==null) startResourceList = mapDefaultResourceId + "||true|";
        var tempSize = 1;
        if (String(this.viewHeight).indexOf("%")!=-1) {
            tempSize = parseInt(this.viewHeight);
            vHeight1 = this.viewHeight;
            this.heightSizeFactor = tempSize / 100;
            this.enableResizeEvent = true;
            if (containerDiv!=null)
                this.viewHeight = Math.round(getElementHeight(containerDiv) * this.heightSizeFactor);
            else 
                this.viewHeight = Math.round(getWinHeight() * this.heightSizeFactor);
            this.height = this.viewHeight;
        }
        if (String(this.viewWidth).indexOf("%")!=-1) {
            vWidth1 = this.viewWidth;
            
            tempSize = parseInt(this.viewWidth);
            this.widthSizeFactor = tempSize / 100;
            this.enableResizeEvent = true;
            if (containerDiv!=null)
                this.viewWidth = Math.round(getElementWidth(containerDiv) * this.widthSizeFactor);
            else 
                this.viewWidth = Math.round(getWinWidth() * this.widthSizeFactor);
            this.width = this.viewWidth;
        }
        var vWidth2 = this.viewWidth + "px";
        var vHeight2 = this.viewHeight + "px";
        if (this.tileWidth==0) this.tileWidth = this.viewWidth;
        if (this.tileHeight==0) this.tileHeight = this.viewHeight;
		var d = this.divId;
	    var s = "";
	    s+='<div id="MapControlDiv_' + this.controlName +'" style="position:relative; background-color:' + this.backColor + '; overflow:hidden; width:' + vWidth1 + '; height: ' + vHeight1 + '; -moz-user-focus: normal;" ';
	    s+=' onmouseover="Maps[\'' + this.controlName + '\'].keyFocus=true; ';
	    if (isIE) s+= 'this.setActive();';
	    s+= '" >\n';	
	    s+= '<a id="' + this.mozillaLinkId + '" ' + ((isNav) ? 'onmouseover="this.focus()" style="-moz-user-focus: normal;"' : '') + '>';
	    
        // backdrop for scaleable div.... hides main div when zooming
		s += '<div id="' + this.backDivId + '" style="position:absolute; left: 0px; top: 0px; width: ' + getWinWidth() + '; height: ' + getWinHeight() + '; visibility: hidden; background-color: ' + this.backColor + ';"  ><img src="' + this.blankImagePath + '" width="'+ getWinWidth() + '" height="' + getWinHeight() + '" hspace="0" vspace="0" /></div>\n';		
        // create scaleable div
		s += '<div id="' + this.divId2 + '" style="position:absolute; left:0px; top:0px;  width:' + vWidth1 + '; height:' + vHeight1 + '; visibility: hidden; background-color: ' + this.backColor + '; "  > \n';		
        //s += '<div id="' + this.divScaleId2 + '" style="position:absolute; left:0px; top:0px;  width:' + vWidth1 + '; height:' + vHeight1 + '; background-color: ' + this.backColor + ';" ></div></div>\n';
        s += '<div id="' + this.divScaleId2 + '" style="position:absolute; left:0px; top:0px;  width:' + vWidth1 + '; height:' + vHeight1 + '; background-color: ' + this.backColor + ';" >';
        s +='</div></div>\n';

			// Map div, container for the map images ... position is absolute within container
		s += '<div id="' + d + '" style="position:absolute; left:0px; top:0px;  width:' + vWidth1 + '; height:' + vHeight1 + '; "  >';
		    // Resource divs... multiple 'layers' for client-side blending... defaults to a single layer
		   var rcList = startResourceList.split(",");
		  // rcList.reverse(); // take top-down list and reverse for bottom-up display
		   for (var r=rcList.length-1; r>=0; r--) { 
		        if (rcList[r].indexOf("|")==-1) rcList[r] += "||true|"; 
		        var rid = rcList[r].split("|");
		        if (rid[1]==null) rid[1] = "";
		        if (rid[2]==null) rid[2] = true;
		        if (rid[4]==null) 
		            rid[4] = "";
		        else
		            rid[4] = rid[4].toLowerCase(); 
		        if (rcList.length==1) mapDefaultResourceId = rid[0];
		        if (r==rcList.length-1) this.baseResourceId = rid[0];
		        this.ResourceCollection[r] = new ResourceObject(rid[0], r,  rid[2].toLowerCase(), this.controlName, rid[1], rid[3], rid[4]); 
		        var resource = this.ResourceCollection[r];
		         s += '<div id="' + resource.divId + '" style="position:absolute; left:0px; top:0px;  width:' + vWidth1 + '; height:' + vHeight1 + '; "  ></div>\n';
		   } 
		s += '</div>\n';		
		
		// create MapTip Layer
        s += '<div id="' + this.maptipDivId + '" style="position:absolute; left:0px; top:0px; visibility:hidden; background-color:transparent;" ></div>\n';	
         
		var ldiv = "LineDiv_" + this.controlName;
		//create Map Vector Layer
		s += '<div id="' + ldiv + '" style="position:absolute; left:0px; top:0px; visibility: visible; background-color:transparent;" >\n';
		//if (isNav) s+= '<canvas id="Canvas_' + this.controlName + '" width="100%" height=100%"></canvas>\n';
		s += '</div>\n';	

        // create a snap circle
        if (isIE) {
            s += '<v:oval id="' + this.snapCircleId + '" style="width:2px; height: 2px; position: absolute; left: 100px; top: 100px; visibility: hidden; cursor: crosshair;"><v:stroke weight="2px" color="red"  dashstyle="solid" opacity="0.5" /><v:fill color="red" opacity="0.10" /></v:oval>\n';
        } else {
            // if Netscape 8, don't use canvas tag.... not supported
            if (nav8) 
                s += '<div id="' + this.snapCircleId + '" style="width:auto; height: auto; position: absolute; left: 100px; top: 100px; visibility: hidden; cursor: crosshair;  -moz-opacity: 0.5;"></div>';
            else   
                s += '<canvas id="' + this.snapCircleId + '" style="width:100px; height: 100px; position: absolute; left: 100px; top: 100px; visibility: hidden; cursor: crosshair;" width="100" height="100"></canvas>\n';
        }
		//create an Overlay Layer... place for icons, text, etc. to be positioned and moved with map... cleared on scale change
		s += '<div id="' + this.overlayDivId + '" style="position:absolute; left:0px; top:0px; visibility: visible; background-color:transparent;" ></div>\n';	
        
	    s += '</a>\n'; 
	    
	    s+='</div>';
	    //alert(s);
	    if (returnString) {
	        // just return the string....  map.setObjects() must be called manually
	        return s;
	        
	    } else {
	        if (mapContainer!=null && mapContainer!="") {
		        var div = document.getElementById(mapContainer);
		        div.innerHTML = s;
		        var box = calcElementPosition(mapContainer);
		        this.viewLeft = box.left;
		        this.viewTop = box.top;
		        //alert("View location: " + box.left + ", " + box.top);
	        } else {
		        document.writeln(s);
	        }
    	
		    this.setObjects();
		}
		if (this.blankImagePath!=null && this.blankImagePath.length>0)
		    this.blankImageObject.src = this.blankImagePath;
   } 
   
	this.setObjects = function () {
	    // add vector object to map
		this.vectorObject = new VectorObject(this.vectorDivId);
		var v = this.vectorObject;
		this.vectorObject.vectordiv = document.getElementById(this.vectorDivId);
		this.vectorObject.linewidth = this.dragLineWidth;
		this.vectorObject.divColor = this.dragBoxColor;
		this.vectorObject.pixelObject = new PixelObject(this.controlName, this.left,this.top,this.width,this.height);
		this.vectorObject.xyCoord = new CoordsObject();
        this.snapCircleObject = document.getElementById(this.snapCircleId);
		//if (isNav && !nav8) {
		if (isNav) {
		    if (nav8) {
		        var svo = new  VectorObject(this.snapCircleId);
		        svo.divColor = "Red";
		        svo.circle(1,1,1);
		        svo.draw();
		        this.snapCircleObject.vectorObject = svo;
		    } else {  
    //		    this.vectorObject.canvas = document.getElementById("Canvas_" + this.controlName);
    //		    if (this.vectorObject.canvas) this.vectorObject.context = this. vectorObject.canvas.getContext("2d");
                var ctx = this.snapCircleObject.getContext("2d");
                if (ctx!=null) {
                    var radius = Math.round(parseFloat(this.snapCircleObject.clientWidth) / 2); 
                    ctx.fillStyle = "rgba(255, 0, 0, 0.1)";
                    ctx.arc(radius, radius, radius, 0, Math.PI*2, true);
                    ctx.fill();
                    ctx.strokeStyle = "rgba(255, 0, 0, 0.5)";
                    ctx.lineWidth = 2;
                    ctx.arc(radius, radius, radius, 0, Math.PI*2, true);
                    ctx.stroke();
                }
              }
		}
        this.snapCircleObject.onmousedown = MapMouseDown;
        this.snapCircleObject.onmouseup = MapMouseUp;
        this.snapCircleObject.onmousemove = MapMouseMove;
        
		this.divObject = document.getElementById(this.divId);
		this.divObject2 = document.getElementById(this.divId2);
		this.divScaleObject2 = document.getElementById(this.divScaleId2);
		this.vectorObject.divObject = document.getElementById(this.vectorObject.divId);
		this.navDivObject = document.getElementById(this.navDivId);
		this.containerObject = document.getElementById(this.containerDivId);
		this.maptipObject = document.getElementById(this.maptipDivId);
		this.overlayObject = document.getElementById(this.overlayDivId);
		this.mozillaLinkObject = document.getElementById(this.mozillaLinkId);
		this.index = mapCount;
		this.pageLeft = parseInt(this.divObject.style.left);
		this.pageTop = parseInt(this.divObject.style.top);
		box = calcElementPosition(this.containerDivId);
		this.containerLeft = box.left;
		this.containerTop = box.top;
		if (isIE) {
		    this.containerLeft+=2;
		    this.containerTop+=2;
		}
		this.viewLeft = box.left;
		this.viewTop = box.top;
		//alert("Container location: " + box.left + ", " + box.top);
		var mcount = MapNames.length;
		MapNames[mcount] = this.controlName;
		mapCount = MapNames.length;
		if (mapUseKeyboardNavigation) {
		   if (isIE) { 
		        // if IE, use the map's container object div 
		        this.containerObject.onkeydown = keyDown;
		        this.containerObject.onkeyup = keyUp;
		   } else {
		        //  else use the map's link tag
                this.mozillaLinkObject.onkeydown = keyDown;
                this.mozillaLinkObject.onkeyup = keyUp;
		   }
		    		    
		} 
        if (this.navigationEnabled) MapDragImage(this.controlName, 'Pan', false);
        if (this.enableResizeEvent) // && isNav)
            window.onresize = AutoResizeMap;
        var rc =  this.ResourceCollection;
        for (var i=0;i<rc.length;i++) {
             rc[i].divObject = document.getElementById(rc[i].divId);
             rc[i].mapObject = Maps[rc[i].mapId];
        }
         rc.mapDiv = this.divObject;
				
	}
	
	// sets the tool for user interaction
	this.setTool = function (mode, showLoading, clientAction, cursor, vectorMode, vectorToolbarState, statusMessage, clearDrawnVectors, vectorCallbackString) {
			// set up events for map div
			
			this.show();
			this.divObject.onclick = null;
			this.preModeExecFunction = null;
			this.divObject.onmousedown = this.MapMouseDown;
			
			this.divObject.style.cursor = cursor;
			this.containerObject.style.cursor = cursor;
			this.snapCircleObject.style.cursor = cursor;
			this.cursor = cursor;
			this.actionType = clientAction;
			this.mode = mode;
			this.tempMode = mode;
            this.tempAction = clientAction;
            this.tempCursor = cursor;
            if (vectorToolbarState==null) vectorToolbarState = "hidden";
            this.vectorCallbackFunctionString = (vectorCallbackString!=null) ? vectorCallbackString : ""; 
            this.currentVectorToolbarState = vectorToolbarState; 
            this.clearDrawnVectors = (clearDrawnVectors!=null) ? clearDrawnVectors : true;
			var v = this.vectorObject;
			if (v!=null) {
				v.mode = vectorMode;			
				if (vectorMode > -1) //for vectors
				{
					v.clear();
					v.draw();
					showLayer(v.divId);
					if (clientAction.toLowerCase()=="dragshape") {
						// dragcircle, dragoval, dragbox - drag enabled
						v.divObject.onclick = null;
						v.divObject.onmousedown = MapMouseDown;
					} else {
						// line, polyline, polygon, circle, oval, box - click enabled
						v.divObject.onmousedown = null;
						this.divObject.onmousedown = null;
						v.divObject.onmouseup = MapMouseUp;
						this.divObject.onmouseup = MapMouseUp;
					}
					v.divObject.style.cursor = cursor;
	
					v.vectorCount = 0;
	
				}
				else {
					hideLayer(this.vectorObject.divId);
				}
			}
			//vector Toolbar
			var tb = document.getElementById(vectortoolbar);
			if (tb!=null) tb.style.visibility = this.currentVectorToolbarState;
			//set up mode and show loading
			this.drawBox = false;
			this.dragImage = false;
			var m = this.controlName + "_mode";
			this.mode = mode;
			//status bar message
			window.status = statusMessage;
	
	}
	
	this.hide = function() {
		hideLayer("MapControlDiv_" + this.controlName);
	}
	
	this.show = function() {
		showLayer("MapControlDiv_" + this.controlName);

	}
	
	this.getContainerRectangle = function() {
		// this gets the absolute page position and dimensions as a RectangleObject
		var box = calcElementPosition(this.containerDivId);
		this.containerLeft = box.left;
		this.containerTop = box.top
		if (isIE) {
		    this.containerLeft+=2;
		    this.containerTop+=2;
		}
		return box;
	}
	
	this.MapMouseDown = MapMouseDown;
	this.MapMouseMove = MapMouseMove;
	this.MapMouseUp = MapMouseUp;
	
	// TODO: Add comments
	this.setUpLevelGrid = function(level, columns, rows, startCol, startRow, leftOffset, topOffset, tileWidth, tileHeight, totalLevels, minCol, minRow, resourceLimits, resourceMapping) 
	{
	    if (this.changeLevelGridCount != esriCurrentResponseCount) {
	        this.minColumn = (minCol==null) ? 0 : minCol;
	        this.minRow = (minRow==null) ? 0 : minRow;
	        var doCreateMapDiv2 = false;
	        keepZooming = false;
	        if (totalLevels!=null) {
	            this.totalLevels = totalLevels;
    	        
	        }
	        if (tileWidth!=null) {
	            if (this.tileWidth!=tileWidth) doCreateMapDiv2 = true;
	            this.tileWidth = tileWidth;
	            this.columnsPerView = Math.ceil(this.viewWidth / this.tileWidth);
	        }
	        if (tileHeight!=null) {
	            if (this.tileHeight!=tileHeight) doCreateMapDiv2 = true;
	            this.tileHeight = tileHeight;
	            this.rowsPerView = Math.ceil(this.viewHeight / this.tileHeight);
	        }
	        if (this.totalLevels>1)
	            this.mapDiv2UpdateDelay = cacheUpdateDelay;
	        else
	            this.mapDiv2UpdateDelay = dynamicUpdateDelay;
	        if (this.columnsPerView * this.rowsPerView > 6)
	            this.mapDiv2UpdateDelay *= 2;
            //alert("totalLevels=" + totalLevels + "\ntileWidth=" + tileWidth + "\ntileHeight=" + tileHeight);
		    this.level = level;
			    this.columns = columns;
			    this.rows = rows;
		    //alert("Cols x Rows: " + this.columns + " x " + this.rows + "\nColumn/Row: " + startCol + ", " + startRow + "\nx,y: " + leftOffset + ", " + topOffset);
		    this.startColumn = startCol;
		    this.startRow = startRow;
		    this.currentLeftColumn = startCol;
		    this.currentTopRow = startRow;

            this.baseTileColumn = startCol;
            this.baseTileRow = startRow;
            this.baseTileXOffset = leftOffset;
            this.baseTileYOffset = topOffset;
            this.gridXOffset = this.tileWidth * startCol;
            this.gridYOffset = this.tileHeight * startRow;
    		
		    this.overlayObject.innerHTML = "";
		    this.vectorObject.restart();
            var loff = 0 - leftOffset;
            var toff = 0 - topOffset;
		    moveLayer(this.divId, loff, toff);
		    moveLayer(this.maptipDivId, loff, toff);
		    moveLayer(this.overlayDivId, loff, toff);
    		
		    //showLayer(this.divId);
		    this.hideMapDiv2();
    		
		    lastX = loff;
		    lasyY = toff;
		    this.displayedTiles = new Array();
		    this.requestedMapTipTiles = null;
		    this.requestedMapTipTiles = new Array();
    		this.pendingTiles.length = 0;     ///// Added for returned tiles check
            this.getTopLeftTile();
            if (resourceLimits==null) resourceLimits = "";    ///// Added for resource limit check
            var rcLimits = resourceLimits.split("|");             ///// Added for resource limit check
            var rc = this.ResourceCollection;
            var limits;                                                         ///// Added for resource limit check
            ///// Added for resource mapping check 	
            if (resourceMapping==null) resourceMapping = "";
            var rcMappedLevels = resourceMapping.split("|");
                       
            ///// Added for resource mapping check 
            for (var i=0;i<rc.length;i++) {
                rc[i].displayedTiles = new Array();
                rc[i].pngTiles = new Array();  
                rc[i].divObject.innerHTML = "";
                ///// Added for resource limit check 
                if (rcLimits[i]!=null)
                    limits = rcLimits[i].split(",");  
                else 
                    limits = "";  
                if (rcLimits[i]="-99,-99,-99,-99") limits=""; 
                rc[i].gridLimits = rcLimits[i];                       
                if (limits.length==4) {
                    rc[i].setLimits(parseInt(limits[0]), parseInt(limits[1]), parseInt(limits[2]), parseInt(limits[3]));
                } else {
                   rc[i].setLimits(-99,-99,-99,-99);  
                } 
                ///// Added for resource limit check    
                ///// Added for resource mapping check
                rc[i].mappedLevel = (rcMappedLevels[i]!=null && rcMappedLevels[i].length>0) ? rcMappedLevels[i]  : level;     
                ///// Added for resource mapping check                                                      
            } 
            //this.divObject.innerHTML = "";
	        this.addViewTiles(startCol, startRow, leftOffset, topOffset, true);
    	    
            if (this.totalLevels > 1) {
                if (hasZoomLevel) updateZoomLevelIcons(level, this.controlName);
            }
    		
		    //this.divObject.style.cursor = "progress";
            
            zoomAnimationDelay = false;
            this.changeLevelGridCount != esriCurrentResponseCount;
        }
	}

	this.shiftGrid = function(startCol, startRow, leftOffset, topOffset) {
		showLayer(this.divId);

	    var xTilesOffset = this.startColumn - startCol;
		var yTilesOffset = this.startRow - startRow;
		this.currentLeftColumn = startCol;
		this.currentTopRow = startRow;

        var loff = (xTilesOffset * this.tileWidth) - leftOffset;
        var toff = (yTilesOffset * this.tileHeight) - topOffset;
        //alert(loff + ", " + toff);
        this.moveTiles(loff, toff, "");
		lastX = loff;
		lasyY = toff;
		
        this.updateView(true);
        
	}


	
	this.addViewTiles = function(startCol, startRow, leftOffset, topOffset, update) {
	    if (update==null) update = false;
	    var bottomRow = startRow + this.rowsPerView;
	    var rightCol = startCol + this.columnsPerView;

	    if (topOffset!=0) bottomRow++;
	    if (leftOffset!=0) rightCol++;
		var lastRow = bottomRow	- 1;
		var lastCol =	rightCol - 1;
		for (var r = startRow;r<bottomRow;r++) {
			for (var c = startCol;c<rightCol;c++) {
				if (update && r==lastRow && c==lastCol)
					this.requestTile(c, r, true);
				else
					this.requestTile(c, r);
			}
		}
	
	}
	
	this.updateView = function(update) {
	    this.getTopLeftTile();
	    this.addViewTiles(this.currentLeftColumn, this.currentTopRow, this.currentXOffset, this.currentYOffset, update);
	    
	    this.dragImage = false;
	}
	
	this.updateResource = function(resourceId) {
	    this.getTopLeftTile();
	    var startCol = this.currentLeftColumn;
	    var startRow = this.currentTopRow;
	    var leftOffset = this.currentXOffset;
	    var topOffset = this.currentYOffset;
	    var bottomRow = startRow + this.rowsPerView;
	    var rightCol = startCol + this.columnsPerView;
        var rc = this.ResourceCollection;
        var resourceIndex = rc.getPosition(resourceId);
        if (resourceIndex!=-1) {
            if (rc[resourceIndex].visible) {
	            if (topOffset!=0) bottomRow++;
	            if (leftOffset!=0) rightCol++;
		        var lastRow = bottomRow	- 1;
		        var lastCol =	rightCol - 1;
		        for (var r = startRow;r<bottomRow;r++) {
			        for (var c = startCol;c<rightCol;c++) {
				        if (r==lastRow && c==lastCol)
					        this.requestResourceTile(c, r, resourceId, true);
				        else
					        this.requestResourceTile(c, r, resourceId);
			        }
		        }
		    } else
		        if (this.useZoomAnimation) this.updateMapDiv2(); 
		} else {
		    alert("Unable to find " + resourceId);
		}
	    
	}
	
	this.showMapDiv2 = function() {
		this.divScaleObject2.style.width = m_imageWidth + "px";
        this.divScaleObject2.style.height = m_imageHeight + "px";

		showLayer(this.divId2);
    }
	
	this.hideMapDiv2 = function() {
	    showLayer(this.divId);
	    showLayer(this.vectorDivId);
	    showLayer(this.maptipDivId);
	    showLayer(this.overlayDivId);
    }
    
	this.clearLevelGrid = function(resourceId, resourceLimits) {
		    var rc = this.ResourceCollection; 
            if (resourceLimits==null) resourceLimits = "";    ///// Added for resource limit check
            var rcLimits = resourceLimits.split("|");             ///// Added for resource limit check
            var limits;                                                         ///// Added for resource limit check             
            if (resourceId==null)	{
	            if (this.clearLevelGridCount != esriCurrentResponseCount) {
	                this.showMapDiv2();
                    this.displayedTiles = new Array();
		            this.requestedMapTipTiles = null;
		            this.requestedMapTipTiles = new Array();
                    for (var i=0;i<rc.length;i++) {
                        rc[i].displayedTiles = new Array(); 
                        rc[i].pngTiles = new Array();
                        rc[i].divObject.innerHTML = ""; 
                        ///// Added for resource limit check 
                        if (rcLimits[i]!=null)
                            limits = rcLimits[i].split(",");  
                        else 
                            limits = "";                        
                        if (rcLimits[i]="-99,-99,-99,-99") limits=""; 
                        rc[i].gridLimits = rcLimits[i];                       
                       if (limits.length==4) {
                            rc[i].setLimits(parseInt(limits[0]), parseInt(limits[1]), parseInt(limits[2]), parseInt(limits[3]));
                        } else {
                            rc[i].setLimits(-99,-99,-99,-99);   
                        } 
                        ///// Added for resource limit check                     
                    } 	
                    if (this.useZoomAnimation) this.updateMapDiv2(); 
	                this.updateView(true);
	                this.clearLevelGridCount = esriCurrentResponseCount; 
	            } 
	        } else {
	            var resource = rc.find(resourceId);
	            if (resource!=null && resource.checkCallbackCount != esriCurrentResponseCount) { 
	                resource.divObject.innerHTML = "";
	                resource.displayedTiles = new Array(); 
	                resource.pngTiles = new Array();
                    ///// Added for resource limit check 
                    if (rcLimits[0]!=null)
                        limits = rcLimits[0].split(",");  
                    else 
                        limits = "";                        
                    if (rcLimits[i]="-99,-99,-99,-99") limits=""; 
                    resource.gridLimits = rcLimits[i];                       
                    if (limits.length==4) {
                        resource.setLimits(parseInt(limits[0]), parseInt(limits[1]), parseInt(limits[2]), parseInt(limits[3]));
                    } else {
                        resource.setLimits(-99,-99,-99,-99);
                    } 
                    ///// Added for resource limit check                     
	                if (this.useZoomAnimation) this.updateMapDiv2();
	                this.updateResource(resourceId); 
	                resource.checkCallbackCount = esriCurrentResponseCount 
	            } 
	        }
	        this.pendingTiles.length = 0;      ///// Added for returned tiles check
	}
	
	this.switchPostBackInterval = null;
	
	this.switchToLevel = function(newLevel) {
		if (newLevel<0) newLevel = 0;
		if (newLevel>=this.totalLevels) newLevel = this.totalLevels - 1;
		if (newLevel==this.level) return;

		var argument = "EventArg=ChangeLevel&coords=" + newLevel;
		var context = this.controlName;	
		this.coords = newLevel;
		postBack(this.controlName, "ChangeLevel");
	}
	
	this.redraw = function(resourceIndex) {
	    var rc = this.ResourceCollection;
	    if (resourceIndex == null) {
	        for (var i=0;i<rc.length;i++) {
	            rc[i].redraw();
	        }  
	    } else {
	        rc[resourceIndex].redraw();
	    }
	}
	
    this.zoomToFullExtent = function() {
        var argument = "ZoomToFullExtent";
        postBack(this.controlName, argument);
    }
   
	
   this.updateTileImage = function(c, r, imageUrl, update, resourceId, imageType) {
        var imageHtml =""; 
        if (update==null) update = false; 
        if (imageType==null) imageType = "";
        var supportedPng = false;
        var resouceSupportedPng = false;
        if (imageType.length>0) {
            if (imageType.indexOf("png")>-1 & imageType!="png24") supportedPng = true;
        } 
        if (resourceId==null) resourceId = mapDefaultResourceId;
        var rc = this.ResourceCollection;
        var resourceIndex = rc.getPosition(resourceId);
        var resource = this.ResourceCollection[resourceIndex];
        if (resource==null)return;
        if (resource.imageFormat.length>0) {
             if (resource.imageFormat.indexOf("png")>-1 & resource.imageFormat!="png24") resouceSupportedPng = true;
        }
		var left = (c * this.tileWidth) - this.gridXOffset;
		var top = (r * this.tileHeight) - this.gridYOffset;
		if (imageUrl == "") 
		    imageUrl = this.blankImagePath;

        var imgObj = null;
        var pngUrl = "";
		var imageName = "MapTileImage_" + this.controlName + "_" + c + "_" + r + "_" + resourceId;
		var tileName = "MapTile_" + this.controlName + "_" + c + "_" + r;
		//if (isIE  && ieVersion < 7 && (imageType=="png32" || imageExtent=="png" || resource.imageFormat=="png32")) {
		if (isIE  && ieVersion < 7 && (supportedPng || resouceSupportedPng)) {
                imageHtml = '<img id="' + imageName + '" name="' + imageName + '" src="' + this.blankImagePath + '" style="visibility: hidden; position: absolute; left: ' + left + 'px; top: ' + top + 'px; width: ' + this.tileWidth + 'px; height: ' + this.tileHeight + 'px; filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'' + imageUrl + '\');" border=0 vspace=0 hspace=0 ';
                imageHtml += 'onload="this.style.visibility=\'visible\'; Maps[\'' + this.id + '\'].pendingTiles.remove(\'' + resourceId +  '_' + c + '_' + r + '\');" ';         ///// Added for returned tiles check
                imageHtml += 'onerror="this.src=\'' + this.blankImagePath + '\'; Maps[\'' + this.id + '\'].ResourceCollection[\'' + resourceIndex + '\'].displayedTiles[\'' + tileName + '\']=\'' + this.blankImagePath + '\';" ';
                imageHtml += ' />';
                
           pngUrl = imageUrl;            
		} else {
            imageHtml = '<img id="' + imageName + '" name="' + imageName + '" src="' + imageUrl + '" style="visibility: hidden; position: absolute; left: ' + left + 'px; top: ' + top + 'px; width: ' + this.tileWidth + 'px; height: ' + this.tileHeight + 'px;" border=0 vspace=0 hspace=0 ';
            imageHtml += 'onload="this.style.visibility=\'visible\';Maps[\'' + this.id + '\'].pendingTiles.remove(\'' + resourceId +  '_' + c + '_' + r + '\');" ';          ///// Added for returned tiles check
            imageHtml += 'onerror="this.src=\'' + this.blankImagePath + '\'; Maps[\'' + this.id + '\'].ResourceCollection[\'' + resourceIndex + '\'].displayedTiles[\'' + tileName + '\']=\'' + this.blankImagePath + '\';" ';

            imageHtml += ' />';
        } 
        if (update)
            if (this.useZoomAnimation) window.setTimeout('Maps["' + this.controlName + '"].updateMapDiv2();', 250);
		if (resource.displayedTiles[tileName]!=null) {
		    imgObj = document.getElementById(imageName); 
		    if (imgObj!=null) {
		            imgObj.src = imageUrl;
		    }else
		        resource.divObject.insertAdjacentHTML("BeforeEnd", imageHtml);
		} else {
	        //alert(tileName + "\n" + imageHtml);
	        resource.divObject.insertAdjacentHTML("BeforeEnd", imageHtml); 
	    }
		resource.displayedTiles[tileName] = imageUrl;
		resource.pngTiles[tileName] = pngUrl;
		this.divObject.style.visible = "visible";
    	// Debug stuff that will be displayed in form element, if it exists
    	var blurb = c + ", " + r + ", " + imageUrl + ", " + update + ", " +  resourceId + ", " + imageType;
   	if (checkForFormElement(document, 0, "MapDebugBox")) document.forms[0].MapDebugBox.value += ("Tile Response: " + blurb + "\n"); 

   } 
   
   
   this.getTopLeftTile = function() {
    	var box = calcElementPosition(this.divId);
		var xDist = (0 - parseInt(this.divObject.style.left)) + this.gridXOffset;
		var yDist = (0 - parseInt(this.divObject.style.top)) + this.gridYOffset;
        var cols = Math.floor(xDist / this.tileWidth);
        var rows = Math.floor(yDist / this.tileHeight);
        var xDist2 = xDist + this.viewWidth - 2;
        var yDist2 = yDist + this.viewHeight - 2;
        var cols2 = Math.floor(xDist2 / this.tileWidth);
        var rows2 = Math.floor(yDist2 / this.tileHeight);
		
		this.currentLeftColumn = cols;
		this.currentTopRow = rows;
		this.currentRightColumn = cols2;
		this.currentBottomRow = rows2;
		this.currentXOffset = Math.abs(xDist) - (Math.floor(Math.abs(xDist) / this.tileWidth) * this.tileWidth);
		this.currentYOffset = Math.abs(yDist) - (Math.floor(Math.abs(yDist) / this.tileHeight) * this.tileHeight);
		
	}
   
   this.moveTiles = function(newX, newY, direction, jumpToTile) {
            if (jumpToTile==null) jumpToTile = false;
   			moveLayer(this.divId, newX, newY);
   			moveLayer(this.maptipDivId, newX, newY);
   			moveLayer(this.overlayDivId, newX, newY);
			var horizDir = newX - lastX;
			var vertDir = newY - lastY;
			lastX = newX;
			lastY = newY;
			this.getTopLeftTile();
			if (this.continuousCallback || jumpToTile) {
                    this.addViewTiles(this.currentLeftColumn, this.currentTopRow, this.currentXOffset, this.currentYOffset);
			}
            this.lastLeftColumn = this.currentLeftColumn;
            this.lastTopRow = this.currentTopRow;   			
            this.lastRightColumn = this.currentRightColumn;
            this.lastBottomRow = this.currentBottomRow; 
            this.lastLeftColumnBuffer = this.currentLeftColumnBuffer;
            this.lastTopRowBuffer = this.currentTopRowBuffer;   			
            this.lastRightColumnBuffer = this.currentRightColumnBuffer;
            this.lastBottomRowBuffer = this.currentBottomRowBuffer; 
              			
   }
   
   // Requests new tiles when a new tile enters the view.... creates buffer all around view
   this.addTiles = function(startCol, startRow, direction) {
        this.addViewTiles(startCol, startRow, this.currentXOffset, this.currentYOffset);

        if (direction==null) direction = "";
        var endRow = startRow + this.rowsPerView;
        var endCol = startCol + this.columnsPerView
        switch (direction) {
            case "up":
                if (startRow > this.minRow) {
                    for (var c = startCol;c < endCol;c++) {
		                this.requestTile(c, startRow - 1);
		            }
                }
                break;
            case "down":
                if (endRow < this.rows + this.minRow) {
                    for (var c = startCol;c < endCol;c++) {
		                this.requestTile(c, endRow);
		            }
                }
                break;
            case "left":
                if (startCol > this.minColumn) {
                    for (var r = startRow;r < endRow;r++) {
		                this.requestTile(startCol - 1, r);
		            }
                }
                break;
            case "right":
                if (endCol < this.columns + this.minColumn) {
                    for (var r = startRow;r < endRow;r++) {
		                this.requestTile(endCol, r);
		            }
                }
                break;
            case "ul":
                if (startRow > this.minRow) {
                    for (var c = startCol;c < endCol;c++) {
		                this.requestTile(c, startRow - 1);
		            }
                }
                if (startCol > this.minColumn) {
                    for (var r = startRow;r < endRow;r++) {
		                this.requestTile(startCol - 1, r);
		            }
                }
                if (startRow > this.minRow && startCol > 0)
                    this.requestTile(startCol - 1, startRow - 1);
                break;
            case "ll":
                if (endRow < this.rows + this.minRow) {
                    for (var c = startCol;c < endCol;c++) {
		                this.requestTile(c, endRow);
		            }
                }
                if (startCol > this.minColumn) {
                    for (var r = startRow;r < endRow;r++) {
		                this.requestTile(startCol - 1, r);
		            }
                }
                if (endRow < this.rows + this.minRow && startCol > 0)
                    this.requestTile(startCol - 1, endRow);
                break;
            case "ur":
                if (startRow > this.minRow) {
                    for (var c = startCol;c < endCol;c++) {
		                this.requestTile(c, startRow - 1);
		            }
                }
                 if (endCol < this.columns + this.minColumn) {
                    for (var r = startRow;r < endRow;r++) {
		                this.requestTile(endCol, r);
		            }
                }
                if (startRow > 0 && endCol < this.columns + this.minColumn)
                    this.requestTile(endCol, startRow - 1);
               break;
            case "lr":
                if (endRow < this.rows + this.minRow) {
                    for (var c = startCol;c < endCol;c++) {
		                this.requestTile(c, endRow);
		            }
                }
                 if (endCol < this.columns + this.minColumn) {
                    for (var r = startRow;r < endRow;r++) {
		                this.requestTile(endCol, r);
		            }
                }
                if (startRow > 0 && endCol < this.columns + this.minColumn)
                    this.requestTile(endCol, endRow);
                break;
   
        }
   }
   
   this.requestTile = function(c, r, update) {
        if (update==null) update = false; 
        var tileName = "";
        var time = new Date();
        var rc = this.ResourceCollection;
        for (var i=rc.length-1; i>=0;i--) {
		    tileName = 'MapTile_' + this.controlName + "_" + c + '_' + r;
		        if (rc[i].displayedTiles[tileName]==null) {
		            rc[i].displayedTiles[tileName] = tileName;
		            if (rc[i].visible) {
		                if (rc[i].isWithinLimits(c, r) && rc[i].mappedLevel>-2) {     ///// Added for resource limit check
		                    if ((rc[i].tileServerUrl.length>0 || rc[i].tileServerUrlGenerator.length>0) && this.totalLevels>0) { 
		                        if (rc[i].mappedLevel>-1) { ///// Added for resource mapping check
		                            this.pendingTiles.add(rc[i].id + "_" + c + "_" + r);     ///// Added for returned tiles check		                             
                                    var imageUrl = "";
                                    if (c>=0 && r>=0) { // don't request a negative tile from a cached resource
                                        if (rc[i].tileServerUrl.length>0 && rc[i].tileServerUrlGenerator.length==0) {
                                            imageUrl = rc[i].tileServerUrl + "&level=" + rc[i].mappedLevel + "&column=" + c + "&row=" + r + "&time=" + time.getTime();  ///// Added for resource mapping check
                                        } else {
                                            var cacheCall = rc[i].tileServerUrlGenerator + "(" + rc[i].mappedLevel + ", " + c + ", " + r + ", '" + rc[i].tileServerUrl + "');";  ///// Added for resource mapping check
                                            imageUrl = eval(cacheCall);
                                        } 
//                                         if (imageUrl!=null && imageUrl.length>0 && imageUrl.toLowerCase().indexOf("http")==-1) {
//                                            alert(imageUrl);
//                                            imageUrl = "";
//                                        }
                                   } 
                                    this.updateTileImage(c, r, imageUrl, update, rc[i].id, false); 
		                        }  else {
		                            this.dynamicTileRequest(rc[i].id, c, r, update);
		                        }  ///// Added for resource mapping check 
		                    } else {
                                this.dynamicTileRequest(rc[i].id, c, r, update);
	                        } // end if
	                    } else {
	                        this.pendingTiles.add(rc[i].id + "_" + c + "_" + r);     ///// Added for returned tiles check 
	                        this.updateTileImage(c, r, "", update, rc[i].id, false); //end if (rc[i].isWithinLimits(c, r))  ///// Added for resource limit check
	                    }
	                } // end  if (rc[i].visible)
            } else if (update) 
                if (this.useZoomAnimation)  this.updateMapDiv2(); // end if (rc[i].displayedTiles[tileName]==null)
        } // end for
   }
  
    this.dynamicTileRequest = function(resourceId, column, row, update) {
            var argument = "EventArg=DrawTile&coords=" + column + "," + row + "&resource=" +resourceId;
            var context = this.controlName;	
            if (update)
                context += ",UpdateDiv2," +  resourceId;
            else
                context += ",," +  resourceId;  
            this.pendingTiles.add(resourceId + "_" + column + "_" + row);     ///// Added for returned tiles check
            window.setTimeout("var argument='" + argument + "'; var context='" + context + "'; eval(\"" + this.tileCallbackFunctionString + "\");", 0);
    }   
  
    this.requestResourceTile = function(c, r, resourceId, update) {
        if (update==null) update = false; 
        if (resourceId==null) resourceId = mapDefaultResourceId;
        var rc = this.ResourceCollection;
        var i = rc.getPosition(resourceId);
        if (i!=-1) {
		    var tileName = 'MapTile_' + this.controlName + "_" + c + '_' + r;
		    if (rc[i].displayedTiles[tileName]==null) {
		        rc[i].displayedTiles[tileName] = tileName;
		        if (rc[i].visible) {
		            if (rc[i].isWithinLimits(c, r) && rc[i].mappedLevel>-2) {        ///// Added for resource limit check
		                if ((rc[i].tileServerUrl.length>0 || rc[i].tileServerUrlGenerator.length>0) && this.totalLevels>0) { 
		                    if (rc[i].mappedLevel>-1) { ///// Added for resource mapping check
		                        this.pendingTiles.add(rc[i].id + "_" + c + "_" + r);     ///// Added for returned tiles check 
                                var imageUrl = "";
                                if (c>=0 && r>=0) { // don't request a negative tile from a cached resource
                                    if (rc[i].tileServerUrl.length>0 && rc[i].tileServerUrlGenerator.length==0) {
                                        imageUrl = rc[i].tileServerUrl + "&level=" + rc[i].mappedLevel + "&column=" + c + "&row=" + r + "&time=" + time.getTime(); ///// Added for resource mapping check 
                                    } else {
                                        var cacheCall = rc[i].tileServerUrlGenerator + "(" + rc[i].mappedLevel + ", " + c + ", " + r + ", '" + rc[i].tileServerUrl + "');";  ///// Added for resource mapping check 
                                        imageUrl = eval(cacheCall);
                                    } 
                                }
                                this.updateTileImage(c, r, imageUrl, update, rc[i].id, false); 
		                    }  else {
		                        this.dynamicTileRequest(rc[i].id, c, r, update);
		                    }  ///// Added for resource mapping check
		                    
		                } else {
			                this.dynamicTileRequest(rc[i].id, c, r, update);
	                    } // end if
	                } else {
	                    this.pendingTiles.add(rc[i].id + "_" + c + "_" + r);     ///// Added for returned tiles check 
	                    this.updateTileImage(c, r, "", update, resourceId, false);  // end if (rc[i].isWithinLimits(c, r))       ///// Added for resource limit check
	                }
	            } // end  if (rc[i].visible)
            } else if (update) 
                if (this.useZoomAnimation)  this.updateMapDiv2(); // end if (rc[i].displayedTiles[tileName]==null)
        } else {
            alert("Unable to find " + resourceId);
        } 
    }      
   
	// function for resizing the map object
	this.resize = function(width, height, adjustExtent) {
	    if (adjustExtent==null) adjustExtent = false;
	    this.lastViewBox = new RectangleObject("dummy", 0, 0, this.viewWidth, this.viewHeight);
        this.viewWidth = width;
        this.viewHeight = height;
        var enlargeView = false;
		var container = this.containerObject;
		if (container!=null) {
			container.style.width = width + "px";
			container.style.height = height + "px";
		}
        this.width = width;
        this.height = height;
        this.columnsPerView = Math.ceil(width/this.tileWidth);
        this.rowsPerView = Math.ceil(height/this.tileHeight);
		this.getTopLeftTile();
        if (this.lastWidth<width || this.lastHeight<height) enlargeView = true;
	    this.lastWidth = width;
	    this.lastHeight = height;
	    this.resizeExtent = adjustExtent;
	    if (this.boxObject!=null) {
	        this.boxObject.style.width = width + "px";
	        this.boxObject.style.height = height + "px";
	    }
	    this.createMapDiv2();
	    var argument = "Resize&width=" + width + "&height=" + height + "&startup=" + this.startUp;
	    if (enlargeView && !this.startUp) 
	        this.updateView(width, height, true);
	    this.startUp = false;

        postBack(this.controlName, argument);
	}
	
	this.resizeToBrowserWindow = function() {
	    var width = getWinWidth();
	    var height = getWinHeight();
	    this.resize(width, height);
    }
    
    this.resizeToWindow = function() {
	    if (this.enableResizeEvent ) {
	        if (isNav) {
	            // shrink the map temporarily for Moz so there are no scrollbars on smaller window
	            this.containerObject.style.width = "1px";
	            this.containerObject.style.height = "1px";
	        }
	        var width = getMapWidth(this.containerObject);
	        var height = getMapHeight(this.containerObject);
	        if (this.lastWidth!=width || this.lastHeight!=height)
	            this.resize(width, height);
        }
    }
	
	this.resizeToParent = function() {
	    if (this.enableResizeEvent ) {
            var topMapDiv = document.getElementById(this.id);
            var width = topMapDiv.parentElement.clientWidth;
            var height = topMapDiv.parentElement.clientHeight;  
	        if (this.lastWidth!=width || this.lastHeight!=height)
	            this.resize(width, height);
        }
	}
	
	// function to obtain array of positions of the tiles that are visible in view
	this.getViewTiles = function() {
	    var vTiles = new Array();
	    this.getTopLeftTile();
		var startCol = this.currentLeftColumn;
		var startRow = this.currentTopRow;
		var lastCol = this.currentRightColumn;
		var lastRow = this.currentBottomRow;
		//alert(startCol + ", " + startRow + ", " + lastCol + ", " + lastRow);
		var i = 0;
	    for (var r=startRow;r<=lastRow;r++) {
	        for (var c=startCol;c<=lastCol;c++) {
	            vTiles[i] = new TileObject(c, r);
	            i++;
	        }
	    }
	    return vTiles;
	}
	
	this.getViewTilesString = function() {
	    this.getTopLeftTile();
		var startCol = this.currentLeftColumn;
		var startRow = this.currentTopRow;
		var lastCol = this.currentRightColumn;
		var lastRow = this.currentBottomRow;
		//alert(startCol + ", " + startRow + ", " + lastCol + ", " + lastRow);
		var s = "";
	    for (var r=startRow;r<=lastRow;r++) {
	        for (var c=startCol;c<=lastCol;c++) {
	            if (s.length>0) s += "|";
	            //s += c + "," + r;
	            s += "MapTileImage_" + this.controlName + "_" + c + "_" + r;
	        }
	    }
	    return s;
	}
	

	this.createMapDiv2 = function() {
        var tw = this.columnsPerView + 1;
        var th = this.rowsPerView + 1;
        m_imageWidth = this.tileWidth * tw;
        m_imageHeight = this.tileHeight * th;
	    m_centerX = m_imageLeft + Math.round(m_imageWidth / 2);
		m_centerY = m_imageTop + Math.round(m_imageHeight / 2);
		//alert(m_imageWidth + " x " + m_imageHeight);
        var s = '<table width="100%" height="100%" cellspacing="0" cellpadding="0" >\n';

        var rc = this.ResourceCollection;
        var ri = rc.getPosition(this.baseResourceId);
        //for (var ri=rc.length-1;ri>=0;ri++) {
        for (var r=0;r<th;r++) {
            s += '<tr height="' + (1 / th * 100) + '%">\n';
            for (var c=0;c<tw;c++) {
                s += '<td width="' + (1 / tw * 100) + '%" height="' + (1 / th * 100) + '%" >\n<div id="' + this.controlName + '_MapAnimationDiv_' + c + '_' + r + '" style="width:' + this.tileWidth + 'px; height:' + this.tileHeight + 'px; overflow: hidden;" >\n';
                //s += '<td width="' + (1 / tw * 100) + '%" height="' + (1 / th * 100) + '%" >\n<div id="' + this.controlName + '_MapAnimationDiv_' + c + '_' + r + '" style="width: 100%; height: 100%; overflow: hidden;" >\n';
	            var imageName2 = "MapTileImage2_" + this.controlName + "_" + c + "_" + r + "_" + this.baseResourceId;
	                s +='<img id="' + imageName2 + '" name="' + imageName2 + '" style="width:100%; height:100%" border=0 vspace=0 hspace=0 src="' + this.blankImageObject.src + '" />';
	            s += '</div></td>\n';
            }
            s += '</tr>\n';
        }
        //}
	    
        s += '</table>\n';
	    this.lastColumnsPerView = this.columnsPerView;
	    this.lastRowsPerView = this.rowsPerView;
	    this.lastTileWidth = this.tileWidth;
	    this.lastTileHeight = this.tileHeight;
        this.divScaleObject2.style.width = m_imageWidth + "px";
        this.divScaleObject2.style.height = m_imageHeight + "px";
	    
        this.divScaleObject2.innerHTML = s;
	}
	
	this.updateMapDiv2 = function() {
        hideLayer(this.divId2);
        var doCreateMapDiv2 = false;	    
	    if (this.tileWidth!=this.lastTileWidth) doCreateMapDiv2 = true;
	    if (this.columnsPerView!=this.lastColumnsPerView) doCreateMapDiv2 = true;
        if (this.tileHeight!=this.lastTileHeight) doCreateMapDiv2 = true;
        if (this.rowsPerView!=this.lastRowsPerView) doCreateMapDiv2 = true;
        
	    if (doCreateMapDiv2)
	        this.createMapDiv2(); 
        this.divObject2.style.zoom = 1.0;
        this.divScaleObject2.style.zoom = 1.0;
        this.divScaleObject2.style.width = m_imageWidth + "px";
        this.divScaleObject2.style.height = m_imageHeight + "px";
        this.getTopLeftTile();
	    var startCol = this.currentLeftColumn;
	    var startRow = this.currentTopRow;
	    var lastCol = this.currentRightColumn;
	    var lastRow = this.currentBottomRow;
        var tw = this.columnsPerView + 1;
        var th = this.rowsPerView + 1;
        if (!isIE) {
            for (var r=0; r<th; r++) {
                for (var c=0; c< tw; c++) {
                    div = document.getElementById(map.controlName + '_MapAnimationDiv_' + c + '_' + r);
                    if (div!=null) {
                        div.style.width = map.tileWidth + "px";
                        div.style.height = map.tileHeight + "px"; 
                    }  
                } 
            } 
        }
	    //alert(startCol + ", " + startRow + ", " + lastCol + ", " + lastRow);
	    if (startCol<0)
	        m_imageLeft = this.currentXOffset - this.tileWidth;
	    else
	        m_imageLeft = 0  - this.currentXOffset;
	    if (startRow<0)
	        m_imageTop = this.currentYOffset - this.tileHeight;
	    else
	        m_imageTop = 0 - this.currentYOffset;
        this.divObject2.style.left = m_imageLeft + "px";
        this.divObject2.style.top = m_imageTop + "px";
        //this.divObject2.style.top = "0px";
        this.divScaleObject2.style.width = m_imageWidth + "px";
        this.divScaleObject2.style.height = m_imageHeight + "px";
	    var imageName, imageName2, imgObj, imgObj2, tileName; 
        var cc = startCol;
        var rr = startRow;
        var rc = this.ResourceCollection;
        var ri = rc.getPosition(this.baseResourceId);
        if (ri>=0) {                   ///// Added for dynamic resource addition/deletion 
            var rcBaseIndex = ri;
            if (!rc[ri].visible) 
                ri = rc.getBottomVisiblePosition();
            var forcePng = false;
            //for (var ri=rc.length;ri>=0;ri++) {
    //        if (rc[ri].visible) {
               for (var r=0;r<th;r++) {
                    for (var c=0;c<tw;c++) {
                        tileName = "MapTile_" + this.controlName + "_" + cc + "_" + rr;
	                    imageName = "MapTileImage_" + this.controlName + "_" + cc + "_" + rr + "_" + this.baseResourceId;
	                    imageName2 = "MapTileImage2_" + this.controlName + "_" + c + "_" + r + "_" + this.baseResourceId;
	                    imgObj = document.getElementById(imageName);
	                    imgObj2 = document.getElementById(imageName2);
	                    forcePng = (rc[ri].pngTiles[tileName]!=null && rc[ri].pngTiles[tileName].length>0); 
	                    if (imgObj!=null) { 
	                        if (imgObj.src!=rc[ri].displayedTiles[tileName])
	                            imgObj2.src = rc[ri].displayedTiles[tileName];
	                        else  
	                            imgObj2.src = imgObj.src;
	                        if (rcBaseIndex!=ri || this.forcePngAlphaOnBase) 
	                            alphaBlend(imgObj2, forcePng); 
	                    } else 
	                        imgObj2.src = this.blankImageObject.src
	                    cc++;
                    }
                    rr++;
                    cc=startCol;
                }
           //} 
    //        }
	  } 	    ///// Added for dynamic resource addition/deletion
     //alert(this.divObject2.outerHTML);
    // Debug stuff that will be displayed in form element, if it exists
    if (checkForFormElement(document, 0, "MapDebugBox")) document.forms[0].MapDebugBox.value += ("Updated MapDiv2\n"); 
    
   	    //this.divObject.style.cursor = this.cursor;
	}

	
	this.checkMapDiv2 = function() {
        this.getTopLeftTile();
	    var startCol = this.currentLeftColumn;
	    var startRow = this.currentTopRow;
	    var lastCol = this.currentRightColumn;
	    var lastRow = this.currentBottomRow;
	    var imageName, imageName2, imgObj, imgObj2, tileName;
        var cc = startCol;
        var rr = startRow;
        var tw = this.columnsPerView + 1;
        var th = this.rowsPerView + 1;
        if (!isIE) {
            for (var r=0; r<th; r++) {
                for (var c=0; c< tw; c++) {
                    div = document.getElementById(map.controlName + '_MapAnimationDiv_' + c + '_' + r);
                    if (div!=null) {
                        div.style.width = map.tileWidth + "px";
                        div.style.height = map.tileHeight + "px"; 
                    }  
                } 
            } 
        }
        var rc = this.ResourceCollection;
        var ri = rc.getPosition(this.baseResourceId);
        if (ri>=0) {            ///// Added for dynamic resource addition/deletion
            var rcBaseIndex = ri;
            if (!rc[ri].visible) 
                ri = rc.getBottomVisiblePosition();
            var forcePng = false;
            //for (var ri=rc.length-1;ri>=0;ri++) {
            //if (rc[ri].visible) {
                for (var r=0;r<th;r++) {
                    for (var c=0;c<tw;c++) {
                        tileName = "MapTile_" + this.controlName + "_" + cc + "_" + rr;
	                    imageName = "MapTileImage_" + this.controlName + "_" + cc + "_" + rr + "_" + this.baseResourceId;
	                    imageName2 = "MapTileImage2_" + this.controlName + "_" + c + "_" + r + "_" + this.baseResourceId;
	                    imgObj = document.getElementById(imageName);
	                    imgObj2 = document.getElementById(imageName2);
	                    if (imgObj!=null) { 
	                        if (imgObj.src!=rc[ri].displayedTiles[tileName])
	                            imgObj2.src = rc[ri].displayedTiles[tileName];
	                        else  
	                            imgObj2.src = imgObj.src;
	                        if (rcBaseIndex!=ri || this.forcePngAlphaOnBase) 
	                            alphaBlend(imgObj2, forcePng); 
	                    } else 
	                        imgObj2.src = this.blankImageObject.src
	                    cc++;
                    }
                    rr++;
                    cc=startCol;
                }
            //}
            //}
        }              ///// Added for dynamic resource addition/deletion
    // Debug stuff that will be displayed in form element, if it exists
    if (checkForFormElement(document, 0, "MapDebugBox")) document.forms[0].MapDebugBox.value += ("Checked MapDiv2\n"); 
	
	}
	
	this.swapMode = function(e) {
	    if (shiftPressed) {
	        this.mode = this.shiftMode;
	        this.actionType = this.shiftAction;
	        this.cursor = this.shiftCursor;
	        this.divObject.style.cursor = this.cursor;
	        
	    } else if (ctrlPressed) {
	        this.mode = this.ctrlMode;
	        this.actionType = this.ctrlAction;
	        this.cursor = this.ctrlCursor;
	        this.divObject.style.cursor = this.cursor;
	        eval(this.ctrlFunction);
	    
	    } else if (altPressed) {
	        this.mode = this.altMode;
	        this.actionType = this.altAction;
	        this.cursor = this.altCursor;
	        this.divObject.style.cursor = this.cursor;
	    
	    }
	}
	
	this.enableScrollWheel = function(useScrollWheel) {
	    this.useScrollWheel = (useScrollWheel!=null) ? useScrollWheel : false;
	    var eventName = isIE ? "onmousewheel" : "DOMMouseScroll";
	    if (this.useScrollWheel) {	        
	        if (isIE) 
	            this.divObject.detachEvent(eventName, funct);
	        else
	            this.divObject.removeEventListener(eventName,onWheelScroll, false);
	    } else {
	        if (this.useZoomAnimation) this.updateMapDiv2;
	        if (isIE) 
	            this.divObject.attachEvent(eventName, funct);
	        else
	            this.divObject.addEventListener(eventName,onWheelScroll, false);
	    }
	}
	
	// convert decimal delimiter, if necessary
    this.setDecimalDelimiter = function(theNumber, delimiter) {
        if (delimiter==null) delimiter = this.decimalDelimiter;
	    var comma = ",";
	    var dot = ".";
	    var charOut = comma;
	    var charIn = dot;
	    var numberString = new String(theNumber);
	    if (delimiter==",") {
		    charOut = dot;
		    charIn = comma;
	    }
	    var pos = numberString.indexOf(charOut);
	    if (pos!=-1) {
		    var begin = numberString.substring(0,pos);
		    var ending = numberString.substring(pos+1, numberString.length);
		    numberString = begin + charIn + ending;
	    }
	    return numberString;
    }

	this.ResourceCollection = new Array();
	this.ResourceCollection.add = esriResourceCollectionAdd;  // map.ResourceCollection.add(resource);
	this.ResourceCollection.contains = esriResourceCollectionContains;	// hasIt =  map.ResourceCollection.contains(resourceId);
	this.ResourceCollection.find = esriResourceCollectionFind;  // resource = map.ResourceCollection.find(resourceId);
	this.ResourceCollection.insert = esriResourceCollectionInsert;    // map.ResourceCollection.insert(resource, position);
	this.ResourceCollection.remove = esriResourceCollectionRemove;  // map.ResourceCollection.remove(resourceId);
	this.ResourceCollection.removeAt = esriResourceCollectionRemoveAt;  // map.ResourceCollection.removeAt(position);
	this.ResourceCollection.getPosition = esriResourceCollectionPosition; // position = map.ResourceCollection.getPosition(resourceId);
    this.ResourceCollection.replace = esriResourceCollectionReplace;    // map.ResourceCollection.replace(newResource, oldResourceId); 
    this.ResourceCollection.replaceAt = esriResourceCollectionReplaceAt;    // map.ResourceCollection.replace(newResource, position); 
    this.ResourceCollection.setObjects = esriResourceCollectionSetObjects;     // map.ResourceCollection.setObjects(); 
    this.ResourceCollection.redraw = esriResourceCollectionRedraw;   //map.ResourceCollection.redraw(resourceId);
    this.ResourceCollection.getBottomVisiblePosition = esriResourceCollectionBottomVisiblePosition;  // position = map.ResourceCollection.getBottomVisiblePosition();
    this.ResourceCollection.mapObject = this; 
    this.baseResourceId = mapDefaultResourceId; 
   
  ///// Added for returned tiles check 
    this.pendingTiles = new Array();
    this.pendingTiles.add = esriPendingTilesAdd;
    this.pendingTiles.find = esriPendingTilesFind;
    this.pendingTiles.remove = esriPendingTilesRemove;  
    this.pendingTiles.mapObject = this; 
    this.pendingTiles.add_onRequestsPending = esriAddOnRequestsPending;
    this.pendingTiles.add_onRequestsRemove = esriAddOnRequestsRemove;
    this.pendingTiles.add_onRequestsCompleted = esriAddOnRequestsCompleted;   
    this.pendingTiles.onRequestsPending = null;   
    this.pendingTiles.onRequestsRemove  = null;
    this.pendingTiles.onRequestsCompleted = null; 
 ///// Added for returned tiles check
   
    this.setSnapCircleSize = function(radius) {
        this.snapCircleObject.style.width = (radius * 2) + "px";
        this.snapCircleObject.style.height = (radius * 2) + "px"; 
        if (isNav && nav8) {
	        //var svo = this.snapCircleObject.vectorObject;
	        var svo = new VectorObject(this.snapCircleId); 
	        svo.clear();
	        svo.divColor = "Red";  
	        svo.circle(radius, radius, radius);
	        svo.draw();
        }
    }  

    this.snapCircleVisible = function(visible) {
        if (visible)
            this.snapCircleObject.style.visibility = "visible";  
        else
            this.snapCircleObject.style.visibility = "hidden";         
    }	
    
} // Map Object

//function createMapObject(controlName, mapContainerName, mapWidth, mapHeight, pageID, backColor, continuousCallback, enableTileCaching, tileServerUrl, navigationEnabled, callBackFunctionString, tileCallbackFunctionString, startResourceList) // debug to test against older build expecting tileServerUrl
function createMapObject(controlName, mapContainerName, mapWidth, mapHeight, pageID, backColor, continuousCallback, navigationEnabled, callBackFunctionString, tileCallbackFunctionString, startResourceList, enableTileCaching, ToolsSupportingClientPostBack)
{
    var percentageBased=false;
    if ((String(mapWidth).indexOf("%")!=-1)||(String(mapHeight).indexOf("%")!=-1)) percentageBased=true;
	
	var width = null;
	var height = null;
	
	if (!percentageBased)
	{
	    width=String(mapWidth).replace("px","");
	    height=String(mapHeight).replace("px","");
	}
	else
	{
	    width=mapWidth;
	    height=mapHeight;
	}
	Maps[controlName] = new MapObject(controlName, width, height, 0, 0, -1, 1, 1);
    map = Maps[controlName]; 
	if (pageID!=null) map.pageID = pageID;
	if (backColor!=null) map.backColor = backColor;
    if (navigationEnabled!=null) map.navigationEnabled = navigationEnabled;
    if (startResourceList==null)  
        startResourceList = mapDefaultResourceId + "||true|";
    map.startResourceList = startResourceList; 
    map.createDivs(mapContainerName, startResourceList);
	if (continuousCallback!=null) map.continuousCallback = continuousCallback;
	if (enableTileCaching!=null) map.enableTileCaching = enableTileCaching;
	if (ToolsSupportingClientPostBack!=null) map.forcePostBackEvent = ToolsSupportingClientPostBack;
    map.callBackFunctionString = callBackFunctionString;
    map.tileCallbackFunctionString = tileCallbackFunctionString;
    map.identifyCallbackFunctionString = identifyCallbackFunctionString;
    map.vectorCallbackFunctionString = vectorCallbackFunctionString;
    if (percentageBased) map.resize(map.viewWidth, map.viewHeight);
}

function updateTiles(tileString, context) {

//    	// Debug stuff that will be displayed in form element, if it exists
//   	if (checkForFormElement(document, 0, "MapDebugBox")) document.forms[0].MapDebugBox.value += ("Tile Response: " + context + ": " + tileString + "\n"); 

   	var contextArray = context.split(",");
    var update = false;
    var resourceId = mapDefaultResourceId; 
    var imageType = ""; 
    if (contextArray.length>1 && contextArray[1]=="UpdateDiv2")  update = true;
    if (contextArray.length>2) resourceId = contextArray[2]; 
    //alert(tileString);
    if (tileString==null) {
        alert("No response");
    } else {  
	    var tileStrings = tileString.split("^^^");
	    var t;
	    for (var i=0;i<tileStrings.length;i++) {
	        t = tileStrings[i].split(",");
	        if (t.length>3)
	        {
	              if (t[3]=="null")
	                resourceId = null;
	              else
	                resourceId = t[3];
	        }
            if (t.length>4) {
                if (t[4].length>0) 
                    imageType = t[4].toLowerCase(); 
            } 	        
			Maps[contextArray[0]].updateTileImage(t[0],t[1],t[2], update, resourceId, imageType);
	    }
	    lastResponseReceivedTime = new Date();  
   } 
 
}

// function for handling server response for scale change
function changeLevel(levelString, context) {
    commonCallbackFree = true;
    lastResponseReceivedTime = new Date();
    var levelArray = levelString.split(":::");
    var contextArray = context.split(",");
    window.setTimeout("Maps['" + levelArray[1] + "'].setUpLevelGrid(" + levelArray[2] + "," + levelArray[3] + "," + levelArray[4] + "," + levelArray[5] + "," + levelArray[6] + "," + levelArray[7] + "," + levelArray[8] + "," + levelArray[9] + "," + levelArray[10] + ");", 1);
}


function TileObject(column, row) {
    this.column = column;
    this.row = row;
}	


// function for setting map control settings	
function addMapControlSettings(mapObj, pageID, toolsForcingPostBack, useScrollWheel, defaultShiftTool, defaultAltTool, useZoomAnimation) {
	mapObj.pageID = pageID;
	//mapObj.toolsForcingPostBack = toolsForcingPostBack;
	if (useScrollWheel!=null) mapObj.useScrollWheel = useScrollWheel;
	if (useZoomAnimation==null) useZoomAnimation = true;
	mapObj.useZoomAnimation = useZoomAnimation;
	if (mapObj.useScrollWheel) {
	    var eventName = isIE ? "mousewheel" : "DOMMouseScroll";
	    var eventHandler = isIE ? mousewheelhandlepiv : onWheelScroll;
	    addEvent(mapObj.divObject, eventName, eventHandler);
	    if (mapObj.snapCircleObject!=null) addEvent(mapObj.snapCircleObject, eventName, eventHandler);
	}
	if (defaultShiftTool!=null) mapObj.shiftMode = defaultShiftTool;
	if (defaultAltTool!=null) mapObj.altMode = defaultAltTool;
}

// function for getting map object assoicated with div event
function getSelectedMapObject(e) {
	var m = null;

		m = getMapObjectByXY(mouseX, mouseY);
		var box = calcElementPosition(m.divId);
		m.pageLeft = box.left;
		m.pageTop = box.top;
		box = calcElementPosition(m.containerDivId);
		m.containerLeft = box.left;
		m.containerTop = box.top;
		if (isIE) {
		    m.containerLeft+=2;
		    m.containerTop+=2;
		}
		m.width = box.width;
		m.height = box.height;
		divObj = document.getElementById(m.divId);
		lastmap = m;
		box=null;

	return m;
}

// function for getting map object by cursor location
function getMapObjectByXY(x,y) {
	var mm = null;
	for (var i=0;i<MapNames.length;i++) {
		var m = Maps[MapNames[i]];
		var box = calcElementPosition(m.containerDivId);
		var right = box.left + box.width;
		var bottom = box.top + box.height;
		if ((x>=box.left) && (x<=right) && (y>=box.top) && (y<=bottom)) {
			mm = m;
			//break;
		}
		box=null;
	}
	return mm;
}

function getMapObjectByDivId(divid) {
	var lastpos = divid.lastIndexOf("_");
	var pos = divid.indexOf("LineDiv_");
	if (pos!=-1) 
	    divid = "MapDiv_" + divid.substring(8);
	else {
	    pos = divid.indexOf("SnapCircle_");
	    if (pos!=-1) divid = "MapDiv_" + divid.substring(11);
	}
	pos = divid.indexOf("MapDiv_");
//	if (pos==-1) pos = divid.indexOf
	var m = null;
	if (pos!=-1) {
		// add logic for testing if the id has an underscore in the name
		var control = divid.substring(7);
		m = Maps[control];
		var box = calcElementPosition(m.divId);
		m.pageLeft = box.left;
		m.pageTop = box.top;
		box = calcElementPosition(m.containerDivId);
		m.containerLeft = box.left;
		m.containerTop = box.top;
		if (isIE) {
		    m.containerLeft+=2;
		    m.containerTop+=2;
		}

		box=null;
	}
	return m;
}


///////////////////////////////////// Set Tool Functions /////////////////////////////////////
// Drag actions - pan
function MapDragImage(divid, mode, showLoading, cursor) {
	var thisCursor = "move";
	if ((cursor!=null) && (cursor!="")) thisCursor = cursor;
	map = Maps[divid];
	if (map!=null) {
		map.setTool(mode, showLoading, "DragImage", thisCursor, -1, "hidden", "");
	}
}
	
// Rectangular actions - zooms, select
function MapDragRectangle(divid, mode, showLoading, cursor) {
	var thisCursor = "crosshair";
	if ((cursor!=null) && (cursor!="")) thisCursor = cursor;
	map = Maps[divid];
	if (map!=null) {
		map.setTool(mode, showLoading, "DragRectangle", thisCursor, -1, "hidden", "");
	}
}
	
// Point actions - identify, CenterAt, ZoomToPoint, etc.
function MapPoint(divid, mode, showLoading, cursor) {
	var thisCursor = "pointer";
	if ((cursor!=null) && (cursor!="")) thisCursor = cursor;
	map = Maps[divid];
	if (map!=null) {
		map.setTool(mode, showLoading, "Point", thisCursor, -1,"hidden", "");
	}
}
	
// Line actions - measure, sketch, select, etc.
function MapLine(divid, mode, showLoading, cursor, vectorToolbarState) {
	var thisCursor = "crosshair";
	if ((cursor!=null) && (cursor!="")) thisCursor = cursor;
	if (vectorToolbarState==null) vectorToolbarState = "hidden";
	map = Maps[divid];
	if (map!=null) {
		map.setTool(mode, showLoading, "ClickShape", thisCursor, 0, vectorToolbarState, 
		"Line - Click to start line. Move cursor to change line and angle. Click again to finish line.");
	}
}

// Polyline action - measure, sketch, select, etc.
function MapPolyline(divid, mode, showLoading, cursor, vectorToolbarState) {
	var thisCursor = "crosshair";
	if ((cursor!=null) && (cursor!="")) thisCursor = cursor;
	if (vectorToolbarState==null) vectorToolbarState = "hidden";
	map = Maps[divid];
	if (map!=null) {
		map.setTool(mode, showLoading, "ClickShape", thisCursor, 1, vectorToolbarState, 
		"Polyline - Click to start line. Click again to add vectors. Double-click to add last vector and complete polyline.");
	}
}

// Polygon action - sketch, select, etc.
function MapPolygon(divid, mode, showLoading, cursor, vectorToolbarState) {
	var thisCursor = "crosshair";
	if ((cursor!=null) && (cursor!="")) thisCursor = cursor;
	if (vectorToolbarState==null) vectorToolbarState = "hidden";
	map = Maps[divid];
	if (map!=null) {
		map.setTool(mode, showLoading, "ClickShape", thisCursor, 2, vectorToolbarState, 
		"Polygon - Click to start line. Click again to add vectors. Double-click to add last vector and complete polygon.");
	}
}

// Circle action - sketch, select, etc.  - click/move/click
//function MapCircleClick(divid, mode, showLoading) {
function MapCircle(divid, mode, showLoading, cursor, vectorToolbarState) {
	var thisCursor = "crosshair";
	if ((cursor!=null) && (cursor!="")) thisCursor = cursor;
	if (vectorToolbarState==null) vectorToolbarState = "hidden";
	map = Maps[divid];
	if (map!=null) {
		map.setTool(mode, showLoading, "ClickShape", thisCursor, 3, vectorToolbarState, 
		"Circle - Click for center of circle. Move cursor to resize circle. Click again to complete circle.");
	}
}

// Circle action - sketch, select, etc. - mousedown/drag/mouseup
function MapDragCircle(divid, mode, showLoading, cursor, vectorToolbarState) {
	var thisCursor = "crosshair";
	if ((cursor!=null) && (cursor!="")) thisCursor = cursor;
	if (vectorToolbarState==null) vectorToolbarState = "hidden";
	map = Maps[divid];
	if (map!=null) {
		map.setTool(mode, showLoading, "DragShape", thisCursor, 3, vectorToolbarState, "");
	}
}

// Oval action - sketch, select, etc. - click/move/click
function MapOval(divid, mode, showLoading, cursor, vectorToolbarState) {
	var thisCursor = "crosshair";
	if ((cursor!=null) && (cursor!="")) thisCursor = cursor;
	if (vectorToolbarState==null) vectorToolbarState = "hidden";
	map = Maps[divid];
	if (map!=null) {
		map.setTool(mode, showLoading, "ClickShape", thisCursor, 4, "hidden", 
			"Oval - Click for start of oval. Move cursor to resize oval. Click again to complete oval.");
	}
}

// Oval action - sketch, select, etc. - mousedown/drag/mouseup
function MapDragOval(divid, mode, showLoading, cursor) {
	var thisCursor = "crosshair";
	if ((cursor!=null) && (cursor!="")) thisCursor = cursor;
	if (vectorToolbarState==null) vectorToolbarState = "hidden";
	map = Maps[divid];
	if (map!=null) {
		map.setTool(mode, showLoading, "DragShape", thisCursor, 4, vectorToolbarState, "");
	}
}

// Box vector action - sketch, select, etc. - click/move/click
function MapBox(divid, mode, showLoading, cursor, vectorToolbarState) {
	var thisCursor = "crosshair";
	if ((cursor!=null) && (cursor!="")) thisCursor = cursor;
	if (vectorToolbarState==null) vectorToolbarState = "hidden";
	map = Maps[divid];
	if (map!=null) {
		map.setTool(mode, showLoading, "ClickShape", thisCursor, 5, vectorToolbarState, "Box - Click for start of box. Move cursor to resize box. Click again to complete box.");
	}
}

// Box vector action - sketch, select, etc. - mousedown/drag/mouseup
function MapDragBox(divid, mode, showLoading, cursor, vectorToolbarState) {
	var thisCursor = "crosshair";
	if ((cursor!=null) && (cursor!="")) thisCursor = cursor;
	if (vectorToolbarState==null) vectorToolbarState = "hidden";
	map = Maps[divid];
	if (map!=null) {
		map.setTool(mode, showLoading, "DragShape", thisCursor, 5, vectorToolbarState, "");
	}
}

// Point actions - identify, CenterAt, ZoomToPoint, etc.
function MapTips(divid, mode, showLoading, cursor) {
	var thisCursor = "pointer";
	if ((cursor!=null) && (cursor!="")) thisCursor = cursor;
	map = Maps[divid];
	if (map!=null) {
		map.setTool(mode, showLoading, "MapTips", thisCursor, -1,"hidden", "");
	}
}

///////////////////////////////////// Set Tool Functions /////////////////////////////////////


////////////////////////////////////// Event Handlers ///////////////////////////////////////

// function for handling mousedown event for a map object
function MapMouseDown(e, controlName) {
    if (getSessionLapse() < maximumLapseTime) {
	    if (isLeftButton(e)) {
	    
	    getXY(e);
	    map = getMapObjectByDivId(this.id);
	    
	    checkShiftCtrlAltKeys(e);
	    if (shiftPressed || ctrlPressed || altPressed)
	        map.swapMode();
	    //alert(map.controlName);
	    switch (map.actionType) {
		    case "DragImage":
				    map.drawBox = false;
				    map.drawShape = false;
				    if (!map.dragImage) {
					    map.dragImage = true;
					    x1=mouseX;
					    y1=mouseY
					    x2=x1;
					    y2=y1;
				        x3 = x2;
				        y3 = y2;
					    document.onmouseup = map.MapMouseUp;
					        map.tempMoveFunction = document.onmousemove;
					    document.onmousemove = map.MapMouseMove;
				        var box = calcElementPosition(map.divId);
		                var box2 = calcElementPosition(map.containerDivId); 
					    panStartLeft = box.left - box2.left;
					    panStartTop = box.top - box2.top;
				    }
			    break;
		    case "DragRectangle":
				    map.dragImage = false;
				    map.drawShape = false;
				    if (!map.drawBox) {
					    map.drawBox = true;
					    x1=mouseX;
					    y1=mouseY;
					    x2=x1+1;
					    y2=y1+1;
    					
					    if (dragbox!=null) {
						    dragbox.divObject.onmousemove = map.MapMouseMove;
						    dragbox.divObject.onmouseup = map.MapMouseUp;
//						    dragbox.update(x1,y1,x2,y2, map.dragBoxColor);
//						    dragbox.show();
                            dragbox.clip(map.dragLineWidth);
					    }
					    document.onmouseup = map.MapMouseUp;
					        map.tempMoveFunction = document.onmousemove;
					    document.onmousemove = map.MapMouseMove;
				    }
			    break;
		    case "Point":
		        if (!ctrlPressed) {
				    map.divObject.style.cursor = "wait";
				    var box = calcElementPosition(map.containerDivId); 
				    zleft = mouseX - box.left;
				    ztop = mouseY - box.top;

				    map.xMin=zleft;
				    map.yMin=ztop;
    			
    			    if (map.preModeExecFunction != null)
	                    eval(map.preModeExecFunction);
    			
				    postBack(map.controlName, 'Point');
				}
			    break;
		    case "DragShape":
		        iframeHideWorkaroundForVML(); 
			    map.dragImage = false;
			    map.drawShape = true;
			    map.drawBox = false;
			    map.divObject.onclick = null;
			    map.divObject.ondblclick = null;
			    map.divObject.onmouseup = map.MapMouseUp;
			    map.vectorObject.vectordiv.onclick = null;
			    map.vectorObject.vectordiv.ondblclick = null;
			    map.vectorObject.vectordiv.onmousemove = map.MapMouseMove;
			    map.vectorObject.vectordiv.onmouseup = map.MapMouseUp;
    			    map.tempMoveFunction = map.divObject.onmousemove;
			    map.divObject.onmousemove = MapMouseMove;
    		
			    controlType = "map";
                
                var box = calcElementPosition(map.containerDivId);
			    map.vectorObject.pixelObject.x1 = mouseX - box.left;
			    map.vectorObject.pixelObject.y1 = mouseY - box.top;

			    map.vectorObject.vectorCount = 1;
			    map.vectorObject.pixelObject.lastX = map.vectorObject.pixelObject.x1;
			    map.vectorObject.pixelObject.lastY = map.vectorObject.pixelObject.y1;
    			
			    break;
	        }
	    }
	} else
	    showLapseAlert();
	return false;
}

// function for handling mousemove event for a map object
function MapMouseMove(e) {
	getXY(e);
	switch (map.actionType) {
		case "DragImage":
			if (map.dragImage) {
				x2 = mouseX;
				y2 = mouseY;
				var xOffset = x2 - lastX;
				var yOffset = y2 - lastY;
				mouseDirection = getMouseDirection(xOffset, yOffset);
				x3 = x2;
				y3 = y2;
				nx = x2-x1;
				ny = y2-y1;
                lastX = x2;
                lastY = y2;
	            var panMoveX = nx + panStartLeft;
	            var panMoveY = ny + panStartTop;
				
			    var currentX = panStartLeft + nx;
			    var currentY = panStartTop + ny;
				map.moveTiles(currentX, currentY, mouseDirection);
			}
			break;
		case "DragRectangle":
			if (map.drawBox) {
				// stretch ZoomBox
				x2=mouseX;
				y2=mouseY;
				// adjustments to keep box within view... vital for zooms
				var box = calcElementPosition(map.containerDivId);
				var mapLeft = box.left;
				var mapTop = box.top;
				var vWidth = parseInt(map.viewWidth);
				var vHeight = parseInt(map.viewHeight);
				if (x2 < mapLeft) x2 = mapLeft;
				if (y2 < mapTop) y2 = mapTop;
				if (x2 > mapLeft + vWidth) x2 = mapLeft + vWidth;
				if (y2 > mapTop + vHeight) y2 = mapTop + vHeight;
				//window.status = x1 + ", " + y1 + ", " + x2 + ", " + y2;
				if (dragbox!=null) {
				    dragbox.clip(map.dragLineWidth);
				    dragbox.show();
			    }  
			}
			break;
		case "ClickShape":
		case "DragShape":
			if (map.drawShape) {
				var vo = map.vectorObject;
				var pix = vo.pixelObject;
				var xycoord = vo.xyCoord;
                var box = calcElementPosition(map.containerDivId);
				pix.x2 = mouseX - box.left;
				pix.y2 = mouseY - box.top;
				switch (vo.mode) {
					case 0:
						vo.clear();
						vo.line(pix.x1, pix.y1, pix.x2, pix.y2);
						vo.draw();
						break;
					case 1:
						var n = xycoord.x.length - 1;
						vo.clear();	
						if (vo.vectorCount>1) {
							vo.polyline(xycoord.x,xycoord.y);
							vo.line(pix.x2, pix.y2, xycoord.x[n], xycoord.y[n]);
						} else if (vo.vectorCount>0){
							vo.line(pix.x1, pix.y1, pix.x2, pix.y2);
						}
						vo.draw();
						break;
					case 2:
						var n = vo.vectorCount;
						if (vo.vectorCount>0) {
							if (vo.vectorCount==1) {
								vo.clear();
								vo.line(xycoord.x[0],xycoord.y[0],pix.x2,pix.y2);
								vo.draw();
							} else if (vo.vectorCount>0){
								var tempx = new Array();
								var tempy = new Array();
								tempx = xycoord.x;
								tempy = xycoord.y;
								tempx[n] = pix.x2;
								tempy[n] = pix.y2;
								vo.clear();
								vo.polygon(tempx, tempy);
								vo.draw();
							}
						}
						vo.draw();
						break;
					case 3:
						var dwidth = Math.abs(pix.x2 - pix.x1);
						var dheight = Math.abs(pix.y2 - pix.y1);
						var dradius;
						if ((dwidth == 0) || (dheight == 0))  {
							dradius = (dwidth == 0) ? dheight : dwidth;
						} else {
							dradius = Math.sqrt((dwidth * dwidth) + (dheight * dheight));
						}
						
						vo.clear();
						vo.circle(pix.x1, pix.y1, dradius, true);
						vo.draw();
						break;
					case 4:
						var dwidth = Math.abs(pix.x2 - pix.x1);
						var dheight = Math.abs(pix.y2 - pix.y1);
						var dleft = (pix.x1 < pix.x2) ? pix.x1 : pix.x2;
						var dtop = (pix.y1 < pix.y2) ? pix.y1 : pix.y2;
						vo.clear();
						vo.oval(dleft, dtop, dwidth, dheight);
						vo.draw();
						break;
					case 5:
						// box
						var dwidth = Math.abs(pix.x2 - pix.x1);
						var dheight = Math.abs(pix.y2 - pix.y1);
						var dleft = (pix.x1 < pix.x2) ? pix.x1 : pix.x2;
						var dtop = (pix.y2 < pix.y1) ? pix.y2 : pix.y1;
						vo.clear();
						vo.box(dleft, dtop,(dleft + dwidth), (dtop + dheight));
						vo.draw();
						break;
				    
				}
				break;
		}
	    case "Point":
	        //return false;
	        break; 
	}
	if (map.moveFunction!=null) {
	    map.moveFunction(e);
	 }
	return false;
}

// function for handling mouseup event for a map object
function MapMouseUp(e) {
	//alert("MouseUp");
	var mapBox = calcElementPosition(map.containerDivId);
	switch (map.actionType) {
		case "DragImage":
			if (map.dragImage) {
				getXY(e);
				document.onmouseup = null;
				document.onmousemove = map.tempMoveFunction;
                
                finishDragImage(map);
				map.dragImage = false;
			}
			break;
		case "DragRectangle":
			
			if (map.drawBox) {
				map.drawBox = false;
				
				map.divObject.style.cursor = "wait";
				
				getXY(e);
				document.onmouseup = null;
				document.onmousemove = map.tempMoveFunction;
				if (dragbox!=null) {
					dragbox.hide();
					dragbox.clip(map.dragLineWidth);
					dragbox.divObject.onmousemove = null;
					dragbox.divObject.onmouseup = null;
				}
				// adjust for offsets
				zleft -= mapBox.left;
				zright -= mapBox.left;
				zbottom -= mapBox.top;
				ztop -= mapBox.top;
				map.xMin=zleft;
				map.yMin=ztop;
				map.xMax=zright;
				map.yMax=zbottom;
                if (map.preModeExecFunction != null)
	                eval(map.preModeExecFunction);                 			
                map.maptipObject.innerHTML = "";
				postBack(map.controlName, 'DragRectangle');
				map.divObject.style.cursor = map.cursor;
			}
			break;
		case "DragShape": 
		    iframeShowWorkaroundForVML();
			map.divObject.style.cursor = "wait";
			map.drawShape = false;
			var restart = false;
			var clientAction = "Line";
			var pix = map.vectorObject.pixelObject;
			switch (map.vectorObject.mode) {
				case 3:
					var dwidth = Math.abs(pix.x2 - pix.x1);
					var dheight = Math.abs(pix.y2 - pix.y1);
					var dradius;
					if ((dwidth == 0) || (dheight == 0))  {
						dradius = (dwidth == 0) ? dheight : dwidth;
					} else {
						dradius = Math.sqrt((dwidth * dwidth) + (dheight * dheight));
					}
					coordString = pix.x1 + ":" + pix.y1 + ":" + dradius;
					clientAction = "Circle";
					break;
				case 4:
					var dwidth = Math.abs(pix.x2 - pix.x1);
					var dheight = Math.abs(pix.y2 - pix.y1);
					var dleft = (pix.x1 < pix.x2) ? pix.x1 : pix.x2;
					var dtop = (pix.y1 < pix.y2) ? pix.y1 : pix.y2;
					var centerX = dleft + (dwidth / 2);
					var centerY = dtop + (dheight / 2);
					coordString = centerX+ ":" + centerY + ":" + dwidth + ":" + dheight;
					clientAction = "Oval";
					break;
				case 5:
		
					// box
					var dwidth = Math.abs(pix.x2 - pix.x1);
					var dheight = Math.abs(pix.y2 - pix.y1);
					var dleft = (pix.x1 < pix.x2) ? pix.x1 : pix.x2;
					var dtop = (pix.y2 < pix.y1) ? pix.y2 : pix.y1;
					coordString = dleft + ":" + dtop + "|" + (dleft + dwidth) + ":" + (dtop + dheight);
					clientAction = "Rectangle";			
					break;
					
			}
			map.vectorObject.vectorCount = 0;
			map.vectorObject.xyCoord.x = new Array();
			map.vectorObject.xyCoord.y = new Array();
		
			map.divObject.ondblclick = null;
			map.vectorObject.vectordiv.onmousemove = null;
			map.vectorObject.vectordiv.ondblclick = null;
			map.divObject.onmousemove = map.tempMoveFunction;
			map.divObject.onmouseup = null;
			
			pix.lastX = -9999;
			pix.lastY = -9999;
			
			var m = map.controlName + "_mode";
			if (checkForFormElement(map.document, docFormID, "PostBackMode")) map.document.forms[docFormID].PostBackMode.value = map.document.forms[docFormID].elements[m].value;
			map.coords = coordString;
			
			postBack( map.controlName, map.document.forms[docFormID].elements[m].value);
			map.divObject.style.cursor = map.cursor;
			
			break;
		case "ClickShape":
			iframeHideWorkaroundForVML();
			map = getMapObjectByDivId(this.id);
			map.dragImage = false;
			map.drawShape = true;
			map.drawBox = false;
			var vo = map.vectorObject;
			var pix = vo.pixelObject;
			var xycoord = vo.xyCoord;
			getXY(e);
		    var tb = document.getElementById(vectortoolbar);
		    if (tb!=null) tb.style.visibility = map.currentVectorToolbarState;
			if (vo.vectorCount==0) {
			    map.tempMoveFunction = map.divObject.onmousemove;
				map.divObject.onmousemove = MapMouseMove;
				vo.vectordiv.onmousemove = MapMouseMove;
				controlType = "map";
			}

			pix.x2 = mouseX - mapBox.left;
			pix.y2 = mouseY - mapBox.top;
			//alert((map.width) + ", " + (map.height));
			if (pix.lastX==pix.x2 && pix.lastY==pix.y2) {
				//if this is a double click(second click)
				//  then send it on to finish up
				MapDoubleClick(e);
			} else {
				if (vo.vectorCount==0) {
					// starting vector
					pix.x1 = mouseX - mapBox.left;
					pix.y1 = mouseY - mapBox.top;
					xycoord.x = new Array();
					xycoord.y = new Array();
					xycoord.x[0] = pix.x1;
					xycoord.y[0] = pix.y1;	
					switch (vo.mode) {
					    case 0:
					        clientAction = "Line";
					        break;
					    case 1:
					        clientAction = "Polyline";
					        break; 
					    case 2:
					        clientAction = "Polygon";   
					        break;
					    case 3:
					        clientAction = "Circle";
					        break;
					    case 4:
					        clientAction = "Oval";
					        break; 
					    case 5:
					        clientAction = "Rectangle";   
					        break;
					      
					}
				
				} else {
					switch (vo.mode) {
						case 0:
							// line
							clientAction = "Line";
							vo.clear();
							vo.line(pix.x1, pix.y1, pix.x2, pix.y2);
							vo.draw();
							jumpToFinish = true;
							break;
						case 1:
							// polyline
							clientAction = "Polyline";
							var n = xycoord.x.length;
							xycoord.x[n] = pix.x2;
							xycoord.y[n] = pix.y2;	
							vo.clear();	
							vo.polyline(xycoord.x,xycoord.y);
							vo.draw();
							break;
						case 2:
							// polygon
							clientAction = "Polygon";
							var n = xycoord.x.length;
							xycoord.x[n] = pix.x2;
							xycoord.y[n] = pix.y2;	
							var tempx = new Array();
							var tempy = new Array();
							var s="";
							tempx = xycoord.x;
							tempy = xycoord.y;
							vo.clear();	
							if (vo.vectorCount>2) vo.polygon(tempx,tempy)
								else vo.polyline(tempx,tempy);
							vo.draw();
							break;
						case 3:
							// click circle
							clientAction = "Circle";
							var dwidth = Math.abs(pix.x2 - pix.x1);
							var dheight = Math.abs(pix.y2 - pix.y1);
							var dradius;
							if ((dwidth == 0) || (dheight == 0))  {
								dradius = (dwidth == 0) ? dheight : dwidth;
							} else {
								dradius = Math.sqrt((dwidth * dwidth) + (dheight * dheight));
							}
							vo.clear();
							vo.circle(pix.x1, pix.y1, dradius, true);
							vo.draw();
							jumpToFinish = true;
							break;
						case 4:
							// click oval
							clientAction = "Oval";
							var dwidth = Math.abs(pix.x2 - pix.x1);
							var dheight = Math.abs(pix.y2 - pix.y1);
							var dleft = (pix.x1 < pix.x2) ? pix.x1 : pix.x2;
							var dtop = (pix.y2 < pix.y1) ? pix.y2 : pix.y1;
							vo.clear();
							vo.oval(dleft, dtop, dwidth, dheight);
							vo.draw();
							jumpToFinish = true;
							break;
						case 5:
							// click box
							clientAction = "Rectangle";
							var dwidth = Math.abs(pix.x2 - pix.x1);
							var dheight = Math.abs(pix.y2 - pix.y1);
							var dleft = (pix.x1 < pix.x2) ? pix.x1 : pix.x2;
							var dtop = (pix.y2 < pix.y1) ? pix.y2 : pix.y1;
							vo.clear();
							vo.box(dleft, dtop,(dleft + dwidth), (dtop + dheight));
							vo.draw();
							jumpToFinish = true;
							break;
					}
				}
				vo.vectorCount++;
				pix.lastX = pix.x2;
				pix.lastY = pix.y2;
			
				if (jumpToFinish) 
				    MapDoubleClick(e);
				else {
		            if (map.vectorCallbackFunctionString!=null && map.vectorCallbackFunctionString.length>0) {
		                // pass back the coords of the current shape
			            coordString ="";
			            if (xycoord.x.length>0) {
			                var n = xycoord.x.length - 1;
			                var m = n - 1;
			                if ((xycoord.x[m]==xycoord.x[n]) && (xycoord.y[m]==xycoord.y[n])) {
				                xycoord.x.length = n;
				                xycoord.y.length = n;
			                }
			                for (var i=0;i<xycoord.x.length;i++) {
				                if (i > 0) coordString += "|";
				                coordString += xycoord.x[i] + ":" + xycoord.y[i];
			                }
		                }
		                var argument = "ControlID=" + map.controlName + "&EventArg=" + clientAction + "&ControlType=Map&coords=" + coordString + "&VectorMode=" + map.mode + "&VectorAction=AddPoint";
		                if (checkForFormElement(document, 0, "MeasureUnits")) argument += "&MeasureUnits=" + document.forms[0].MeasureUnits.value;
		                if (checkForFormElement(document, 0, "AreaUnits")) argument += "&AreaUnits=" + document.forms[0].AreaUnits.value;
		                if (checkForFormElement(document, 0, "MapUnits")) argument += "&MapUnits=" + document.forms[0].MapUnits.options[document.forms[0].MapUnits.selectedIndex].value;
		                
		                var context = map.controlName + "," + clientAction;

    	// Debug stuff that will be displayed in form element, if it exists
   	if (checkForFormElement(document, 0, "MapDebugBox")) document.forms[0].MapDebugBox.value += ("Vector Request: " + context + ": " + coordString + "\n"); 
		                
		                eval(map.vectorCallbackFunctionString);
		            }
		        }				
			}
			break;
	    case "Point":
	        return false;
	        break; 
	}
	return false;
}

function MapDoubleClick(e) {
    iframeShowWorkaroundForVML();
	var vo = map.vectorObject;
	var pix = vo.pixelObject;
	var xycoord = vo.xyCoord;
	map.divObject.style.cursor = "wait";
	var restart = false;
	var clientAction = "Line";
	switch (vo.mode) {
		case 0:
			coordString = pix.x1 + ":" + pix.y1 + "|" + pix.x2 + ":" + pix.y2;
			restart = true;
			break;
		case 1:
			var blurb = "PolyLine:\n";
			coordString ="";
			for (var i=0;i<xycoord.x.length;i++) {
				blurb += "[" + (i+1) + "] " + xycoord.x[i]+ ", "  + xycoord.y[i] + "\n";
				if (i > 0) coordString += "|";
				coordString += xycoord.x[i] + ":" + xycoord.y[i];
			}
			restart = true;
			clientAction = "Polyline";
			break;
		case 2:
			var n = xycoord.x.length - 1;
			var m = n - 1;
			if ((xycoord.x[m]==xycoord.x[n]) && (xycoord.y[m]==xycoord.y[n])) {
				xycoord.x.length = n;
				xycoord.y.length = n;
			}
				
			if (vo.vectorCount>2) {
				var blurb = "Polygon:\n";
				coordString ="";
				for (var i=0;i<xycoord.x.length;i++) {
					blurb += "[" + (i+1) + "] " + xycoord.x[i] + ", "  + xycoord.y[i] + "\n";
					if (i > 0) coordString += "|";
					coordString += xycoord.x[i] + ":" + xycoord.y[i];
				}
				coordString += "|" + xycoord.x[0] + ":" + xycoord.y[0];
				restart = true;
				clientAction = "Polygon";
			} else {
				alert("A Polygon needs at least three vectors.");
			}
			
			break;
		case 3:
			var dwidth = Math.abs(pix.x2 - pix.x1);
			var dheight = Math.abs(pix.y2 - pix.y1);
			var dradius;
			if ((dwidth == 0) || (dheight == 0))  {
				dradius = (dwidth == 0) ? dheight : dwidth;
			} else {
				dradius = Math.sqrt((dwidth * dwidth) + (dheight * dheight));
			}
			coordString = pix.x1 + ":" + pix.y1 + ":" + dradius;
			restart = true;
			clientAction = "Circle";
			break;
		case 4:
			var dwidth = Math.abs(pix.x2 - pix.x1);
			var dheight = Math.abs(pix.y2 - pix.y1);
			var dleft = (pix.x1 < pix.x2) ? pix.x1 : pix.x2;
			var dtop = (pix.y1 < pix.y2) ? pix.y1 : pix.y2;
			var centerX = dleft + (dwidth / 2);
			var centerY = dtop + (dheight / 2);
			coordString = centerX+ ":" + centerY + ":" + dwidth + ":" + dheight;
			restart = true;
			clientAction = "Oval";
			break;
		case 5:

			// box
			var dwidth = Math.abs(pix.x2 - pix.x1);
			var dheight = Math.abs(pix.y2 - pix.y1);
			var dleft = (pix.x1 < pix.x2) ? pix.x1 : pix.x2;
			var dtop = (pix.y2 < pix.y1) ? pix.y2 : pix.y1;
			coordString = dleft + ":" + dtop + "|" + (dleft + dwidth) + ":" + (dtop + dheight);
			restart = true;
			clientAction = "Rectangle";			
			break;
	}
	if (restart) {
		vo.vectorCount = 0;
		xycoord.x = new Array();
		xycoord.y = new Array();

		map.divObject.ondblclick = null;
		vo.vectordiv.onmousemove = null;
		vo.vectordiv.ondblclick = null;
		pix.lastX = -9999;
		pix.lastY = -9999;
		
		map.coords = coordString;
		
		if (map.vectorCallbackFunctionString!=null && map.vectorCallbackFunctionString.length>0) {
		    //
		    var argument = "ControlID=" + map.controlName + "&EventArg=" + clientAction + "&ControlType=Map&coords=" + coordString + "&VectorMode=" + map.mode + "&VectorAction=Finish";
		    var context = map.controlName + "," + clientAction;
		    eval(map.vectorCallbackFunctionString);
		} else
		{
		    if (map.preModeExecFunction != null)
		        eval(map.preModeExecFunction);
		
		    postBack( map.controlName, clientAction);
		}
		
		//vo.clear();
		vo.restart(map.clearDrawnVectors);
		map.divObject.style.cursor = map.cursor;
	}
	jumpToFinish = false;
	map.drawShape = false;
	return false;
}


function getMouseDirection(xOffset, yOffset) {
    var dir = "";
    if (xOffset>0 && yOffset>0) {
        // nw
        dir = "ul";
        
    } else if (xOffset<0 && yOffset>0) {
        // ne
        dir = "ur"
    } else if (xOffset>0 && yOffset<0) {
        // sw
        dir = "ll";
    } else if (xOffset<0 && yOffset<0) {
        // se
        dir = "lr";
    } else if (yOffset>0) {
        // north
        dir = "up";
    } else if (yOffset<0) {
        // south
        dir = "down";
    } else if (xOffset>0) {
        // west
        dir = "left";
    } else if (yOffset<0) {
        // east
        dir = "right";
    }
    return dir;
        
}

// common function for finishing up a drag image type movement... 
    // used by DragImage, keyboard movement, Nav Control, and overview AOI movement
    // uses global temps nx and ny, calculated by the above actions
function finishDragImage(mapObj) {
	var	centerX = Math.round(mapObj.viewWidth/2);
	var	centerY = Math.round(mapObj.viewHeight/2);
	var newX = centerX - nx;
	var newY = centerY - ny;
	mapObj.xMin=newX;
	mapObj.yMin=newY;
	if (!mapObj.continuousCallback && mapObj.enableTileCaching) {
	    mapObj.getTopLeftTile();
	    mapObj.updateView(true);
	}
    if (nx==0 && ny==0) {
        // no action currently
    } else { 
        mapObj.maptipObject.innerHTML = "";  
	    postBack(mapObj.controlName, 'DragImage');	
    }
    if (mapObj.useZoomAnimation) mapObj.updateMapDiv2();		
	nx = 0;
	ny = 0;

}

function zoomToBox(controlName, left, top, right, bottom) {
    //alert(controlName);
    map = Maps[controlName];
    if (map!=null) {
	    map.xMin=left;
	    map.yMin=ztop;
	    map.xMax=right;
	    map.yMax=bottom;
	    postBack(controlName, 'DragRectangle');
	} else
	    alert(controlName + " not found.");

}
///////////////////////////// IE MouseWheel functions ... zoom ////////////////////////

	// Note: enable by adding these lines after the complete setup of the map object and divs:
		// map.divObject.onmousewheel = mousewheelhandlepiv;
		// setWheelParams(map);
		
		var m_zoomFactor = 1.0;
		// these are hard-coded for testing
		var m_imageWidth = 1800;
		var m_imageHeight = 1200;
		var m_imageLeft = -600;
		var m_imageTop = -400;
		var m_imageXOffset = 0;
		var m_imageYOffset = 0;
		var m_centerX = 300;
		var m_centerY = 200;
		var m_zoomIncre = 0.1;
		var m_zoomEnd = 2.0;
		
		var m_lastZoomFactor = 0;
		var m_moveWheel = false;
		var m_wheelCheckInterval;
		var slideXoffset = 0;
		var slideYoffset = 0;
		var m_canSlide = false;
		var m_sliderId = "";
		var keepZooming = false;
		var zoomAnimationDelay = false;
		var m_mouseWheelForceDelay = 1000; // force delay so multiple zooms will not be triggered on single wheel movement 
		var m_mouseWheelLastUseTime = new Date();
		var m_mouseWheelUseTime = null;
		
		function mousewheelhandlepiv(evt){
		    m_mouseWheelUseTime = new Date();
		    if (m_mouseWheelUseTime - m_mouseWheelLastUseTime > m_mouseWheelForceDelay) {
		        if (getSessionLapse() < maximumLapseTime) {
		            if (!keepZooming) {
		                setWheelParams();
		                if (mouseWheelAwayZoomIn) {
			                if (event.wheelDelta >= 120 && canWheelZoom("in")) 
			                    zoomIn(evt);
			                else if (event.wheelDelta <= -120 && canWheelZoom("out")) 
			                    zoomOut(evt);
			            } else { 
			                if (event.wheelDelta >= 120 && canWheelZoom("out")) 
			                    zoomOut(evt);
			                else if (event.wheelDelta <= -120 && canWheelZoom("in")) 
			                    zoomIn(evt);
			            } 
		            }
		        } else 
		            showLapseAlert();
		        m_mouseWheelLastUseTime = m_mouseWheelUseTime;
		    }
		}
		
		function onWheelScroll(evt) {
		    m_mouseWheelUseTime = new Date();
		    if (m_mouseWheelUseTime - m_mouseWheelLastUseTime > m_mouseWheelForceDelay) {
		        if (getSessionLapse() < maximumLapseTime) {
		            if (!keepZooming) {
		                setWheelParams();
		                if (mouseWheelAwayZoomIn) { 
			                if (evt.detail < 0 && canWheelZoom("in"))
				                zoomIn(evt);
			                else if (evt.detail > 0 && canWheelZoom("out")) 
			                    zoomOut(evt);
			            } else {
			                if (evt.detail < 0 && canWheelZoom("out"))
				                zoomOut(evt);
			                else if (evt.detail > 0 && canWheelZoom("in")) 
			                    zoomIn(evt);
			            }  
		            }		
		        } else 
		                showLapseAlert();
		        m_mouseWheelLastUseTime = m_mouseWheelUseTime;
		    }
		}
		
		function canWheelZoom(dir) {
		    var goAhead = false;
		    if (map.totalLevels<1)
		        goAhead = true;
		    else {
		        if (dir=="in" && map.level<map.totalLevels-1) 
		            goAhead = true;
		        else if (dir=="out" && map.level>0)
		            goAhead = true;
		    }
		    return goAhead;
		}
		
		function setZoom(which) {
		        // update zoom factor
		        m_zoomFactor += m_zoomIncre;
		        // use zoom factor to set params for scale div
			    var iw = m_imageWidth * m_zoomFactor;
			    var ih = m_imageHeight * m_zoomFactor;
			    var ixw = m_imageXOffset * m_zoomFactor;
			    var iyw = m_imageYOffset * m_zoomFactor;
			    var il = m_centerX - ixw;
			    var it = m_centerY - iyw;	
			    // make sure it's visible
    			map.divObject2.style.visibility = "visible";
    			// update size and position of scale div
    			if (isIE) {
			        map.divScaleObject2.style.zoom = m_zoomFactor;
			    } else {
			        var div;
			        var tw = (map.columnsPerView + 1);
                    var th = (map.rowsPerView + 1);
                    for (var r=0; r<th; r++) {
                        for (var c=0; c< tw; c++) {
                            div = document.getElementById(map.controlName + '_MapAnimationDiv_' + c + '_' + r);
                            if (div!=null) {
                                div.style.width = Math.round(map.tileWidth * m_zoomFactor) + "px";
                                div.style.height = Math.round(map.tileHeight * m_zoomFactor) + "px"; 
                            }  
                        } 
                    } 
			        map.divScaleObject2.style.width = Math.floor(iw) + "px";
			        map.divScaleObject2.style.height = Math.floor(ih) + "px";
			    }
			    map.divObject2.style.left = Math.floor(il) + "px";
			    map.divObject2.style.top = Math.floor(it) + "px";
		}


		
		function zoomOut(evt) {
			m_zoomFactor = 1;
			m_zoomIncre = -0.05;
			m_zoomEnd = 0.5;
			keepZooming = true;
			if (map.useZoomAnimation) 
		        map.showMapDiv2();
			window.setTimeout("navZoomOut(null, '" + map.controlName + "'); zoomAnimationDelay = true;", 0);
			map.maptipObject.innerHTML = "";
			if (map.useZoomAnimation) {
			    var speed = 25;
			    var timer = 0;
			    var start = m_zoomFactor
			    for (var i = start; i >= m_zoomEnd; i+=m_zoomIncre) {
			        window.setTimeout("setZoom();", (timer * speed));
			        timer++;
			    }  
			     keepZooming = false;
			}
			else
			    keepZooming = false;
			var rc = map.ResourceCollection;
			for (var i=0;i<rc.length;i++) {
			    rc[i].divObject.innerHTML = "";
			}
		}

		function zoomIn(evt) {
			m_zoomFactor = 1;
			m_zoomIncre = 0.1;
			m_zoomEnd = 2.0;
			keepZooming = true;
			if (map.useZoomAnimation) 
		        map.showMapDiv2();
		    window.setTimeout("navZoomIn(null, '" + map.controlName + "'); zoomAnimationDelay = true;", 0);
		    map.maptipObject.innerHTML = ""; 
		    //alert("zoomIn"); 
			if (map.useZoomAnimation) {
			    var speed = 25;
			    var timer = 0;
			    var start = m_zoomFactor
			    for (var i = start; i <= m_zoomEnd; i+=m_zoomIncre) {
			        window.setTimeout("setZoom();", (timer * speed));
			        timer++;
			    }  
			     keepZooming = false;
			}
			else
			     keepZooming = false;
			var rc = map.ResourceCollection;
			for (var i=0;i<rc.length;i++) {
			    rc[i].divObject.innerHTML = "";
			}
		}
		
		function setWheelParams(map2) {
			if (map2!=null) map = map2;
			if (map.useZoomAnimation) map.checkMapDiv2();
	        m_centerX = Math.floor(map.viewWidth / 2);
	        m_centerY = Math.floor(map.viewHeight / 2);
	        m_imageLeft = parseInt(map.divObject2.style.left);
		    m_imageTop = parseInt(map.divObject2.style.top);
		    m_imageXOffset = m_centerX + (0 - m_imageLeft);
		    m_imageYOffset = m_centerY + (0 - m_imageTop);

		}
		
function checkNavDirection(type) {
	var xDir = 0;
	var yDir = 0;
	if (nav_active) {
		switch (type) {
			case "up":
				ny+=map.mapMoveIncrement;
				yDir = 1;
				break;
			case "ur":
				nx-=map.mapMoveIncrement;
				ny+=map.mapMoveIncrement;
				xDir = -1;
				yDir = 1;
				break;
			case "right":
				nx-=map.mapMoveIncrement;
				xDir = -1;
				break;
			case "lr":
				nx-=map.mapMoveIncrement;
				ny-=map.mapMoveIncrement;
				xDir = -1;
				yDir = -1;
				break;
			case "down":
				ny-=map.mapMoveIncrement;
				yDir = -1;
				break;
			case "ll":
				nx+=map.mapMoveIncrement;
				ny-=map.mapMoveIncrement;
				xDir = 1;
				yDir = -1;
				break;
			case "left":
				nx+=map.mapMoveIncrement;
				xDir = 1;
				break;
			case "ul":
				nx+=map.mapMoveIncrement;
				ny+=map.mapMoveIncrement;
				xDir = 1;
				yDir = 1;
				break;
		}
	} else {
		nx=0;
		ny=0;	
	}
	var panMoveX = nx + panStartLeft;
	var panMoveY = ny + panStartTop;
	navDir = type;
	
	var currentX =0;
	var currentY = 0;
	var tLeft = 0-(map.tileWidth * map.columns);
	var tTop = 0-(map.tileHeight * map.rows);
	currentX = panStartLeft + nx;
	currentY = panStartTop + ny;
	
	map.moveTiles(currentX, currentY, navDir);
	return false;
}

		function keyDown(e) {
		    if (map.keyFocus) {
		        var theKey;
		        var dir = "";
	            if (isIE) 
		            theKey = event.keyCode;
	            else
		            theKey = e.which;
		        checkShiftCtrlAltKeys(e);
		        if (shiftPressed)
		            map.divObject.style.cursor = map.shiftCursor;
		        else if (ctrlPressed)
		            map.divObject.style.cursor = map.ctrlCursor;
		        else if (altPressed)
		            map.divObject.style.cursor = map.altCursor;
	            switch (theKey)
	            {
	            case 37:
		            // left
		            dir = "left";
		            break;
	            case 38:
		            // up
		            dir = "up";
		            break;
	            case 39:
		            // right
		            dir = "right";
		            break;
	            case 40:
		            // down
		            dir = "down";
		            break;
	            case 33:
		            // PgUp... ur
		            dir = "ur";
		            break;
	            case 34:
		            // PgDn... lr
		            dir = "lr";
		            break;
	            case 35:
		            // End... ll
		            dir = "ll";
		            break;
	            case 36:
		            // Home... ul
		            dir = "ul";
		            break;
		        case 107:
		            // shift-plus ... zoom in
		            if (shiftPressed) {
		                dir ="";
    		            if (getSessionLapse() < maximumLapseTime) {
		                    nav_active = false;
    		               setWheelParams(); 
    		               if (canWheelZoom("in"))
    		                zoomIn(e); 
    		            } else
    		                showLapseAlert();
    		        }
    		        break;
		        case 109:
		            // shift-minus ... zoom out
		            if (shiftPressed) {
		                dir ="";
		                if (getSessionLapse() < maximumLapseTime) {
		                    nav_active = false;
    		               setWheelParams(); 
    		               if (canWheelZoom("out"))
    		                zoomOut(e); 
    		            } else
    		                showLapseAlert();
    		        }
    		        break;
		        default:
		            // no direction
		            nav_active = false;
	            }
    	        
		        if (dir!="") {
		            if (getSessionLapse() < maximumLapseTime) {
		                if (!nav_active) {
		                    var box = calcElementPosition(map.divId);
		                    var box2 = calcElementPosition(map.containerDivId); 
					        panStartLeft = box.left - box2.left;
					        panStartTop = box.top - box2.top;
		                    map.dragImage = true;
		                    nav_active = true;
		                }
		                var tempIncre = map.mapMoveIncrement;
		                map.mapMoveIncrement *= 2;
		                checkNavDirection(dir);
		                map.mapMoveIncrement = tempIncre;
		                if (map.vectorObject!=null) map.vectorObject.restart();
		            } else
		                showLapseAlert();
                }
                else if (theKey == 27) { // Escape
                    if (map.vectorObject!=null) map.vectorObject.restart();
		        }
		    }
		}
		
		function keyUp(e) {
	        map.dragImage = false;
	        if (nav_active) {
	            nav_active = false;
            	finishDragImage(map);
	            nx = 0;
	            ny = 0;
		    }
		    dir=""; 
		    map.divObject.style.cursor = map.tempCursor;
		    
		}
		
		function setMapFocus(control) {
		    //alert(control);
		    map = Maps[control];
		    map.keyFocus = true;
		}
		function setMapBlur(control) {
		    //
		    map.keyFocus = false;
		}
		
function navZoomIn(e, controlName)
{
    if (getSessionLapse() < maximumLapseTime) {
        map = Maps[controlName];
        if (map!=null) {
	        if (map.totalLevels<1) {
		        // dynamic tiles
	            map.coords = "2";
	            postBack(map.controlName, "ScrollWheelZoom");
	        } else {
		        // static tiles
	            var level = map.level;
	            if (level<map.totalLevels-1) {
		            level++;
		            map.switchToLevel(level);
	            }
	        }
	    }
	} else
	    showLapseAlert();
	return false;
}

function navZoomOut(e, controlName)
{
    if (getSessionLapse() < maximumLapseTime) {
        map = Maps[controlName];
        if (map!=null) {
	        if (map.totalLevels<1) {
		        // dynamic tiles
	            map.coords = map.setDecimalDelimiter(1 / 2);
	            postBack(map.controlName, "ScrollWheelZoom");
	        } else {
		        var level = map.level;
		        if (level>0) {
			        level--;
			        map.switchToLevel(level);
		        }
		    }
		}
	} else
	    showLapseAlert();
	return false;
}

 function fixedZoomIn(e, controlName) 
{
    if (getSessionLapse() < maximumLapseTime) {
        map = Maps[controlName];
        if (map!=null) { 
            nav_active = false;
           setWheelParams(); 
           if (canWheelZoom("in"))
                zoomIn(e); 
      } 
    } else
        showLapseAlert();
}

function fixedZoomOut(e, controlName)
{
    if (getSessionLapse() < maximumLapseTime) {
        map = Maps[controlName];
        if (map!=null) { 
            nav_active = false;
           setWheelParams();
           if (canWheelZoom("out")) 
                zoomOut(e); 
        }
    } else
        showLapseAlert();

}
  

function AutoResizeMap(event, controlName) {
    window.clearTimeout(reloadTimer);
    if (controlName==null) {
        // call the function that will check the maps
	    reloadTimer = window.setTimeout("AutoResizeMapToParent();",1000);
    } else {    
	    // a map controlname passed in... resize that one
	    reloadTimer = window.setTimeout("if (Maps['" + controlName + "'].enableResizeEvent) Maps['" + controlName + "'].resizeToParent();",1000);
    }
}

function AutoResizeMapToWindow(event, controlName) {
    window.clearTimeout(reloadTimer);
	    // a map controlname passed in... resize that one
	reloadTimer = window.setTimeout("if (Maps['" + controlName + "'].enableResizeEvent) Maps['" + controlName + "'].resizeToWindow();",1000);
}

function AutoResizeMapToParent() {
    var m;
    if (MapNames.length==1 && map!=null) {
        // only one map... resize that one if permitted
        if (map.enableResizeEvent)
            map.resizeToParent();
    } else {
        // loop through all maps and resize those that are permitted
        for (var i=0;i<MapNames.length;i++) {
            m = Maps[MapNames[i]];
            if (m.enableResizeEvent)
                m.resizeToParent();
        }
    }
}

function moveSnapCircle(e) {
        var snap = map.snapCircleObject;
        getXY(e);
		var mx = mouseX;
		var my = mouseY;
		if (isIE) {
		    // undo adjustment for ie... not necessary for snap circle;
		    mx+=3;
		    my+=3;
		}  
        if (snap!=null) {
            var box = calcElementPosition(map.containerObject.id);
		    snap.style.left = (mx - Math.round(parseFloat(snap.clientWidth) / 2) - box.left) + "px";
		    snap.style.top = (my - Math.round(parseFloat(snap.clientHeight) / 2)- box.top) + "px";
	    } 
}
	
/* Resource related properties
*/

function ResourceObject(id, index, visible, mapId, tileServerUrl, tileServerUrlGenerator, tileServerImageFormat, gridLimits, mappedLevel) {
    this.id = id;
    this.index = (index!=null) ? index : 0;
    this.visible = (visible!=null) ? eval(visible) : true;  
    this.mapId = (mapId!=null) ? mapId : "Map1";
    this.tileServerUrl = (tileServerUrl!=null) ? tileServerUrl : ""; 
    this.tileServerUrlGenerator = (tileServerUrlGenerator!=null) ? tileServerUrlGenerator : ""; 
    this.mapObject = null; 
    this.divObject = null;
    this.divId = "MapResourceDiv_" +  this.mapId + "_ " + this.id ;  
    this.displayedTiles = new Array();
    this.pngTiles = new Array();
    this.imageFormat = (tileServerImageFormat!=null) ? tileServerImageFormat : ""; 
    this.checkCallbackCount = 0;
    ///// Added for resource limit check 
    this.minColumn = 0;
    this.maxColumn = 0;  
    this.minRow = 0;
    this.maxRow = 0;      
    this.gridLimits = (gridLimits==null) ? "" : gridLimits;
    var limits = this.gridLimits.split(",");
    if (limits.length==4) {
        this.minColumn = parseInt(limits[0]);
        this.minRow = parseInt(limits[1]);
        this.maxColumn = parseInt(limits[2]);
        this.maxRow = parseInt(limits[3]);
    }   
   ///// Added for resource limit check
    this.mappedLevel = (mappedLevel==null) ? 0 : mappedLevel; ///// Added for resource mapping check
     
    this.redraw = function() {
        // clear resource grid and redraw resource tiles displayed in view  
        this.mapObject.clearLevelGrid(this.id, this.gridLimits);
    }  
   
    this.show = function() {
        this.visible = true;
        this.redraw();
    }     

    this.hide = function() {
        this.visible = false;
        this.redraw();
    }     

    this.toggle = function() {
        this.visible = !this.visible;
        this.redraw();
    }    
   
    ///// Added for resource limit check 
    this.isWithinLimits = function(column, row) {
        // do not set limits if .gridLimits is nothing or all limits equal -99 
        if (this.gridLimits==null || this.gridLimits=="" || (this.minColumn==-99 && this.minRow==-99 && this.maxColumn==-99 && this.maxRow==-99))
            return true;
        else  
            return (column>= this.minColumn && column<=this.maxColumn && row>=this.minRow && row<=this.maxRow);
    }
   
    this.setLimits = function(minColumn, minRow, maxColumn, maxRow) {    
        this.minColumn = minColumn;
        this.minRow = minRow;
        this.maxColumn = maxColumn;
        this.maxRow = maxRow;
        this.gridLimits = minColumn + "," + minRow + "," + maxColumn + "," + maxRow;
        if (this.gridLimits="-99,-99,-99,-99") {
            this.gridLimits = ""; 
        }
    } 
    ///// Added for resource limit check 
}

function esriResourceCollectionAdd(resource, draw) { 
        var position = this.length;
        this[this.length] = resource;  
        this[position].index = position;
        if (draw==null) draw = false;
        var resourceHtml =  '<div id="' + resource.divId + '" style="position:absolute; left:0px; top:0px;  width:' + this.mapObject.viewWidth + '; height:' + this.mapObject.viewHeight + '; "  ></div>\n';
        this.mapObject.divObject.insertAdjacentHTML("AfterBegin", resourceHtml);           ///// Added for dynamic resource addition/deletion
        this.setObjects();
        if (draw) this.redraw(resource.id);
}

function esriResourceCollectionContains(id) {
	for (var i=0; i<this.length; i++ ) {
		if (this[i].id == id)
			return true;
	}
	return false;
}

function esriResourceCollectionFind(id) {
	for (var i=0; i<this.length;i++) {
		if (this[i].id == id)
		    return this[i];
	}
    return null;    
}
		
function esriResourceCollectionInsert(resource, position, draw) {
    //var length = this.length - 1;
    if (draw==null) draw = false; 
    ///// Added for dynamic resource addition/deletion 
    var node = null;
    var resourceHtml =  '<div id="' + resource.divId + '" style="position:absolute; left:0px; top:0px;  width:' + this.mapObject.viewWidth + '; height:' + this.mapObject.viewHeight + '; "  ></div>\n';
    if (position>this.length) position = this.length;
    if (position==this.length) {
        this.add(resource, draw);
    } else  {
        node = document.getElementById(this[position].divId);
        if (node!=null) {
            node.insertAdjacentHTML("AfterEnd", resourceHtml);  
	        for (var i=this.length; i>position;i--) {
		        this[i] = this[i-1];
		        this[i].index = i;
//                this[i].displayedTiles = new Array();
//                this[i].pngTiles = new Array();
	        }
    ///// Added for dynamic resource addition/deletion 
	        this[position] = resource;
	        this[position].index = position;
	    } else {
	        alert("Cannot insert new resource. Unable to find " + this[position].divId + ".");
	    }
	}
	this.setObjects();
	if (draw) this.redraw(resource.id);
	
}
		
function esriResourceCollectionRemove(id) {
    var position = this.getPosition(id);
    if (position>-1) {
         this.removeAt(position, false);
    }  
}

function esriResourceCollectionRemoveAt(position) {
///// Added for dynamic resource addition/deletion
//    if (this.length>1) {
	    var length = this.length - 1;
	    var node = null;
	    if (position>-1 && position<this.length) 
            node = document.getElementById(this[position].divId);
        if (node!=null) {
            var id = this[position].id; 
            node.removeNode(true);
	            for (var i=position; i<this.length;i++) {
		            if (i<length) this[i] = this[i+1];
		            this[i].index = i; 
                    //this[i].displayedTiles = new Array();
                    //this[i].pngTiles = new Array();
	            }
	            this.length = length;
	        if (id==this.mapObject.baseResourceId && this.length>0) {
	            this.mapObject.baseResourceId = this[this.length - 1].id; 
	            this.mapObject.createMapDiv2();
	        }
    	    
	    } else {
            alert("Cannot remove resource. Unable to find resource at position " + position + ".");	
        }
//    } else {
//        alert("Cannot remove resource if it is the only resource.");
//    }
///// Added for dynamic resource addition/deletion
}

function esriResourceCollectionPosition(id) {
    var position = -1;
	for (var i=0; i<this.length;i++) {
		if (this[i].id == id)
		    return i;
	}
    return position;    
}	


function esriResourceCollectionReplace(newResource, oldResourceId, draw) {
    var position = this.getPosition(oldResourceId);
    if (draw==null) draw = false; 
    if (position>-1) 
        this.replaceAt(newResource, position, draw); 

}

function esriResourceCollectionReplaceAt(newResource, position, draw) {
    if (position==null || isNaN(position)) position = 0;
    if (draw==null) draw = false; 
    var length = this.length - 1; 
    this[position] = resource; 
    this[position].index = position;
    if (draw) this.redraw(newResource.id);  
}

function esriResourceCollectionSetObjects() {
    for (var i=0;i<this.length;i++) {
        this[i].divObject = document.getElementById(this[i].divId);
        this[i].mapObject = Maps[this[i].mapId];
    }  
}

function esriResourceCollectionRedraw(id) {
    var resourceIndex = this.getPosition(id);
    var resource = this[resourceIndex];
    var gridLimits = resource.gridLimits;
    this.mapObject.clearLevelGrid(id, gridLimits);
}

function esriResourceCollectionBottomVisiblePosition() {
    var position = 0;
	for (var i=0; i<this.length;i++) {
		if (this[i].visible)
		    position = i;
	}
    return position;    
}

///// Added for returned tiles check
function esriPendingTilesAdd(tileString) {
    this.push(tileString);
    this.mapObject.divObject.style.cursor = "progress";
    if (this.onRequestsPending!=null) this.onRequestsPending(this.mapObject);
}

function esriPendingTilesFind(tileString) {
    var found = new Array();
    for (var i=0;i<this.length; i++) {
        if (this[i]==tileString) found.push(i);
    }  
    return found; 
}

function esriPendingTilesRemove(tileString) {
    var found = this.find(tileString);
    if (found.length>0) {
        for (var i=found.length-1;i>=0; i--) {
            this.splice(found[i],1);
        }
    }
    if (this.onRequestsRemove!=null) this.onRequestsRemove(this.mapObject); 
    if (this.length==0) {
        this.mapObject.divObject.style.cursor = this.mapObject.cursor;
        if (this.onRequestsComplete!=null) this.onRequestsComplete(this.mapObject);  
    }  
}

function esriAddOnRequestsPending(theHandler) {
    this.onRequestsPending = theHandler;
}

function esriAddOnRequestsRemove(theHandler) {
    this.onRequestsRemove = theHandler;
}

function esriAddOnRequestsCompleted(theHandler) {
    this.onRequestsComplete = theHandler;
}


///// Added for returned tiles check
	
//alert("map.js loaded");