// © 2006 LogiFleet SA / INSER SA

// arcims.js
var request;
var requestOver;
var preloadImage;

function ArcIMS(params) {    
  this.service = "rt";
  this.imageService = params.imageService;
  this.featureService = params.featureService;
  this.mode = params.mode;
  this.setAuto('autoOff');
  this.listRT = params.listRT;
  this.listHisto = params.listHisto;
  this.scrollEnabled = params.scrollEnabled;
  this.codeId = params.codeId;
  this.mobile = params.mobile;
  
  this.mapDiv = xGetElementById(params.mapDiv);
  this.mapImg = xGetElementById(params.mapImg);
  this.mapBorderDiv = xGetElementById(params.mapBorderDiv);
  this.mapLoadingDiv = xGetElementById(params.mapLoadingDiv);
  if (this.mapLoadingDiv === null) {
    document.write('<div id="mapLoadingDiv"><img title="En chargement ...." alt="En chargement ...." src="images/roller_big.gif" width="54" height="55" /></div>');
    this.mapLoadingDiv = xGetElementById(params.mapLoadingDiv)
  }
  this.mapZoomDiv = xGetElementById(params.mapZoomDiv);
  if (this.mapZoomDiv === null) {
    document.write('<div id="mapZoomDiv"><img src="images/spacer.gif" alt="" width="1" height="1"/></div>');
    this.mapZoomDiv = xGetElementById(params.mapZoomDiv)
  }
  
  this.overDiv = xGetElementById(params.overDiv);
  this.overImg = xGetElementById(params.overImg);
  this.overZoomImg = xGetElementById(params.overZoomImg);
  this.overBorderDiv = xGetElementById(params.overBorderDiv);
  this.overLoadingDiv = xGetElementById(params.overLoadingDiv);
  this.overZoomDiv = xGetElementById(params.overZoomDiv);
  
  var envelope = new Envelope(params.envelopeMinX, params.envelopeMinY, params.envelopeMaxX, params.envelopeMaxY);
  this.initEnvelope = envelope;
  this.envelope = envelope.clone();
  
  this.mapOffset = new Point(0, 0);
  this.mapDivPosition = findPos(this.mapDiv);
  this.overDivPosition = findPos(this.overDiv);
  //this.overDivPosition = new Point(0, 0);
  this.imageSize = new ImageSize(params.imageSizeWidth, params.imageSizeHeight);
  this.overSize = new ImageSize(params.overSizeWidth, params.overSizeHeight);
  this.updatePositions();
  
  this.histoDiv = xGetElementById(params.histoDiv);
  this.infoHisto = xGetElementById(params.infoHisto);
  this.boats = new Array();
  this.boats[1]= null;
  this.boats[2]= null;
  this.boats[3]= null;
  this.boats[4]= null;
  this.boats[5]= null;
  this.start = xGetElementById(params.start);
  this.stop = xGetElementById(params.stop);
  
  this.legendLayer1 = params.legendLayer1;
  this.legendLayer2 = params.legendLayer2;
  
  this.listDiv = xGetElementById(params.listDiv);
  this.boatSelect = xGetElementById(params.boatSelect);
  
  this.pan = new Pan(this, this.mapDiv, this.mapDivPosition);
  this.zoomIn = new ZoomIn(this, this.mapDiv, this.mapDivPosition, this.mapZoomDiv);
  this.over = new Over(this, this.overDiv, this.overDivPosition, this.overZoomDiv);
  
  this.legend = new Legend(this, params.legendLayer1, params.legendFields, 
                           xGetElementById(params.legendDiv), xGetElementById(params.legendLoadingDiv),
                           params.legendOffset);
  this.meteo = new Meteo(this, params.meteoLayer, params.meteoField, params.meteoWhere, xGetElementById(params.infoRT), xGetElementById(params.dateMeteo));
  this.label = new Label(this, params.legendLayer2, params.infoUrl, params.labelRange);
  this.printUrl = params.printUrl;
  this.kmlUrl = params.kmlUrl;
  
  this.buoyLayer = params.buoyLayer;
  
  this.copyright = params.copyright;
  this.minimum = params.minimum;
  this.autoTime = params.autoTime;
  this.alert = params.alert;
  
  this.catURL = "http://" + document.location.host + "/servlet/com.esri.esrimap.Esrimap?ServiceName=";
  
  this.resetMap();
  
  if (!this.mobile) {
    xEnableDrag(this.mapDiv, onDragStart, onDrag, onDragStop);
    xAddEventListener(this.mapDiv, "mouseover", onMouseOver);
    xAddEventListener(this.mapDiv, "mouseout", onMouseOut);
    xAddEventListener(this.mapDiv, "mousemove", onMouseMove);
    xAddEventListener(this.mapDiv, "click", onMapClick);
  
    xVisibility(this.overZoomDiv, false);
  
    xClip(this.overDiv, 0, xWidth(this.overDiv) - this.mapOffset.x, xHeight(this.overDiv) - this.mapOffset.y, 0);
    xClip(this.overZoomDiv, 0, xWidth(this.overDiv) - this.mapOffset.x, xHeight(this.overDiv) - this.mapOffset.y, 0);
  }
}

function ArcIMS_swapService(aService) {
  var newService = null;
  if (aService == 'rt' && this.service != aService) {
    this.boats[1]= null;
    this.boats[2]= null;
    this.boats[3]= null;
    this.boats[4]= null;
    this.boats[5]= null;
    xGetElementById("histo").className = "menu";
    xGetElementById("rt").className = "menuSelected";
    if (this.listRT && xGetElementById("listFrame").src.indexOf(this.listRT) == -1) {
      xGetElementById("listFrame").src = this.listRT;
    }
    newService = 'rt';
    this.legend.visibility(true);
    this.meteo.visibility(true);
    xDisplay(this.histoDiv, "none");
    xDisplay(this.infoHisto, "none");
  } else if (aService == 'histo' && this.service != aService) {
    if (!this.mobile) {
		xGetElementById("rt").className = "menu";
	}
	if (!this.mobile) {
		xGetElementById("histo").className = "menuSelected";
	}
    if (this.listHisto && xGetElementById("listFrame").src.indexOf(this.listHisto) == -1) {
      xGetElementById("listFrame").src = this.listHisto;
    }
    newService = 'histo';
    
    this.legend.visibility(false);
    this.meteo.visibility(false);
    xDisplay(this.histoDiv, "block");
    xDisplay(this.infoHisto, "block");
  }
  if (newService != null) {
    this.service = newService;
    request = null;
    this.updateMap();
    this.updateOver();
  }
}

function ArcIMS_autoUpdate() {
  if (this.auto == 'autoOn') {
    if (this.service == "rt") {
      this.updateMap();
     }
    window.setTimeout('autoUpdate()', this.autoTime);
  }
}

function ArcIMS_setAuto(aMode) {
  if (aMode != this.auto) {
    this.auto = aMode;
    if (this.auto == 'autoOn') {
      this.autoUpdate();
    }
  }
}

function ArcIMS_resetMap() {
  xMoveTo(this.mapDiv, this.mapDivPosition.x, this.mapDivPosition.y);
  if (!this.mobile) {
    xClip(this.mapDiv, 0, xWidth(this.mapDiv) - this.mapOffset.x, xHeight(this.mapDiv) - this.mapOffset.y, 0);
  }
}

function ArcIMS_updateMap() {
  xVisibility(this.mapLoadingDiv, true);
  this.mapDiv.style.opacity = "0.6";
  
  this.envelope.limit(this.initEnvelope, this.minimum);
  
  if (this.service == "rt") {
    this.meteo.update();
    this.label.update();
  }
  
  if (this.alert && this.auto == 'autoOff' && request != null && 
      request.readyState != 4) {
    alert("Carte en chargement, attendez la fin du chargement");
  } else {
    request = getXMLRequest();
    this.getImageXML("map");
  }
}

function ArcIMS_updateOver(notUpdateImage) {
  xVisibility(this.overZoomDiv, false);
  var sizeX = this.overSize.width * this.envelope.width() / this.initEnvelope.width();
  var sizeY = this.overSize.height * this.envelope.height() / this.initEnvelope.height();
  var deltaX = this.overSize.width * (this.envelope.minx - this.initEnvelope.minx) / this.initEnvelope.width();
  var deltaY = this.overSize.height * (this.initEnvelope.maxy - this.envelope.maxy) / this.initEnvelope.height();
  if (sizeX < 6) {
    deltaX = deltaX + sizeX / 2 - 3;
    sizeX = 6;
  }
  if (sizeY < 4) {
    deltaY = deltaY + sizeY / 2 - 2;
    sizeY = 4;
  }
  var offset = 0;
  if (is_ie) {
    offset = 1;
  }
  xMoveTo(this.overZoomDiv, xLeft(this.overDiv) + deltaX + offset, xTop(this.overDiv) + deltaY);
  xResizeTo(this.overZoomDiv, sizeX - offset, sizeY);
  xClip(this.overZoomDiv, - deltaY, xWidth("overDiv") - this.mapOffset.x - deltaX, xHeight("overDiv") - this.mapOffset.y - deltaY + offset, - deltaX);
  xResizeTo(this.overZoomImg, sizeX - offset, sizeY);
  xVisibility(this.overZoomDiv, true);
  
  if (!notUpdateImage && this.overDiv !== null) {
    requestOver = getXMLRequest();
    this.getImageXML("over");
  }
}

function ArcIMS_getImageXML(aMode, aCallback) {
  var req = (aMode == "map") ? request : requestOver;
  req.open("POST", this.catURL + this.imageService, true);
  req.onreadystatechange = (aMode == "map") ? callback : callbackOver;
  if (!is_opera) {
    req.setRequestHeader("Content-Type", "text/xml");
  }
  var textXML = 
    '<ARCXML version="1.1">' +
    '<REQUEST>' +
    '<GET_IMAGE>' +
    '<PROPERTIES>' + 
    ((aMode == "map") ? this.envelope : this.initEnvelope).toXML()  + 
    ((aMode == "map") ? this.imageSize : this.overSize).toXML() + 
    '<LAYERLIST>';
  if (this.service == "histo") {
    if (!this.listRT && !this.mobile) {
      this.boats[1] = xGetElementById('boat1').value;
      this.boats[2] = xGetElementById('boat2').value;
    }
    for (var i = 0; i < this.boats.length; i++) {
      if (this.boats[i]!= null && this.boats[i].length > 0) {
        textXML += 
          '<LAYERDEF id="' + i + '">' +
          '<QUERY where="CELLNUMBER = \'' + this.boats[i] + 
            '\' AND MTIME &gt;= ' + getSeconds(this.start) + 
            ' AND MTIME &lt;= ' + getSeconds(this.stop);
        if (this.codeId) {
          textXML += ' AND CODE_ID = \'' + this.codeId + '\'';
        }
        textXML += '" />' +
          '</LAYERDEF>';
      }
    }
  } else {
    textXML += '<LAYERDEF id="wind" visible="true" />';
    
    var query = "";
    if (this.codeId) {
      query = '<QUERY where="CODE_ID = \'' + this.codeId + '\' AND MTIME &gt;= ' + getSeconds(this.start) + '" />';
    }

    textXML += '<LAYERDEF id="trace" visible="true">' + query + '</LAYERDEF>';

    textXML += '<LAYERDEF id="blue" visible="true">' + query + '</LAYERDEF>';
    textXML += '<LAYERDEF id="green" visible="true">' + query + '</LAYERDEF>';

    textXML += '<LAYERDEF id="red" visible="true">' + query + '</LAYERDEF>';

    if (this.selected) {
      textXML +=
        '<LAYERDEF id="' + this.legendLayer1 + '" visible="true">' +
        '<QUERY where="CELLNUMBER IN (' + this.selected + ')';
      if (this.codeId) {
        textXML += ' AND CODE_ID = \'' + this.codeId + '\' AND MTIME &gt;= ' + getSeconds(this.start) + '';
      }
      textXML += '" />' +
        '</LAYERDEF>' +
        '<LAYERDEF id="' + this.legendLayer2 + '" visible="true">' +
        '<QUERY where="CELLNUMBER IN (' + this.selected + ')';
      if (this.codeId) {
        textXML += ' AND CODE_ID = \'' + this.codeId + '\' AND MTIME &gt;= ' + getSeconds(this.start) + '';
      }
      textXML += '" />' +
        '</LAYERDEF>';
      }
  }
  if (this.buoyLayer) {
    if (this.buoyLayer == "bom07") {
      textXML += '<LAYERDEF id="ligne_arrivee" visible="true" />';
      textXML += '<LAYERDEF id="ligne_depart_07" visible="true" />';
      textXML += '<LAYERDEF id="degagement_07" visible="true" />';
      textXML += '<LAYERDEF id="chaland" visible="true" />';
      textXML += '<LAYERDEF id="arrivee" visible="true" />';
    }
    textXML += '<LAYERDEF id="' + this.buoyLayer + '" visible="true" />';
  } else {
    textXML += '<LAYERDEF id="ligne_arrivee" visible="true" />';
    textXML += '<LAYERDEF id="ligne_depart" visible="true" />';
    textXML += '<LAYERDEF id="chaland" visible="true" />';
    textXML += '<LAYERDEF id="arrivee" visible="true" />';
  }
  textXML += '<LAYERDEF id="copyright" visible="' + this.copyright + '" />';
  textXML += 
    '</LAYERLIST>' +
    '</PROPERTIES>' + 
    '</GET_IMAGE>' +
    '</REQUEST>' +
    '</ARCXML>';
  req.send(textXML);
}

function ArcIMS_callback() {
  if (request.readyState == 4) {
    if (request.status == 200) {
      var xmlDocument = stringToDocument(request.responseText);
      if (contain(xmlDocument, "ERROR")) {
        error(xmlDocument);
      } else if (contain(xmlDocument, "IMAGE")) {
        this.envelope.parseXML(xmlDocument);
        this.updateOver(true);
        if (contain(xmlDocument, "OUTPUT")) {
          xVisibility(this.mapDiv, false);
          preloadImage = new Image();
          preloadImage.onload = onMapLoaded;
          preloadImage.src = xmlDocument.getElementsByTagName("OUTPUT")[0].attributes.getNamedItem("url").nodeValue;
        }
      }
    }
  }
}

function ArcIMS_onMapLoaded() {
  this.resetMap();
  xGetElementById(this.mapImg).src = preloadImage.src;
  this.mapDiv.style.opacity = "1.0";
  xVisibility(this.mapDiv, true);
  xVisibility(this.mapLoadingDiv, false);
}

function ArcIMS_callbackOver() {
  if (requestOver.readyState == 4) {
    if (requestOver.status == 200) {
      var xmlDocument = stringToDocument(requestOver.responseText);
      if (contain(xmlDocument, "ERROR")) {
        error(xmlDocument);
      } else if (contain(xmlDocument, "IMAGE")) {
        if (contain(xmlDocument, "OUTPUT")) {
          xVisibility(this.overDiv, false);
          xGetElementById(this.overImg).src = xmlDocument.getElementsByTagName("OUTPUT")[0].attributes.getNamedItem("url").nodeValue;
          xVisibility(this.overDiv, true);
          xVisibility(this.overLoadingDiv, false);
        }
      }
    }
  }
}

function ArcIMS_mapPan(x, y) {
  this.scroll();
  
  var deltaX = this.envelope.width() / this.imageSize.width * x;
  var deltaY = this.envelope.height() / this.imageSize.height * y;
  this.envelope.translate(-deltaX, deltaY);
  
  this.updateMap();
}

function ArcIMS_mapZoomIn(x, y, width, height) {
  if (width < 10 && height < 10) {
    this.zoom(x, y, 0.25);
  } else {
    this.scroll();
    
    var deltaX = this.envelope.width() / this.imageSize.width * x;
    var deltaY = this.envelope.height() / this.imageSize.height * y;
    this.envelope.translate(deltaX, -deltaY);
    
    var newWidth = this.envelope.width() / this.imageSize.width * width;
    var newHeight = this.envelope.height() / this.imageSize.height * height;
    this.envelope.maxx = parseFloat(this.envelope.minx) + newWidth;
    this.envelope.miny = parseFloat(this.envelope.maxy) - newHeight;v
  
    this.updateMap();
  }
}

function ArcIMS_zoomOut(x, y) {
  this.zoom(x, y, 4);
}

function ArcIMS_zoom(x, y, ratio) {
  this.scroll();
  
  if (typeof x === "undefined") {
    x = this.imageSize.width / 2;
  }
  if (typeof y === "undefined") {
    y = this.imageSize.height / 2;
  }
  
  var deltaX = this.envelope.width() / this.imageSize.width * (this.imageSize.width / 2 - x);
  var deltaY = this.envelope.height() / this.imageSize.height * (this.imageSize.height / 2 - y);
  this.envelope.translate(-deltaX, deltaY);
  
  var newWidth = this.envelope.width() * ratio;
  var newHeight = this.envelope.height() * ratio;
  this.envelope.resize(newWidth, newHeight);
  
  this.updateMap();
}

function ArcIMS_setMode(aMode) {
  xGetElementById(this.mode).className = "menu";
  this.mode = aMode;
  xGetElementById(this.mode).className = "menuSelected";
}

function ArcIMS_reset() {
  this.scroll();
  
  this.envelope = this.initEnvelope.clone();
  this.updateMap();
}

function ArcIMS_onMapClick(e) {
  var evt = new xEvent(e);
  if (this.mode == "zoomout") {
    this.zoomOut(evt.offsetX, evt.offsetY);
  }
  if (this.mode == "info") {
    this.label.info();
  }
}

function ArcIMS_onMouseOver() {
  if (this.mode == "pan") {
    this.mapDiv.style.cursor = "move";
  }
  if (this.mode == "zoomin") {
    this.mapDiv.style.cursor = "crosshair";
  }
  if (this.mode == "zoomout") {
    this.mapDiv.style.cursor = "crosshair";
  }
  if (this.mode == "info") {
    if (!is_ie || is_ie6 || is_ie6up) {
      this.mapDiv.style.cursor = "pointer";
    }
  }
}

function ArcIMS_onMouseOut() {
  this.mapDiv.style.cursor = "default";
}

function ArcIMS_onMouseMove(e) {
  this.label.show(new xEvent(e));
}

function ArcIMS_onDragStart(ele, mx, my)
{
  if (this.mode == "pan") {
    this.pan.onDragStart(ele, mx, my);
  }
  if (this.mode == "zoomin") {
    this.zoomIn.onDragStart(ele, mx, my);
  }
}

function ArcIMS_onDrag(ele, mdx, mdy)
{
  if (this.mode == "pan") {
    this.pan.onDrag(ele, mdx, mdy);
  }
  if (this.mode == "zoomin") {
    this.zoomIn.onDrag(ele, mdx, mdy);
  }
}

function ArcIMS_onDragStop(ele, mx, my)
{
  if (this.mode == "pan") {
    this.pan.onDragStop(ele, mx, my);
  }
  if (this.mode == "zoomin") {
    this.zoomIn.onDragStop(ele, mx, my);
  }
}

function ArcIMS_onOverDragStart(ele, mx, my)
{
  this.over.onDragStart(ele, mx, my);
}

function ArcIMS_onOverDrag(ele, mdx, mdy)
{
  this.over.onDrag(ele, mdx, mdy);
}

function ArcIMS_onOverDragStop(ele, mx, my)
{
  this.over.onDragStop(ele, mx, my);
}

function ArcIMS_onOverClick(e) {
  this.over.onClick(e);
}

function ArcIMS_zoomTo(id) {
  xShow(this.mapLoadingDiv);
  xGetElementById(this.mapDiv).style.opacity = "0.6";
  this.legend.zoomTo(id);
}

function ArcIMS_setHisto(index, cellnumber) {
  if (cellnumber != null && cellnumber.length > 0) {
    this.boats[index] = cellnumber;
  } else {
    this.boats[index] = null;
  }
}

function ArcIMS_scroll() {
  if (this.scrollEnabled) {
    window.scrollTo(0, 100);
  }
}

function ArcIMS_printPDF(kml) {
  boats = new Array();
  boats[0] = xGetElementById('boat1');
  boats[1] = xGetElementById('boat2');
  
  if (boats[0].value == null || boats[0].value.length == 0) {
    return;
  }
  
  var params = "";
  for (i = 0; i < 2; i++) {
    if (boats[i].value != null && boats[i].value.length > 0) {
      if (params.length > 0) {
        params += "&";
      }
      params += "cell" + (i + 1) + "=" + boats[i].value;
      var id = boats[i].options[boats[i].selectedIndex].text;
      params += "&id" + (i + 1) + "=" + escape(id);
      var boat;
      var boatId;
      for (boatId in this.legend.boats) {
        boat = this.legend.boats[boatId];
        if (boat[3] != null && boat[3] != "none" && (boat[2] == id || boat[2] == " " + id)) {
          params += "&name" + (i + 1) + "=" + escape(boat[3]);
        }
      }
    }
  }
  
  params += "&start=" + getSeconds(this.start);
  params += "&stop=" + getSeconds(this.stop);
  
  if (kml == null || kml != 'kml') {
    open(this.printUrl + params);
  } else {
    open(this.kmlUrl + params);
  }
}

function ArcIMS_updatePositions() {
  var position = findPos(this.mapBorderDiv);
  if (typeof position === 'undefined') {
    return;
  }
  this.mapDivPosition.x = position.x;
  this.mapDivPosition.y = position.y;
  xMoveTo(this.mapDiv, this.mapDivPosition.x, this.mapDivPosition.y);
  xMoveTo(this.mapLoadingDiv, this.mapDivPosition.x, this.mapDivPosition.y + xHeight(this.mapLoadingDiv));
  
  var old = this.overDivPosition.clone();
  position = findPos(this.overBorderDiv);
  if (typeof position !== 'undefined') {
    this.overDivPosition.x = position.x;
    this.overDivPosition.y = position.y;
  }
  if (typeof this.overDivPosition !== 'undefined') {
    var zoom = this.overDivPosition;
    if (old != null) {
      zoom =  findPos(this.overZoomDiv);
      zoom.x += this.overDivPosition.x - old.x;
      zoom.y += this.overDivPosition.y - old.y;
    }
    xMoveTo(this.overZoomDiv, zoom.x, zoom.y);
    xMoveTo(this.overDiv, this.overDivPosition.x, this.overDivPosition.y);
    xMoveTo(this.overLoadingDiv, this.overDivPosition.x, this.overDivPosition.y + xHeight(this.overLoadingDiv));
  }
  
  xClip(this.overDiv, 0, xWidth(this.overDiv) - this.mapOffset.x, xHeight(this.overDiv) - this.mapOffset.y, 0);
  xClip(this.overZoomDiv, 0, xWidth(this.overDiv) - this.mapOffset.x, xHeight(this.overDiv) - this.mapOffset.y, 0);
}

ArcIMS.prototype.updateMap = ArcIMS_updateMap;
ArcIMS.prototype.updateOver = ArcIMS_updateOver;
ArcIMS.prototype.callback = ArcIMS_callback;
ArcIMS.prototype.callbackOver = ArcIMS_callbackOver;
ArcIMS.prototype.mapPan = ArcIMS_mapPan;
ArcIMS.prototype.mapZoomIn = ArcIMS_mapZoomIn;
ArcIMS.prototype.zoomOut = ArcIMS_zoomOut;
ArcIMS.prototype.zoom = ArcIMS_zoom;
ArcIMS.prototype.resetMap = ArcIMS_resetMap;
ArcIMS.prototype.setMode = ArcIMS_setMode;
ArcIMS.prototype.reset = ArcIMS_reset;
ArcIMS.prototype.onMapClick = ArcIMS_onMapClick;
ArcIMS.prototype.onMouseOver = ArcIMS_onMouseOver;
ArcIMS.prototype.onMouseOut = ArcIMS_onMouseOut;
ArcIMS.prototype.onMouseMove = ArcIMS_onMouseMove;
ArcIMS.prototype.onDragStart = ArcIMS_onDragStart;
ArcIMS.prototype.onDrag = ArcIMS_onDrag;
ArcIMS.prototype.onDragStop = ArcIMS_onDragStop;
ArcIMS.prototype.onOverDragStart = ArcIMS_onOverDragStart;
ArcIMS.prototype.onOverDrag = ArcIMS_onOverDrag;
ArcIMS.prototype.onOverDragStop = ArcIMS_onOverDragStop;
ArcIMS.prototype.onOverClick = ArcIMS_onOverClick;
ArcIMS.prototype.zoomTo = ArcIMS_zoomTo;
ArcIMS.prototype.swapService = ArcIMS_swapService;
ArcIMS.prototype.getImageXML = ArcIMS_getImageXML;
ArcIMS.prototype.onMapLoaded = ArcIMS_onMapLoaded;
ArcIMS.prototype.setAuto = ArcIMS_setAuto;
ArcIMS.prototype.autoUpdate = ArcIMS_autoUpdate;
ArcIMS.prototype.setHisto = ArcIMS_setHisto;
ArcIMS.prototype.scroll = ArcIMS_scroll;
ArcIMS.prototype.printPDF = ArcIMS_printPDF;
ArcIMS.prototype.updatePositions = ArcIMS_updatePositions;

// arcims-setup.js

ArcIMS.setup = function (params) {
  function param_default(pname, def) { 
    if (typeof params[pname] == "undefined") { 
      params[pname] = def;
    }
  };
  
  param_default("imageService", "bor");
  param_default("featureService", "bor_feat");
  
  param_default("envelopeMinX", 493000);
  param_default("envelopeMinY", 112000);
  param_default("envelopeMaxX", 565000);
  param_default("envelopeMaxY", 160000);
  
  param_default("mapDiv", "mapDiv");
  param_default("mapImg", "mapImg");
  param_default("imageSizeWidth", "600");
  param_default("imageSizeHeight", "400");
  
  param_default("overDiv", "overDiv");
  param_default("overImg", "overImg");
  param_default("overSizeWidth", "180");
  param_default("overSizeHeight", "120");
  
  param_default("mapBorderDiv", "mapBorderDiv");
  param_default("mapLoadingDiv", "mapLoadingDiv");
  param_default("mapZoomDiv", "mapZoomDiv");
  
  param_default("overZoomImg", "overZoomImg");
  param_default("overBorderDiv", "overBorderDiv");
  param_default("overLoadingDiv", "overLoadingDiv");
  param_default("overZoomDiv", "overZoomDiv");
  
  param_default("legendLayer1", "select_trace");
  param_default("legendLayer2", "select_point");
  
  param_default("legendDiv", "legendDiv");
  param_default("legendLoadingDiv", "legendLoadingDiv");
  param_default("legendFields", "CELLNUMBER ID NAME");
  param_default("legendOffset", 1000);
  
  param_default("histoDiv", "histoDiv");
  param_default("start", "start");
  param_default("stop", "stop");
  
  param_default("infoRT", "infoRT");
  param_default("infoHisto", "infoHisto");
  
  param_default("meteoLayer", "wind");
  param_default("meteoField", "DATE_TIME");
  param_default("meteoWhere", "STN LIKE 'AIG'");
  param_default("dateMeteo", "dateMeteo");
  
  param_default("listDiv", "listDiv");
  param_default("boatSelect", "boatSelect");
  
  param_default("buoyLayer", null);
    
  param_default("copyright", true);
  
  param_default("minimum", 100);
  param_default("autoTime", 120000);
  param_default("mobile", false);
  param_default("alert", true);
  param_default("labelRange", 4);
  
  param_default("scrollEnabled", false);
  param_default("mode", "zoomin");
  
  param_default("codeId", null);
  
  var agent = navigator.userAgent||navigator.vendor||window.opera;
  if (!params.mobile && 
      /android|avantgo|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(agent) || 
	  /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|e\-|e\/|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(di|rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|xda(\-|2|g)|yas\-|your|zeto|zte\-/i.test(agent.substr(0,4))) {
    if (confirm("Passer à la version mobile?")) {
	  window.location = "mobile.html";
	}
  }
  
  arcIMS = new ArcIMS(params);
  if (!params.mobile) {
    arcIMS.setMode(params.mode);
  }
  
  var rt = xGetElementById("rt");
  if (rt !== null) {
    xGetElementById("rt").className = "menuSelected";
  }
  
  // For real-time
  if (!arcIMS.listRT) {
    arcIMS.legend.update();
  }
  
  if (getArgs().id) {
    arcIMS.swapService('histo');
  } else {
    if (arcIMS.listRT) {
      xGetElementById("listFrame").src = arcIMS.listRT;
    }
    arcIMS.updateMap();
    arcIMS.updateOver();
  }
  
  // For history only (remove comment)
  arcIMS.swapService('histo');
}

// envelope.js
function Envelope(minx, miny, maxx, maxy) {
  this.minx = minx;
  this.miny = miny;
  this.maxx = maxx;
  this.maxy = maxy;
}

function Envelope_toXML() {
  return '<ENVELOPE minx="' + this.minx + '" miny="' + this.miny + '" maxx="' + this.maxx + '" maxy="' + this.maxy + '" />';
}

function Envelope_toString() {
  return 'minx="' + this.minx + '" miny="' + this.miny + '" maxx="' + this.maxx + '" maxy="' + this.maxy;
}

function Envelope_parseXML(xmlDocument) {
  var elements = xmlDocument.getElementsByTagName("ENVELOPE");
  if (elements.length > 0) {
    this.minx = getAttribute(elements[0], "minx");
    this.miny = getAttribute(elements[0], "miny");
    this.maxx = getAttribute(elements[0], "maxx");
    this.maxy = getAttribute(elements[0], "maxy");
  }
  for (var i = 1; i < elements.length; i++) {
    if (getAttribute(elements[i], "minx") < this.minx) {
      this.minx = getAttribute(elements[i], "minx");
    }
    if (getAttribute(elements[i], "miny") < this.miny) {
      this.miny = getAttribute(elements[i], "miny");
    }
    if (getAttribute(elements[i], "maxx") > this.maxx) {
      this.maxx = getAttribute(elements[i], "maxx");
    }
    if (getAttribute(elements[i], "maxy") > this.maxy) {
      this.maxy = getAttribute(elements[i], "maxy");
    }
  }
}

function Envelope_width() {
  return this.maxx - this.minx;
}

function Envelope_height() {
  return this.maxy - this.miny;
}

function Envelope_translate(x, y) {
  this.minx = parseFloat(this.minx) + x;
  this.miny = parseFloat(this.miny) + y;
  this.maxx = parseFloat(this.maxx) + x;
  this.maxy = parseFloat(this.maxy) + y;
}

function Envelope_resize(width, height) {
  var x = this.centerX();
  var y = this.centerY();
  this.minx = x - width / 2;
  this.miny = y - height / 2;
  this.maxx = x + width / 2;
  this.maxy = y + height / 2;
}

function Envelope_center(x, y) {
  this.translate(x - (parseFloat(this.minx) + parseFloat(this.maxx)) / 2, 
                 y - (parseFloat(this.miny) + parseFloat(this.maxy)) / 2);
}

function Envelope_expand(offset) {
  this.minx = parseFloat(this.minx) - offset;
  this.miny = parseFloat(this.miny) - offset;
  this.maxx = parseFloat(this.maxx) + offset;
  this.maxy = parseFloat(this.maxy) + offset;
}

function Envelope_clone() {
  return new Envelope(this.minx, this.miny, this.maxx, this.maxy);
}

function Envelope_toRectangle() {
  return this.minx + ' ' + this.miny + ';' +  
         this.minx + ' ' + this.maxy + ';' +  
         this.maxx + ' ' + this.maxy + ';' + 
         this.maxx + ' ' + this.miny + ';' + 
         this.minx + ' ' + this.miny;
}

function Envelope_toCenter() {
  return this.centerX() + ' ' + this.centerY();
}

function Envelope_centerX() {
  return (parseFloat(this.minx) + parseFloat(this.maxx)) / 2;
}

function Envelope_centerY() {
  return (parseFloat(this.miny) + parseFloat(this.maxy)) / 2;
}

function Envelope_limit(limitEnv, minimum) {
  if (this.width() > limitEnv.width()) {
    var deltaX = (this.width() - limitEnv.width()) / 2;
    this.minx += deltaX;
    this.maxx -= deltaX;
  }
  if (this.height() > limitEnv.height()) {
    var deltaY = (this.height() - limitEnv.height()) / 2;
    this.miny += deltaY;
    this.maxy -= deltaY;
  }
  if (this.width() < minimum) {
    var deltaX = (this.width() - minimum) / 2;
    this.minx += deltaX;
    this.maxx -= deltaX;
  }
  if (this.height() < minimum) {
    var deltaY = (this.height() - minimum) / 2;
    this.miny += deltaY;
    this.maxy -= deltaY;
  }
  
  var x = this.centerX();
  if (x < limitEnv.minx) {
    x = limitEnv.minx;
  }
  if (x > limitEnv.maxx) {
    x = limitEnv.maxx;
  }  
  var y = this.centerY();
  if (y < limitEnv.miny) {
    y = limitEnv.miny;
  }
  if (y > limitEnv.maxy) {
    y = limitEnv.maxy;
  }  
  this.center(x, y);
}

Envelope.prototype.toXML = Envelope_toXML;
Envelope.prototype.toString = Envelope_toString;
Envelope.prototype.parseXML = Envelope_parseXML;
Envelope.prototype.width = Envelope_width;
Envelope.prototype.height = Envelope_height;
Envelope.prototype.center = Envelope_center;
Envelope.prototype.translate = Envelope_translate;
Envelope.prototype.resize = Envelope_resize;
Envelope.prototype.expand = Envelope_expand;
Envelope.prototype.clone = Envelope_clone;
Envelope.prototype.toRectangle = Envelope_toRectangle;
Envelope.prototype.toCenter = Envelope_toCenter;
Envelope.prototype.centerX = Envelope_centerX;
Envelope.prototype.centerY = Envelope_centerY;
Envelope.prototype.limit = Envelope_limit;

// functions.js
// © 2005 LogiFleet SA / INSER SA
var arcIMS;

function setMode(aMode) {
  arcIMS.setMode(aMode);
}

function swapService(aService) {
  arcIMS.swapService(aService);
}

function callback() {
  arcIMS.callback();
}

function callbackOver() {
  arcIMS.callbackOver();
}

function legendCallback() {
  arcIMS.legend.callback();
}

function labelCallback() {
  arcIMS.label.callback();
}

function meteoCallback() {
  arcIMS.meteo.callback();
}

function onMapClick(e) {
  arcIMS.onMapClick(e);
}

function onMouseOver() {
  arcIMS.onMouseOver();
}

function onMouseOut() {
  arcIMS.onMouseOut();
}

function onMouseMove(e) {
  arcIMS.onMouseMove(e);
}

function onDragStart(ele, mx, my)
{
  arcIMS.onDragStart(ele, mx, my);
}

function onDrag(ele, mdx, mdy)
{
  arcIMS.onDrag(ele, mdx, mdy);
}

function onDragStop(ele, mx, my)
{
  arcIMS.onDragStop(ele, mx, my);
}

function onOverDragStart(ele, mx, my)
{
  arcIMS.onOverDragStart(ele, mx, my);
}

function onOverDrag(ele, mdx, mdy)
{
  arcIMS.onOverDrag(ele, mdx, mdy);
}

function onOverDragStop(ele, mx, my)
{
  arcIMS.onOverDragStop(ele, mx, my);
}

function onOverClick(e) {
  arcIMS.onOverClick(e);
}

function zoomTo(id) {
  arcIMS.zoomTo(id);
}

function zoomOut(x, y) {
  arcIMS.zoomOut(x, y);
}

function zoom(ratio) {
  arcIMS.zoom(undefined, undefined, ratio);
}

function refresh() {
  arcIMS.scroll();
  
  arcIMS.updateMap();
  arcIMS.updateOver();
}

function reset() {
  arcIMS.reset();
}

function onMapLoaded() {
  arcIMS.onMapLoaded();
}

function setAuto(aMode) {
  arcIMS.setAuto(aMode);
}

function autoUpdate() {
  arcIMS.autoUpdate();
}

function setHisto(index, cellnumber) {
  arcIMS.setHisto(index, cellnumber);
}

function setCode(codeId) {
  arcIMS.codeId = codeId;
}

function printPDF(kml) {
  arcIMS.printPDF(kml);
}

function updatePositions() {
  arcIMS.updatePositions();
}

// imagesize.js
// © 2005 LogiFleet SA / INSER SA
function ImageSize(width, height) {
  this.width = width;
  this.height = height;
}

function ImageSize_toXML() {
  return '<IMAGESIZE width="' + this.width + '" height="' + this.height + '" />';
}

function ImageSize_toString() {
  return 'width="' + this.width + '" height="' + this.height;
}

function ImageSize_parseXML(xmlDocument) {
  var element = xmlDocument.getElementsByTagName("IMAGESIZE")[0];
  this.width = getAttribute(element, "width");
  this.height = getAttribute(element, "height");
}

ImageSize.prototype.toXML = ImageSize_toXML;
ImageSize.prototype.toString = ImageSize_toString;
ImageSize.prototype.parseXML = ImageSize_parseXML;

// label.js
// © 2005 LogiFleet SA / INSER SA
var labelRequest;

function Label(arcIMS, layer, infoUrl, range) {
  this.arcIMS = arcIMS;
  this.layer = layer;
  this.infoUrl = infoUrl;
  this.range = range;
  this.labelDiv = xGetElementById("labelDiv");
  if (this.labelDiv === null) {
	if (this.arcIMS.mobile) {
		document.write('<div id="labelDiv" class="label" style="visibility: hidden;">');
		document.write('<table border="0" cellspacing="0" cellpadding="0">');
		document.write('<tr>');
		document.write('<td class="label">&nbsp;<span id="idValue"></span>&nbsp;</td>');
		document.write('</tr>');
		document.write('<tr>');
		document.write('<td class="label">&nbsp;<span id="speedValue"></span>&nbsp;</td>');
		document.write('</tr>');
		document.write('<tr>');
		document.write('<td class="label">&nbsp;<span id="mtimeValue"></span>&nbsp;</td>');
		document.write('</tr>');
		document.write('</table>');
		document.write('</div>');
	} else {
		document.write('<div id="labelDiv" class="label" style="visibility: hidden;">');
		document.write('<table border="0" cellspacing="0" cellpadding="0">');
		document.write('<tr>');
		document.write('<td class="label">&nbsp;<span id="idValue"></span>&nbsp;</td>');
		document.write('<td class="label" align="right">&nbsp;&nbsp;<span id="speedValue"></span></td>');
		document.write('</tr>');
		document.write('<tr>');
		document.write('<td class="label" colspan="2">&nbsp;<span id="nameValue"></span>&nbsp;</td>');
		document.write('</tr>');
		document.write('<tr>');
		document.write('<td class="label" colspan="2">&nbsp;<span id="mtimeValue"></span>&nbsp;</td>');
		document.write('</tr>');
		document.write('</table>');
		document.write('</div>');
	}
    this.labelDiv = xGetElementById("labelDiv");
  }
  this.labelDiv.style.opacity = "0.8";
  if (!this.arcIMS.listRT) {
    this.idValue = xGetElementById("idValue");
  }
  this.nameValue = xGetElementById("nameValue");
  this.speedValue = xGetElementById("speedValue");
  this.mtimeValue = xGetElementById("mtimeValue");
  this.codeTypeValue = xGetElementById("codeTypeValue");
  
  this.boats = new Array();
  this.selected = null;
}

function Label_update() {
  labelRequest = getXMLRequest();
  labelRequest.open("POST", this.arcIMS.catURL + this.arcIMS.featureService, true);
  if (!is_opera) {
    labelRequest.setRequestHeader("Content-Type", "text/xml");
  }
  labelRequest.onreadystatechange = labelCallback;
  var textXML = 
    '<ARCXML version="1.1">' +
    '<REQUEST>' +
    '<GET_FEATURES outputmode="newxml" geometry="true" envelope="false" >' +
    '<LAYER id="' + this.layer + '" />' +
    '<QUERY subfields="CELLNUMBER ID NAME STATUS SPEED MTIME CLASS #SHAPE#"';
  if (this.arcIMS.codeId) {
    textXML += ' where="CODE_ID = \'' + this.arcIMS.codeId + '\' AND MTIME &gt;= ' + getSeconds(this.arcIMS.start) + '" ';
  }
  textXML += 
    '>' +
    '</QUERY>' +
    '</GET_FEATURES>' +
    '</REQUEST>' +
    '</ARCXML>';
  labelRequest.send(textXML);
}

function Label_callback() {
  if (labelRequest.readyState == 4) {
    if (labelRequest.status == 200) {
      var xmlDocument = stringToDocument(labelRequest.responseText);
      if (contain(xmlDocument, "ERROR")) {
        error(xmlDocument);
      } else if (contain(xmlDocument, "FEATURES") && !contain(xmlDocument, "ENVELOPE")) {
        var features = xmlDocument.getElementsByTagName("FEATURE");
        this.boats = new Array();
        for (var i = 0; i < features.length; i++) {
          var fields = features[i].getElementsByTagName("FIELD");
          var cellnumber;
          var idLabel;
          var nameLabel;
          var status;
          var speed;
          var mtime;
          var classId;
          for (var j = 0; j < fields.length; j++) {
            var name = fields[j].attributes.getNamedItem("name").nodeValue;
            if (name.indexOf("CELLNUMBER") != -1) {
              cellnumber = fields[j].attributes.getNamedItem("value").nodeValue;
            }
            if (name.indexOf("ID") != -1) {
              idLabel = fields[j].attributes.getNamedItem("value").nodeValue;
            }
            if (name.indexOf("NAME") != -1) {
              nameLabel = fields[j].attributes.getNamedItem("value").nodeValue;
            }
            if (name.indexOf("STATUS") != -1) {
              status = fields[j].attributes.getNamedItem("value").nodeValue;
            }
            if (name.indexOf("SPEED") != -1) {
              speed = fields[j].attributes.getNamedItem("value").nodeValue;
            }
            if (name.indexOf("MTIME") != -1) {
              mtime = fields[j].attributes.getNamedItem("value").nodeValue;
            }
            if (name.indexOf("CLASS") != -1) {
              classId = fields[j].attributes.getNamedItem("value").nodeValue;
            }
          }
          if (typeof boatData !== 'undefined') {
            var boat = boatData[idLabel];
            if (boat != null) {
              idLabel = boat[0];
              if (boat[1].length > 0) {
                nameLabel = boat[1];
              }
            }
          }
          fields = features[i].getElementsByTagName("MULTIPOINT")[0].getElementsByTagName("POINT")[0].attributes;
          var x = fields.getNamedItem("x").nodeValue;
          var y = fields.getNamedItem("y").nodeValue;
          this.boats.push([x, y, cellnumber, idLabel, nameLabel, status, speed, formatDate(mtime * 1000), classId]);
        }
      }
    }
  }
}

function Label_show(evt) {
  if (this.arcIMS.service == "histo") {
    this.selected = null;
    xHide(this.labelDiv);
    return;
  }
  var boatX;
  var boatY;
  var boat;
  for (var i = 0; i < this.boats.length; i++) {
    boatX = (this.boats[i][0] - this.arcIMS.envelope.minx) * this.arcIMS.imageSize.width / this.arcIMS.envelope.width();
    boatY = this.arcIMS.imageSize.height * (1 - (this.boats[i][1] - this.arcIMS.envelope.miny) / this.arcIMS.envelope.height());
    if (Math.abs(evt.offsetX - boatX) < this.range && 
        Math.abs(evt.offsetY - boatY) < this.range) {
      boat = this.boats[i];
      break;
    }
  }
  if (boat != null) {
    if (this.idValue) {
      this.idValue.innerHTML = boat[3];
      if (this.idValue.innerHTML.charAt(0) == ' ') {
        this.idValue.innerHTML = this.idValue.innerHTML.substr(1);
      }
    }
	if (this.nameValue !== null) {
		this.nameValue.innerHTML = boat[4];
	}
    this.speedValue.innerHTML = Math.round(boat[6] / 0.1852, 1) / 10 + "&nbsp;n&oelig;uds";
    this.mtimeValue.innerHTML = boat[7];
    var status = new Number(boat[5]);
    var color = "#2ECB00";
    if (status == 14 || status > 128) {
      color = "#0000FF";
    } else if (status == 13) {
      color = "#E11A1A";
    }
    if (boat[8] != "M1" && boat[8] != "M2") {
      if (boat[6] >= 15) {
        color = "#E11A1A";
      }
    } else {
      if (boat[6] >= 23) {
        color = "#E11A1A";
      }
    }
    if (this.codeTypeValue !== null) {
      if (boat[2].length > 3 && boat[2].substr(0, 3) == "MMT") {
        this.codeTypeValue.innerHTML = "balise personnelle";
        this.speedValue.innerHTML = "";
        color = "#FF9000";
      } else {
        this.codeTypeValue.innerHTML = "balise officielle";
      }
    }
    xBackground(this.labelDiv, color);
    xMoveTo(this.labelDiv, evt.pageX + 3, evt.pageY - 3 - xHeight(this.labelDiv));
    this.selected = boat[2];
    xShow(this.labelDiv);
  } else {
    this.hide();
  }
}

function Label_hide() {
  this.selected = null;
  xHide(this.labelDiv);
}

function Label_info() {
  if (this.selected != null) {
    launch(this.infoUrl + this.selected.substr(1));
  }
}

Label.prototype.update = Label_update;
Label.prototype.callback = Label_callback;
Label.prototype.show = Label_show;
Label.prototype.hide = Label_hide;
Label.prototype.info = Label_info;

// legen.js
// © 2005 LogiFleet SA / INSER SA
var legendRequest;

function Legend(arcIMS, layer, fields, legendDiv, legendLoadingDiv, offset) {
  this.arcIMS = arcIMS;
  this.layer = layer;
  this.fields = fields;
  this.legendDiv = legendDiv;
  this.offset = offset;
  if (!this.arcIMS.listRT) {
    this.legendLoadingDiv = legendLoadingDiv;
    this.boat1 = xGetElementById("boat1");
    this.boat2 = xGetElementById("boat2");
  }
  this.boats = new Array();
}

function Legend_update() {
  legendRequest = getXMLRequest();
  legendRequest.open("POST", this.arcIMS.catURL + this.arcIMS.featureService, true);
  if (!is_opera) {
    legendRequest.setRequestHeader("Content-Type", "text/xml");
  }
  legendRequest.onreadystatechange = legendCallback;
  var textXML = 
    '<ARCXML version="1.1">' +
    '<REQUEST>' +
    '<GET_FEATURES outputmode="newxml" geometry="false" envelope="false" >' +
    '<LAYER id="' + this.layer + '" />' +
    '<QUERY subfields="OBJECTID ' + this.fields + '"';
  if (this.arcIMS.codeId) {
    textXML += ' where="CODE_ID = \'' + this.arcIMS.codeId + '\' AND MTIME &gt;= ' + getSeconds(this.arcIMS.start) + '" ';
  }
  textXML += 
    '>' +
    '</QUERY>' +
    '</GET_FEATURES>' +
    '</REQUEST>' +
    '</ARCXML>';
  legendRequest.send(textXML);
}

function Legend_callback() {
  if (legendRequest.readyState == 4) {
    if (legendRequest.status == 200) {
      var xmlDocument = stringToDocument(legendRequest.responseText);
      var fieldArray = this.fields.split(" ");
      if (contain(xmlDocument, "ERROR")) {
        error(xmlDocument);
      } else if (contain(xmlDocument, "FEATURES") && !contain(xmlDocument, "ENVELOPE")) {
        var features = xmlDocument.getElementsByTagName("FEATURE");
        var ids = new Array();
        for (var i = 0; i < features.length; i++) {
          var fields = features[i].getElementsByTagName("FIELD");
          var oid;
          var cell;
          var id;
          var name;
          for (var j = 0; j < fields.length; j++) {
            var fieldName = fields[j].attributes.getNamedItem("name").nodeValue;
            if (fieldName.indexOf("OBJECTID") != -1) {
              oid = fields[j].attributes.getNamedItem("value").nodeValue;
            } else if (fieldName.indexOf(fieldArray[0]) != -1) {
              cell = fields[j].attributes.getNamedItem("value").nodeValue;
            } else if (fieldName.indexOf(fieldArray[1]) != -1) {
              id = fields[j].attributes.getNamedItem("value").nodeValue;
            } else if (fieldName.indexOf(fieldArray[2]) != -1) {
              name = fields[j].attributes.getNamedItem("value").nodeValue;
            }
          }
          if (typeof boatData !== 'undefined') {
            var boat = boatData[id];
            if (boat != null) {
              if (boat[0].length > 0) {
                id = boat[0];
              }
              if (boat[1].length > 0) {
                name = boat[1];
              }
            }
            ids[i] = id;
            this.boats[id] = [oid, cell, id, name, boat];
          }
        }
        
        var boat;
        if (typeof boatData !== 'undefined') {
          for (id in boatData) {
            boat = boatData[id];
            if (this.boats[boat[0]] == null) {
              if (boat[5] != null && boat[5].length > 0) {
                ids[ids.length] = boat[0];
                this.boats[boat[0]] = [0, boat[5], boat[0], boat[1], boat];
              }
            }
          }
        }
        
        ids.sort();

        var table = '<table width="160">';
        for (var i = 0; i < ids.length; i++) {
          boat = this.boats[ids[i]];
          table += '<tr><td>';
          if (boat[4] != null && boat[4][5] != null && boat[4][5].length > 0) {
            table += '<span class="legendLink" href="#" title="' + boat[3] + '">' + boat[2] + '</span>';
          } else {
            table += '<a class="legendLink" href="javascript:zoomTo(\'' + boat[1] + '\')" title="' + boat[3] + '">' + boat[2] + '</a>';
          }
          table += '</td>';
          if (boat[4] != null && boat[4][2] != null && boat[4][2].length > 0) {
            table += '<td><a class="legendLink" target="_new" href="' + boat[4][2] + '" title="' + boat[4][4] + '">' + boat[4][3] + '</a></td>';
          }
          table += '</tr>';
          if (this.boat1 !== null) {
            this.boat1.options[this.boat1.length] = new Option(boat[2], boat[1]);
          }
          if (this.boat2 !== null) {
            this.boat2.options[this.boat2.length] = new Option(boat[2], boat[1]);
          }
        }

        table += "</table>";
        if (this.legendDiv !== null) {
          this.legendDiv.innerHTML = table;
        }
        
        if (this.arcIMS.service == "rt") {
          xShow(this.legendDiv);
        }
        xHide(this.legendLoadingDiv);
      } else if (contain(xmlDocument, "FEATURES") && contain(xmlDocument, "ENVELOPE")) {
        this.arcIMS.envelope.parseXML(xmlDocument);
        this.arcIMS.envelope.expand(this.offset);
        this.arcIMS.updateMap();
      } else {
        this.arcIMS.updateMap();
      }
    }
  }
}

function Legend_zoomTo(id) {
  var queryString = "";
  var splitString = id.toString().split(",");
  for (var i = 0; i < splitString.length; i++) {
    if (i > 0) {
      queryString += ",";
    }
    queryString += "\'" + splitString[i] + "\'";
  }
  
  if (this.arcIMS.selected == queryString) {
    this.arcIMS.selected = null;
    this.arcIMS.updateMap();
    return;
  }
  
  this.arcIMS.selected = queryString;
  
  legendRequest = getXMLRequest();
  legendRequest.open("POST", this.arcIMS.catURL + this.arcIMS.featureService, true);
  if (!is_opera) {
    legendRequest.setRequestHeader("Content-Type", "text/xml");
  }
  legendRequest.onreadystatechange = legendCallback;
  var textXML = 
    '<ARCXML version="1.1">' +
    '<REQUEST>' +
    '<GET_FEATURES outputmode="newxml" geometry="false" envelope="true" >' +
    '<LAYER id="' + this.layer + '" />' +
    '<QUERY subfields="#SHAPE#" where="CELLNUMBER IN (' + this.arcIMS.selected + ')';
  if (this.arcIMS.codeId) {
    textXML += ' AND CODE_ID = \'' + this.arcIMS.codeId + '\' AND MTIME &gt;= ' + getSeconds(this.arcIMS.start) + '';
  }
  textXML += '">' +
    '</QUERY>' +
    '</GET_FEATURES>' +
    '</REQUEST>' +
    '</ARCXML>';
  legendRequest.send(textXML);
}

function Legend_visibility(show) {
  var value = "none";
  if (show) {
    value = "block";
  }
  xDisplay(this.legendDiv, value);
}

Legend.prototype.update = Legend_update;
Legend.prototype.callback = Legend_callback;
Legend.prototype.zoomTo = Legend_zoomTo;
Legend.prototype.visibility = Legend_visibility;

// meteo.js
// © 2006 LogiFleet SA / INSER SA
var meteoRequest;

function Meteo(arcIMS, layer, field, where, meteoDiv, dateMeteo) {
  this.arcIMS = arcIMS;
  this.layer = layer;
  this.field = field;
  this.where = where;
  this.meteoDiv = meteoDiv;
  this.dateMeteo = dateMeteo;
}

function Meteo_update() {
  if (this.layer == null || this.layer.length == 0) {
    return;
  }
  meteoRequest = getXMLRequest();
  meteoRequest.open("POST", this.arcIMS.catURL + this.arcIMS.featureService, true);
  if (!is_opera) {
    meteoRequest.setRequestHeader("Content-Type", "text/xml");
  }
  meteoRequest.onreadystatechange = meteoCallback;
  var textXML = 
    '<ARCXML version="1.1">' +
    '<REQUEST>' +
    '<GET_FEATURES outputmode="newxml" geometry="false" envelope="false" >' +
    '<LAYER id="' + this.layer + '" />' +
    '<QUERY subfields="OBJECTID ' + this.field + '"';
  if (this.where != null) {
    textXML += ' where="' + this.where + '" ';
  }
  textXML += 
    '>' +
    '</QUERY>' +
    '</GET_FEATURES>' +
    '</REQUEST>' +
    '</ARCXML>';
  meteoRequest.send(textXML);
}

function Meteo_callback() {
  if (meteoRequest.readyState == 4) {
    if (meteoRequest.status == 200) {
      var xmlDocument = stringToDocument(meteoRequest.responseText);
      if (contain(xmlDocument, "ERROR")) {
        error(xmlDocument);
      } else if (contain(xmlDocument, "FEATURES") && !contain(xmlDocument, "ENVELOPE")) {
        var features = xmlDocument.getElementsByTagName("FEATURE");
        var newDate = "";
        for (var i = 0; i < features.length; i++) {
          var fields = features[i].getElementsByTagName("FIELD");
          for (var j = 0; j < fields.length; j++) {
            var name = fields[j].attributes.getNamedItem("name").nodeValue;
            if (name.indexOf(this.field) != -1) {
              newDate = fields[j].attributes.getNamedItem("value").nodeValue;
            }
          }
        }
        
        if (newDate.length > 0) {
          newDate = formatDate(newDate);
          if (this.dateMeteo.innerHTML != newDate) {
            if (this.dateMeteo.innerHTML.length > 0) {
              this.arcIMS.updateOver();
            }
            this.dateMeteo.innerHTML = newDate;
          }
        } else {
          this.dateMeteo.innerHTML = "";
        }
      }
    }
  }
}

function Meteo_visibility(bShow) {
  if (bShow) {
    xDisplay(this.meteoDiv, "block");
  } else {
    xDisplay(this.meteoDiv, "none");
  }
}

Meteo.prototype.update = Meteo_update;
Meteo.prototype.callback = Meteo_callback;
Meteo.prototype.visibility = Meteo_visibility;

// over.js
// © 2005 LogiFleet SA / INSER SA
function Over(arcIMS, overDiv, overDivPosition, overZoomDiv) {
  this.arcIMS = arcIMS;
  this.overDiv = overDiv;
  this.overDivPosition = overDivPosition;
  this.overZoomDiv = overZoomDiv;
  
  this.mapOffset = new Point(0, 0);
  if (is_ie) {
    this.mapOffset = new Point(0, 4);
  }
  
  if (this.overZoomDiv !== null) {
    xEnableDrag(this.overZoomDiv, onOverDragStart, onOverDrag, onOverDragStop);
    this.overZoomDiv.style.cursor = "move";
  }
  if (this.overDiv !== null) {
    xAddEventListener(this.overDiv, "click", onOverClick);
    this.overDiv.style.cursor = "crosshair";
  }
}

function Over_onDragStart(ele, mx, my)
{
  if (xWidth(this.overZoomDiv) > 25) {
    this.maxx = this.overDivPosition.x + xWidth(this.overDiv) - 25;
    this.minx = this.overDivPosition.x - xWidth(this.overZoomDiv) + 25;
  } else {
    this.maxx = this.overDivPosition.x + xWidth(this.overDiv) - xWidth(this.overZoomDiv);
    this.minx = this.overDivPosition.x;
  }
  if (xHeight(this.overZoomDiv) > 25) {
    this.maxy = this.overDivPosition.y + xHeight(this.overDiv) - 25;
    this.miny = this.overDivPosition.y - xHeight(this.overZoomDiv) + 25;
  } else {
    this.maxy = this.overDivPosition.y + xHeight(this.overDiv) - xHeight(this.overZoomDiv);
    this.miny = this.overDivPosition.y;
  }
  this.overZoomDiv.tx = xLeft(this.overZoomDiv);
  this.overZoomDiv.ty = xTop(this.overZoomDiv);
}

function Over_onDrag(ele, mdx, mdy)
{
  this.overZoomDiv.tx += mdx;
  this.overZoomDiv.ty += mdy;
  xMoveTo(this.overZoomDiv, 
          Math.max(Math.min(this.overZoomDiv.tx, this.maxx), this.minx), 
          Math.max(Math.min(this.overZoomDiv.ty, this.maxy), this.miny));
   xClip(this.overZoomDiv, 
         this.overDivPosition.y - xTop(this.overZoomDiv), 
         this.overDivPosition.x + xWidth(this.overDiv) - xLeft(this.overZoomDiv) - this.mapOffset.x, 
         this.overDivPosition.y + xHeight(this.overDiv) - xTop(this.overZoomDiv) - this.mapOffset.y, 
         this.overDivPosition.x - xLeft(this.overZoomDiv));
}

function Over_onDragStop(ele, mx, my)
{
  var x = this.arcIMS.initEnvelope.minx + this.arcIMS.initEnvelope.width() / xWidth(this.overDiv) * 
          (xLeft(this.overZoomDiv) - this.overDivPosition.x + xWidth(this.overZoomDiv) / 2);
  var y = this.arcIMS.initEnvelope.maxy - this.arcIMS.initEnvelope.height() / xHeight(this.overDiv) * 
          (xTop(this.overZoomDiv) - this.overDivPosition.y + xHeight(this.overZoomDiv) / 2);
  this.arcIMS.envelope.center(x, y);
  
  this.arcIMS.updateMap();
}

function Over_onClick(e) {
  var e = new xEvent(e);
  
  var x = this.arcIMS.initEnvelope.minx + this.arcIMS.initEnvelope.width() / xWidth(this.overDiv) * e.offsetX;
  var y = this.arcIMS.initEnvelope.maxy - this.arcIMS.initEnvelope.height() / xHeight(this.overDiv) * e.offsetY;
  this.arcIMS.envelope.center(x, y);
  
  this.arcIMS.updateMap();
}

Over.prototype.onDragStart = Over_onDragStart;
Over.prototype.onDrag = Over_onDrag;
Over.prototype.onDragStop = Over_onDragStop;
Over.prototype.onClick = Over_onClick;

// pan.js
// © 2005 LogiFleet SA / INSER SA
function Pan(arcIMS, mapDiv, mapDivPosition) {
  this.arcIMS = arcIMS;
  this.mapDiv = mapDiv;
  this.mapDivPosition = mapDivPosition;
  
  this.mapOffset = new Point(0, 0);
  if (is_ie) {
    this.mapOffset = new Point(0, 4);
  }
  this.maxx = xWidth(this.mapDiv) + this.mapDivPosition.x - 100;
  this.minx = 100 - xWidth(this.mapDiv) - this.mapDivPosition.x;
  this.maxy = xHeight(this.mapDiv) + this.mapDivPosition.y - 100;
  this.miny = 100 - xHeight(this.mapDiv) - this.mapDivPosition.y;
}

function Pan_onDragStart(ele, mx, my)
{
  this.mapDiv.tx = xLeft(this.mapDiv);
  this.mapDiv.ty = xTop(this.mapDiv);
}

function Pan_onDrag(ele, mdx, mdy)
{
  this.mapDiv.tx += mdx;
  this.mapDiv.ty += mdy;
  xMoveTo(ele, 
          Math.max(Math.min(this.mapDiv.tx, this.maxx), this.minx), 
          Math.max(Math.min(this.mapDiv.ty, this.maxy), this.miny));
  xClip(this.mapDiv, 
        this.mapDivPosition.y - xTop(this.mapDiv), 
        xWidth(this.mapDiv) - xLeft(this.mapDiv) + this.mapDivPosition.x - this.mapOffset.x, 
        xHeight(this.mapDiv) - xTop(this.mapDiv) + this.mapDivPosition.y - this.mapOffset.y, 
        this.mapDivPosition.x - xLeft(this.mapDiv));
}

function Pan_onDragStop(ele, mx, my)
{
  this.arcIMS.mapPan(this.mapDiv.tx - this.mapDivPosition.x, this.mapDiv.ty - this.mapDivPosition.y);
}

Pan.prototype.onDragStart = Pan_onDragStart;
Pan.prototype.onDrag = Pan_onDrag;
Pan.prototype.onDragStop = Pan_onDragStop;

// point.js
// © 2005 LogiFleet SA / INSER SA
function Point(x, y) {
  this.x = x;
  this.y = y;
}

function Point_clone()
{
  return new Point(this.x, this.y);
}

Point.prototype.clone = Point_clone;

// util.js
// © 2005 LogiFleet SA / INSER SA
function getAttribute(element, attributeName) { 
  return element.attributes.getNamedItem(attributeName).nodeValue;
}

function stringToDocument(xmlText) {
  xmlText = xmlText.replace(/&/g, "&amp;");
  if (window.ActiveXObject && !window.DOMParser) { //IE
    var doc = new ActiveXObject("Microsoft.XMLDOM");
    doc.async="false";
    doc.loadXML(xmlText);
    return doc
  }
  if (window.DOMParser) { //FF,OP
    return new DOMParser().parseFromString(xmlText, "text/xml");
  } 
  if (document.implementation && document.implementation.createDocument) { //KQ
    var doc = document.implementation.createDocument("", "", null);
    doc.loadXML(xmlText);
    return doc;
  }
  if (navigator.userAgent && navigator.vendor && 
      (navigator.userAgent.toLowerCase().indexOf("applewebkit") != -1 || 
       navigator.vendor.indexOf("Apple") != -1)) { //SF
      var xmlhttp = new XMLHttpRequest();
      xmlhttp.open("GET", "data:text/xml;charset=utf-8," + encodeURIComponent(str), false);
      xmlhttp.send(null);
      return xmlhttp.responseXML;
  }
  alert("Sorry but your browser is not supported!");
}

function UTF2HTML() {
}

function contain(xmlDocument, elementName) {
  return count(xmlDocument, elementName) > 0;
}

function count(xmlDocument, elementName) {
  return xmlDocument.getElementsByTagName(elementName).length;
}

function getXMLRequest() {
  if (window.ActiveXObject && !window.XMLHttpRequest) {
    return new ActiveXObject("Microsoft.XMLHTTP");
  }
  if (window.XMLHttpRequest) {
    return new XMLHttpRequest();
  }
}

function error(xmlDocument) {
  alert(xmlDocument.getElementsByTagName("ERROR")[0].childNodes[0].nodeValue);
}

function getSeconds(element) {
  var dateTime = element.value.split(" ");
  var dateOnly = dateTime[0].split(".");
  var timeOnly = dateTime[1].split(":");
  var dateObject = new Date(dateOnly[2], dateOnly[1] - 1, dateOnly[0], timeOnly[0], timeOnly[1]);
  return Math.round(Date.UTC(dateObject.getUTCFullYear(), dateObject.getUTCMonth(), dateObject.getUTCDate(), 
                             dateObject.getUTCHours(), dateObject.getUTCMinutes()) / 1000);
}

function formatDate(milliseconds) {
  var newDate = new Date(Number(milliseconds));
  var day = newDate.getDate().toString();
  if (day.length == 1) {
    day = "0" + day;
  }
  var month = (newDate.getMonth() + 1).toString();
  if (month.length == 1) {
    month = "0" + month;
  }
  var hours = newDate.getHours().toString();
  if (hours.length == 1) {
    hours = "0" + hours;
  }
  var minutes = newDate.getMinutes().toString();
  if (minutes.length == 1) {
    minutes = "0" + minutes;
  }
  return day + "." + month + "." + newDate.getFullYear() + " " + hours + ":" + minutes;
}

function getArgs() {
  var args = new Object();
  var query = location.search.substring(1);
  var pairs = query.split("&");
  for(var i = 0; i < pairs.length; i++) {
    var pos = pairs[i].indexOf('=');
    if (pos == -1) continue;
    var argname = pairs[i].substring(0,pos);
    var value = pairs[i].substring(pos+1);
    args[argname] = unescape(value.replace(/\+/g, " "));
  }
  return args;
}

function launch(url) {
  if (window.top.opener) {
    if ((typeof window.top.opener != 'undefined') && !(window.top.opener.closed)) {
      window.top.opener.location.href=url;
    } else {
      window.open(url);
    }          
  } else {
    if (window.top.opener != null) {
      window.top.opener.location.href=url;
    } else {
      window.open(url);
    }
  }
}

function findPos(obj) {
  if (obj === null) {
    return;
  }
  var point = new Point(0, 0);
  if (obj.offsetParent) {
    point.x = obj.offsetLeft
    point.y = obj.offsetTop
    while (obj = obj.offsetParent) {
      point.x += obj.offsetLeft
      point.y += obj.offsetTop
    }
  }
  return point;
}

//zoomin.js
// © 2005 LogiFleet SA / INSER SA
function ZoomIn(arcIMS, mapDiv, mapDivPosition, zoomDiv) {
  this.arcIMS = arcIMS;
  this.mapDiv = mapDiv;
  this.mapDivPosition = mapDivPosition;
  this.zoomDiv = zoomDiv;
  
  this.mapOffset = new Point(0, 0);
  if (is_ie) {
    this.mapOffset = new Point(4, 4);
  }
}

function ZoomIn_onDragStart(ele, mx, my)
{
  this.zoomDiv.tx = mx;
  this.zoomDiv.ty = my;
  this.zoomDiv.tw = 0;
  this.zoomDiv.th = 0;
  xMoveTo(this.zoomDiv, mx, my);
  xResizeTo(this.zoomDiv, 2, 2);
  xVisibility(this.zoomDiv, true);
}

function ZoomIn_onDrag(ele, mdx, mdy)
{
  this.zoomDiv.tw += mdx;
  this.zoomDiv.th += mdy;
  var width = Math.max(Math.abs(this.zoomDiv.tw), 2);
  var height = Math.max(Math.abs(this.zoomDiv.th), 2);
  if (this.zoomDiv.tw < 0) {
    xLeft(this.zoomDiv, Math.max(this.zoomDiv.tx + this.zoomDiv.tw, xLeft(this.mapDiv)));
    width = Math.min(width, this.zoomDiv.tx - xLeft(this.zoomDiv));
  } else {
    width = Math.min(width, xLeft(this.mapDiv) + xWidth(this.mapDiv) - this.zoomDiv.tx - this.mapOffset.x);
  }
  if (this.zoomDiv.th < 0) {
    xTop(this.zoomDiv, Math.max(this.zoomDiv.ty + this.zoomDiv.th, xTop(this.mapDiv)));
    height = Math.min(height, this.zoomDiv.ty - xTop(this.zoomDiv));
  } else {
    height = Math.min(height, xTop(this.mapDiv) + xHeight(this.mapDiv) - this.zoomDiv.ty - this.mapOffset.y);
  }
  xResizeTo(this.zoomDiv, width, height);
}

function ZoomIn_onDragStop(ele, mx, my)
{
  xVisibility(this.zoomDiv, false);
  this.arcIMS.mapZoomIn(xLeft(this.zoomDiv) - xLeft(this.mapDiv), xTop(this.zoomDiv) - xTop(this.mapDiv), 
                     xWidth(this.zoomDiv), xHeight(this.zoomDiv));
}

ZoomIn.prototype.onDragStart = ZoomIn_onDragStart;
ZoomIn.prototype.onDrag = ZoomIn_onDrag;
ZoomIn.prototype.onDragStop = ZoomIn_onDragStop;

// touch.js
// © 2011 INSER SA

/**
 * Object to manage the touch interface (iPhone, Android, ...).
 */
function Touch(arcIMS) {
  this.arcIMS = arcIMS;
  this.mapDiv = this.arcIMS.mapDiv;
  this.mapImg = this.arcIMS.mapImg;
  
  this.listDiv = this.arcIMS.listDiv;
  this.boatSelect = this.arcIMS.boatSelect;
  this.label = this.arcIMS.label;
  
  this.dragging = false;
  this.sizing = false;
  this.list = false;
  
  // Initialize the position
  this.originalPosition = findPos(this.mapDiv);
  this.originalSize = new Point(xWidth(this.mapDiv), xHeight(this.mapDiv));
  this.reset();
  
  // Configure the event consumers
  this.mapDiv.ontouchstart = touchStart;
  this.mapDiv.ontouchmove = touchMove;
  this.mapDiv.ontouchend = touchEnd;
  this.mapDiv.ongesturestart = gestureStart;
  this.mapDiv.ongesturechange = gestureChange;
  this.mapDiv.ongestureend = gestureEnd;
}

/**
 * Start of a touch.
 */
function Touch_touchStart(evt) {
  //console.log("Touch_touchStart");
  this.label.hide();
  if (evt.changedTouches.length > 0) {
    this.dragging = new Point(
        evt.changedTouches[0].pageX - xLeft(this.mapDiv), 
        evt.changedTouches[0].pageY - xTop(this.mapDiv));
  }
}

/**
 * Change of a touch.
 */
function Touch_touchMove(evt) {
  //console.log("Touch_touchMove");
  evt.preventDefault();
  if (this.dragging && !this.sizing && evt.changedTouches.length > 0) {
    //console.log((evt.changedTouches[0].pageX - this.dragging.x) + " " + (evt.changedTouches[0].pageY - this.dragging.y));
    xMoveTo(this.mapDiv, evt.changedTouches[0].pageX - this.dragging.x, 
      evt.changedTouches[0].pageY - this.dragging.y);
  }
}

/**
 * End of a touch.
 */
function Touch_touchEnd(evt) {
  //console.log("Touch_touchEnd");
  if (this.dragging && !this.sizing) {
    //console.log("Drag: " + xLeft(this.mapDiv) + " " + xTop(this.mapDiv));
    var x = xLeft(this.mapDiv) - this.originalPosition.x;
    var y = xTop(this.mapDiv) - this.originalPosition.y;
    if (Math.abs(x) > 3 || Math.abs(y) > 3) {
      //console.log("mapPan: " + x + ", " + y);
      this.arcIMS.mapPan(x, y);
      this.dragging = false;
      window.scrollTo(0, 1);
    } else {
      //console.log("touch");
      var event = new xEvent(evt);
      event.offsetX = evt.changedTouches[0].pageX - xLeft(this.mapDiv);
      event.offsetY = evt.changedTouches[0].pageY - xTop(this.mapDiv);
      event.pageX = evt.changedTouches[0].pageX;
      event.pageY = evt.changedTouches[0].pageY;
      this.label.show(event);
    }
  }
}

/**
 * Start of a gesture.
 */
function Touch_gestureStart(evt) {
  this.label.hide();
  this.dragging = false;
  // Save the original size
  this.sizing = new Point(xWidth(this.mapDiv), xHeight(this.mapDiv));
}

/**
 * Change of a gesture.
 */
function Touch_gestureChange(evt) {
  if (this.sizing) {
    // Change size using the scale property
    xResizeTo(this.mapImg, this.sizing.x * evt.scale, this.sizing.y * evt.scale);
    xMoveTo(this.mapDiv,
      this.originalPosition.x + (this.originalSize.x - xWidth(this.mapImg)) / 2, 
      this.originalPosition.y + (this.originalSize.y - xHeight(this.mapImg)) / 2);
  }
}

/**
 * End of a gesture.
 */
function Touch_gestureEnd(evt) {
  if (this.sizing) {
    // Zoom to the scale property
    this.zoom(1/evt.scale);
    this.dragging = false;
    this.sizing = false;
    this.reset();
  }
}

/**
 * Reset the map to the original position and size.
 */
function Touch_reset() {
  this.label.hide();
  xMoveTo(this.mapDiv, this.originalPosition.x, this.originalPosition.y);
  xResizeTo(this.mapImg, this.originalSize.x, this.originalSize.y);
  window.scrollTo(0, 1);
}

/**
 * Zoom to a specified zoom ratio.
 */
function Touch_zoom(ratio) {
  this.label.hide();
  if (this.list === false) {
    this.arcIMS.zoom(undefined, undefined, ratio);
  }
}

/**
 * Zoom to the selected boat.
 */
function Touch_zoomTo() {
  this.arcIMS.zoomTo(this.boatSelect.options[this.boatSelect.selectedIndex].value);
  this.togleList();
}

/**
 * Toggle the boat's list and fill the list if needed.
 */
function Touch_togleList() {
  this.label.hide();
  if (this.list === false) {
    while (this.boatSelect.length > 1) {
      this.boatSelect.remove(1);
    }
    
    var boat;
    var boats = new Array();
    var names = new Array();
    for (var i = 0; i < this.label.boats.length; i++) {
      boat = this.label.boats[i];
      boats[boat[3].toUpperCase()] = boat;
      names[i] = boat[3].toUpperCase();
    }
    
    names.sort();
    
    for (var i = 0; i < names.length; i++) {
      boat = boats[names[i]];
      this.boatSelect.add(new Option(boat[3], boat[2], false, false), null);
    }
    
    this.list = true;
    xShow(this.listDiv);
  } else {
    this.list = false;
    xHide(this.listDiv);
  }
}

Touch.prototype.touchStart = Touch_touchStart;
Touch.prototype.touchMove = Touch_touchMove;
Touch.prototype.touchEnd = Touch_touchEnd;
Touch.prototype.gestureStart = Touch_gestureStart;
Touch.prototype.gestureChange = Touch_gestureChange;
Touch.prototype.gestureEnd = Touch_gestureEnd;
Touch.prototype.reset = Touch_reset;
Touch.prototype.togleList = Touch_togleList;
Touch.prototype.zoom = Touch_zoom;
Touch.prototype.zoomTo = Touch_zoomTo;

var touch;

function touchStart(evt) {
  touch.touchStart(evt);
}

function touchEnd(evt) {
  touch.touchEnd(evt);
}

function touchMove(evt) {
  touch.touchMove(evt);
}

function gestureStart(evt) {
  touch.gestureStart(evt);
}

function gestureChange(evt) {
  touch.gestureChange(evt);
}

function gestureEnd(evt) {
  touch.gestureEnd(evt);
}
