  var mapWidth  = 3;
  var mapHeight = 2;

  var quadrantSize = 200; //[pixels]
  var mapBorderWidth = 35;
  var containerLayer;
  var containerLayerDoc;
  var areaphotosLayer;
  var frameLayer;

  var resolution = 8;     //[m/pixel], default (not used!). Initial is obtained from applet

  var mapsLayer;
  var startpointLayer;
  var markpointLayer;
  var infoboxLayer;

  //later those constants should be calculated dynamicaly.
  var load = 6;
  var loadCount=0;

  function checkL() {
    loadCount++;
    if (loadCount == load) restoreStatus ();
  }
  function restoreStatus () {
    self.status='';
  }
  function catchStatus () {
    self.status='loading maps';
    return true;
  }
  function setMoveStatus(txt) {
    self.status='Move in ' + txt + ' direction';
  }
  function setResStatus(txt) {
    self.status='Switch to ' + txt + ' meters in 1 pixel resolution';
  }

  function pan(x,y) {
    loadCount = 0;
    catchStatus ();

    if (document.areal)
      document.areal.moveCenter (x, y);
    showStartPoint();
    initMap (areaphotosLayer);
    initMap (mapsLayer);
  }

  function setLayerMapPosition (layer, x, y) {
    if (!layer) return;
    mapOffsetX=0;
    mapOffsetY=0;
    if (typeof(containerLayer.offsetLeft) == 'number') {
      mapOffsetX = containerLayer.offsetLeft + containerLayer.scrollLeft + mapBorderWidth;
      mapOffsetY = containerLayer.offsetTop + containerLayer.scrollTop + mapBorderWidth;
    }
    else if (containerLayer.pageX) {
      mapOffsetX = containerLayer.pageX + mapBorderWidth;// + document.body.scrollLeft;
      mapOffsetY = containerLayer.pageY + mapBorderWidth;// + document.body.scrollTop;
    }
    var xx = x + mapOffsetX;
    var yy = y + mapOffsetY;
    setPosition (layer, xx, yy);
  }

  function showStartPoint ()  {
    if (!startpointLayer) return;
    if (document.areal) {
      scrPoint = document.areal.getStartPixels ();
      if (typeof(scrPoint) != 'object') //something went wrong
        return;
      if (scrPoint == null) { //starting point is outside the frame
        hideLayer (startpointLayer);
        return;
      }
      x = scrPoint.getX ();
      y = scrPoint.getY ();
      if ((x > -1) && (y > -1) && (x<mapWidth*quadrantSize) && (y<mapHeight*quadrantSize)) {
        setLayerMapPosition (startpointLayer, x-7, y-7);
        showLayer (startpointLayer);
      }
      else
        hideLayer (startpointLayer);
    }
  }

  function showMarkPoint (x, y)  {
    if (!markpointLayer) return;
    if (typeof(markpointLayer) == 'undefined') return;
    if ((x > -1) && (y > -1) && (x<mapWidth*quadrantSize) && (y<mapHeight*quadrantSize)) {
      setLayerMapPosition (markpointLayer, x-7, y-7);
      showLayer (markpointLayer);
    }
  }

  function getTable (targetLayer) {
    if (!targetLayer) return '';
    txt = '<TABLE border="0" cellspacing="0" cellpadding="0">';
    for (i=0; i<mapHeight; i++) {
      txt += '<TR>';
      for (j=0; j<mapWidth; j++)
        txt += '<td><IMG align="top" height=200 width=200 src="' + document.areal.getPictureAddress (j, i, targetLayer) + '" height=200 width=200 border="0" onAbort="javascript:checkL();" onLoad="javascript:checkL();"></td>\n';
      txt += '</TR>';
    }
    txt += '</TABLE>';
    return txt;
  }

  function initMap (layer) {
    if (!layer) return;
    if (!layerShown (layer)) return;

    tabletext = getTable (layer.id);
    setText (layer, tabletext);
  }

  function getImageObject (imageName, layerName) {
    var imageObj;
    if (document.images) {
      imageObj  = document.images[imageName]; 
    }  
    if ((typeof (imageObj) == 'undefined') && (document.layers)) {
      if (layerName) {
        obj = document.layers[layerName]; //try to find layer in parent document
        if (!obj) {
          obj = containerLayerDoc.layers[layerName]; //search for layer in Container layer
        }
        if (obj)
          imageObj  = obj.document.images[imageName];                
      }
    }
    return imageObj;            
  }

  function scale (newScale)  {
    if (newScale != resolution) {
      obj = getImageObject ('scale' + resolution, 'resolutionDiv');
      if (typeof(obj) != 'undefined') 
        obj.src = '/images/bres'+resolution+'.gif';
      resolution = newScale;
      obj = getImageObject ('scale' + resolution, 'resolutionDiv');
      if (typeof(obj) != 'undefined') 
        obj.src = '/images/bres'+resolution+'_p.gif';
      document.areal.setResolution (newScale);
      pan (0,0);
    }
  }
  
  function controlDown (control) {
    img = getImageObject (control+'Img', control + 'Div');
    if (img) img.src = '/images/b'+control+'_p.gif';
    return true;

  }
  function controlUp (control) {
    img = getImageObject (control+'Img', control + 'Div');
    if (img) img.src = '/images/b'+control+'.gif';
    return true;
  }
  function controlOut (control) {
    controlUp (control);
  }

  function initVars () {
    containerLayer  = getMainDocLayer ('containerDiv');
    if (document.layers) // NN 4+
      containerLayerDoc = containerLayer.document;

    infoboxLayer    = getMainDocLayer ('infoboxDiv');
    areaphotosLayer = getMainDocLayer ('areaphotosDiv', containerLayerDoc);
    startpointLayer = getMainDocLayer ('startPointDiv');
    markpointLayer  = getMainDocLayer ('markPointDiv');
    frameLayer      = getMainDocLayer ('frameDiv', containerLayerDoc);
    framecoverLayer = getMainDocLayer ('frameCoverDiv', containerLayerDoc);

    mapsLayer       = getMainDocLayer ('mapsDiv', containerLayerDoc);

    initControls ();

    //for NN version prior to 6.0 and IE version prioor to 6.0 we need to adjust frame layer
    if (document.all && document.documentElement) { // IE 5+
      t = navigator.userAgent.toLowerCase();
      if (t.indexOf ('msie 5.') + 1)
        if (frameLayer.style) frameLayer.style.left = -3;
    }
    else if (document.all)  //IE 4
      if (frameLayer.style) frameLayer.style.left = -3;
    else if (document.layers) // NN 4+ 
      frameLayer.left = -3;
  }

  function initControls () {
    //Skip resizing-repositioning if NN4.7-
    if (document.layers) {
      showControls ();
      return;
    }
 
    //Skip resizing-repositioning if default are used
    if ((mapWidth != 3) || (mapHeight != 2)) {
      butOffset = 6;
      w = mapBorderWidth*2 + mapWidth*quadrantSize;
      h = mapBorderWidth*2 + mapHeight*quadrantSize;
      resWidth = 160;  //approx. width of resolution control

      var control;
      imgObj = getImageObject ('frameImg', 'frameDiv');
      if (imgObj)
        imgObj.src = '/images/vframe' + mapWidth + mapHeight + '.gif';

      imgObj = getImageObject ('coverImg', 'frameCoverDiv');
      if (imgObj) {
        imgObj.width = mapWidth*quadrantSize;
        imgObj.height = mapHeight*quadrantSize;
      }

      control = getMainDocLayer ('resolutionDiv'); 
      setPosition (control, 3*w/4 -24/4 - butOffset/2 - resWidth/2, h - 35);
      control = getMainDocLayer ('topleftDiv');
      setPosition (control, butOffset, butOffset);
      control = getMainDocLayer ('topDiv');
      setPosition (control, (w - 24)/2, butOffset);
      control = getMainDocLayer ('toprightDiv');
      setPosition (control, w - 24 - butOffset, butOffset);
      control = getMainDocLayer ('leftDiv');
      setPosition (control, butOffset, (h - 24)/2);
      control = getMainDocLayer ('rightDiv');
      setPosition (control, w- 24 - butOffset, (h - 24)/2);
      control = getMainDocLayer ('bottomleftDiv');
      setPosition (control, butOffset, h - 24 - butOffset);
      control = getMainDocLayer ('bottomDiv');      
      setPosition (control, (w - 24)/2, h - 24 - butOffset);
      control = getMainDocLayer ('bottomrightDiv');
      setPosition (control, w - 24 - butOffset, h - 24 - butOffset);
    }
    showControls ();
  }

  function showControls () {
    var control;

    showLayer (frameLayer);
    showLayer (framecoverLayer);

    control = getMainDocLayer ('resolutionDiv', containerLayerDoc); 
    showLayer (control);
    control = getMainDocLayer ('topleftDiv', containerLayerDoc);
    showLayer (control);
    control = getMainDocLayer ('topDiv', containerLayerDoc);
    showLayer (control);
    control = getMainDocLayer ('toprightDiv', containerLayerDoc);
    showLayer (control);
    control = getMainDocLayer ('leftDiv', containerLayerDoc);
    showLayer (control);
    control = getMainDocLayer ('rightDiv', containerLayerDoc);
    showLayer (control);
    control = getMainDocLayer ('bottomleftDiv', containerLayerDoc);
    showLayer (control);
    control = getMainDocLayer ('bottomDiv', containerLayerDoc);
    showLayer (control);
    control = getMainDocLayer ('bottomrightDiv', containerLayerDoc);
    showLayer (control);
  }

  function initResolution() {
    resolution = document.areal.getResolution();
    obj = getImageObject ('scale' + resolution, 'resolutionDiv');
    if (typeof(obj) != 'undefined') 
      obj.src = '/images/bres'+resolution+'_p.gif';
  }

  function initLayers () {
    showLayer (areaphotosLayer);
    showLayer (mapsLayer);
    pan (0,0);
    showStartObject ();
  }


  function showStartObject () {
    if (!infoboxLayer) return;
    if (document.areal) {
      scrPoint = document.areal.getStartPixels ();
      if (typeof(scrPoint) != 'object') //something went wrong
        return;
      if (scrPoint == null) { //starting point is outside the frame
        hideLayer (startpointLayer);
        return;
      }
      x = scrPoint.getX ();
      y = scrPoint.getY ();

      txt = document.areal.getWelcomeMessage ();
      showNearestObject (x, y, txt);
    }
  }

  function checkInfoBox (ev) {
    if (typeof(infoboxLayer) == 'undefined') return;
    if (layerShown (infoboxLayer)) hideLayer(infoboxLayer);
    if (layerShown (markpointLayer)) hideLayer (markpointLayer);
    if (document.all) {
      if (ev) ev.cancelBubble = true;
    }
  }
  function checkInfoBoxAndRoute (evt) {
    checkInfoBox ();
    if (document.layers) {
      return document.routeEvent(evt);
    }
    else if (document.routeEvent) {
      document.routeEvent(evt);
    }
  }

  function initHandlers () {
    if (document.all)
      document.onmouseup = checkInfoBox;
    else if (document.layers) {
      document.captureEvents(Event.CLICK); 
      document.onclick = checkInfoBoxAndRoute;
      containerLayerDoc.captureEvents(Event.CLICK);
      containerLayerDoc.onclick = checkInfoBoxAndRoute;
      window.captureEvents(Event.RESIZE);
      window.onresize = reinit;
    }
    else if (document.addEventListener) {
      document.addEventListener('click',checkInfoBoxAndRoute,true);
    }
  }

function JREVersion () {
  var appletMimeType = navigator.mimeTypes['application/x-java-vm'];
  if (!appletMimeType || !appletMimeType.enabledPlugin)
    return null;
  var re = /JRE (\d\.\d(\.\d))/
  var match = re.exec(appletMimeType.enabledPlugin.description);
  if (!match)
    return null
  else {
    var jreVersion = match[1];
    return jreVersion;
  }
}

  var attempt_count = 0;
  function init () {
    attempt_count++;
    if (attempt_count >= 11) {   //applet was not initialized in 10 seconds...
      window.clearInterval (timer_id);
      document.write ('<b>Applet failed to be started</b><br>Possible reason: absence of required Java plug-in.<br>');
      document.write ('You may find the information about plug-in and download it <A href="http://plugins.netscape.com/plug-in_finder.adp?mimetype=application/x-java-vm">here</A>');      
      document.close();
    }
    if (document.areal) {
//      alert(JREVersion());
      t = document.areal.isActive();
      if (t) {
        window.clearInterval (timer_id);
    
        loc = window.location;
        if (loc && (loc.hash.indexOf ('#set') != -1)) {
          query = loc.search;
          if ((query == '') && (loc.hash.length > 4)) //in Gecko 1.0.1 bug: query = ''
            query = loc.hash.substring (4);
          if (query != '') {
            if (document.layers)
              query += '&resize=false'; 
            document.areal.initFromQuery (query);
//            mapWidth  = document.areal.getMapWidth ();
//            mapHeight = document.areal.getMapHeight ();
          }
        }
        mapWidth  = document.areal.getMapWidth ();
        mapHeight = document.areal.getMapHeight ();
        initVars ();
        initResolution();
        initLayers();
        initHandlers();
      }
    }
  }

  var timer_id;
  function waitForApplet() {
    timer_id = window.setInterval ("init()", 1000);
  }

  function reinit() {
//an attempt to fix Netscape 4.7- bug with resizing. Reload relative to center coordinates
    txt='';
    loc = self.location;
    if (loc.protocol) txt += loc.protocol+'//';
    if (loc.hostname) txt += loc.hostname;
    if (loc.pathname) txt += loc.pathname;

    if (document.layers) {
      txt += '#set?';
      if (document.areal) {
        gdcPoint = document.areal.getGdcPoint (mapWidth*quadrantSize /2, mapHeight*quadrantSize /2);
        if ((typeof(gdcPoint) == 'object') && (gdcPoint != null)) {
          txt += 'lat='  + gdcPoint.getLatitude();
          txt += '&lon=' + gdcPoint.getLongitude();
        }
        txt += '&res=' + document.areal.getResolution();
      }

      self.location = txt;
    }
  }

  function frameClicked (ev)  {
    checkInfoBox();
    if (!ev) {
      if (window.event) ev = window.event;    //DOM
      else return;                            //failure, emergency exit.
    }

    mapX = 0;
    mapY = 0;
    if (typeof (ev.layerX) == 'number') {   //NS 4, NS 6+, Mozilla 0.9+
      mapX = ev.layerX;
      mapY = ev.layerY;
    } 
    else {
      if (typeof (ev.offsetX) == 'number') {   //IE, Opera, NS 6+, Mozilla 0.9+, except that NS 6+ and Mozilla 0.9+ did pageX ...
        mapX = ev.offsetX;
        mapY = ev.offsetY;
      }
      else //cannot get mouse coordinates
        return;
    }

    showNearestObject (mapX, mapY);
    if (document.all)
      event.cancelBubble = true;
    return true;  
  }

  function showNearestObject (x, y, prefix) {
    txt = '';
    if (typeof(prefix) != 'undefined')
      txt = prefix;
    obj = document.areal.getNearestObjectAtPixelLocation (x, y);
    if (typeof(obj) != 'object') {
      txt = 'object type is expected';
    }
    else if (obj == null) {
      txt += 'No object available for this map view';
      txt += '\n<br><b>map click coordinates:</b> ' + x + ' x ' + y;
      txt += getCoordinates (x, y);
//      txt += getLayerCoordinatesInfo (containerLayer);
    }
    else {
      if (document.areal) {
        if (document.areal.gdcPointIsOutsideTheFrame (obj.getLatitude(), obj.getLongitude()))
          txt += obj.getOutOfFrameInfo ();
        else {
          txt += obj.getObjectInfo ();
          scrPoint = document.areal.getScreenPoint (obj.getLatitude(), obj.getLongitude());
          if ((typeof(scrPoint) == 'object') && (scrPoint != null)) {
            x = scrPoint.getX ();
            y = scrPoint.getY ();
          }
        }
      }
    }
    drowObjectInfoBox (x, y, txt);
  }
  
  function drowObjectInfoBox (x, y, text) {
    //x, y -- frame pixel coordinates, might need adjustment
    if (!infoboxLayer) return;
    if (!document.areal) return;
    if (!text || (text == '')) return;

    txt = '<TABLE width="334" border="2"><tr><td>' +
          '<A href="javascript:void(0);" onClick="checkInfoBox(event);return false;" onmouseDown="javascript:controlDown(\'infobox\');" onmouseUp="javascript:controlUp(\'infobox\');" onmouseout="javascript:controlOut(\'infobox\');" onFocus="this.blur();">' +
          '<IMG name="infoboxImg" src="/images/binfobox.gif" width="14" height="13" align="right" border="0">' +
          '</A><br>'+
          text + '</td></tr></TABLE>';    
    setText (infoboxLayer, txt);

    setLayerMapPosition (infoboxLayer, x+5, y+5);
    showLayer (infoboxLayer);
    return false;
  }

  function goToObject (latitude, longitude) {
    if (document.areal) {
      if (document.areal.gdcPointIsOutsideTheFrame (latitude, longitude)) {
        document.areal.initWithGDCPoint (latitude, longitude);
        pan (0,0);
      }

      scrPoint = document.areal.getScreenPoint (latitude, longitude);
      if ((typeof(scrPoint) == 'object') && (scrPoint != null)) {
        var xx = scrPoint.getX ();
        var yy = scrPoint.getY ();
        window.scrollTo (xx, yy);
        showMarkPoint (xx, yy);
        showNearestObject (xx, yy);
      }
    }
  }

  function getCoordinates (x, y) {
    txt = '\n<br><b>GDC:</b>';
    if (document.areal) {
      gdcPoint = document.areal.getGdcPoint (x, y);
      if ((typeof(gdcPoint) == 'object') && (gdcPoint != null)) {
        prec = 10000;
        lat = Math.round (gdcPoint.getLatitude() * prec) / prec;
        lon = Math.round (gdcPoint.getLongitude()* prec) / prec;
        txt += '\n lat: ' + lat + ';  long: ' + lon;
      }
      utmPoint = document.areal.getUtmPoint (x, y);
      if ((typeof(utmPoint) == 'object') && (utmPoint != null)) {
        txt += '\n<br><b>UTM:</b>';
        prec = 100;
        xx = Math.round (utmPoint.getEasting() * prec) / prec;
        yy = Math.round (utmPoint.getNorthing()* prec) / prec;
        zz = utmPoint.getZone();
        txt += '\n x: ' + xx + ';  y: ' + yy + '; z: ' + zz;
      }
    }
    return txt;
  }

  function showHTML (layer) {
    alert (layer.innerHTML);
  }

  function showWindowLocation () {
    alert ('loc.hash:      ' + loc.hash + 
           '\nloc.host     ' + loc.host + 
           '\nloc.hostanme ' + loc.hostanme + 
           '\nloc.href     ' + loc.href +
           '\nloc.pathname ' + loc.pathname +
           '\nloc.port     ' + loc.port +
           '\nloc.protocol ' + loc.protocol +
           '\nloc.search   ' + loc.search);
  }
