/*
 * $Archive:  $
 * $Date:  $
 * $Revision:  $
 * $Author:  $
 * $History:  $
 * $NoKeywords:  $
 * 
 * Copyright Notice "Copyright (c) 2002 GeoWise Limited"
 */
/** all.js
	This file contains common mapping functions for web pages, using RELATIVELY positioned
	map images.
	Some functions called by the functions here are implemented in browser specific .js files:
	ie5.js, ie4.js (incomplete), nn4.js and nn6.js.
*/
/** Global variables related to mapping functionality */
/** Current status of mouse action */
var zooming = false;
/** Current status of mouse action */
var panning = false;
/** Current mouse position (w.r.t. map image, not page) */
var mouseX = 0;
/** Current mouse position (w.r.t. map image, not page) */
var mouseY = 0;
/** Mouse position at start of drag (w.r.t. map image, not page) */
var x1 = 0;
/** Mouse position at start of drag (w.r.t. map image, not page) */
var y1 = 0;
/** Mouse position at end of drag (w.r.t. map image, not page) */
var x2 = 0;
/** Mouse position at end of drag (w.r.t. map image, not page) */
var y2 = 0;
/** Map Minimum X coordinate - should be updated by JSP or ASP code */
var minx = 0;
/** Map Minimum Y coordinate - should be updated by JSP or ASP code */
var miny = 0;
/** Map Maximum X coordinate - should be updated by JSP or ASP code */
var maxx = 0;
/** Map Maximum Y coordinate - should be updated by JSP or ASP code */
var maxy = 0;
/** Real World (i.e. true coordinate) position at start of drag */
var rx1 = 0;
/** Real World (i.e. true coordinate) position at start of drag */
var ry1 = 0;
/** Real World (i.e. true coordinate) position at end of drag */
var rx2 = 0;
/** Real World (i.e. true coordinate) position at end of drag */
var ry2 = 0;
/** These I'm not sure - maye cut them out - may be related to absolute postioning */
var zleft=0;
var zright=0;
var ztop=0;
var zbottom=0;
var xLayerOffset = 0;
/** Horizontal offset of the map into the page - generated dynamically
	@see #setLayer(obj)
	*/
var hspc = -1;
/** Vertical offset of the map into the page - generated dynamically
	@see #setLayer(obj)
	*/
var vspc = -1;
/** Map Tool Status - must be one of "PAN", "ZOOM_IN", "ZOOM_OUT", "SELECT" or "IDENTIFY" */
var toolStatus = "ZOOM_IN";
/** Zoom Box Colour as Hex */
var zoomBoxColor = "#7C0049";
/** Zoom Box Line Width */
var ovBoxSize = 3;
/** Map Image Width (in pixels) - should be updated by JSP or ASP code */
var iWidth = 400;
/** Map Image Height (in pixels) - should be updated by JSP or ASP code */
var iHeight = 300;
/** Zoom factor for single click zooms */
var zoomFactor = 2.0;
/** Behaviour on pan/identify */
var onPanTinyBehaviour = 'recenter';

	/** Draw the zoom box at a given set of page coordinates (in pixels).
		This calls browser specific scripts (in other .js files) to do the actual
		drawing work.
		@param theLeft The left hand side coordinate.
		@param theTop The top side coordinate.
		@param theRight The right hand side coordinate.
		@param theBottom The bottom side coordinate.
		@see #clipLayer(name)
		@see #showLayer(name)
		*/
	function boxIt(theLeft, theTop, theRight, theBottom) {
		theLeft += hspc;
		theRight += hspc;
		theTop += vspc;
		theBottom += vspc;
		clipLayer("zoomBoxTop", theLeft, theTop, theRight, theTop + ovBoxSize);
		clipLayer("zoomBoxLeft", theLeft, theTop, theLeft+ovBoxSize, theBottom);
		clipLayer("zoomBoxRight", theRight - ovBoxSize, theTop, theRight, theBottom);
		clipLayer("zoomBoxBottom", theLeft, theBottom - ovBoxSize, theRight, theBottom);	
		showLayer("zoomBoxTop");
		showLayer("zoomBoxLeft");
		showLayer("zoomBoxRight");
		showLayer("zoomBoxBottom");
	}
	
	/** Start drawing a zoom box (or a select box) and update the real world 
		zoom or selection coordinates (rx1...ry2).
		@param e Mouse event that triggered this.
		*/
	function startZoomBox(e) {
		getImageXY(e);	
		// keep it within the MapImage
		if ((mouseX >= 0) && (mouseY >= 0) && (mouseX<iWidth) && (mouseY<iHeight)) {
			if (zooming) {
				stopZoomBox(e);
			} 
			else {
				x1=mouseX;
				y1=mouseY
				x2=x1+1;
				y2=y1+1;
				zleft=x1;
				ztop=y1;
				zbottom=y1;
				zright=x1
				boxIt(x1,y1,x2,y2);
				zooming=true;
			}
		}
		return false;
	}

	/** Close down the display of the zoom or select box.
		@param e The mouse "up" event.
		*/
	function stopZoomBox(e) {
		zooming = false;
		hideLayer("zoomBoxTop");
		hideLayer("zoomBoxLeft");
		hideLayer("zoomBoxRight");
		hideLayer("zoomBoxBottom");
		window.scrollTo(0,0);
		return true;
	}

	/** Get the coords at mouse position and update the screen.
		Updates all global variables related to the zoom or select box.
		@param e The mouse "move" event.
		*/
	function getMouse(e) {
		if ((hspc < 0) || (vspc < 0)) {
			var obj = new getObj('theMap');
			setMapLayer(obj);
			return true;
		}
		window.status = currentStatusText;
		// Do a lookup for the position of the map image
		getImageXY(e);
		if (!zooming && !panning && ((mouseX > iWidth) || (mouseY > iHeight) || (mouseX < 0) || (mouseY < 0))) return true;
		// Panning - reload as soon as they hit the side of the page
		else if (panning && ((mouseX > iWidth) || (mouseY > iHeight) || (mouseX <= 0) ||(mouseY <= 0))) {
			chkMouseUp(e);
			return true;
		} 
		else {
			if (zooming) {
				// Constrain zoom box to the size of the image
				if (mouseX > iWidth) mouseX = iWidth;
				if (mouseY > iHeight) mouseY = iHeight;
				if (mouseX <= 0) mouseX = 0;
				if (mouseY <= 0) mouseY = 0;
				x2 = mouseX;
				y2 = mouseY;
				setClip();
			}
			else if (panning) {
				x2 = mouseX + xLayerOffset;
				y2 = mouseY;
				panMouse();	
				return false;
			}
			rx1 = Math.round(((maxx - minx) * (x1 / iWidth)) + minx);
			ry1 = Math.round(((maxy - miny) * ((iHeight - y1) / iHeight)) + miny);
			rx2 = Math.round(((maxx - minx) * (x2 / iWidth)) + minx);
			ry2 = Math.round(((maxy - miny) * ((iHeight - y2) / iHeight)) + miny);
			if (rx1 > rx2) {
				tmp = rx1;
				rx1 = rx2;
				rx2 = tmp;
			}
			if (ry1 > ry2) {
				tmp = ry1;
				ry1 = ry2;
				ry2 = tmp;
			}
			var mouseString = "";
			if (zooming) mouseString += "Zoom Box: [" + rx1 + "m," + ry1 + "m to " + rx2 + "m," + ry2 + "m]    ";
			var userX = Math.round(((maxx - minx) * (mouseX / iWidth)) + minx);
			var userY = Math.round(((maxy - miny) * ((iHeight - mouseY) / iHeight)) + miny);
			var ngRef = convertXYtoRef(userX, userY);
			mouseString += "National Grid: " + ngRef + " (" + userX + "m East, " + userY + "m North)";	
			window.status = mouseString;
			return false;
		}
		// next line needed for Mac
		return true;
	}

	/** Clip zoom box layer to mouse coords.
		Requires update of screen coordinates by another method, typically getMouse(e).
		*/
	function setClip() {	
		var tempX = x1;
		var tempY = y1;
		if (x1 > x2) {
			zright = x1;
			zleft = x2;
		} 
		else {
			zleft = x1;
			zright = x2;
		}
		if (y1 > y2) {
			zbottom = y1;
			ztop = y2;
		} 
		else {
			ztop = y1;
			zbottom = y2;
		}
		if ((x1 != x2) && (y1 != y2)) {
			boxIt(zleft, ztop, zright, zbottom);
		}
	}

	
	/** Check for mouseup if this has occurred call other methods both to update 
		browser screen and (optionally) trigger update of the map.
		This requires the designer to provide a JavaScript method called 
		triggerUpdate(), either in the page or in a custom .js file.
		This method should do all the work of gathering together the map coords 
		and layer requests and then passing these to the server or page.
		@param e Mouse "up" event.
		*/
	function chkMouseUp(e) {
		// Allow only left clicks
		var rightclick = false;
		if (!e) var e = window.event;
		if (e.which) rightclick = (e.which == 3);
		else if (e.button) rightclick = (e.button == 2);
		// Right click? Return...
		if (rightclick) return true;
		if (zooming) {
			stopZoomBox(e);
			if (toolStatus == 'ZOOM_IN') {
				var nWidth = Math.abs(x2 - x1);
				var zoomer = ZOOM_MULTIPLIER * ZOOM_MULTIPLIER; //zoomFactor * zoomFactor;
				if (nWidth < 5) {
					x1 = mouseX - (iWidth / zoomer);
					x2 = mouseX + (iWidth / zoomer);
				}
				var nHeight = Math.abs(y2 - y1);
				if (nHeight < 5) {
					y1 = mouseY - (iHeight / zoomer);
					y2 = mouseY + (iHeight / zoomer);
				}
				rx1 = ((maxx - minx) * (x1 / iWidth)) + minx;
				ry1 = ((maxy - miny) * ((iHeight - y1) / iHeight)) + miny;
				rx2 = ((maxx - minx) * (x2 / iWidth)) + minx;
				ry2 = ((maxy - miny) * ((iHeight - y2) / iHeight)) + miny;
				if (rx1 > rx2) {
					tmp = rx1;
					rx1 = rx2;
					rx2 = tmp;
				}
				if (ry1 > ry2) {
					tmp = ry1;
					ry1 = ry2;
					ry2 = tmp;
				}
			}
			else if (toolStatus == 'ZOOM_OUT') {
				var xCentre = ((maxx - minx) / 2.0) + minx;
				var yCentre = ((maxy - miny) / 2.0) + miny;
				var nWidth = Math.abs(x2 - x1);
				if (nWidth < 5) {
					nWidth = iWidth / ZOOM_MULTIPLIER;
					xCentre = ((maxx - minx) * (x1 / iWidth)) + minx;
				}
				var nHeight = Math.abs(y2 - y1);
				if (nHeight < 5) {
					nHeight = iHeight / ZOOM_MULTIPLIER;
					yCentre = ((maxy - miny) * ((iHeight - y1) / iHeight)) + miny;
				}
				var xnRes = (maxx - minx) / nWidth;
				var ynRes = (maxy - miny) / nHeight;
				rx1 = xCentre - (xnRes * (iWidth / 2));
				ry1 = yCentre - (ynRes * (iHeight / 2));
				rx2 = xCentre + (xnRes * (iWidth / 2));
				ry2 = yCentre + (ynRes * (iHeight / 2));
			}
			else if (toolStatus == 'SELECT') {
				var nWidth = Math.abs(x2 - x1);
				if (nWidth < 5) {
					x1 = x1 - 5;
					x2 = x1 + 5;
				}
				var nHeight = Math.abs(y2 - y1);
				if (nHeight < 5) {
					y1 = y1 - 5;
					y2 = y1 + 5;
				}
				rx1 = minx;
				ry1 = miny;
				rx2 = maxx;
				ry2 = maxy;
			}
			triggerUpdate();
			return false;
		}
		else if ((toolStatus == 'PAN') && (panning)) {
			stopPan(e);
			return false;
		}
		// Edited KWM 11/7/02
		else if ((toolStatus == 'IDENTIFY') || (toolStatus == 'ACETATE')) {
			if ((!zooming) && (!panning) && (mouseX >= 0) && (mouseX <= iWidth) && 
				(mouseY >= 0) && (mouseY <= iHeight)) {
				x1 = mouseX;
				y1 = mouseY;
				triggerUpdate();
				return false;
			}
			else return true;
		}
		return true;
	}

	/** Trigger a specific response to a mouse action, based on the current status 
		of the mapping tools - one of ZOOM_IN, ZOOM_OUT, PAN, SELECT or IDENTIFY.
		@param e Mouse evenet.
		*/
	function mapTool(e) {
		// Allow only left clicks
		var rightclick = false;
		if (!e) var e = window.event;
		if (e.which) rightclick = (e.which == 3);
		else if (e.button) rightclick = (e.button == 2);
		// Right click? Return...
		if (rightclick) return true;
		if ((!zooming) && (!panning) && (mouseX >= 0) && (mouseX <= iWidth) && 
				(mouseY >= 0) && (mouseY <= iHeight)) {
			if (toolStatus == "PAN") startPan(e);
			else if ((toolStatus == 'IDENTIFY') || (toolStatus == 'ACETATE')) getImageXY(e);
			else startZoomBox(e);
			// Trap for NN7+
			if (e.stopPropagation) {
				e.stopPropagation();
			}
			if (e.preventDefault) {
				e.preventDefault();
			}
			return false;
		}
		return true;
	}
	
	var mouseWheelDelta = 0;
	
	/** Trigger a map zoom in/out if the user moves the mouse wheel.
		*/
	function mapWheel(evt){
		var delta = 0;
		if (!evt) {
			evt = window.event;
		}
		getImageXY(evt);	
		// keep it within the MapImage
		if ((mouseX >= 0) && (mouseY >= 0) && (mouseX<iWidth) && (mouseY<iHeight)) {
			if (evt.wheelDelta) {
				delta = evt.wheelDelta/120; 
				if (window.opera) {
					delta = -delta;
				}
			} 
			else if (evt.detail) {
				delta = -evt.detail/3;
			}
			if (delta) {
				window.clearTimeout();
				mouseWheelDelta += delta;
				drawMapWheelBox();
				window.setTimeout('doMapWheelZoom()', 200);
			}
			if (evt.preventDefault) {
				evt.preventDefault();
			}
			evt.returnValue = false;
		}
	}
	
	function drawMapWheelBox() {
		var zoomer = ZOOM_MULTIPLIER;
		if (mouseWheelDelta > 0) {
			for (var i = 0; i < mouseWheelDelta; i++) {
				zoomer = zoomer * ZOOM_MULTIPLIER;
			}
		}
		else if (mouseWheelDelta < 0) {
			for (var i = 0; i > mouseWheelDelta; i--) {
				zoomer = zoomer / ZOOM_MULTIPLIER;
			}
		}
		var mwx1 = mouseX - (iWidth / zoomer);
		var mwx2 = mouseX + (iWidth / zoomer);
		var mwy1 = mouseY - (iHeight / zoomer);
		var mwy2 = mouseY + (iHeight / zoomer);
		if (mouseWheelDelta > 0) {
			boxIt(Math.max(0, mwx1), Math.max(0, mwy1), Math.min(iWidth, mwx2), Math.min(iHeight, mwy2));
		}
	}
	
	function doMapWheelZoom() {
		if (mouseWheelDelta == 0) {
			return;
		}
		var zoomer = ZOOM_MULTIPLIER;
		if (mouseWheelDelta > 0) {
			for (var i = 0; i < mouseWheelDelta; i++) {
				zoomer = zoomer * ZOOM_MULTIPLIER;
			}
		}
		else if (mouseWheelDelta < 0) {
			for (var i = 0; i > mouseWheelDelta; i--) {
				zoomer = zoomer / ZOOM_MULTIPLIER;
			}
		}
		x1 = mouseX - (iWidth / zoomer);
		x2 = mouseX + (iWidth / zoomer);
		y1 = mouseY - (iHeight / zoomer);
		y2 = mouseY + (iHeight / zoomer);
		if (mouseWheelDelta > 0) {
			boxIt(Math.max(0, x1), Math.max(0, y1), Math.min(iWidth, x2), Math.min(iHeight, y2));
		}
		rx1 = ((maxx - minx) * (x1 / iWidth)) + minx;
		ry1 = ((maxy - miny) * ((iHeight - y1) / iHeight)) + miny;
		rx2 = ((maxx - minx) * (x2 / iWidth)) + minx;
		ry2 = ((maxy - miny) * ((iHeight - y2) / iHeight)) + miny;
		if (rx1 > rx2) {
			tmp = rx1;
			rx1 = rx2;
			rx2 = tmp;
		}
		if (ry1 > ry2) {
			tmp = ry1;
			ry1 = ry2;
			ry2 = tmp;
		}
		mouseWheelDelta = 0;
		triggerUpdate();
	}

	/** Move map image with the mouse (may not work correctly in NN4-)
		*/
	function panMouse() {
		var xMove = x2 - x1;
		var yMove = y2 - y1;
		var cLeft = -xMove ;
		var cTop = -yMove;
		var cRight = iWidth;
		var cBottom = iHeight;
		if (xMove > 0) {
			cLeft = 0; // initial left pos of grag
			cRight = iWidth - xMove;
		}
		if (yMove > 0) {
			cTop = 0;
			cBottom = iHeight - yMove;
		}
		//cliplayer will ensure that the image layer is unable to appear to be moving out of the extent of the map space 
		clipLayer2("theMap", cLeft + xLayerOffset, cTop, cRight + xLayerOffset, cBottom);
		showLayer("theMap");
		moveLayer("theMap", xMove + hspc, yMove + vspc);
		return false;
	}
	
	/** Start the pan - image will move.
		Called by MapTool (pan on mouse down event).
		@param e Mouse event.
		*/
	function startPan(e) {
		getImageXY(e);
		// keep it within the MapImage
		if ((mouseX < iWidth) && (mouseY < iHeight)) {
			if (panning) {
				stopPan(e);
			} 
			else {
				x1 = mouseX; 
				y1 = mouseY;
				x2 = x1 + 1;
				y2 = y1 + 1;
				panning = true;
			}
			return false;
		}
		return true;
	}
		
	/** Stop moving image - pan.
		@param e Mouse "up" event.
		*/
	function stopPan(e) {
		if ((Math.abs(x2 - x1) < 3) && (Math.abs(y2 - y1) < 3)) {
			// the move is too small
			if (onPanTinyBehaviour == 'identify') {
				if ((mouseX >= 0) && (mouseX <= iWidth) && 
					(mouseY >= 0) && (mouseY <= iHeight)) {
					x1 = mouseX;
					y1 = mouseY;
					toolStatus = 'IDENTIFY';
					triggerUpdate();
				}
			}
			else {
				recenter(e);
			}
			panning = false;
		} 
		else  {
			window.scrollTo(0,0);
			panning = false;
			var width = Math.abs(maxx - minx);
			var height = Math.abs(maxy - miny);
			var tempLeft = minx;
			var tempRight = maxx;
			var tempTop = maxy;
			var tempBottom = miny;
			var ixOffset = (x2 - x1) - xLayerOffset;        //added by JC for new position // this prevents the layer from being offset by 100 from center of pan
			var iyOffset = y1 - y2;
			pixelX = width / iWidth;
			//var theY = iHeight - zmaxy;
			pixelY = height / iHeight;
			var xOffset = pixelX * ixOffset;
			var yOffset = pixelY * iyOffset;
			rx1 = minx - xOffset;
			ry1 = miny - yOffset;
	     	rx2 = maxx - xOffset;
			ry2 = maxy - yOffset;
			triggerUpdate();
		}
		return true;
	}
	
	/** Recenter map is the default option
		recenter occurs also when the zoombox is too small
		and when the select box is too small
		This enables the resetting of the XY accordingly
		for zoom set XY to recenter
		for select set XY to a point
		*/
	function recenter(e) {
		var xnRes = (maxx - minx) / nWidth;
		var ynRes = (maxy - miny) / nHeight;
		var xCentre = (mouseX * xnRes) + minx
		var yCentre = ((iHeight - mouseY) * ynRes) + miny
		rx1 = xCentre - (xnRes * (iWidth / 2));
		ry1 = yCentre - (ynRes * (iHeight / 2));
		rx2 = xCentre + (xnRes * (iWidth / 2));
		ry2 = yCentre + (ynRes * (iHeight / 2));
		triggerUpdate();
	}
	
	/** Move the map in a given direction by a given amount 
		@param direction Direction of movement - one of  NORTH, EAST, SOUTH, WEST,
							NORTHEAST, SOUTHEAST, SOUTHWEST, NORTHWEST.
		@param factor Amount of movement as a fraction i.e. 0.5 means move the map by 50%.
		*/
	function moveMap(direction, factor) {
		var rw = maxx - minx;
		var rh = maxy - miny;
		rx1 = minx;
		rx2 = maxx;
		ry1 = miny;
		ry2 = maxy;
		toolStatus = 'PAN';
		if (direction == 'EAST') {
			var offx = rw * factor;
			rx1 = minx + offx;
			rx2 = maxx + offx;
		}
		else if (direction == 'WEST') {
			offx = rw * factor;
			rx1 = minx - offx;
			rx2 = maxx - offx;
		}
		else if (direction == 'NORTH') {
			offy = rh * factor;
			ry1 = miny + offy;
			ry2 = maxy + offy;
		}
		else if (direction == 'SOUTH') {
			offy = rh * factor;
			ry1 = miny - offy;
			ry2 = maxy - offy;
		}
		else if (direction == 'NORTHEAST') {
			offx = rw * factor;
			offy = rh * factor;
			rx1 = minx + offx;
			ry1 = miny + offy;
			rx2 = maxx + offx;
			ry2 = maxy + offy;
		}
		else if (direction == 'NORTHWEST') {
			offx = rw * factor;
			offy = rh * factor;
			rx1 = minx - offx;
			ry1 = miny + offy;
			rx2 = maxx - offx;
			ry2 = maxy + offy;
		}
		else if (direction == 'SOUTHEAST') {
			offx = rw * factor;
			offy = rh * factor;
			rx1 = minx + offx;
			ry1 = miny - offy;
			rx2 = maxx + offx;
			ry2 = maxy - offy;
		}
		else if (direction == 'SOUTHWEST') {
			offx = rw * factor;
			offy = rh * factor;
			rx1 = minx - offx;
			ry1 = miny - offy;
			rx2 = maxx - offx;
			ry2 = maxy - offy;
		}
		triggerUpdate();
	}
	
	/** Finds the X position of a specific object within the HTML page.
		@param obj The object to look for.
		@see #setMapLayer(layer)
		*/
	function findPosX(obj) {
		var curleft = 0;
		if (document.getElementById || document.all) {
			while (obj.offsetParent) {
				curleft += obj.offsetLeft
				obj = obj.offsetParent;
			}
		}
		else if (document.layers) {
			curleft += obj.x;
		}
		return curleft;
	}
	
	/** Finds the Y position of a specific object within the HTML page.
		@param obj The object to look for.
		@see #setMapLayer(layer)
		*/
	function findPosY(obj) {
		var curtop = 0;
		if (document.getElementById || document.all) {
			while (obj.offsetParent) {
				curtop += obj.offsetTop
				obj = obj.offsetParent;
			}
		}
		else if (document.layers)
			curtop += obj.y;
		return curtop;
	}
	
	/** Finds a specific named object within the HTML page.
		For IE and NN6+ this should be a <div> tag that contains the map image.
		For NN4 it should be an anchor (<a name="theMap">) that contains the map image.
		@param name The name or id of the object.
		*/
	function getObj(name) {
		 if (document.getElementById) {
				this.obj = document.getElementById(name);
				this.style = document.getElementById(name).style;
		 }
		 else if (document.all) {
				this.obj = document.all[name];
				this.style = document.all[name].style;
		 }
		 else if (document.layers) {
				if (document.layers[name]) {
					this.obj = document.layers[name];
					this.style = document.layers[name];
				}
				else if (document.anchors[name]) {
					this.obj = document.anchors[name];
					this.style = document.anchors[name];
				 }
		 }
		 return this.obj;
	}
	
	/** Sets the internal hspc and vspc global variables, by finding the location
		of a specific layer (IE and NN6+) or anchor (NN4) within the HTML page.
		It then moves the (floating) glass pane over that layer.
		@param layer An object representing the layer or anchor.
		*/
	function setMapLayer(layer) {
		if ((hspc >= 0) && (vspc >= 0)) return;
		hspc = findPosX(layer);
		vspc = findPosY(layer);
		//moveLayer("theTop", hspc, vspc);
		//showLayer("theTop");
	}
	
	/** Initialises the mapping tools.
		This function MUST be called by any page that wants to use the map functions - 
		e.g. as <body><script language="JavaScript1.2" type="text/javascript">initialiseMap();</script>, 
		as this writes some extra content into the page - do NOT do 
		<body onload="initialiseMap();"> - it won't work!
		Calls browser specific functions to do the actual work (in other .js files)
		@see #createLayer(name, x, y, width, height, visible, content)
		*/
	function initialiseMap() {
		/** "glass" top layer  - this will be moved when we know where the map is */
		var content = '<img name="pixel" src="./images/pixel.gif" width=1 height=1>';
		//createLayer("theTop", hspc - 1, vspc - 1, (iWidth + 1), (iHeight + 1), false, content);
		// zoom/selection box
		content = '<img name="zoomImageTop" src="./images/pixel.gif" width=1 height=1>';
		createLayer("zoomBoxTop", hspc, vspc, iWidth, iHeight, false, content);
		content = '<img name="zoomImageLeft" src="./images/pixel.gif" width=1 height=1>';
		createLayer("zoomBoxLeft", hspc, vspc, iWidth, iHeight, false, content);
		content = '<img name="zoomImageRight" src="./images/pixel.gif" width=1 height=1>';
		createLayer("zoomBoxRight", hspc, vspc, iWidth, iHeight, false, content);
		content = '<img name="zoomImageBottom" src="./images/pixel.gif" width=1 height=1>';
		createLayer("zoomBoxBottom", hspc, vspc, iWidth, iHeight, false, content);
		// set zoom box color
		setLayerBackgroundColor("zoomBoxTop", zoomBoxColor);
		setLayerBackgroundColor("zoomBoxLeft", zoomBoxColor);
		setLayerBackgroundColor("zoomBoxRight", zoomBoxColor);
		setLayerBackgroundColor("zoomBoxBottom", zoomBoxColor);
		var obj = new getObj('theMap');
		setMapLayer(obj);
	}
	
	
	/** Shortcut! */
	function initMap() {
		initialiseMap();
	}
	
	/** Resets the horizontal and vertical spacing values so that getMouse will update them.
		Useful for responding to window.resize events (which are handled by default - see
		browser specific Javascript files)
		*/
	function refreshSpacing(e) {
		hspc = -1;
		vspc = -1;
		return true;
	}
	
	/* Called in getMouse(e) function and siteCheckMouseClick
	* GeoWise (494) edited version - should work for anywhere in UK
	*/
	function convertXYtoRef(xIn, yIn) {
		// Origin is off to the left so
		var outerTileSize = 500000;
		xIn += outerTileSize;
		var outerTileRefs = 'ghjmnorst';
		var outerCrossTiles = 3;
		var innerTileSize = 100000;
		var innerTileRefs = 'abcdefghjklmnopqrstuvwxyz';
		var innerCrossTiles = 5;
		var outer = '';
		var inner = '';
		// Coordinate system is reversed so
		yIn = (outerTileSize * outerCrossTiles) - yIn;
		// Outer tile
		var hpos = Math.floor(xIn / outerTileSize);
		var vpos = Math.floor(yIn / outerTileSize);
		hpos += (vpos * outerCrossTiles);
		outer = outerTileRefs.substring(hpos, hpos + 1).toUpperCase();
		hpos = Math.floor(xIn / outerTileSize);
		// Inner tile
		var x = xIn - (hpos * outerTileSize);
		var y = yIn - (vpos * outerTileSize);
		hpos = Math.floor(x / innerTileSize);
		vpos = Math.floor(y / innerTileSize);
		x = x - (innerTileSize * hpos);
		hpos += (vpos * innerCrossTiles);
		inner = innerTileRefs.substring(hpos, hpos + 1).toUpperCase();
		// Now show the position within the square
		y = outerTileSize - y;
		y = y - (innerTileSize * Math.floor(y / innerTileSize));
		x = Math.floor(x / 100);
		y = Math.floor(y / 100);
		var fullref = outer + inner + " " + x + " " + y;
		if (fullref == "  ") fullref="";
		return fullref;
	}
	
	function doInsetClick(e) {
		// Inset map zoom / pan
		//getImageXY(e);
		// Ignore the real map offset
		var mX = mouseX + hspc;
		var mY = mouseY + vspc;
		// Position on map in pixels.
		var pixelX = (mX - mapInsetX) * 1.0;
		var pixelY = (mY - mapInsetY) * 1.0;
		// Position on map in real world coordinates.
		var realX = realInsetX1 + ((pixelX / mapInsetWidth) * realInsetWidth);
		var realY = realInsetY2 - ((pixelY / mapInsetHeight) * realInsetHeight);
		// Get the amount to translate by.
		var xTrans = (maxx - minx) / 2;
		var yTrans = (maxy - miny) / 2;
		// Reset the bbox coords.
   		rx1 = realX - xTrans; 
		rx2 = realX + xTrans;
		ry1 = realY - yTrans; 
		ry2 = realY + yTrans;
		// Update the map.
		toolStatus = 'ZOOM_IN';
		triggerUpdate();
		return false;
	}
