// $Header$
////////////////////////////////////////////////////////////////////////////////

// Used to determine whether initalisation has completed
// Mouse over events in mapping_body.jsp should test for this eg.
// onmouseover="if(loaded)imagemapMouseOver()"
// This will prevent functionality be actived by user before map has initialised
var loaded=false;

// Flag for determining if we have the divPopup open (on a Map; poi divs et al)
// If this is false we can assume our div doesn't need to be visible
var keepDivVisible = false;

////////////////////////////////////////////////////////////////////////////////
// The following variables are initalise by mappong_hdr.jsp
////////////////////////////////////////////////////////////////////////////////

// Define the area of the map in metres east and north
var eLeft, eRight, eTop, eBottom

// Height and width of map in pixcels
var iHeight, iWidth;

// Height and width of overview map in pixcels
var i2Width, i2Height;

// Mode of interaction with map
// 1=in; 2=out; 3=inDragBox; 4=dragMap;
var toolMode;

// Top left corner of the map relative to the "div" containing the background image
var hspc, vspc;

// The URL to be executed to obtain next map
var formAction;

// Array containing the x and y cordinates (pixcels) of "popup" text to be displayed on map
var popuptextx, popuptexty;

// The prefix used to name "popup" divs
var popuptextdiv;

// Width and height of map browser in pixcels
var browserWidth, browserHeight;

////////////////////////////////////////////////////////////////////////////////
// These rectangles are defined in metres North and East)
////////////////////////////////////////////////////////////////////////////////

// Restrict display of map to the following rectangle (metres North and East)
var limitLeft = -700000.0;
var limitRight = 700000.0;
var limitTop = 1250000.0;
var limitBottom = -24937.744799999986;

// The rectangle (metres North and East) of overview map
var fullOVLeft = -230000.0;
var fullOVRight =  730000.0;
var fullOVTop =  1250000.0;
var fullOVBottom =  -30000.06;
var fullOVWidth = Math.abs(fullOVRight - fullOVLeft);
var fullOVHeight = Math.abs(fullOVTop - fullOVBottom);

var ns4 = (document.layers);
var ie4 = (document.all && !document.getElementById);
var ie5 = (document.all && document.getElementById);
var ns6 = (!document.all && document.getElementById);

////////////////////////////////////////////////////////////////////////////////
// Dimensions & saleses
////////////////////////////////////////////////////////////////////////////////

// How far to pan when using pan buttons
// 0.5 represents half of the map
var panFactor = 0.5;

// Horizontal distance of map in metres
var xDistance = Math.abs(eRight-eLeft);

// Vertical distance of map in metres
var yDistance = Math.abs(eTop-eBottom);

// Half width of map in metres
var xHalf = xDistance / 2;

// Half height of map in metres
var yHalf = yDistance / 2;

// Distance to pan left, right using pan buttons in meters
var panX = xDistance * panFactor;

// Distance to pan up or down using pan buttons in meters
var panY = yDistance * panFactor;

// Number of metrrs per horizontal pixcel
var pixelX = xDistance/iWidth;

// Number of metres per vertical pixcel
var pixelY = yDistance/iHeight;

// Width of lines that make up the zoom box
var zoomBoxSize = 2;

// Width of lines that make up box on overview
var ovBoxSize = 1;

////////////////////////////////////////////////////////////////////////
// The follwoing variables control user interaction with map
/////////////////////////////////////////////////////////////////////////

// Position of map click in pixcels from left of map
var mouseX=0;

// Position of map click in pixcels from top of map
var mouseY=0;

// Position of map click in meters East
var mapX = eLeft;

// Positin of map click in metres North
var mapY = eTop;

// Is the user dragging a zoom box
var zooming = false;

// Is the user draging the map
var panning = false;

// Control the dragging of the zoom box
var x1= 0, y1=0;
var x2=0 , y2=0;
var zleft=0, zright=0, ztop=0, zbottom=0;

// Set to true when request for map is sent
// Prevents multiple zoom ins experience with Mozilla
var sent=false;

////////////////////////////////////////////////////////////////////////////////
// The following variable are used to control the layout of map objects
////////////////////////////////////////////////////////////////////////////////

// Location of zoom to scale drop down div relative to background image (pixcels)
var goHspc=226;
var goVspc=7;

// Height and width (pixcels) of zoom to scale drop down div relative to background image
var goWidth =200;
var goHeight=50;

// Location of over viewmap relative to background image (pixcels)
var ovHspc = 508;
var ovVspc = 48;

// Location of zoom controls relative to background image (pixcels)
var zoomHspc=1;
var zoomVspc=48;

// Size of the pan images (pixcels)
var panNSWidth  =213;
var panNSHeight =14;
var panEWWidth  =14;
var panEWHeight =205;

// Location of map tools relative to background image (image)
var toolHspc = ovHspc -4;
var toolVspc = ovVspc + i2Height +6;

// Hight and width of map tools (pixcels)
var toolWidth= i2Width;
var toolHeight=300;

///////////////////////////////////////////////////////////////////////////////
// Variables to manage array of Popup text
//////////////////////////////////////////////////////////////////////////////

// The div currently being poped up
var divPopup;

// The id of the div currently being poped up
var divPopupId;

// Off set to ensure mouse is inside div when poped up
var divPopupDelta=-10;

////////////////////////////////////////////////////////////////////////////////
// The following functions are used to write a style sheet
// into the header of the page (see mapping_hdr.jsp)
// These styles allow us to dynamically position objects
////////////////////////////////////////////////////////////////////////////////
function CreateCss()
{
  var vis = null;

  writeCSS(

    // This div contains all the other divs. All other divs are position relative to this one
    css('maplayer', null , null, null, null, null) +

    // The div containing the zoom to scale drop down
    css('mapGo',goHspc,goVspc,goWidth,goHeight,null,vis)+


    // The div cotaining the zoom to scale bars
    css('mapZoom',zoomHspc,zoomVspc,browserWidth,browserHeight,null,vis)+

    // The div containing to tools for zooming in/out and dragging on map
    css('theControls',toolHspc,toolVspc,toolWidth,toolHeight, null, vis)+

    // The div containing tha map image
    css('theMap',hspc,vspc,iWidth,iHeight, null, vis)+

    // The divs used to draw the zoom in box
    css('zoomBoxTop', hspc,vspc,iWidth,iHeight, 'red', 'hidden' , null, 'clip:rect(0px,0px,0px,0px)')+
    css('zoomBoxBottom',hspc,vspc,iWidth,iHeight, 'red', 'hidden', null, 'clip:rect(0px,0px,0px,0px)')+
    css('zoomBoxLeft',hspc,vspc,iWidth,iHeight, 'red', 'hidden', null, 'clip:rect(0px,0px,0px,0px)')+
    css('zoomBoxRight',hspc,vspc,iWidth,iHeight, 'red', 'hidden', null, 'clip:rect(0px,0px,0px,0px)')+

    // Divs used to give popup text a border
    css('mapTextNorth', ovHspc,ovVspc,300,200, null, 'hidden', null, 'clip:rect(0px,0px,0px,0px)')+
    css('mapTextSouth', ovHspc,ovVspc,300,200, null, 'hidden', null, 'clip:rect(0px,0px,0px,0px)')+
    css('mapTextEast', ovHspc,ovVspc,300,200, null, 'hidden', null, 'clip:rect(0px,0px,0px,0px)')+
    css('mapTextWest', ovHspc,ovVspc,300,200, null, 'hidden', null, 'clip:rect(0px,0px,0px,0px)')+

    // Divs containg the pan buttons
    css('thePanNorth',hspc + (iWidth-panNSWidth)/2,vspc - panNSHeight,              panNSWidth, panNSHeight, null, vis)+        // use (hspc - 145) to amend position to left: 171.5px; use vspc - 14 to give top: 34px
    css('thePanSouth',hspc + (iWidth-panNSWidth)/2,vspc + iHeight,                  panNSWidth, panNSHeight, null, vis)+
    css('thePanEast', hspc + iWidth,               vspc + (iHeight - panEWHeight)/2,panEWWidth, panEWHeight, null, vis)+
    css('thePanWest', hspc - panEWWidth,           vspc + (iHeight - panEWHeight)/2,panEWWidth, panEWHeight, null, vis)+

    // Div containing the overview image
    css('ovLayer', ovHspc, ovVspc, i2Width-2,i2Height-2 ,null, vis) +

    // The divs used to draw the box on the overview image
    css('zoomOVBoxTop', ovHspc,ovVspc,i2Width,i2Height, 'red', 'hidden', null)+
    css('zoomOVBoxLeft', ovHspc,ovVspc,i2Width,i2Height, 'red', 'hidden', null)+
    css('zoomOVBoxRight', ovHspc,ovVspc,i2Width,i2Height, 'red', 'hidden', null)+
    css('zoomOVBoxBottom', ovHspc,ovVspc,i2Width,i2Height, 'red', 'hidden', null)

    )
}

// Create a single line of the style sheet for a div
function css(id,left,top,width,height,color,vis,z,other) {
    if (id=="START") return '<STYLE TYPE="text/css">\n'
    else if (id=="END") return '</STYLE>'
    var str = (left!=null && top!=null)? '#'+id+' {position:absolute; left:'+left+'px; top:'+top+'px;' : '#'+id+' {position:relative;'
    if (arguments.length>=4 && width!=null) str += ' width:'+width+'px;'
    if (arguments.length>=5 && height!=null) {
        str += ' height:'+height+'px;'
        if (arguments.length<9 || other.indexOf('clip')==-1) str += ' clip:rect(0px '+width+'px '+height+'px 0px);'
    }
    if (arguments.length>=6 && color!=null) str += (document.layers)? ' layer-background-color:'+color+';' : ' background-color:'+color+';'
    if (arguments.length>=7 && vis!=null) str += ' visibility:'+vis+';'
    if (arguments.length>=8 && z!=null) str += ' z-index:'+z+';'
    if (arguments.length==9 && other!=null) str += ' '+other

    str += '}\n'
    return str
}

// Write the complete stylesheet in to the header of the page
function writeCSS(str,showAlert) {
    str = css('START')+str;
        str+=css('END');

    document.write(str)
}

///////////////////////////////////////////////////////////////////////////
// Called from <body onload=""     >
// To load map
////////////////////////////////////////////////////////////////////////////
function loadMap()
{
  // Initialse broswer independent functionality
  // to manage divs and mouse clicks (see dynamicobjects.js)
  initialiseMouse();
  initialiseDivs();

  // Specify functions to handle mouse events
  mouse.ondown  = mapMouseDown;
  mouse.onup    = mapMouseUp;
  mouse.onmove  = mapMouseMove;

  // Initialise zoom butons
  initZoom();

  // Display overview box on map
//  clipOV();
//alert("loaded");
  loaded=true;
}

//////////////////////////////////////////////////////////////////////////
// Object to repesent a zoom button
//////////////////////////////////////////////////////////////////////////
// pId   :  "01", "02" ... two character numeric strings to identify button
// pLabel:  Text to be used to describe button eg "100km"
// pWidth:  Width of map to be shown at this scale (metres)
//////////////////////////////////////////////////////////////////////////
function Zoom(pId, pLabel, pWidth){

    // Integer repesenting scale 0 = zoomed right out , 11 = zoomed right in
    this.level  = parseInt(pId,10);

    // id of the button image in page
    this.id     = "zoom"+pId;

    // lable used to describe button eg "100km"
    this.label  = pLabel;

    // Width of map to be shown (metres)
    this.width  = pWidth;

    // Ensure button images is preload for speed
    this.on     = new Image();
    this.on.src = "/images/maps/zoom_bar_yellow.gif";
    this.off    = new Image();
    this.off.src    = "/images/maps/zoom_bar_white.gif";

    // "alt" label for button
    this.alt    = "Zoom to "+pLabel;

}

// Dynamically define the properties of the zoom buttons
var zoomBtns=new Array();
zoomBtns[0] =new Zoom("00", "1000km",1000000);
zoomBtns[1] =new Zoom("01", "500km",  500000);
zoomBtns[2] =new Zoom("02", "250km",  250000);
zoomBtns[3] =new Zoom("03", "100km",  100000);
zoomBtns[4] =new Zoom("04", "50km",   50000);
zoomBtns[5] =new Zoom("05", "25km",   25000);
zoomBtns[6] =new Zoom("06", "10km",   10000);
zoomBtns[7] =new Zoom("07", "5000m",   5000);
zoomBtns[8] =new Zoom("08", "2500m",   2500);
zoomBtns[9] =new Zoom("09", "1000m",   1000);
zoomBtns[10]=new Zoom("10", "500m",    500);
zoomBtns[11]=new Zoom("11", "250m",    250);

// Assume initally we are zoomed out
var curZoom=zoomButton[0];

//////////////////////////////////////////////////////////////////////////
// Initialises zoom bar ad zoom drop down
//////////////////////////////////////////////////////////////////////////
function initZoom(){

    // Define functins used to set hightlight on and off on zoom buttons
    Zoom.prototype.setOn      = new Function("document.images[this.id].src = this.on.src");
    Zoom.prototype.setOff     = new Function("document.images[this.id].src = this.off.src");

    // Get a handle on the sclae drop down list
    var scale = document.mapGo.scale;
    var opts = scale.options;
    opts.length=0;

    // Go through all the zoom levels
    for (var i=0;i<zoomBtns.length;i++){

        // Intialise zoom buttons events
        var btn = zoomBtns[i];
        document.images[btn.id].onblur      = new Function("zoomOff("+i+")");
        document.images[btn.id].onfocus     = new Function("zoomOn ("+i+")");
        document.images[btn.id].onmouseover     = new Function("zoomOn ("+i+")");
        document.images[btn.id].onmouseout      = new Function("zoomOff("+i+")");
        document.images[btn.id].alt   =     btn.alt;

        // Initialise drop down list with same values as zoom bar
        opts[opts.length] = new Option(i);
        opts[i].text      = btn.label;
    }

    // Determine the current zoom level
    curZoom=getZoomLevelForWidth(eRight - eLeft);
    curZoom.setOn();

    // Ensure scale drop down consistent with zoom level
    synchScaleDropDown();

    // Ensure map tools shows current value
    synchToolMode();
}

//////////////////////////////////////////////////////////////////////////
// Called to switch images as user plays with zoom bar
//////////////////////////////////////////////////////////////////////////
// level: 0 - 11
function zoomOn(level){
    var btn = zoomBtns[level];
    if(curZoom.id!=btn.id)
        btn.setOn();
}

//////////////////////////////////////////////////////////////////////////
// Called to switch images as user plays with zoom bar
//////////////////////////////////////////////////////////////////////////
// level: 0 - 11
function zoomOff(level){
    var btn = zoomBtns[level];
    if(curZoom.id!=btn.id)
        btn.setOff();
}

//////////////////////////////////////////////////////////////////////////
// Called when the user clicks on a button in the zoom bar
//////////////////////////////////////////////////////////////////////////
// level: 0 - 11
function zoomTo(level){
    zoomToLevel(zoomBtns[level], (eLeft +eRight)/2, (eBottom+eTop)/2);

}

//////////////////////////////////////////////////////////////////////////
// Called when the user clicks 'go' having chosen a new scale from drop down
//////////////////////////////////////////////////////////////////////////
function zoomGo(){
    zoomTo(document.getElementById('scale').selectedIndex);
}

//////////////////////////////////////////////////////////////////////////
// Called when the user clicks on the "zoom plus" button in the zoom bar
//////////////////////////////////////////////////////////////////////////
function zoomPlus(){
    if(curZoom.level+1<zoomBtns.length)
        zoomTo(curZoom.level+1);
}

//////////////////////////////////////////////////////////////////////////
// Called when the user clicks on the "zoom minus" button in the zoom bar
//////////////////////////////////////////////////////////////////////////
function zoomMinus(){
    if(curZoom.level>0)
        zoomTo(curZoom.level-1);
}

//////////////////////////////////////////////////////////////////////////
// Called when the user zooms in a level by clicking somwhere on the map
//////////////////////////////////////////////////////////////////////////
// x: metres east
// y: metres north
function zoomIn(x,y) {
      // Netscape seems to be sending two zoom to point events !
      if(sent==true)
        return;
      else
         sent=true;

      if(curZoom.level+1<zoomBtns.length)
    zoomToLevel(zoomBtns[curZoom.level+1], x, y);
}

//////////////////////////////////////////////////////////////////////////
// Called when the user zooms out a level by clicking somewhere on the map
//////////////////////////////////////////////////////////////////////////
// x: metres east
// y: metres north
function zoomOut(x,y) {
      // Netscape seems to be sending two zoom to point events !
      if(sent==true)
        return;
      else
         sent=true;

      if(curZoom.level>0)
    zoomToLevel(zoomBtns[curZoom.level-1], x, y);
}

//////////////////////////////////////////////////////////////////////////
// Given a zoom level and a point, zooms to a envelope centred on that
// point at that level
//////////////////////////////////////////////////////////////////////////
// x: metres east
// y: metres north
function zoomToLevel(zoomBtn, x , y){

    // Construct new rectangle for map
    eLeft       = x - (zoomBtn.width/2);
    eRight      = x + (zoomBtn.width/2);
    eTop        = y + (zoomBtn.width*iHeight/iWidth/2);
    eBottom     = y - (zoomBtn.width*iHeight/iWidth/2);

    // Ensure new rectangle is within limits
    if(eLeft<limitLeft){
        eRight  +=limitLeft-eLeft;
        eLeft   =limitLeft;
    }
    if(eRight>limitRight){
        eLeft   -=eRight-limitRight;
        eRight  =limitRight;
    }
    if(eBottom<limitBottom){
        eTop    +=limitBottom-eBottom;
        eBottom =limitBottom;
    }
    if(eTop>limitTop){
        eBottom -=eTop-limitTop;
        eTop    =limitTop;
    }

    // Highlight new zoom level button
    curZoom.setOff();
    curZoom=zoomBtn;
    curZoom.setOn();

    // Ensure scale drop down shows correct value
    synchScaleDropDown();

    // Send request for new page
    sendMapXML();

}

////////////////////////////////////////////////////////////////////////////
// Synchronise sclae drop down list with current zoom level
///////////////////////////////////////////////////////////////////////////
function synchScaleDropDown(){
    var scale = document.mapGo.scale;
    scale.options[curZoom.level].selected=true;
}

///////////////////////////////////////////////////////////////////////
// Called when user select a new tool (radio button)
///////////////////////////////////////////////////////////////////////
// 1=in; 2=out; 3=inDragBox; 4=dragMap;
//
function zoomButton(zoomType) {
  toolMode = zoomType;
}

///////////////////////////////////////////////////////////////////////////
// Synchronise map tool radio buttons to correct value
//////////////////////////////////////////////////////////////////////////
function synchToolMode(){
    var tools = document.getElementById("tools");
    for(i=0; i<tools.tools.length;i++){
        if (tools.tools[i].value==toolMode)
            tools.tools[i].checked=true;
    }
}

//////////////////////////////////////////////////////////////////////////
// Given a width return best suited zoom level button
//////////////////////////////////////////////////////////////////////////
function getZoomLevelForWidth(width){
    var rtnBtn=zoomBtns[0];
    for (var i=zoomBtns.length-1; i>=0; i--){
        btn = zoomBtns[i];
        // Allow 25% margin of error above and below
        if(btn.width+(btn.width/2)>width){
            rtnBtn = btn;
            break;
        }
    }
    return rtnBtn
}

//////////////////////////////////////////////////////////////////////////
// The zoom in drag box has finished
// So zoom in if appropriate
//////////////////////////////////////////////////////////////////////////
function stopZoomInBox() {
    zooming=false;

    // Hide zoom in box
    divs.zoomBoxTop.hide();
    divs.zoomBoxLeft.hide();
    divs.zoomBoxRight.hide();
    divs.zoomBoxBottom.hide();

    // Make sure we have draged a box at least 5 pixcels in size!
    if (Math.abs(zright-zleft)>5  && Math.abs(zbottom-ztop)>5)
    {

        var theY    = iHeight - ztop;

        eTop    = pixelY * theY   + eBottom;
        eRight  = pixelX * zright + eLeft;
        eLeft   = pixelX * zleft  + eLeft;

        theY    = iHeight - zbottom;
        eBottom = pixelY * theY + eBottom;

        zoomToLevel(
            getZoomLevelForWidth(eRight-eLeft),
            (eLeft + eRight)/2,
            (eTop  + eBottom)/2);

    }
    return true;
}

////////////////////////////////////////////////////////////////////////////////
// Start to drag zoom in box
////////////////////////////////////////////////////////////////////////////////
function startZoomInBox() {

  // Make sure we are on the map
  if ((mouseX<iWidth) && (mouseY<iHeight)) {
      x1=mouseX;
      y1=mouseY
      x2=x1+1;
      y2=y1+1;
      zleft=x1;
      ztop=y1;
      zbottom=y1;
      zright=x1

      // Show the zoom box
      zooming=true;
      boxIt(x1,y1,x2,y2);
  }
  return false;
}

//////////////////////////////////////////////////////////////////////////
// Called when user clicks a pan button
//////////////////////////////////////////////////////////////////////////
function panButton(panType) {
    
//alert(panType);

  switch(panType) {

    case 1:
      //west
      eLeft  = eLeft - panX;
      eRight = eLeft + xDistance;
      break
    case 2:
      // north
      eTop    = eTop + panY;
      eBottom = eTop - yDistance;
      break
    case 3:
      // east
      eRight = eRight + panX;
      eLeft  = eRight - xDistance;
      break
    case 4:
      // south
      eBottom = eBottom - panY;
      eTop   = eBottom + yDistance;
      break
    case 5:
      // north west
      eLeft  = eLeft - panX;
      eRight = eLeft + xDistance;
      eTop    = eTop + panY;
      eBottom = eTop - yDistance;
      break
    case 6:
      // north east
      eRight = eRight + panX;
      eLeft  = eRight - xDistance;
      eTop    = eTop + panY;
      eBottom = eTop - yDistance;
      break
    case 7:
      // south east
      eRight = eRight + panX;
      eLeft  = eRight - xDistance;
      eBottom = eBottom - panY;
      eTop   = eBottom + yDistance;
      break
    case 8:
      // south west
      eLeft  = eLeft - panX;
      eRight = eLeft + xDistance;
      eBottom = eBottom - panY;
      eTop   = eBottom + yDistance;
      break
  }
  sendMapXML();
  return;
}

////////////////////////////////////////////////////////////////////////////////
// Start dragging the map
///////////////////////////////////////////////////////////////////////////////
function startPan(e) {

  // Make sur we are on the map
  if ((mouseX<iWidth) && (mouseY<iHeight)) {
      x1=mouseX;
      y1=mouseY;
      x2=x1+1;
      y2=y1+1;
      panning=true;
  }
  return false;
}

//////////////////////////////////////////////////////////////////////////////////
// Stop dragging the map
//////////////////////////////////////////////////////////////////////////////////
function stopPan(e) {

  var ixOffset = x2-x1;
  var iyOffset = y1-y2;
  panning=false;

  // Make sure the map has been moved at least 5 pixcels !
  if (Math.abs(ixOffset)>5  || Math.abs(iyOffset)>5) {

      var theY  = iHeight - ztop;
      var xOffset   = pixelX * ixOffset;
      var yOffset   = pixelY * iyOffset;

      eTop      = eTop      - yOffset;
      eRight    = eRight    - xOffset;
      eLeft     = eLeft     - xOffset;
      eBottom   = eBottom   - yOffset;
      divs.theMap.hide();

      sendMapXML();

  } else{
    // Move the map back!
    divs.theMap.moveTo(hspc,vspc);
  }
  return true;
}

//////////////////////////////////////////////////////////////////////////////////
// Determine the position of mouse event in pixcels
// from the top left corner of map and in metres east and north
//////////////////////////////////////////////////////////////////////////////////
function getImageXY(e) {

    // mouse is the broswer indepenent object that gives the x and y
    // of the mouse event in pixcels relative to top left of
    // browesr window
    mouseX=mouse.x;
    mouseY=mouse.y;

    // Subtract out the position of the map div relative to the browser window
    // This gives us the position relative to the map div
    mouseX -= divs.theMap.windowOffsetLeft();
    mouseY -= divs.theMap.windowOffsetTop();
    if        (ns4) { // Netscape 4
    } else if (ie4) { // Explorer 4
    } else if (ie5) { // W3C - Explorer 5+
    } else if (ns6) { // W3C - Netscape 6+
        mouseX -= divs.maplayer.windowOffsetLeft();
        mouseY -= divs.maplayer.windowOffsetTop();
    }

    // Subtract out the position of the map image in the maplayer
    // This gives us position of the click relative to the map image (pixcels)
//    mouseX -= hspc;
//    mouseY -= vspc;

    // Also calculate the position of the click in metres east and north
    mapX = pixelX * mouseX + eLeft;
    mapY = pixelY * (iHeight-mouseY) + eBottom;
}

////////////////////////////////////////////////////////////////////////////////////
// Called when user clicks down on mouse
///////////////////////////////////////////////////////////////////////////////////
function mapMouseDown (e) {
  // Dont allow user to use tools if
  // the mouse in in a "popup" div
  if(!divPopup){

      // Work out where the use has clicked in pixcels and metres
      getImageXY(e)

      // Make sure we are over the map
      if ((mouseX>=0) && (mouseX<iWidth) && (mouseY>=0) && (mouseY<iHeight)) {

        switch(toolMode) {
          case 1:
            zoomIn(mapX,mapY);
            break
          case 2:
            zoomOut(mapX, mapY);
            break
          case 3:
            startZoomInBox(e);
            break

          case 4:
            startPan(e);
            break

          default:
        break
        }
      }
      // Forward events on
      else if (!document.all)
        routeEvent(e);
  }
  return (!zooming && !panning);
}

////////////////////////////////////////////////////////////////////////
// Called when user lets the map button up
////////////////////////////////////////////////////////////////////////
function mapMouseUp(e) {

  // If we are showing a "popup" div then ignore this event
  if (divPopup)
    return true;

  // If we are dragging a zoom in box the zoom in
  if ((toolMode == 3) && (zooming)) {
    stopZoomInBox(e);
  }

  // If we are dragging the map then get the new  map
  if ((toolMode == 4) && (panning)) {
    stopPan(e);
  }

  // next line needed for Mac
  return (!zooming && !panning);
}

////////////////////////////////////////////////////////////////////////
// Returns the position of the mouse pointer on the X axis
// relative to the browser screen
////////////////////////////////////////////////////////////////////////
function getMouseX() {
	var e = window.event;
	if (e.pageX) {// can we use these event properties to get the cursor position?
		return e.pageX;
	} else if (e.clientX) {// compatible with most browsers
		return e.clientX + document.body.scrollLeft
			+ document.documentElement.scrollLeft;
	}
}

////////////////////////////////////////////////////////////////////////
// Returns the position of the mouse pointer on the Y axis
// relative to the browser screen
////////////////////////////////////////////////////////////////////////
function getMouseY() {
	var e = window.event;
	if(e.pageY) {
		return e.pageY;
	} else if (e.clientY) { 
		return divY = e.clientY + document.body.scrollTop
			+ document.documentElement.scrollTop;
	}
}


//////////////////////////////////////////////////////////////////////////////
// Called when the user hovers over the image map corresponding to a "popup" div
//////////////////////////////////////////////////////////////////////////////
function imagemapMouseOver()
{
    // Ignore if we are dragging a zoom box or draging the map
    if(panning || zooming)
        return;

    // If we are showing an old "popup" then hide it
    if (divPopup!=null  && divPopup.isVisible())
    {
      divPopup.hide();
//    } else {
//        alert("mouse.x="+mouse.x+" popuptextx["+divPopupId+"]="+popuptextx[divPopupId]
//            +" divs.maplayer.windowOffsetLeft()="+divs.maplayer.windowOffsetLeft()
//            +" divs.mapDisplay.windowOffsetLeft()="+divs.mapDisplay.windowOffsetLeft()
//            +" divs.theMap.windowOffsetLeft()="+divs.theMap.windowOffsetLeft()
//            +" hspc="+hspc);
    }

    // The id of the popup is passed into this function
    divPopupId= arguments[0];

    // get a handle on the popup div
    divPopup = eval('divs.'+popuptextdiv+divPopupId);

    // The popup div might not exist if there are too many
    // If it does not exist the display the default popup
    if( divPopup == null )
    {
		divPopup=divs.mapDefaultText;
    }

    // Calculate where the divs should be relative to top left corner of browser
    var divX = popuptextx[divPopupId];
    var divY = popuptexty[divPopupId];
	divX += divs.theMap.windowOffsetLeft();
	divY += divs.theMap.windowOffsetTop();

    if (ns4) { // Netscape 4
//        alert("ns4");
    } else if (ie4) { // Explorer 4
//        alert("ie4");
    } else if (ie5) { // W3C - Explorer 5+
    } else if (ns6) { // W3C - Netscape 6+
        divX += divs.maplayer.windowOffsetLeft();
        divY += divs.maplayer.windowOffsetTop()
    }

    // If we are on the right side of the map popup the div towards the left
    if (popuptextx[divPopupId] > (iWidth/2))
    {
        divX -= divPopup.getWidth();

        // Ensure that the popup is above the mouse position to allow hyperlinks
        // embedded in the popup to work
        divX -= divPopupDelta;
    }
    else 
	{
    	// otherwise let it flow to the left
        divX += divPopupDelta;
	}

    // If we are on the bottom half of the map, popup the div highe up
    if (popuptexty[divPopupId]> (iHeight/2))
    {
        divY -= divPopup.getHeight();

        // Popup over mouse position (again)
        divY -= +divPopupDelta;
    }
    else
	{
    	// Otherwise let the div flow down
        divY += divPopupDelta;
	}
	
	if( !divX || !divY ) {
		// couldn't get the x/y of the popup text
		// assign divX&y to the mouse position
		//alert("Assigning divX & divY to mouse position");
		divX = getMouseX();
		divY = getMouseY();
	}
	//alert("x/y at start:"+divX+"/"+divY+" "+"popuptextx.length="+popuptextx.length+" | popuptexty.length="+popuptexty.length+" | divPopupId="+divPopupId);
	
    // Display the popup div
    divPopup.moveTo(divX, divY);
    divPopup.setZIndex(1);


    // Move the border for the div to correct place
    divs.mapTextNorth.moveTo(divX-1, divY-1);
    divs.mapTextSouth.moveTo(divX-1, divY-1);
    divs.mapTextEast.moveTo(divX-1, divY-1);
    divs.mapTextWest.moveTo(divX-1, divY-1);

    // Clip border to fit popup div
    divs.mapTextNorth.setClip(0, divPopup.getWidth()+2, 1, 0);
    divs.mapTextSouth.setClip(divPopup.getHeight()+1, divPopup.getWidth()+2, divPopup.getHeight()+2, 0);
    divs.mapTextEast.setClip(0, divPopup.getWidth()+2, divPopup.getHeight()+2, divPopup.getWidth()+1);
	divs.mapTextWest.setClip(0, 1, divPopup.getHeight()+2, 0);


    // Show borders
    divs.mapTextNorth.setZIndex(1);
    divs.mapTextSouth.setZIndex(1);
    divs.mapTextEast.setZIndex(1);
    divs.mapTextWest.setZIndex(1);


    divs.mapTextNorth.show();
    divs.mapTextSouth.show();
    divs.mapTextEast.show();
    divs.mapTextWest.show();
    divPopup.show();
	keepDivVisible = true;

}

////////////////////////////////////////////////////////////////////////////////
// Prevents the browser from not allowing a user to click-zoom after hovering over a POI
////////////////////////////////////////////////////////////////////////////////
function imagemapMouseOut() {
    // Ignore if we are dragging a zoom box or draging the map
    if(panning || zooming)
        return;

	if(divPopup != null) {
		divPopup.hide();
		divPopup = null;
	}
}

// sets the value of keepDivVisible
// true to flag it to stay visible, false to flag it for hiding
function flagDivPopupVisibility(bool) {
	keepDivVisible = bool;
}

////////////////////////////////////////////////////////////////////////////////
// Called when user moves mouse
////////////////////////////////////////////////////////////////////////////////
function mapMouseMove(e) {
  // window.status="";

  // Get the position odf the mouse in pixcels and in metres
  getImageXY(e);

  // change mouse cursor when drag or drag zoom
  if ((mouseX>=0) && (mouseX<iWidth) && (mouseY>=0) && (mouseY<iHeight)) {
                switch(toolMode) {
                  case 1:
                        //document.body.style.cursor = "default";
                break
                  case 2:
                        //document.body.style.cursor = "default";
                break
                  case 3:
                        document.body.style.cursor = "crosshair";
                break

                  case 4:
                        document.body.style.cursor = "move";
                break

                  default:

                break
                }
          }
          else{
                document.body.style.cursor = "default";
      }


  // If we have "popedup" a div the check to see
  // if we have moved off it and if so hide it
  // unless keepDivVisible is true (meaning we're still over a POI)
  if(divPopup && !keepDivVisible){

    var minX = popuptextx[divPopupId];
    var maxX = popuptextx[divPopupId];
    var minY = popuptexty[divPopupId];
    var maxY = popuptexty[divPopupId];

    // Work out where we positioned the popup
    if (popuptextx[divPopupId] > (iWidth/2)) {
      minX -= divPopup.getWidth();
      minX -= divPopupDelta;
      maxX -= divPopupDelta;
    }
    else {
      maxX += divPopup.getWidth();
      maxX += divPopupDelta;
      minX += divPopupDelta;
    }

    if (popuptexty[divPopupId] > (iHeight/2)) {
      minY -= divPopup.getHeight();
      minY -= divPopupDelta;
      maxY -= divPopupDelta;
    }
    else {
      maxY += divPopup.getHeight();
      maxY += divPopupDelta;
      minY += divPopupDelta;
    }


    // Hide the popup div if we have slipped off
    if ( (mouseX<maxX) && (mouseX>minX) && (mouseY<maxY) && (mouseY>minY)) {
    } else {
      divs.mapTextNorth.hide();
      divs.mapTextSouth.hide();
      divs.mapTextEast.hide();
      divs.mapTextWest.hide();

      divPopup.hide();
      divPopup=null;
      divPopupId=-1;
    }
  }

  // If we have moved of the map then simulate a mouse up event
  if ((mouseX>iWidth) || (mouseY>iHeight) || (mouseX<=0) ||(mouseY<=0)) {
    mapMouseUp(e);
  } else {

    if (zooming) {
      // Update corner of zoom box
      x2=mouseX;
      y2=mouseY;
      moveZoomBox();

    } else if (panning) {
      // Update map drag position
      x2=mouseX;
      y2=mouseY;
      moveMap();
    }

    var mouseString = "";
    if (zooming) mouseString += "ZoomBox: [" + x1 + "," + y1 + " x " + x2 + "," + y2 + "]    ";
    mouseString += "Coords: " + mouseX + " , " + mouseY +"  "+parseInt(mapY)+"N "+parseInt(mapX)+"E";
    // 12/02/04 removed due to legal reasons
    //window.status = mouseString;
  }
  return (!zooming && !panning);
}

////////////////////////////////////////////////////////////////////////////////
// Move map to new location
// (x1, y1) Position at start of pan (pixcels)
// (x2, y2) Current postion of mouse (pixcels)
///////////////////////////////////////////////////////////////////////////////
function moveMap() {
  var xMove = x2-x1;
  var yMove = y2-y1;
  var cLeft = -xMove;
  var cTop  = -yMove;
  var cRight = iWidth;    // - xMove;
  var cBottom = iHeight;  // - yMove;

  if (xMove>0) {
    cLeft = 0;
    cRight = iWidth - xMove;
  }
  if (yMove>0) {
    cTop = 0;
    cBottom = iHeight - yMove;
  }

  // Move the map and make sure it is clipped
 divs.theMap.setClip(cTop,cRight,cBottom, cLeft);
  divs.theMap.moveTo(xMove+hspc,yMove+vspc);
}

/////////////////////////////////////////////////////////////////////
// Move the zoom in box
// (x1, y1) Initial corner of zoom box
// (x2, y2) Dynamic cornr of zoom box
/////////////////////////////////////////////////////////////////////
function moveZoomBox() {
  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);
  }
  return false;
}

////////////////////////////////////////////////////////////////////
// Called when user clicks on overview map
///////////////////////////////////////////////////////////////////
function ovMap2Click(e) {

  // Switch to zoom inm mode
  zooming=false;
  panning=false;
  toolMode=1;

  // Determine location of click in pixcels on overview map
  getOVImageXY(e);

  ovMapClick(mouseX,mouseY);
}



//////////////////////////////////////////////////////////////////////
// Determine the location in pixcels of click on overeview map
/////////////////////////////////////////////////////////////////////
function getOVImageXY(e) {

  // get number of pixcels from top left corner of browser
  mouseX=mouse.x;
  mouseY=mouse.y;


  // subtract the position of the maplayer in bowser
  mouseX-=divs.maplayer.windowOffsetLeft();
  mouseY-=divs.maplayer.windowOffsetTop();


  // subtract position of map relative to map layer
  mouseX -= ovHspc;
  mouseY -= ovVspc;


}
///////////////////////////////////////////////////////////////////////
// Move to new position on map overview
///////////////////////////////////////////////////////////////////////
function ovMapClick(x,y) {
  var ovXincre  = fullOVWidth  / i2Width;
  var ovYincre  = fullOVHeight / i2Height;

  var ovX       = x;
  var ovY       = i2Height - y;

  var ovmapX    = ovX * ovXincre + fullOVLeft;
  var ovmapY    = ovY * ovYincre + fullOVBottom;

  eLeft       = ovmapX - xHalf;
  eRight      = ovmapX + xHalf;
  eTop        = ovmapY + yHalf;
  eBottom     = ovmapY - yHalf;

  sendMapXML();
}

///////////////////////////////////////////////////////////////////////////////
// Draw zoom box on map
///////////////////////////////////////////////////////////////////////////////
function boxIt(theLeft,theTop,theRight,theBottom) {
  divs.zoomBoxTop.setClip(theTop,theRight,theTop+zoomBoxSize, theLeft);
  divs.zoomBoxLeft.setClip(theTop,theLeft+zoomBoxSize,theBottom, theLeft);
  divs.zoomBoxRight.setClip(theTop,theRight,theBottom, theRight-zoomBoxSize);
  divs.zoomBoxBottom.setClip(theBottom-zoomBoxSize,theRight,theBottom, theLeft);

  divs.zoomBoxTop.show();
  divs.zoomBoxLeft.show();
  divs.zoomBoxRight.show();
  divs.zoomBoxBottom.show();
}

////////////////////////////////////////////////////////////////////////////
// Draw the overview box on the over view map
////////////////////////////////////////////////////////////////////////////
function clipOV(){
  var ovXincre = fullOVWidth / i2Width;
  var ovYincre = fullOVHeight / i2Height;
  var vleft    = parseInt((eLeft - fullOVLeft) / ovXincre );
  var vright   = parseInt((eRight - fullOVLeft) / ovXincre );
  var vtop     = parseInt((fullOVTop - eTop) / ovYincre );
  var vbottom  = parseInt((fullOVTop - eBottom) / ovYincre );

  divs.zoomOVBoxTop.setClip( vtop-ovBoxSize, vright, vtop, vleft);
  divs.zoomOVBoxLeft.setClip(vtop-ovBoxSize, vleft, vbottom, vleft-ovBoxSize);
  divs.zoomOVBoxRight.setClip(vtop-ovBoxSize,vright+ovBoxSize, vbottom, vright);
  divs.zoomOVBoxBottom.setClip(vbottom-ovBoxSize, vright, vbottom, vleft);

  divs.zoomOVBoxTop.show();
  divs.zoomOVBoxLeft.show();
  divs.zoomOVBoxRight.show();
  divs.zoomOVBoxBottom.show();

}


//////////////////////////////////////////////////////////////////////////////
// Send request for new map
//////////////////////////////////////////////////////////////////////////////
function sendMapXML() {


      var mapForm=window.divs.maplayer.div.document.mapForm;
      if (formAction!="")
        mapForm.action=formAction;
      else
        mapForm.action=window.location.href.replace(/\?.*/, "");

      // Speicy new image
      mapForm.minx.value        = eLeft;
      mapForm.miny.value        = eBottom;
      mapForm.maxx.value        = eRight;
      mapForm.maxy.value        = eTop;

      // Height and with currently do not change
      mapForm.height.value      = iHeight;
      mapForm.width.value       = iWidth;

      // Preseve current map tool mode
      mapForm.toolMode.value        = toolMode;

      // Ensure we havea map displayed
      mapForm.gp.value              = "map";

      mapForm.submit();

}
////////////////////////////////////////////////////////////////////////////////////
// Function used in page to request a new page when not actually intreacting with map
// The specified url is used additional params are added from mapForm
// Ensures map state is preserved by examining mapForm
/////////////////////////////////////////////////////////////////////////////////////
function mappingRedirect(url)
{
  if (!url)
  {
      if (formAction!="")
        url=formAction;
      else
        url=window.location.href.replace(/\?.*/, "");
  }
  url+="?";
  var mapForm=window.divs.maplayer.div.document.mapForm;
  var elems = mapForm.elements;

  // Update on the form any additional values passed
  for (var i=1; i+1<arguments.length; i++)
  {
    var found=false;
    for (var j=0; j<elems.length; j++)
    {
      if(elems[j].name == arguments[i])
      {
        elems[j].value= escape(arguments[i+1]);
        found=true;
      }
    }
    if(found==false)
    {
      url+="&"+arguments[i] +"=" +escape(arguments[i+1]);
    }
    i++;
  }
  // Construct URL adding query params from form
  for ( i=0; i<elems.length; i++)
  {
    url+="&" + elems[i].name +"=" + escape(elems[i].value);
  }
  window.document.location.href=url;
  return false;
}
////////////////////////////////////////////////////////////////////////////////////
// Function used in page to request a new page when not actually intreacting with map
// Parameters from the specified form is usedmand supllement with params from map form
// Ensures map state is preserved by examining mapForm
/////////////////////////////////////////////////////////////////////////////////////
function mappingFormRedirect(form)
{
  var url;

  if (form)
  {
      url = formAction;
      url+="?";
      var elems =form.elements;

      // use params from supplied form
      for (var i=0; i<elems.length; i++)
      {
        if (elems[i].type!='checkbox' || elems[i].checked )
          url+="&" + elems[i].name + "=" +escape(elems[i].value);
      }

      if(document.mapForm)
      {
        // Add missing elems from MapForm
        var mapForm=document.mapForm;
        var mapElems = mapForm.elements;

        // Update on the form any additional values passed
        for (var i=0; i<mapElems.length; i++)
        {
          var found=false;
          for (var j=0; j<elems.length; j++)
          {
            if(elems[j].name == mapElems[i].name)
            {
              found=true;
              break;
            }
          }
          if(found==false)
          {
            url+="&"+mapElems[i].name +"=" +escape(mapElems[i].value);
          }
        }
      }
      window.document.location.href=url;
  }
  return false;
}
///////////////////////////////////////////////////////////////////////
// ??????????????????????????
///////////////////////////////////////////////////////////////////////
function convert() {
  if (mode == "travelwatch") {
    tmode = "travelwatch";
  }
 }






