/**
 *<settings
 *  bounds_sw.lat="51.85" bounds_sw.lng="4.625" bounds_ne.lat="52.35" bounds_ne.lng="5.625"
 *  restricted="false" extend.lat="0.5" extend.lng="0.75">
 * </settings>
 */

function hbMap (settings, lazy)
{
  this.settings = settings;
  this.bounds = new GLatLngBounds (new GLatLng (-90, -180), new GLatLng (90, 180));
  this.defaultZoom = 0;
  this.defaultCenter = this.bounds.getCenter ();
  this.restricted = false;
  this.restriction = null;
  this.extendedRestriction = null;
  this.busyZoom = false;
  this.busyPan = false;
  this.nameToLayer = new Object ();
  this.isInitialized = function () {return false;};
  this.isInfoWindowOpened = false;
  this.veil = null;
/*
  var veilSettings = settings.get ("veil");
  
  if (veilSettings)
  {
    var veilUrl = veilSettings [0] ["url"];
    var png = veilUrl.toLowerCase ().lastIndexOf (".png");
    var isAPng = (png < veilUrl.length - 4) ? false : true;

    this.veil = new GTileLayerOverlay (new hbVeilLayer (
        null,
        0,
        17,
        {opacity: veilSettings [0] ["opacity"],
         isPng: isAPng,
         tileUrlTemplate: veilUrl}));
  }
*/
  if (true == this.settings.isInitialized ())
  {
    this.initialize (lazy);
  }
}

hbMap.prototype.initialize = function ()
{
  if (GBrowserIsCompatible ())
  {
    this.map = new GMap2 (document.getElementById ("map"));
    this.map.addControl (new GLargeMapControl ());
    this.map.addControl (new GMapTypeControl ());
    this.map.addControl (new GScaleControl ());
    this.map.addControl (new GOverviewMapControl ());
    this.map.enableDoubleClickZoom ();
    this.map.enableContinuousZoom ();
    this.map.enableScrollWheelZoom ();
    this.map.enableInfoWindow ();
    
    this.bounds = new GLatLngBounds (
        new GLatLng (settings.get ("bounds_sw.lat"), settings.get ("bounds_sw.lng")),
        new GLatLng (settings.get ("bounds_ne.lat"), settings.get ("bounds_ne.lng")));
    this.defaultCenter = this.bounds.getCenter ();
    this.defaultZoom = this.map.getBoundsZoomLevel (this.bounds);

    var lastZoom = vcnlinfoCookies.get ("zoom");
    var lastCenter = vcnlinfoCookies.get ("center");

    if (lastZoom && lastCenter && (0 < lastZoom.length) && (0 < lastCenter.length))
    {
      var coords = lastCenter.split (" ");
      var lastCenterLatLng = new GLatLng (coords [0], coords [1]);
      this.map.setCenter (lastCenterLatLng, parseInt (lastZoom));
    }
    else
    {
      this.map.setCenter (this.defaultCenter, this.defaultZoom);
    }
/*
    if (null != this.veil)
    {
      this.map.addOverlay (this.veil);
      this.veil.show ();
    }

    var tableauSettings = settings.get ("tableau");
  
    if (tableauSettings)
    {
      var opacity = tableauSettings [0] ["opacity"];
      var url = tableauSettings [0] ["url"];
      var bounds = new GLatLngBounds (
          new GLatLng (tableauSettings [0] ["bounds_sw.lat"], tableauSettings [0] ["bounds_sw.lng"]),
          new GLatLng (tableauSettings [0] ["bounds_ne.lat"], tableauSettings [0] ["bounds_ne.lng"]));
      //this.groundOverlay = new GGroundOverlay (url, bounds);
      this.groundOverlay = new Rectangle(bounds);
    }
 */
    var _restricted = settings.get ("restricted");

    if ("true" == _restricted)
    {
      this.restricted = true;
      var latExtension = settings.get ("extend.lat");
      var lngExtension = settings.get ("extend.lng");

      this.restriction = this.bounds;
      this.extendedRestriction = new GLatLngBounds (
          new GLatLng (this.bounds.getSouthWest().lat () - latExtension,
                       this.bounds.getSouthWest().lng () - lngExtension),
          new GLatLng (this.bounds.getNorthEast().lat () + latExtension,
                       this.bounds.getNorthEast().lng () + lngExtension));
    }

    GEvent.addListener (this.map,
                        "infowindowopen",
                        this.getHandleOpenInfoWindowFct ());

    GEvent.addListener (this.map,
                        "infowindowclose",
                        this.getHandleCloseInfoWindowFct ());

    GEvent.addListener (this.map,
                        "zoomend",
                        this.getHandleZoomFct ());

    GEvent.addListener (this.map,
                        "moveend",
                        this.getHandleMoveFct ());

    GEvent.addListener (this.map,
                        "click",
                        this.getHandleClickFct ());

    this.isInitialized = function () {return true;};
  }
}

hbMap.prototype.setView = function (center, zoom)
{
  this.map.setCenter (center, zoom);
}

hbMap.prototype.getZoom = function ()
{
  return this.map.getZoom ();
}

hbMap.prototype.getCenter = function ()
{
  return this.map.getCenter ();
}

hbMap.prototype.resetView = function ()
{
  this.map.setCenter (this.defaultCenter, this.defaultZoom);
}

hbMap.prototype.getHandleClickFct = function ()
{
  var thisMap = this;

  return function (overlay, point)
  {
    if (undefined == overlay)
    {
      if (null != hbToken.prototype.visible)
      {
        hbToken.prototype.visible.clear ();
      }
    }

    if (undefined != mapFeedback)
    {
      setTimeout (function () {
        var iw = thisMap.map.getInfoWindow ();

        if (!iw.isHidden ())
        {
          mapFeedback (hbReport.prototype.infoWindowOpenedOfReport, iw.getSelectedTab ());
        }
      }, 300);
    }
  }
}

hbMap.prototype.getHandleOpenInfoWindowFct = function ()
{
  var thisMap = this;

  return function ()
  {
    thisMap.isInfoWindowOpened = true;

    if (null != hbToken.prototype.visible)
    {
      hbToken.prototype.visible.clearOnClick ();
    }
  }
}

hbMap.prototype.getHandleCloseInfoWindowFct = function ()
{
  var thisMap = this;

  return function ()
  {
    thisMap.isInfoWindowOpened = false;
    thisMap.getHandleMoveFct ().call (this);
  }
}

hbMap.prototype.getHandleZoomFct = function ()
{
  var thisMap = this;

  return function (oldLevel, newLevel)
  {
    vcnlinfoCookies.set ("zoom", newLevel);

    if (true == thisMap.isInfoWindowOpened)
    {
      thisMap.map.closeInfoWindow ();
    }

    if (null != hbToken.prototype.visible)
    {
      hbToken.prototype.visible.clear ();
    }

    if (true == thisMap.restricted)
    {
      if (newLevel < thisMap.defaultZoom)
      {
        if (false == thisMap.busyZoom)
        {
          thisMap.busyZoom = true;
          thisMap.map.setZoom (thisMap.defaultZoom);
          thisMap.busyZoom = false;
        }
      }
    }
  }
}

hbMap.prototype.getHandleMoveFct = function ()
{
  var thisMap = this;

  return function ()
  {
    var center = thisMap.map.getCenter ();
    vcnlinfoCookies.set ("center", "" + center.lat () + " " + center.lng ());

    if (true == thisMap.restricted)
    {
      if (true == thisMap.busyPan)
      {
        return;
      }

      thisMap.busyPan = true;

      var restrictedTo = thisMap.restriction;

      if (true == thisMap.isInfoWindowOpened)
      {
        restrictedTo = thisMap.extendedRestriction;
      }

      var bounds = thisMap.map.getBounds ();

      var sw = bounds.getSouthWest();
      var ne = bounds.getNorthEast();

      var panByLat = 0.0;
      var panByLng = 0.0;

      var diffLat = Math.min (Math.abs (restrictedTo.getNorthEast ().lat () - ne.lat ()),
                              Math.abs (restrictedTo.getSouthWest ().lat () - sw.lat ()));
      var diffLng = Math.min (Math.abs (restrictedTo.getNorthEast ().lng () - ne.lng ()),
                              Math.abs (restrictedTo.getSouthWest ().lng () - sw.lng ()));

      if (    (restrictedTo.getNorthEast ().lat () < ne.lat ())
           && (restrictedTo.getSouthWest ().lat () < sw.lat ()))
      {
        panByLat = -diffLat;
      }
      else if (    (restrictedTo.getSouthWest ().lat () > sw.lat ())
                && (restrictedTo.getNorthEast ().lat () > ne.lat ()))
      {
        panByLat = diffLat;
      }

      if (    (restrictedTo.getNorthEast ().lng () < ne.lng ())
           && (restrictedTo.getSouthWest ().lng () < sw.lng ()))
      {
        panByLng = -diffLng;
      }
      else if (    (restrictedTo.getSouthWest ().lng () > sw.lng ())
                && (restrictedTo.getNorthEast ().lng () > ne.lng ()))
      {
        panByLng = diffLng;
      }

      var panLatLng = new GLatLng (panByLat + center.lat (),
                                   panByLng + center.lng ());
      thisMap.map.panTo (panLatLng);
      thisMap.busyPan = false;
    }
  }
}

hbMap.prototype.addLayer = function (layerMgr)
{
  for (var layer in layerMgr.nameToLayer)
  {
    this.nameToLayer [layer] = layerMgr.nameToLayer [layer];
  }
}

hbMap.prototype.showFeedInfo = function ()
{
  if (false == this.isInitialized ())
  {
    return;
  }

  var whatToShow = this.settings.get ("showInfo");
  var infos = new Object ();

  for (var what in whatToShow)
  {
    var i = whatToShow [what] ["elementName"];
    infos [i] = new Object ();
    infos [i].caption = whatToShow [what] ["caption"];
    infos [i].unit = whatToShow [what] ["unit"];
    infos [i].value = 0.0;
    infos [i].present = false;
  }

//  var complete = true;

  for (var l in this.nameToLayer)
  {
    if (true == this.nameToLayer [l].isVisible ())
    {
/*      if (false == this.nameToLayer [l].isInitialized ())
      {
        complete = false;
        continue;
      }
*/
      var layerInfos = this.nameToLayer [l].getInfo ();

      for (var i in infos)
      {
        if (i in layerInfos)
        {
          infos [i].value += parseFloat (layerInfos [i]);
          infos [i].present = true;
        }
      }
    }
  }

  var text = "";

  for (var i in infos)
  {
    if (true == infos [i].present)
    {
      text += infos [i].caption + infos [i].value + infos [i].unit + " ";
    }
  }

  var newFeedInfo = document.createElement ("div");
  var oldFeedInfo = document.getElementById ("feedInfo");

  if (!newFeedInfo)
  {
    return;
  }

  newFeedInfo.id = "feedInfo";

  if ("" != text)
  {
    var textNode = document.createTextNode (text);
    var formattedNode = document.createElement ("font");
    formattedNode.color = "white";
    formattedNode.face = "Arial";
    formattedNode.size = "3";
    formattedNode.appendChild (textNode);
    newFeedInfo.appendChild (formattedNode);
  }

  if (oldFeedInfo)
  {
    document.body.replaceChild (newFeedInfo, oldFeedInfo);
  }
  else
  {
    document.body.appendChild (newFeedInfo);
  }

/*  if (false == complete)
  {
    var thisMap = this;
    setTimeout (function () {thisMap.showFeedInfo ()}, 500);
  }*/
}

hbMap.prototype.redraw = function (layerSpec)
{
  if (false == this.isInitialized ())
  {
    return;
  }

 // showBusyCursor ();
/*
  this.map.addOverlay (this.groundOverlay);
*/

  if (null != hbToken.prototype.visible)
  {
    hbToken.prototype.visible.clear ();
  }

  for (var l in this.nameToLayer)
  {
    var toShow = false;

    if (layerSpec)
    {
      for (var ls in layerSpec)
      {
        if (layerSpec [ls].layername == l)
        {
          toShow = true;
          break;
        }
      }
    }

    if (true == toShow)
    {
      this.nameToLayer [l].setFilter (layerSpec [ls]);
      this.nameToLayer [l].show ();
    }
    else
    {
      this.nameToLayer [l].hide ();
    }
  }

  this.showFeedInfo ();

//  hideBusyCursor ();
}

hbMap.prototype.clearOverlays = function ()
{
  if (false == this.isInitialized ())
  {
    return;
  }

  for (var l in this.nameToLayer)
  {
    this.nameToLayer [l].hide ();
  }

  this.map.clearOverlays ();
/*
  if (null != this.veil)
  {
    this.map.addOverlay (this.veil);
    this.veil.show ();
  }*/
}
