function globals(){}
globals.theMap; // this is needed because some methods are used as callback functions for event handlers where self-reference doesn't work
globals.theRequest;
globals.restoreMode=null;
globals.lastRequest;
globals.windowWidth;
globals.lastHist=1;
  function getInternetExplorerVersion() {
      var rv = -1; // Return value assumes failure.
      if (navigator.appName == 'Microsoft Internet Explorer') {
          var ua = navigator.userAgent;
          var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
          if (re.exec(ua) != null)
              rv = parseFloat(RegExp.$1);
      }
      return rv;
  }

  function checkVersion() {
    var msg = "You're not using Windows Internet Explorer.";
    var ver = getInternetExplorerVersion();
    if (ver > -1) {
        if (ver >= 8.0)
            msg = "You're using a recent copy of Windows Internet Explorer."
        else
            msg = "You should upgrade your copy of Windows Internet Explorer.";
    }
    alert(msg); 
  }
    
    /****************MAP***********/
  function Map(baseUrl,page,ext,hasRef,useCookie,h,w,activeLayer,showlegend,service){
    globals.theMap=this; // need this for event handlers to work
    this.baseURL=baseUrl +"MapService" +service;  // url to map service
    this.drawURL=baseUrl +"DrawLines";  // url to map service
    this.cmdParm=useCookie; // also used for mark - not implemented in this script yet
    this.extInfo; // procedure called by showInfo instead of internal procif not null
    this.mode="refresh";
    this.lastMode=this.mode; // required to restore mode after 'update'and 'lastext'
    this.isPanning=false; // map is being panned
    this.isDrawing=false; // in process of drawing a polygon
//    this.chart;
    this.button; // used by application; currently for copying map to output
    this.notify=null; // notify application when a map has been refreshed
    this.print=null; // print map function
    this.screenCoordinates; //image coordinates string for zoom and pan and some get info commands
    this.mouseX; // last click in image coordinates
    this.mouseY;
    this.mapImgURL; //source of map image
    this.page=page; // Page where map is drawn, not necessarily where script is loaded
    this.width;// width of map image
    this.height; // height of map image
    this.gpxLink;
    this.showLegend=showlegend; // legend should be drawn on map
//    this.showChart=false; //
    this.showRefmap=hasRef;  // refmap is optional as it requires a separate mv run
    this.mapExtent=ext.split(","); // map extent in world coordinates
    this.scale=0; // scale of map, used for scalebar and to determine visibility of layers
    this.degPerPix; // image scale used for coordinates display and intermediate distance measuring
    this.lastExtent=new Array(4);
    for (var i=0;i<4;i++)
      this.lastExtent[i]=this.mapExtent[i]; // previous extent
    this.ie=true; // boolean, internet explorer browser used
    if(navigator.appName=="Netscape")  // Safari also currently has 'Netscape' in its name string
      this.ie=false;
    if(h==0 || w==0){
      if(this.ie){ // give full page to map
        this.width=this.page.document.body.offsetWidth-2;
        this.height=this.page.document.body.offsetHeight-2;
        globals.windowWidth=top.document.body.offsetWidth;
      }
      else{
        this.width=this.page.innerWidth;//window.innerWidth;
        this.height=this.page.innerHeight; //window.innerHeight;
        globals.windowWidth=top.innerWidth;
      }
    }
    else{
      this.width=w;
      this.height=h;
    }
    this.msgBox=this.page.document.createElement("div"); // create the div that is to hold the map
    this.msgBox.style.display="none";
    this.msgBox.style.position="absolute";
    this.msgBox.style.top="100";
    this.msgBox.style.left="100";
    this.msgBox.style.zIndex="1000";
    this.msgBox.style.color="red";
    this.msgBox.style.border="2px groove darkred";
    this.msgBox.style.fontSize="20pt";
    this.msgBox.innerHTML="<img src=\"../images/sphere.gif\"><br>Updating Map. Please wait...";
    page.document.body.appendChild(this.msgBox);
    this.mapDiv=page.document.createElement("div"); // create the div that is to hold the map
    this.mapDiv.style.position="absolute";
    this.mapDiv.style.overflow="hidden";
    this.mapDiv.style.paddingTop=0;
//    this.mapDiv.style.marginTop=0;
//    this.mapDiv.style.top=0;
//    this.mapDiv.style.left=0;
    this.mapDiv.style.width=this.width-2; // allow for frame
    this.mapDiv.style.height=this.height-2; // allow for tabs
    this.mapDiv.style.borderWidth="thin";
    this.mapDiv.style.borderStyle="solid";
    this.mapImg=page.document.createElement("img"); // the map image
    this.mapImg.style.position="absolute"
    this.mapImg.style.overflow="hidden";
    this.mapImg.style.top=0;
    this.mapImg.style.left=0;
    this.history=new Array();
    this.mapImg.style.width=this.mapDiv.style.width;
    this.mapImg.style.backgroundColor="transparent";
    this.mapImg.style.height=this.mapDiv.style.height;
    this.mapOverlay=page.document.createElement("img"); // the map image
    this.mapImg.src="../images/wait.png"; // in case there is no map
    this.mapDiv.appendChild(this.mapImg);
    this.mapDiv.appendChild(this.mapOverlay);
    page.document.body.appendChild(this.mapDiv);
    this.infoTool=new InfoTool(activeLayer,this); //displays attributes
    this.currentBasemap; // basemap currently set
    this.layers=new Array(); // layers for this map
    this.originalLayerCount=this.getServerLayers(this); // retrieve predefined layers for this mapservice, may add locally defined jdbc layers
    this.setActiveLayer(activeLayer);
    this.basemaps=""; // list of basemap names and descriptions for this map
    this.getServerBasemaps(this); // retrieve basemaplist for the mapservice
    this.polygonTool=new PolygonTool(this); // uses Drawline servlet to draw lines on map
    this.rectangleTool=new RectangleTool(this); // uses clipped images to draw rectangle on map
    this.measureTool=new MeasureTool(this); // uses polygon tool to draw and infotool to display distance and area
    this.scalebar=new Scalebar(this); // display scale text and image
    this.coordsbar=new Coordsbar(this); // display world coordinates for mouse position
    this.toolbar=new Toolbar(this); // standard toolbar
    this.refmap=new Refmap("UL",4,this); // create a reference map
    this.areaOfInterest= new AreaOfInterest(this);
//    this.refresh(); // get the map image from the mapservice
//    window.onresize = this.resizeMap;
    this.mapImg.onmousedown = this.chkMouseDown; // event handlers
    this.mapImg.onmouseup = this.chkMouseUp;
//    this.mapImg.onmousemove = this.chkMouseMove;
    var newEvt;
    if(this.ie){
  		newEvt=document.createEventObject();
    	newEvt.fromElement=this.toolbar.im[1];
		this.toolbar.im[1].fireEvent("onclick",newEvt);
	}
    else{
    	newEvt=document.createEvent("MouseEvents");
    	newEvt.initEvent("click",true,true);
    	this.toolbar.im[1].dispatchEvent(newEvt);
    }
    this.marker=null;
  }

  Map.prototype.addButton=function(label,action){
    this.button=new ToolButton(this,label,action);
  }


  Map.prototype.addLayer=function(layer){
    this.layers.push(layer);
  }

  Map.prototype.addHistory=function(hist){
    var hist=new History();
    var k=this.scalebar.label.innerHTML.indexOf("(");
//    hist.title=new Number((new Number(this.mapExtent[2])+new Number(this.mapExtent[0]))/2).toFixed(2) + "," +
//    new Number((new Number(this.mapExtent[3])+new Number(this.mapExtent[1]))/-2).toFixed(2) + " " +
    hist.title=globals.lastHist + ": Scalebar " + this.scalebar.label.innerHTML.substring(0,k);
    globals.lastHist++;
    hist.mapURL=this.mapImg.src;
    hist.mapExtent0=this.mapExtent[0];
    hist.mapExtent1=this.mapExtent[1];
    hist.mapExtent2=this.mapExtent[2];
    hist.mapExtent3=this.mapExtent[3];
    hist.layerStatus; //Stage3 array with name,visibility - probably dont need this
    hist.scaleBarWidth=this.scalebar.im.style.width;
    hist.scaleBarLabel=this.scalebar.label.innerHTML;
    hist.degPerPix=this.degPerPix;
    hist.lastExtent=this.lastExtent;
    if(globals.theMap.history.length>20)
      this.history.shift();
    this.history.push(hist);
  }

  Map.prototype.chkMouseDown=function (e) {
    if (globals.theMap.ie)
      e=globals.theMap.page.event;
    globals.theMap.mouseX=e.clientX;
    globals.theMap.mouseY=e.clientY;
    if (globals.theMap.mode == "zoomin" || globals.theMap.mode == "zoomout" || globals.theMap.mode == "inforect")
      globals.theMap.isDrawing=true;
    else if (globals.theMap.mode == "pan")
      globals.theMap.isPanning=true;
    return false;
  }


  Map.prototype.chkMouseMove=function (e) {
    if (globals.theMap.ie)
      e=globals.theMap.page.event;
    var x=e.clientX;
    var y=e.clientY;
    var cX=new Number(globals.theMap.mapExtent[0])+(new Number(x)*new Number(globals.theMap.degPerPix));
    var cY=new Number(globals.theMap.mapExtent[3]) - (new Number(y)*new Number(globals.theMap.degPerPix));
    if (globals.theMap.mode!="infomeasure"){
      var ldDegreeLon=Math.floor(cX);
      var ldMinuteLon=Math.floor((cX-ldDegreeLon)*60);
      var ldDegreeLat=Math.ceil(cY);
      var ldMinuteLat=Math.floor((ldDegreeLat-cY)*60);
      globals.theMap.coordsbar.label.innerHTML= "Lat " + ldDegreeLat + "d " +ldMinuteLat + "m Lon " + ldDegreeLon + "d " + ldMinuteLon + "m" ;
    }
    if (globals.theMap.isDrawing==true)
     globals.theMap.rectangleTool.drawRect(x,y);
    else if (globals.theMap.isPanning)
      globals.theMap.drawPan(x,y);
    return false;
  }

Map.prototype.chkMouseUp=function (e) {
    if (globals.theMap.ie){
      e=globals.theMap.page.event;
      e.cancelBubble=true;
      }
//    alert("up "+e.clientX);
     if(globals.theMap.isDrawing==true && globals.theMap.mode!="inforect"){
      globals.theMap.rectangleTool.od.style.display="none";
    }
    var x=e.clientX;
    var y=e.clientY;
    if (globals.theMap.mode.indexOf("zoom")==0)
      globals.theMap.endZoom(x,y);
    else if (globals.theMap.mode=="infopt")
      globals.theMap.getInfo(x,y);
    else if (globals.theMap.mode=="inforect")
      globals.theMap.getInfo(x,y);
    else if (globals.theMap.mode=="pan" && globals.theMap.isPanning)
      globals.theMap.endPan(x,y);
    else if (globals.theMap.mode == "infomeasure")
      globals.theMap.measureTool.measure(x,y);
    else if (globals.theMap.mode == "infopoly" || globals.theMap.mode == "gpxline" || globals.theMap.areaOfInterest.type=="draw")
      globals.theMap.polygonTool.drawPolygon(x,y);
    else if (globals.theMap.mode == "aoiClick") {
      globals.theMap.areaOfInterest.rowId=x + "," + y;
      globals.theMap.lastMode = "aoiClick";
      globals.theMap.mode="update";
      globals.theMap.refresh();
    }
    if(!globals.theMap.ie)
      e.stopPropagation();
  }


  Map.prototype.clearAreaOfInterest=function(){
    this.areaOfInterest.type=null;
	this.areaOfInterest.name="";
    this.areaOfInterest.table="";
    this.areaOfInterest.idColumn="";
    this.areaOfInterest.recordId="";
    this.areaOfInterest.dataSource="";
	this.areaOfInterest.polygon="";
	this.zoomTo=false;
  }

  Map.prototype.clearClientLayers=function(){
	var n=this.originalLayerCount;
	while (this.layers.length>n)
        this.layers.pop();
  }

  Map.prototype.clearHistory=function(){
	while (this.history.length>0)
        this.history.pop();
  }

/*  Map.prototype.removeClientLayers=function(){
    var n=globals.theMap.originalLayerCount;
    var m=globals.theMap.layers.length-n;
    this.layers.splice(n,m);
  }
*/

  Map.prototype.commandEnable=function(bool){
    if (bool){
      this.mapDiv.onmousedown = this.chkMouseDown;
      this.mapDiv.onmouseup = this.chkMouseUp;
      this.mapDiv.onmousemove = this.chkMouseMove;
    }
    else{
      this.mapDiv.onmousedown = null;
      this.mapDiv.onmouseup = null;
      this.mapDiv.onmousemove = null;
    }
  }


  Map.prototype.drawPan=function(x,y) {

//		var clipTop, clipLeft;
    var clipBottom, clipRight;

		if ( y<globals.theMap.mouseY ){ // moving up
//				clipTop = 1 ;//zY1-mouseY;
				clipBottom =globals.theMap.height;// -  (globals.theMap.mouseY - y);
        }
		else{
//				clipTop = y-globals.theMap.mouseY;
				clipBottom = globals.theMap.height-(y-globals.theMap.mouseY);
        }

		if (x < globals.theMap.mouseX) { // move left
//				clipLeft = 1 ; //zX1-mouseX ;
				clipRight = globals.theMap.width;//-(globals.theMap.mouseX-x) (globals.theMap.mouseX-x);
        }
		else {
//				clipLeft = x-globals.theMap.mouseX;
				clipRight = globals.theMap.width-(x-globals.theMap.mouseX);
		}
    if ( x == globals.theMap.width-1 || x ==1 || y == globals.theMap.height-1 || y ==1 )
			globals.theMap.endPan(x,y);
		else 	{
      var panStyle = globals.theMap.mapDiv.style;
      panStyle.left = x-globals.theMap.mouseX ;
      panStyle.top = y-globals.theMap.mouseY ;
      panStyle.clip =  "rect(0 " +  clipRight + " " + clipBottom + " 0)";
//      panStyle.clip =  "rect(" + clipTop + " " +  clipRight + " " + clipBottom + " " + clipLeft +")";
    }
	}




  Map.prototype.endPan=function(x,y){
    globals.theMap.isPanning=false;
     for (var i=0;i<4;i++)
      globals.theMap.lastExtent[i]=globals.theMap.mapExtent[i]; // previous extent
    globals.theMap.screenCoordinates=(new Number(globals.theMap.mouseX)-x)+"," + (new Number(globals.theMap.mouseY-y));
    var panStyle = globals.theMap.mapDiv.style;
    panStyle.clip =  "rect(0 " +  this.width + " " + this.height + " 0)";
    panStyle.left = 0 ;
    panStyle.top = 0 ;
    globals.theMap.refresh();
  }



  Map.prototype.endZoom=function(x,y){

    if(globals.theMap.ie && globals.theMap.isDrawing==false)
     return;
    globals.theMap.isDrawing=false;
     for (var i=0;i<4;i++)
      globals.theMap.lastExtent[i]=globals.theMap.mapExtent[i]; // previous extent
    if (Math.abs(globals.theMap.mouseX-x)>10 && Math.abs(globals.theMap.mouseY-y)>10){
      globals.theMap.screenCoordinates=globals.theMap.mouseX + "," + globals.theMap.mouseY + "," + x + "," + y ;
      globals.theMap.refresh();
    }
  }

  Map.prototype.getActiveLayer=function(){
    return this.infoTool.activeLayer;
  }

   Map.prototype.getBasemapList=function() {
    return this.basemaps;
  }

  Map.prototype.getInfo=function(x,y){
      globals.theMap.isDrawing=false;
    if(globals.theMap.mode=="infopt")
      globals.theMap.screenCoordinates=x + "," + y;
    else if(globals.theMap.mode=="inforect")
      globals.theMap.screenCoordinates=globals.theMap.mouseX + "," + globals.theMap.mouseY + "," + x + "," + y ;
    globals.theMap.refresh();
  }
    /* general database query can be spatial_i,spatial_w,restrict,current or nonspatial)*/
  Map.prototype.getData=function(asDs,asQuery,asGeomCol,asCoords,asQueryType) {
    var asRestrict="";
    var mr="<mapservice_request request_type=\"data\">"+
    "<data_request  type=\"query\"><query type=\"" + asQueryType + "\">" +
     asQuery +"</query>" + "<data_source>" +asDs +
     "</data_source><geom_col>" +asGeomCol + "</geom_col><coords>" +
     asCoords + "</coords></data_request>" + asRestrict + "</mapservice_request>";
    if (typeof XMLHttpRequest!="undefined")
      req= new XMLHttpRequest();
    else
      req=new ActiveXObject("MSXML2.XMLHttp.3.0");
    req.open("post",this.baseURL,false);
    req.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
    req.send(mr);
    if(req.responseText!=null){
      var q=req.responseText;

      q=q.replace(/e\g/,"eg");
      var xmlDoc;
      if(this.ie){
        xmlDoc=new ActiveXObject("Microsoft.XmlDom");
        xmlDoc.loadXML(q);
      }
      else{
       var op=new DOMParser();
       xmlDoc=op.parseFromString(q,"text/xml");
      }
//      alert(req.responseText);
      var ndResponse=xmlDoc.documentElement;  // root node=mapservice_response
      var ndRow=ndResponse.firstChild;
      var result="";
      if(ndRow!=null){
        var ndCol;
        do{
          ndCol=ndRow.firstChild;
          if(ndCol!=null ){
            do{
            if(ndCol.firstChild!=null)
                result+=ndCol.firstChild.nodeValue +"," ;
              else
                result+="," ;
            }while ((ndCol=ndCol.nextSibling)!=null);
            result+="^"
          }
        }while ((ndRow=ndRow.nextSibling)!=null);
      }
    if(globals.theMap.notify!=null)
     globals.theMap.notify();
    }
    else
      alert("Get Data: No Response") ;
    return result;
  }


   Map.prototype.getDetail=function(layerName,queryType,criteria) {
	var layer=this.getLayerByName(layerName);
    var mr="<mapservice_request request_type=\"data\">"+
    "<data_request  type=\"query\"><query type=\"" + queryType + "\">" +
     layer.detailQuery + criteria + "</query>" + "<data_source>" +asDs +
     "</data_source><geom_col>" +layer.geomCol + "</geom_col><coords>" +
     "</coords></data_request></mapservice_request>";
    if (typeof XMLHttpRequest!="undefined")
      req= new XMLHttpRequest();
    else
      req=new ActiveXObject("MSXML2.XMLHttp.3.0");
    req.open("post",this.baseURL,false);
    req.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
    req.send(mr);
    if(req.responseText!=null){
        var xmlDoc;
      if(this.ie){
        xmlDoc=new ActiveXObject("Microsoft.XmlDom");
        xmlDoc.loadXML(req.responseText);
      }
      else{
       var op=new DOMParser();
       xmlDoc=op.parseFromString(req.responseText,"text/xml");
      }
//      alert(req.responseText);
      var ndResponse=xmlDoc.documentElement;  // root node=mapservice_response
      var ndRow=ndResponse.firstChild;
      var result="";
      if(ndRow!=null){
        var ndCol;
        do{
          ndCol=ndRow.firstChild;
          if(ndCol!=null){
            do{
                result+=ndCol.firstChild.nodeValue +"," ;
            }while ((ndCol=ndCol.nextSibling)!=null);
            result+="^"
          }
        }while ((ndRow=ndRow.nextSibling)!=null);
      }
    }
    else
      alert("Get Data: No Response") ;
    return result;
  }



  Map.prototype.getHistory=function() {
    var hist="";
    for (var n=0;n<globals.theMap.history.length;n++){
      hist+=globals.theMap.history[n].title + ";";
    }
    return hist;
  }


  /* return a layer from its name (theme) return null if name not found  */
  Map.prototype.getLayerByName=function(layerName){
    for (var n=0;n<globals.theMap.layers.length;n++){
      if(globals.theMap.layers[n]!=null && layerName==globals.theMap.layers[n].layerName){
        return globals.theMap.layers[n];
      }
    }
    return null;
  }

  Map.prototype.getLayerList=function() {
    var layerList="";
    for (var n=0;n<globals.theMap.layers.length;n++){
      layerList+=globals.theMap.layers[n].layerGroup + "," +
      globals.theMap.layers[n].layerName + "," +
      globals.theMap.layers[n].title + "," +
      globals.theMap.layers[n].isEnabled + "," +
      globals.theMap.layers[n].isActive + "," +
      globals.theMap.layers[n].canBeActive + ";" ;
    }
    return layerList;
  }

  Map.prototype.getLastRequest=function() {
    return globals.lastRequest;
  }

  Map.prototype.getServerBasemaps=function(map){
    var mr="<mapservice_request request_type=\"data\">"+
    "<data_request  type=\"basemaplist\"></data_request>" +
    "</mapservice_request>";
    if (typeof XMLHttpRequest!="undefined")
      req= new XMLHttpRequest();
    else
      req=new ActiveXObject("MSXML2.XMLHttp.3.0");
    req.open("post",map.baseURL,false);
    req.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
    req.send(mr);
    var xmlDoc;
    if(req.responseText!=null){
      if(this.ie){
        xmlDoc=new ActiveXObject("Microsoft.XmlDom");
        xmlDoc.loadXML(req.responseText);
      }
      else{
       var op=new DOMParser();
       xmlDoc=op.parseFromString(req.responseText,"text/xml");
      }
      var ndResponse=xmlDoc.documentElement;  // root node=mapservice_response
      var ndRow=ndResponse.firstChild;
        do{
          if (ndRow.nodeName=="basemaplist")
            this.basemaps=ndRow.firstChild.nodeValue.split(";");
          else if (ndRow.nodeName=="activelayer")
            this.infoTool.activeLayer=ndRow.firstChild.nodeValue;

        }while ((ndRow=ndRow.nextSibling)!=null);
    }
    else
      alert("GetBasemaps: No Response") ;
 }

  Map.prototype.getServerLayers=function(map){
    var count=0;
    var lyr;
    var ndCol;
    var enabledLayers="";
    var mr="<mapservice_request request_type=\"data\">"+
    "<data_request  type=\"layerlist\"></data_request>" +
    "</mapservice_request>";
    if (typeof XMLHttpRequest!="undefined")
     globals.theRequest= new XMLHttpRequest();
    else
      globals.theRequest=new ActiveXObject("MSXML2.XMLHttp.3.0");
    globals.theRequest.open("post",map.baseURL,false);
    globals.theRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
    //alert(cmd);
    globals.theRequest.send(mr);
    if(globals.theRequest.readyState==4){
    if(globals.theRequest.responseText!=null){
      var q=globals.theRequest.responseText;
      var xmlDoc;
      if(this.ie){
        xmlDoc=new ActiveXObject("Microsoft.XmlDom");
        xmlDoc.loadXML(globals.theRequest.responseText);
      }
      else{
       var op=new DOMParser();
       xmlDoc=op.parseFromString(globals.theRequest.responseText,"text/xml");
      }
      var ndResponse=xmlDoc.documentElement;  // root node=mapservice_response
      if(ndResponse.firstChild==null)
        return 0;
      var ndRow=ndResponse.firstChild;
        do{
          if (ndRow.tagName=="enabledlayers")
            enabledLayers=ndRow.firstChild.nodeValue;
          else if (ndRow.tagName.indexOf("enabled")!=-1)
            enabledLayers=ndRow.firstChild.nodeValue;
          else if (ndRow.tagName=="activelayer")
            this.setActiveLayer(ndRow.firstChild.nodeValue);
          else if (ndRow.tagName=="showlegend"){
            if(ndRow.firstChild.nodeValue=="false")
							this.showLegend=false;
						else
							this.showLegend=true;
						}
          else if (ndRow.tagName=="basemap")
            this.currentBasemap=ndRow.firstChild.nodeValue;
          else if (ndRow.tagName=="showrefmap"){
            if(ndRow.firstChild.nodeValue=="false")
							this.showRefmap=false;
						else
							this.showRefmap=true;
						}
          else if (ndRow.tagName=="layer"){
            lyr=new Layer();
            ndCol=ndRow.firstChild;
              do{

                  switch (ndCol.tagName){
                    case "layerType":
                      lyr.layerType=ndCol.firstChild.nodeValue;
                      break;
                    case "layerName":
                      lyr.layerName=ndCol.firstChild.nodeValue;
                      break;
                    case "layerGroup":
                      lyr.layerGroup=ndCol.firstChild.nodeValue;
                      break;
                    case "title":
                      lyr.title=ndCol.firstChild.nodeValue;
                      break;
                    case "geometryType":
                      lyr.geometryType=ndCol.firstChild.nodeValue;
                      break;
                    case "infoColumnsFormat":
                      lyr.infoColumnsFormat=ndCol.firstChild.nodeValue;
                      break;
                    case "detailColumnsFormat":
                      lyr.detailColumnsFormat=ndCol.firstChild.nodeValue;
                       break;
                   case "isEnabled":
                      if(ndCol.firstChild.nodeValue=="true")
                        lyr.isEnabled=true;
                      else
                        lyr.isEnabled=false;
                      break;
                    case "dontDisplay":
                      lyr.dontDisplay=ndCol.firstChild.nodeValue;
                       break;
                    case "maxZoom":
                      lyr.maxZoom=ndCol.firstChild.nodeValue;
                       break;
                    case "minZoom":
                      lyr.minZoom=ndCol.firstChild.nodeValue;
                       break;
                   case "canBeActive":
                      lyr.canBeActive=ndCol.firstChild.nodeValue;
                      break;
                  }
                }while ((ndCol=ndCol.nextSibling)!=null);
            this.addLayer(lyr);
            count++;
           }
        } while ((ndRow=ndRow.nextSibling)!=null);
        for (var n=0;n<this.layers.length;n++){
          ln=this.layers[n];
          if(ln.layerName==this.infoTool.activeLayer)
            ln.isActive==true;
          else
            ln.isActive=false;
          if(enabledLayers.length>2){
              if(enabledLayers.indexOf("$" + ln.layerName +"$")!=-1)
                ln.isEnabled=true;
              else
                ln.isEnabled=false;
          }
      }
    }
    else
      alert("GetLayers: No Response") ;
    globals.theRequest=null;
   }
    return count;
  }

    Map.prototype.gpxLine=function(action,linkObject){
        if(action=="gpxline"){
          this.polygonTool.toggle();
          }
        else if(action=="draw"){
          this.gpxLink=linkObject;
          this.lastMode=this.mode;
          this.mode="gpxline";
          this.toolbar.activateBtn();
          this.polygonTool.toggle();
        }
    }


  /* print the contents of the printmap div */
  Map.prototype.printMap=function(){
//    call print function in MI
  }
  Map.prototype.refresh=function(restoreMode){
    globals.theMap.lastMode=globals.theMap.mode;
    if(restoreMode!=null)
      globals.restoreMode=restoreMode;
    else{
      if(globals.theMap.mode=="lastext" || globals.theMap.mode=="refmap" || globals.theMap.mode=="update" || globals.theMap.mode=="gpxline")
        globals.restoreMode="last";
    }
    if(globals.theMap==null)
      globals.theMap=this;
    globals.theMap.msgBox.style.display="block";
    globals.theMap.commandEnable(false);

    var layerStatus="";
    var mr;
    if(!globals.theMap.showRefmap)
      globals.theMap.refmap.refmapImg.style.display="none";
    if(globals.theMap.mode=="lastext" || globals.theMap.mode=="update"){
      globals.theMap.mode="refresh";
      globals.theMap.toolbar.activateBtn();
    }
    if(globals.theMap.layers.length>0){
      layerStatus="<layer_status>";
      for (var p=0;p<globals.theMap.layers.length;p++){
        if(p>0)
          layerStatus+=";";
  //      if(globals.theMap.layers[p].layerType!="chart")
        layerStatus+=globals.theMap.layers[p].layerName +"," + globals.theMap.layers[p].isEnabled;
      }
      layerStatus+="</layer_status>";
    }
    mr="<mapservice_request request_type=\"map\">";
    mr+="<map_request  width=\"" + globals.theMap.width + "\" height=\"" +
    globals.theMap.height + "\" basemap=\"" + globals.theMap.currentBasemap + "\">";
    mr+="<box><coordinates>";
    if(globals.theMap.areaOfInterest.table=="special")
      mr+="129,-26,138,-10.8</coordinates></box>";
    else
      mr+=globals.theMap.mapExtent.join(",") + "</coordinates></box>";
    if (!globals.theMap.showLegend)
      mr+="<nolegend></nolegend>";
    if (globals.theMap.showRefmap)
      mr+="<refmap></refmap>";
    mr+="<active_layer>" + globals.theMap.infoTool.activeLayer + "</active_layer>";
    mr+="</map_request><command name=\"" + globals.theMap.mode + "\">";
    mr+="<cmdparm>" + globals.theMap.cmdParm + "</cmdparm><screen_coordinates>" + globals.theMap.screenCoordinates +"</screen_coordinates></command>";
    if (globals.theMap.layers.length>globals.theMap.originalLayerCount){
      mr+="<client_layers count=\"" + (globals.theMap.layers.length-globals.theMap.originalLayerCount) + "\">";
      for (var i=globals.theMap.originalLayerCount;i<globals.theMap.layers.length;i++){
        mr+="<layer type=\"" +globals.theMap.layers[i].layerType + "\"  name=\"" + globals.theMap.layers[i].layerName + "\" title=\"" + globals.theMap.layers[i].title + "\" geometrytype=\"" + globals.theMap.layers[i].geometryType + "\"";
        mr+=" geometrycol=\"" + globals.theMap.layers[i].geometryCol + "\" datasource=\"" + globals.theMap.layers[i].dataSource + "\" enabled=\"" + globals.theMap.layers[i].isEnabled + "\" areaRestricted=\"false\"";
        mr+=" activate=\""+ globals.theMap.layers[i].canBeActive + "\" minscale=\"" + globals.theMap.layers[i].minZoom + "\" maxscale=\"" + globals.theMap.layers[i].maxZoom + "\" display=\"true\" index=\"" + (i-1) + "\" group=\"" + globals.theMap.layers[i].layerGroup +"\" >";
        mr+="<jdbcquery>" + globals.theMap.layers[i].jdbcQuery + "</jdbcquery>";
        mr+="<infoquery><query>" + globals.theMap.layers[i].infoQuery + "</query><format>"+ globals.theMap.layers[i].infoFormat + "</format></infoquery>";
        mr+="<detailquery><query> " + globals.theMap.layers[i].detailQuery + "</query><format> " + globals.theMap.layers[i].detailFormat + "</format></detailquery>";
        mr+="<src>"+ globals.theMap.layers[i].jdbcUrl  + "</src>";
        mr+="<jdbclabel>"+ globals.theMap.layers[i].jdbcLabel + "</jdbclabel><jdbcsymbol>" + globals.theMap.layers[i].jdbcSymbol + "</jdbcsymbol></layer>";
      }
      mr+="</client_layers>"
    }
    if (globals.theMap.areaOfInterest.type!=null && globals.theMap.areaOfInterest.type!="draw" && globals.theMap.areaOfInterest.table!="special")
      mr+="<arealimit type=\""+ globals.theMap.areaOfInterest.type + "\" table=\"" + globals.theMap.areaOfInterest.table + "\" zoomto=\"" + globals.theMap.areaOfInterest.zoomTo +
	  "\" datasource=\"" +  globals.theMap.areaOfInterest.dataSource +"\" rowid=\"" +  globals.theMap.areaOfInterest.rowId + "\" geomcol=\"" + globals.theMap.areaOfInterest.geometryCol +
        "\" idcolumn=\"" + globals.theMap.areaOfInterest.idColumn +
"\" mask=\"" + globals.theMap.areaOfInterest.mask +
"\" reverse=\"" + globals.theMap.areaOfInterest.reverse +
"\">" + globals.theMap.areaOfInterest.polygon + "</arealimit>";
  if (globals.theMap.marker!=null)
    mr+="<highlight>" + globals.theMap.marker + "</highlight>";
    if (globals.theMap.areaOfInterest.zoomTo)
      globals.theMap.areaOfInterest.zoomTo=false;
    mr+= layerStatus + "</mapservice_request>";
    if (typeof XMLHttpRequest!="undefined")
      globals.theRequest= new XMLHttpRequest();
    else
       globals.theRequest=new ActiveXObject("MSXML2.XMLHttp.3.0");
     globals.theRequest.open("post",globals.theMap.baseURL,true);
     globals.theRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
     globals.theRequest.onreadystatechange=globals.theMap.updateMap;
 //    alert(mr);
      globals.lastRequest=mr;
     globals.theRequest.send(mr);
  }


    Map.prototype.updateMap=function(){
     if(globals.theRequest.readyState==4){

    var xmlDoc;
    if(globals.theRequest.responseText!=null){
//    alert(globals.theRequest.responseText);
      if(globals.theMap.ie){
        xmlDoc=new ActiveXObject("Microsoft.XmlDom");
        xmlDoc.loadXML(globals.theRequest.responseText);
      }
      else{
//       var oXmlDom=document.implementation.createDocument("","",null);
       var op=new DOMParser();
       xmlDoc=op.parseFromString(globals.theRequest.responseText,"text/xml");
      }
      var ndResponse=xmlDoc.documentElement;  // root node=mapservice_response
      var nd=ndResponse.firstChild;
      if(globals.theMap.mode.indexOf("info")==0){
        do{
          if (nd.nodeName=="info_table")
              globals.theMap.infoTool.result=decodeURIComponent(nd.firstChild.nodeValue);
          else if (nd.nodeName=="info_rect")
              globals.theMap.infoTool.extent=nd.firstChild.nodeValue;
          else if (nd.nodeName=="measure_table")
            globals.theMap.infoTool.measure=decodeURIComponent(nd.firstChild.nodeValue);
          else if (nd.nodeName=="arealimit"){
            globals.theMap.areaOfInterest.polygon=nd.firstChild.nodeValue;
            if (this.areaOfInterest.type=="polygon")
              globals.theMap.theMap.areaOfInterest.type="polygonW";
          }
          else if (nd.nodeName=="info_message"){
              var msg=nd.firstChild.nodeValue;
              if(msg.indexOf("error")>0)
                alert(msg);
          }
        }while ((nd=nd.nextSibling)!=null);
        globals.theMap.showInfo();
      }
      else if(globals.theMap.mode=="refmap"){
        do{
          if (nd.nodeName=="refmap_url"){
              globals.theMap.refmap.refmapImg.src=nd.firstChild.nodeValue;
              break;
          }
        } while ((nd=nd.nextSibling)!=null);
      }
      else if(globals.theMap.mode=="gpxline"){
        do{
          if (nd.nodeName=="gpx_url"){
              globals.theMap.gpxLink.href= "../" + nd.firstChild.nodeValue;
              globals.theMap.gpxLink.style.color="blue";
              break;
          }
        } while ((nd=nd.nextSibling)!=null);
      }
      else {
        var attMap;
        do{
          if (nd.nodeValue!=null && nd.nodeValue.indexOf("XML Parsing Error")!=-1){
            if (globals.theMap.lastMode=="aoiClick"){
              globals.theMap.lastMode == "refresh";
              globals.theMap.setAreaOfInterest('clear',null,null,null,null);
              alert("No Property found");
            }
            else
              alert(nd.nodeValue);
            break;
          }
          if (nd.nodeName=="map_url")
              globals.theMap.mapImg.src=nd.firstChild.nodeValue;
          else if (nd.nodeName=="refmap_url" && globals.theMap.showRefmap){
            globals.theMap.refmap.refmapImg.src=nd.firstChild.nodeValue;
            globals.theMap.refmap.refmapImg.style.display="block";
          }
          else if (nd.nodeName=="current_extent"){
            attMap=nd.attributes;
            globals.theMap.mapExtent[0]=attMap.getNamedItem("llx").nodeValue;
            globals.theMap.mapExtent[1]=attMap.getNamedItem("lly").nodeValue;
            globals.theMap.mapExtent[2]=attMap.getNamedItem("urx").nodeValue;
            globals.theMap.mapExtent[3]=attMap.getNamedItem("ury").nodeValue;
           }
          else if (nd.nodeName=="arealimit"){
            if (globals.theMap.areaOfInterest.type=="db")
              globals.theMap.areaOfInterest.rowId=nd.firstChild.nodeValue;
            else
              globals.theMap.areaOfInterest.polygon=nd.firstChild.nodeValue;
            if (globals.theMap.areaOfInterest.type=="polygon")
              globals.theMap.areaOfInterest.type="polygonW";
          }
          else if (nd.nodeName=="aoiarea")
            globals.theMap.areaOfInterest.area=nd.firstChild.nodeValue;
          else if (nd.nodeName=="map_scale"){
            globals.theMap.currentScale=nd.firstChild.nodeValue;
            for (var p=0;p<globals.theMap.layers.length;p++){
              if (globals.theMap.layers[p].minZoom>=globals.theMap.currentScale && globals.theMap.layers[p].maxZoom<=globals.theMap.currentScale)
                globals.theMap.layers[p].isVisible=true;
              else
                globals.theMap.layers[p].isVisible=false;
            }
          }
        } while ((nd=nd.nextSibling)!=null);
        globals.theMap.scalebar.setScale(globals.theMap.mapExtent[3],globals.theMap.mapExtent[1]);
        var cX=(new Number(globals.theMap.mapExtent[0])+new Number(globals.theMap.mapExtent[2]))/2;
        var cY=(new Number(globals.theMap.mapExtent[1])+new Number(globals.theMap.mapExtent[3]))/-2;
        var ldDegreeLon=Math.floor(cX);
        var ldMinuteLon=Math.floor((cX-ldDegreeLon)*60);
        var ldDegreeLat=-Math.ceil(cY)+1;
        var ldMinuteLat=Math.floor((ldDegreeLat+cY)*60);
        globals.theMap.coordsbar.label.innerHTML= "Lat " + ldDegreeLat + "d " +ldMinuteLat + "m Lon " + ldDegreeLon + "d " + ldMinuteLon + "m" ;
        globals.theMap.scalebar.setScale(globals.theMap.mapExtent[3],globals.theMap.mapExtent[1]);
      }
    }
    else
      alert("GetMap: No Response") ;
    if(globals.theMap.lastMode == "aoiClick")
      globals.theMap.lastMode="refresh";
    if(globals.restoreMode=="last" )
      globals.theMap.mode=globals.theMap.lastMode;
    else if(globals.restoreMode!=null){
      globals.theMap.mode=globals.restoreMode;
      globals.theMap.toolbar.activateBtn(globals.theMap.toolbar.getButton(globals.restoreMode));
      globals.restoreMode=null;
    }

    globals.theMap.commandEnable(true);
    globals.theMap.msgBox.style.display="none";
    globals.theMap.toolbar.pallette.style.top=globals.theMap.height-38;
    globals.theMap.scalebar.scalebarDiv.style.top=globals.theMap.height-34;
    globals.theMap.coordsbar.label.style.top=globals.theMap.height-53;
    globals.theMap.addHistory();
    if(globals.theMap.notify!=null)
     globals.theMap.notify();
  }
}


  // this is for locally defined jdbc layers only
  Map.prototype.removeLayerByName=function(layerName){
    for (var n=globals.theMap.originalLayerCount-1;n<globals.theMap.layers.length;n++){
      if(globals.theMap.layers[n]!=null && layerName==globals.theMap.layers[n].layerName){
        this.layers.splice(n,1);
      }
    }
  }

Map.prototype.resize=function(){
//    this.width=width;
//    this.height=height;
  if(navigator.appName=="Netscape"){
        this.width=this.width+top.innerWidth-globals.windowWidth;//window.innerWidth;
        this.height=this.page.innerHeight+4; //window.innerHeight;
        globals.windowWidth=top.innerWidth;
      }
   else{
        this.width=this.page.document.body.offsetWidth+2;
        this.height=this.page.document.body.offsetHeight+2;
        globals.windowWidth=top.document.body.offsetWidth;
      }
    this.page.frameElement.style.width=this.width;
    this.page.frameElement.style.height=this.height;
    this.mapDiv.style.width=this.width; // allow for frame
    this.mapDiv.style.height=this.height; // allow for tabs
    this.mapImg.style.width=this.mapDiv.style.width;
    this.mapImg.style.height=this.mapDiv.style.height;
    this.mode="update";
    this.refresh(); // get the map image from the mapservice
    return this.width;
}


  /* set active layer for queries */
  Map.prototype.setActiveLayer=function(layerName){
    this.infoTool.activeLayer=layerName;
    var ln;
    for (var n=0;n<globals.theMap.layers.length;n++){
      ln=globals.theMap.layers[n];
       if(ln.layerName==layerName)
        ln.isActive=true;
      else
        ln.isActive=false;
    }
  }
  Map.prototype.setMarker=function(asMarker){
    this.marker=asMarker;
  }

  Map.prototype.setAreaOfInterest=function(type,reverse,datasource,table,recordid,geometryCol,zoom,idColumn){
      var h;
      var w;
    this.areaOfInterest.type=type;
    this.areaOfInterest.reverse=reverse;
    if(type=="db"){
      this.areaOfInterest.polygon="$AOI$";
      this.areaOfInterest.table=table;
      this.areaOfInterest.idColumn=idColumn;
      this.areaOfInterest.dataSource=datasource;
      this.areaOfInterest.geometryCol=geometryCol;
      this.areaOfInterest.zoomTo=zoom;
      if(recordid=="click")
        this.mode="aoiClick";
      else
        this.areaOfInterest.rowId=recordid;
    }
    else if(type=="draw"){
      this.mode="refresh";
      this.toolbar.activateBtn();
      this.polygonTool.toggle();
    }
    else if(type=="polygon"){
//      if(name=="set")
        this.areaOfInterest.polygon=this.polygonTool.pointList;
      this.polygonTool.toggle();
	  }
    else if(type=="rectangle"){
      h=this.height;
      w=this.width;
      this.areaOfInterest.polygon="1,1,1," + h + "," + w + "," + h + "," + w + ",1,1,1";
      this.areaOfInterest.type="polygon";
	}
    else if(type=="current"){
      h=this.height;
      w=this.width;
      this.areaOfInterest.polygon="2,2,2," + (h-2) + "," + (w-2) + "," + (h-2) + "," + (w-2) + ",2,2,2";
      this.areaOfInterest.type="polygon";
	}
    else if(type=="clear"){
      this.polygonTool.cancel();
      this.areaOfInterest.polygon="";
      this.areaOfInterest.type=null;
    }

    else if(type=="none"){
      this.areaOfInterest.type=null;
    }
 }

   /* displays a basemap and optionally hides other basemaps */
  Map.prototype.setBasemap=function(bmName){
      this.currentBasemap=bmName;
  }

//  Map.prototype.setChart=function(asDs,asQuery,asCoords,asChartType,asColors) {
//    this.chart.chartImg.src=this.getChart(asDs,asQuery,asCoords,asChartType,asColors);
//    this.showTheChart(true);
//  }

  Map.prototype.setEnabled=function(layerName,bool){
    var l=this.getLayerByName(layerName);
        if(l!=null)
          l.isEnabled=bool;
    }

  Map.prototype.setExtinfo=function(fn){
        this.extInfo=fn;
    }

 Map.prototype.setHistory=function(index){
    var hist=globals.theMap.history[index];
    globals.theMap.mapImg.src=hist.mapURL;
    globals.theMap.mapExtent[0]=hist.mapExtent0;
    globals.theMap.mapExtent[1]=hist.mapExtent1;
    globals.theMap.mapExtent[2]=hist.mapExtent2;
    globals.theMap.mapExtent[3]=hist.mapExtent3;
    globals.theMap.scalebar.im.style.width=hist.scaleBarWidth;
    globals.theMap.scalebar.label.innerHTML=hist.scaleBarLabel;
    globals.theMap.degPerPix=hist.degPerPix;
    globals.theMap.lastExtent=hist.lastExtent;
//    if(index>0)
//      globals.theMap.commandEnable(false);
  }


  Map.prototype.setInfoLinkTo=function(fn){
        this.infoTool.linkTo=fn;
    }
  Map.prototype.setNotify=function(fn){
        this.notify=fn;
    }

  Map.prototype.setPrint=function(fn){
        this.print=fn;
    }

/*  Map.prototype.showTheChart=function(bool){
    this.showChart=bool;
    if(bool)
      this.chart.chartImg.style.display="block";
    else
      this.chart.chartImg.style.display="none";
    this.chart.isVisible=bool;
    } */

     Map.prototype.showMessage=function(msg){
        globals.theMap.msgBox.style.display="block";
        globals.theMap.msgBox.innerHTML=msg;
}
    Map.prototype.hideMessage=function(){
        globals.theMap.msgBox.style.display="none";
        globals.theMap.msgBox.innerHTML="<img src=\"../images/sphere.gif\"><br>Updating Map. Please wait...";
}

 Map.prototype.showInfo=function(){
    if (this.extInfo!=null && this.mode.indexOf("info")==0){
      if(this.extInfo(this.infoTool.result)==false)
        this.infoTool.displayInfo();
    }
    else
      this.infoTool.displayInfo();//popup info list, use measure tool
  }


  Map.prototype.showScalebar=function(bool){
    if(bool)
      this.scalebar.scalebarDiv.style.display="block";
    else
      this.scalebar.scalebarDiv.style.display="none";
  }

  /* show or hide the reference map */
  Map.prototype.showTheRefmap=function(bool){
    this.showRefmap=bool;
//      this.mode="refmap";
//      this.refresh();
    }

  Map.prototype.showTheLegend=function(bool){
    this.showLegend=bool;
  }

  Map.prototype.showToolbar=function(bool){
    if(bool)
      this.toolbar.pallette.style.display="block";
    else
      this.toolbar.pallette.style.display="none";
  }

  Map.prototype.showCoordsbar=function(bool){
    if(bool)
      this.coordsbar.label.style.display="block";
    else
      this.coordsbar.label.style.display="none";
  }
  Map.prototype.toggleTheRefmap=function(){
    this.showRefmap=!this.showRefmap;
      this.mode="update";
      this.refresh();
    }

  Map.prototype.toggleTheLegend=function(){
    this.showLegend=!this.showLegend;
      this.mode="update";
      this.refresh();
  }
  Map.prototype.zoomToCoords=function(rect,restoreMode){
    var newExt=rect.split(",");
     for (var i=0;i<4;i++)
      this.lastExtent[i]=this.mapExtent[i]; // previous extent
     for (i=0;i<4;i++)
      this.mapExtent[i]=newExt[i]; //new extent
    this.mode="update"
    this.refresh(restoreMode);
  }

 /****************AREAOFINTEREST***********/

  function AreaOfInterest(map){
	this.parent=map;
	this.type=null;
	this.dataSource;
	this.table;
	this.idColumn;
	this.rowId;
	this.geometryCol;
	this.polygon;
	this.reverse;
	this.zoomTo=false;
	this.mask=false;
	this.area=0;
        this.name;
  }
 /****************CHART***********

  function Chart(map,type,width){
    this.isVisible=false;
    if(type=="pie"){
      this.chartImg=map.page.document.createElement("img");
      this.chartImg.style.position="absolute"
      this.chartImg.style.top=120;
//      if(map.width<3*width)
//        this.chartImg.style.width=map.width/3;
//      else
        this.chartImg.style.width=width;
      this.chartImg.style.left=5;
      this.chartImg.style.zIndex=10;
      map.page.document.body.appendChild(this.chartImg);
    }
  }
 /****************COORDINATES***********/

  function Coordsbar(map){
    this.label=map.page.document.createElement("div");
    this.label.style.position="absolute"
    this.label.className="coordinateslabel_"
    this.label.style.top=map.height-24;
    this.label.style.left=5;
    this.label.style.zIndex=10;
    map.page.document.body.appendChild(this.label);
  }

 /****************HISTORY***********/
  function History(map){
    this.label; // extent of map + time
    this.mapURL; //Stage1 theMap.mapImg.src
    this.mapExtent0; //Stage2 theMap.mapExtent
    this.mapExtent1; //Stage2 theMap.mapExtent
    this.mapExtent2; //Stage2 theMap.mapExtent
    this.mapExtent3; //Stage2 theMap.mapExtent
    this.scaleBarWidth;//Stage1 theMap.scalebar.im.style.width
    this.scaleBarLabel;//Stage1 theMap.scalebar.label.innerHTML
    this.degPerPix;//Stage3 theMap.degPerPix
    this.lastExtent;//Stage3 theMap.lastExtent
  }

 /****************INFO***********/

  function InfoTool(activeL,map){
    this.linkTo;
    this.result;
    this.measure;
    this.extent; // world coordinates for last info request
    this.activeLayer=activeL; //active layer
    this.p=map.page.document.createElement("div");
    this.p.style.overflow="auto";
    this.p.style.position="absolute";
    this.p.className="info_";
    this.table=map.page.document.createElement("table");
    this.table.className="info_";
    this.table.style.zIndex="1000";
    this.p.style.display="none";
    this.p.style.height="200";
    this.p.style.width="330";
    this.p.appendChild(this.table);
    map.page.document.body.appendChild(this.p);
    this.parent=map;
  }

  InfoTool.prototype.clear=function(){
    while (this.table.rows.length>0)
      this.table.deleteRow(0);
  }

  InfoTool.prototype.displayInfo=function(){
    while (this.table.rows.length>0)
      this.table.deleteRow(0);
    var row;
    var cell;
    var btn;
    var infoRows=null;
    if(globals.theMap.mode.indexOf("measure")==-1)
      infoRows=this.result.split("$$$");
    else
      infoRows=this.measure.split("$$$");
    var k;
    var cols;
    for (var i=0;i<infoRows.length;i++){
      row=this.table.insertRow(-1);
      row.className="info_";
      cols=infoRows[i].split("$$");
      for (k=0;k<cols.length;k++){
        cell=row.insertCell(-1);
      if(i==0)
        cell.className="infoh_";
      else
        cell.className="info_";
      if((cols[k]).length>0){
        if(cols[k].indexOf("http://")==0)
            cell.innerHTML="<a target=\"_blank\" href=\"" + cols[k] + "\">link</a>";
        else if(cols[k].indexOf("www.")==0)
            cell.innerHTML="<a target=\"_blank\" href=\"http://" + cols[k] + "\">link</a>";
        else if(cols[k].indexOf("MARK$")==0){
            btn=this.parent.page.document.createElement("input");
            btn.type="button";
            btn.id= cols[k].substring(5);
            btn.value="Mark";
            cell.appendChild(btn);
//            cell.innerHTML="<button id=\"" + cols[k].substring(5) + "\">Mark</button>";
            if(globals.theMap.ie)
                btn.attachEvent("onclick",this.markPoint);
          else
                btn.addEventListener("click",this.markPoint,false);
        }
       else
            cell.innerHTML=cols[k].replace(new RegExp(/\u002B/g)," ");
      }
      else
        cell.innerHTML="-";
      }
      if(i==0){
        cell=row.insertCell(-1);
        cell.innerHTML="X";
        cell.style.cursor="pointer";
        cell.style.border="solid black 1px";
        cell.onClick="javascript:globals.theMap.infoTool.p.style.display=\"none\"";
        if(globals.theMap.ie)
          cell.attachEvent("onclick",this.hide);
        else
          cell.addEventListener("click",this.hide,false);
        }
      }
       this.p.style.top=30;
      this.p.style.left=5;
      /*
        if(globals.theMap.mouseY>globals.theMap.mapDiv.clientHeight-200)
          this.p.style.top=globals.theMap.mapDiv.clientHeight-210;
        else
          this.p.style.top=globals.theMap.mouseY;
        if(globals.theMap.mouseX>globals.theMap.mapDiv.clientWidth-280)
          this.p.style.left=globals.theMap.mapDiv.clientWidth-290;
        else
          this.p.style.left=globals.theMap.mouseX;
          */
    this.p.style.display="block";
      if(globals.theMap.mode=="infomeasure"){
        globals.theMap.polygonTool.toggle();
      }
  }

  InfoTool.prototype.hide=function(){
      globals.theMap.infoTool.p.style.display="none";
  }

  InfoTool.prototype.markPoint=function(e){
    var p;
    var mode=globals.theMap.mode;
    if(globals.theMap.ie){
        p=globals.theMap.page.window.event.srcElement;
        }
   else
       p=e.target;
//   alert(p.id);
    globals.theMap.setMarker(p.id +";MDSYS:M.STAR; ;T.SERIF12");
//    globals.theMap.infoTool.p.style.display="none";
    globals.theMap.mode="update";
    globals.theMap.refresh(mode);
  }
 /****************LAYER***********/


  function Layer(){
    this.layerType; // jdbc,predefined,wms
    this.layerName; // name of layer, for all but jdbc match the OMS theme name
    this.layerGroup; // group name of layer, used for layer list display only
    this.title;// a title to be displayed in theme list
    this.geometryType; // geometry type, can be point,line,polygon or raster
    this.geometryCol;// name of geometry column
    this.dataSource; // an OMS datasource
    this.infoQuery; // attribute sql query
    this.detailQuery; // detail sql query
    this.jdbcQuery; // map definition query for dynamic theme
    this.infoColumnsFormat; // column headings and formatting  for attribute data
    this.detailColumnsFormat; // column headings and formatting  for detail data
    this.isEnabled=true; // show this layer?
    this.dontDisplay=false; // don't display in layer list
    this.canBeActive=true; // attributes available
    this.isActive=false; // attributes available
    this.jdbcUrl; // location of layer for jdbc
    this.jdbcSymbol; // for jdbc layers
    this.jdbcLabel; // label column for jdbc layers
    this.minZoom; // minimum zoom level for display of this layer
    this.maxZoom;// maximum zoom level for display of this layer
	   this.index;
  }

  Layer.prototype.setEnabled=function(vis){
    this.isEnabled=vis;
  }
  // the next layer methods are only useable for jdbc layers
  Layer.prototype.setInfoColumnsFormat=function(fmt){
    this.columnFormat=fmt;
  }

  Layer.prototype.setDetailColumnsFormat=function(title){
    this.infoHeading=title;
  }

  Layer.prototype.setTitle=function(title){
    this.title=title;
  }

  Layer.prototype.setInfoQuery=function(query){
    this.infoQuery=query;
  }

   Layer.prototype.setDetailQuery=function(query){
    this.DetailQuery=query;
  }

  Layer.prototype.setJdbcQuery=function(query,symbol,label,url){
    this.jdbcQuery=query;
    this.jdbcUrl=url;
    this.jdbcSymbol=symbol;
    this.jdbcLabel=label;
  }


  Layer.prototype.setZoomLimits=function(minZoom,maxZoom){
    this.minZoom=minZoom;
    this.maxZoom=maxZoom;
  }

 /****************MEASURE***********/

  function MeasureTool(map){
    this.label=map.page.document.createElement("span");
    this.label.className="measurelabel_";
    this.label.style.position="absolute";
    this.label.style.border="1px solid ";
    this.label.style.display="none";
    this.totDist=0;
    this.lastPointX;
    this.lastPointY;
    map.page.document.body.appendChild(this.label);
    this.parent=map;
  }


  MeasureTool.prototype.measure=function(x,y,map){
    if(globals.theMap.polygonTool.pointCount==0){
      this.label.innerHTML= "";
      this.totDist=0;
    }
    else{
      var distance=Math.sqrt(Math.pow(this.lastPointX-x,2) + Math.pow(this.lastPointY-y,2))*this.parent.degPerPix*60*1.852;
      this.totDist+=distance ;
      this.label.innerHTML= "&nbsp;Segment: " + Math.round(distance) +" km Total: " + Math.round(this.totDist) +" km&nbsp;";
      this.label.style.top=y-20;
      this.label.style.left=x+10;
      this.label.style.display="block";
    }
    this.lastPointX=x;
    this.lastPointY=y;
    this.parent.polygonTool.drawPolygon(x,y);
  }

  function PolygonTool(map){
    this.pointCount;
    this.started=false;
    this.firstPointX;
    this.firstPointY;
    this.pointList;
    this.im=map.page.document.createElement("img");
    this.im.style.position="absolute";
    this.im.height=map.height;
    this.im.width=map.width;
    this.im.style.top="0";
    this.im.style.left="0";
    this.im.style.display="none";
    map.mapDiv.appendChild(this.im);
    this.parent=map;
  }


   /****************POLYGON***********/

  var warning=0;
  PolygonTool.prototype.drawPolygon=function(x,y){
    if (this.pointCount>0){
      if(true) { //(globals.theMap.ie) {
        if( this.pointCount>10 && warning==0){
          alert("Warning, max 50 points using Internet Explorer - max 40 points left");
          warning=1;
          }
        else if( this.pointCount>40 && warning==1){
          alert("Warning, max 10 points left");
          warning=2;
          }
        else if( this.pointCount>50 && warning==2){
          alert("Aborting");
          warning=3;
          this.cancel();
          }
        }
      this.im.style.display="block";
      if(Math.abs(x-this.firstPointX)<10 && Math.abs(y-this.firstPointY)<10)
        this.pointList= this.pointList + "," + this.firstPointX  + "," + this.firstPointY ;
      else
        this.pointList= this.pointList + "," + x  + "," + y ;
      var src=globals.theMap.drawURL + "?color=FF00FF&height=" + globals.theMap.height + "&width=" + globals.theMap.width +
      "&coordinates=" + this.pointList;
      if (navigator.appName.indexOf("Microsoft") != -1) {
          this.im.src = "blank.gif";
          this.im.runtimeStyle.filter = "progid:DXImageTransform.Microsoft." +
        "AlphaImageLoader(src='" + src + "',sizingMethod='scale')";
      }
      else{
        this.im.src=src;
      }
    }
    else{
      this.pointList= x + ","  + y ;
      this.firstPointX=x;
      this.firstPointY=y;
    }
    this.pointCount++;
  }
  PolygonTool.prototype.cancel=function(){
      this.im.style.display="none";
      this.pointCount=0;
      this.pointList="";
      if(!this.started){
		    this.parent.refresh();
		    this.parent.toolbar.activateBtn();
		    this.parent.mode="update"
		    }
      this.started=false;

  }

  PolygonTool.prototype.toggle=function(){
      if (!this.started){
        globals.theMap.mapImg.style.cursor = "help";
       this.started=true;
    }
    else{
      globals.theMap.mapImg.style.cursor = "default";
     if (this.pointCount>2){
		  this.parent.screenCoordinates=this.pointList;
		  globals.restoreMode="update";
		  this.parent.refresh();
      }
      else{
        if(globals.theMap.mode=="infomeasure"){
         globals.theMap.mode="update";
          if(this.parent.polygonTool.label)
            this.parent.polygonTool.label.style.display="none";
        }
      globals.theMap.toolbar.origImg="../images/infomeasure_1.gif";
      this.started=false;
      }
  }
  this.im.style.display="none";
  this.pointCount=0;
  this.pointList="";
  }


 /****************RECTANGLE***********/


  function RectangleTool(map){
    this.od=map.page.document.createElement("div")
      this.od.style.position="absolute";
      this.od.height=map.height;
      this.od.width=map.width;
      this.od.style.top="0";
      this.od.style.left="0";
      this.od.style.display="none";
    this.d=new Array(4);
    for (var i=0;i<4;i++){
      this.d[i]=map.page.document.createElement("img");
      this.d[i].src="../images/pixel.gif";
      this.d[i].style.position="absolute";
      this.d[i].height=map.height;
      this.d[i].width=map.width;
      this.d[i].style.top="0";
      this.d[i].style.left="0";
      this.d[i].style.clip="rect(0 1 1 1)";
      this.od.appendChild(this.d[i]);
    }
    map.mapDiv.appendChild(this.od);
    this.parent=map;
  }

  RectangleTool.prototype.drawRect=function(x,y) {
    var zTop;
    var zBottom;
    var zRight;
    var zLeft;
    if (globals.theMap.mouseX>x) {
      zRight=globals.theMap.mouseX;
      zLeft=x;
    } else {
      zLeft=globals.theMap.mouseX;
      zRight=x;
    }
    if (globals.theMap.mouseY>y) {
      zBottom=globals.theMap.mouseY;
      zTop=y;
    } else {
      zTop=globals.theMap.mouseY;
      zBottom=y;
    }
    if ((this.parent.mouseX != x) && (this.parent.mouseY != y)) {
      this.d[0].style.clip="rect("  + zTop + " " + zRight + " " + (new Number(zTop)+2) + " " + zLeft +")";
      this.d[1].style.clip="rect("  + zTop + " " + (new Number(zLeft)+2) + " " + zBottom + " " + zLeft +")";
      this.d[2].style.clip="rect("  + (new Number(zBottom)-2) + " " + zRight + " " + zBottom + " " + zLeft +")";
      this.d[3].style.clip="rect("  + zTop + " " + zRight + " " + zBottom + " " + (new Number(zRight)-2) +")";
    }
    this.od.style.display="block";
  }



 /****************REFMAP***********/


  function Refmap(pos,scale,map){
    var left;
    var top;
    this.scale;
    this.refmapImg=map.page.document.createElement("img");
    this.refmapImg.className="refmap_";
    this.refmapImg.style.position="absolute";
//    this.refmapImg.style.width=map.width/scale;
//    this.refmapImg.style.height=map.height/scale;
//    this.refmapImg.style.display="none";
    if (pos=="UL"){
      left=5;
      top=2;
    }
    else if (pos=="LL"){
      left=1;
      top=this.height*0.75;;
    }
    else if (pos=="UR"){
      left=this.width*0.75;
      top=0;
    }
    else if (pos=="LR"){
      left=this.width*0.75;
      top=this.height*0.75;;
    }
    left=left-3;
    this.refmapImg.style.top=top;
    this.refmapImg.style.left=left;
     this.refmapImg.style.zIndex=map.mapImg.style.zIndex-1;
     map.mapDiv.appendChild(this.refmapImg);
  }


   /****************SCALEBAR***********/


  function Scalebar(map){
    this.scalebarDiv=map.page.document.createElement("div");
    this.scalebarDiv.style.position="absolute";
    this.scalebarDiv.style.top=map.height-24;
    this.scalebarDiv.style.left=265;
    this.scalebarDiv.className="scalebar_";
    this.scalebarDiv.style.zIndex=10;
    this.scale;
    this.label=map.page.document.createElement("span");
    this.scalebarDiv.appendChild(this.label);
    this.im=map.page.document.createElement("img");
    this.im.style.position="absolute";
    this.im.style.height="3";
    this.im.style.top="15";
    this.im.style.left="1";
    this.im.src="../images/scalebar.png";
    this.scalebarDiv.appendChild(this.label);
    this.scalebarDiv.appendChild(this.im);
    map.page.document.body.appendChild(this.scalebarDiv);
    this.parent=map;
  }

  Scalebar.prototype.setScale=function(ury,lly,map){
    var x=(new Number(ury)-new Number(lly))/new Number(globals.theMap.height); //degrees per pixel
    var scaleFraction=Math.round(x*4200000)*100; // assuming 96 dpi screen rounded to nearest 100
    var scalebarWidth;
    this.scale=x*11112; // km per pixel*100
    var sc=this.scale;
    var p=1000; // 10km per pixel starting point for length of bar
    while(p>0.001){ // keep dividing by ten until less than 100m per pixel or
      if (sc>p){
        scalebarWidth=Math.round((p*100)/sc);
        sc=p;
        break;
      }
      p=p/2;
      if (sc>p){
        scalebarWidth=Math.round((p*100)/sc);
        sc=p;
        break;
      }
      p=p/2;
      if (sc>p){
        scalebarWidth=Math.round((p*100)/sc);
        sc=p;
        break;
      }
      p=p/2.5;
    }
    this.parent.degPerPix=(ury-lly)/new Number(globals.theMap.height);
    this.im.style.width=scalebarWidth;
    this.label.innerHTML=sc + " km (1:" + scaleFraction + ")";

  }


 /****************TOOLBAR***********/

  function Toolbar(map){
    var buttons=["lastext","Zoom to previous map extent",
    "zoomin","Draw rectangle to zoom in","zoomout",
    "Draw rectangle to zoom out","pan","Drag to pan","infopt",
    "Get attributes near point","infopoly","Get attributes inside polygon",
    "inforect","Get attributes inside rectangle","infomeasure",
    "Measure distance and area","legendtoggle","Legend on/off","refmaptoggle",
    "Reference Map on/off","print","Print Map"];
    this.im =new Array();// image array for buttons
    this.cl; // table cells
    this.origImg; // last mouseover image
    this.btn; //current mouseover button
    this.pallette=map.page.document.createElement("div");
    this.pallette.style.position="absolute";
    this.pallette.className="toolbar_";
    this.pallette.style.zIndex=0;
    this.pallette.style.height=20;
    this.pallette.style.width=250;
    this.pallette.style.top=map.height-24;
    this.pallette.style.left=5;
    for(var i=0;i<11;i++){
      this.im[i]=map.page.document.createElement("img");
      this.im[i].id=buttons[i*2];
      this.im[i].src="../images/" + this.im[i].id  +"_1.gif";
      this.im[i].alt=buttons[i*2+1];
      this.im[i].style.zIndex=1000;
      this.im[i].style.margin="3px";
      if(globals.theMap.ie){
        this.im[i].attachEvent("onmouseover",this.hover);
        this.im[i].attachEvent("onmouseout",this.unHover);
        this.im[i].attachEvent("onclick",this.doAction);
        this.pallette.appendChild(this.im[i]);
      }
      else{
        this.im[i].addEventListener("mouseover",this.hover,false);
        this.im[i].addEventListener("mouseout",this.unHover,false);
        this.im[i].addEventListener("click",this.doAction,false);
        this.pallette.appendChild(this.im[i]);
      }
    }
    map.page.document.body.appendChild(this.pallette);
    this.parent=map;
  }

  Toolbar.prototype.activateBtn=function(btn){
    for(var i=0;i<8;i++)
      this.im[i].src="../images/" + this.im[i].id  +"_1.gif";
    if(btn){
      var activeImg="../images/" + btn.getAttribute("id") + "_2.gif";
      btn.setAttribute("src",activeImg);
      this.origImg=activeImg;
    }
  }

  Toolbar.prototype.doAction=function(e){
    var btn;
    if (globals.theMap.ie){
    	if(e!=null)
    		btn=e.srcElement;
    	else
      		btn=globals.theMap.page.event.srcElement;
     }
    else
      btn=e.target;
    globals.theMap.infoTool.p.style.display="none";
    globals.theMap.measureTool.label.style.display="none";
    globals.theMap.rectangleTool.od.style.display="none";
    globals.theMap.polygonTool.im.style.display="none";
    globals.theMap.lastMode=globals.theMap.mode;
    globals.theMap.mode=btn.id;
    switch(btn.id){
      case "legendtoggle":
        globals.theMap.toggleTheLegend();
        break;
      case "refmaptoggle":
        globals.theMap.toggleTheRefmap();
        break;
      case "lastext":
        var temp=new Array(4);
        for (var i=0;i<4;i++)
          temp[i]=globals.theMap.lastExtent[i]; // previous extent
         for (i=0;i<4;i++)
          globals.theMap.lastExtent[i]=globals.theMap.mapExtent[i]; // previous extent
        for (i=0;i<4;i++)
          globals.theMap.mapExtent[i]=temp[i]; // previous extent
        globals.theMap.mode="lastext";
        globals.theMap.refresh();
        break;
      case "zoomin":
      case "zoomout":
         for (i=0;i<4;i++)
          globals.theMap.lastExtent[i]=globals.theMap.mapExtent[i]; // previous extent
        globals.theMap.toolbar.activateBtn(btn);
        globals.theMap.mapImg.style.cursor = "crosshair";
        break;
      case "pan":
         for (i=0;i<4;i++)
          globals.theMap.lastExtent[i]=globals.theMap.mapExtent[i]; // previous extent
        globals.theMap.toolbar.activateBtn(btn);
        globals.theMap.mapImg.style.cursor = "move";
        break;
      case "infomeasure":
      case "infopoly":
        globals.theMap.polygonTool.toggle();
        if(!globals.theMap.polygonTool.started){
          globals.theMap.toolbar.activateBtn(null);
        }
        else{
          globals.theMap.toolbar.activateBtn(btn);
        }
        break;
      case "infopt":
      case "inforect":
        globals.theMap.toolbar.activateBtn(btn);
        globals.theMap.mapImg.style.cursor = "help";
        break;
      case "print":
        globals.theMap.print();
    }
}
  Toolbar.prototype.hover=function(e){
    var btn;
    if (globals.theMap.ie)
      btn=globals.theMap.page.event.srcElement;
    else
      btn=e.target;
    globals.theMap.toolbar.origImg=btn.src;
    btn.setAttribute("src","../images/" + btn.getAttribute("id") + "_1_m.gif");
  }

  Toolbar.prototype.unHover=function(e){
    var btn;
    if (globals.theMap.ie)
      btn=globals.theMap.page.event.srcElement;
    else
      btn=e.target;
     btn.src=globals.theMap.toolbar.origImg;
  }

  Toolbar.prototype.getButton=function(buttonName){
     for(var i=0;i<11;i++){
      if(this.im[i].id==buttonName)
        return this.im[i];
      }
      return null;

  }

  function ToolButton(map,label,action){
    this.button=map.page.document.createElement("button");
    this.button.innerHTML=label;
    this.button.style.position="absolute";
    if(!map.ie)
      this.button.type="button";
    this.button.className="toolbutton_";
    this.button.style.zIndex=0;
    this.button.style.width=150;
    this.button.style.height=40;
    this.button.style.top=10;
    this.button.style.left=map.width-160;
    if(map.ie){
      this.button.attachEvent("onclick",action);
    }
    else{
      this.button.addEventListener("click",action,false);
    }
    map.page.document.body.appendChild(this.button);
    this.parent=map;
  }
