/*
Class: DocktabGoogle


License:
  MIT-style license.

Author:
  Takashi Mizohata <beatak@nydd.org>

Copyright:
  2008 [nydd](http://code.nydd.org/).

Code & Documentation:
  [nydd jslib](http://code.nydd.org/).
*/

var DocktabGoogle = function (favicon, lat, lon)
{
  this.PIX_FRAME_WIDTH    = 10;
  this.PIX_MINIMUM_WIDTH  = 400;
  this.PIX_MINIMUM_HEIGHT = 300;
  this.PIX_OFFSET_TOP     = 34;
  this.PIX_OFFSET_BOTTOM  = this.PIX_OFFSET_TOP + this.PIX_FRAME_WIDTH;
  this.PIX_PADDING_BOTTOM = 300;
  this.RATIO_WIDTH        = .7;
  this.RATIO_HEIGHT       = .5;
  this.SCALE_ZOOM_ANIME   = 1.25;
  this.SEC_TAB_DISAPPEAR  = 1.3;
  this.SEC_TAB_APPEAR     = 1.5
  this.INDEX_INITIAL_ZOOM = 8;
  this.INT_MAX_RESOLUTION = 10
  this.INT_MIN_RESOLUTION = 6;

  this.elm        = {};
  this.elm.icon   = favicon;
  this.elm.tab    = $('#docktab div.tab.google').get(0);
  this.elm.close  = $('img.close', this.elm.tab).get(0);
  this.elm.ok     = $('button.ok', this.elm.tab).get(0);
  this.elm.map    = $('#googlemap').get(0);

  this.latitude         = lat;
  this.longitude        = lon;
  this.map              = null;
  this.mapController    = null;
  this.markers          = [];
  this.tempMarker       = null;

  this.isInitialized    = false;
  this.isLocal          = false;
  this.isMarkerVisible  = true;

  this.fnCache = {};
  this.fnCache.onResize         = jQuery.scope(this, this.onResize);
  this.fnCache.onClose          = jQuery.scope(this, this.onClose);
  this.fnCache.onAddOverlayDrop = jQuery.scope(this, this.onAddOverlayDrop);
  this.fnCache.onAddOverlayZoom = jQuery.scope(this, this.onAddOverlayZoom);
  this.fnCache.onDropPin        = jQuery.scope(this, this.onDropPin);
  this.fnCache.onZoomEnd        = jQuery.scope(this, this.onZoomEnd);
  

  this.onResize();
  $(window).bind('resize', this.fnCache.onResize);
  $(this.elm.close).bind('click', this.fnCache.onClose);
  $(this.elm.ok).bind('click', this.fnCache.onDropPin);

  this.prepareMap();
}

DocktabGoogle.prototype.prepareMap = function ()
{
  if (window.location.host.indexOf('.local') !== -1)
  {
    this.isLocal = true;
    return;
  }

  if (!GBrowserIsCompatible()) {
    throw new Error('Not compatible browser!?');
  }

  this.pinicon = new GIcon();
  this.pinicon.image      = Config.url.pinicon_image;
  this.pinicon.shadow     = Config.url.pinicon_shadow;
  this.pinicon.iconSize   = new GSize(15, 34);
  this.pinicon.shadowSize = new GSize(27, 37);
  this.pinicon.iconAnchor = new GPoint(7, 33);

  this.captureicon_6            = new GIcon();
  this.captureicon_6.image      = Config.url.captureicon_6;
  this.captureicon_6.shadow     = Config.url.captureicon_6_shadow;
  this.captureicon_6.iconSize   = new GSize(36, 36);
  this.captureicon_6.shadowSize = new GSize(36, 36);
  this.captureicon_6.iconAnchor = new GPoint(18, 18);

  this.captureicon_7            = new GIcon();
  this.captureicon_7.image      = Config.url.captureicon_7;
  this.captureicon_7.shadow     = Config.url.captureicon_7_shadow;
  this.captureicon_7.iconSize   = new GSize(68, 68);
  this.captureicon_7.shadowSize = new GSize(68, 68);
  this.captureicon_7.iconAnchor = new GPoint(34, 34);

  this.captureicon_8            = new GIcon();
  this.captureicon_8.image      = Config.url.captureicon_8;
  this.captureicon_8.shadow     = Config.url.captureicon_8_shadow;
  this.captureicon_8.iconSize   = new GSize(134, 134);
  this.captureicon_8.shadowSize = new GSize(134, 134);
  this.captureicon_8.iconAnchor = new GPoint(67, 67);

  this.captureicon_9            = new GIcon();
  this.captureicon_9.image      = Config.url.captureicon_9;
  this.captureicon_9.shadow     = Config.url.captureicon_9_shadow;
  this.captureicon_9.iconSize   = new GSize(220, 220);
  this.captureicon_9.shadowSize = new GSize(220, 220);
  this.captureicon_9.iconAnchor = new GPoint(110, 110);

  this.captureicon_10            = new GIcon();
  this.captureicon_10.image      = Config.url.captureicon_10;
  this.captureicon_10.shadow     = Config.url.captureicon_10_shadow;
  this.captureicon_10.iconSize   = new GSize(532, 532);
  this.captureicon_10.shadowSize = new GSize(532, 532);
  this.captureicon_10.iconAnchor = new GPoint(266, 266);

}


// SCRATCH PADS
// _______________________________________________________________________


DocktabGoogle.prototype.onZoomEnd = function (past, current)
{
  switch (true)
  {
    case (current > this.INT_MAX_RESOLUTION):
      this.map.setZoom(this.INT_MAX_RESOLUTION);
      return;
    break;

    case (current < this.INT_MIN_RESOLUTION):
      if (this.isMarkerVisible)
      {
        for (var i = 0, len = this.markers.length; i < len; ++i)
        {
          this.markers[i].hide();
        }

        if (this.tempMarker)
        {
          this.tempMarker.hide();
        }
        this.isMarkerVisible = false;
      }
    break;

    default:
      if (!this.isMarkerVisible)
      {
        for (var i = 0, len = this.markers.length; i < len; ++i)
        {
          this.markers[i].show();
        }

        if (this.tempMarker)
        {
          this.tempMarker.show();
        }
        this.isMarkerVisible = true;
      }
    break;
  }

  if (this.isMarkerVisible)
  {
    for (var i = 0, len = this.markers.length; i < len; ++i)
    {
      var old_marker = this.markers[i];
      this.map.removeOverlay(old_marker);
      var marker = this.makeMarker(old_marker.getLatLng(), current);
      this.map.addOverlay(marker);
      this.markers[i] = marker;
    }

    if (this.tempMarker)
    {
      this.map.removeOverlay(this.tempMarker);
      var tmp_marker = this.makeMarker(this.tempMarker.getLatLng(), current);
      this.map.addOverlay(tmp_marker);
      this.tempMarker = tmp_marker;
    }
  }
}

DocktabGoogle.prototype.makeMarker = function (LatLng, zoom)
{
  zoom = zoom || this.map.getZoom();
  return new GMarker(LatLng, {'icon': this['captureicon_' + zoom]});
}


DocktabGoogle.prototype.initMap = function ()
{
  if (this.isLocal)
  {
    return;
  }
  
  if (!this.isInitialized)
  {

    this.onResize();
    this.map = new GMap2(this.elm.map);
    this.map.setCenter(new GLatLng(this.latitude, this.longitude), this.INDEX_INITIAL_ZOOM);

    this.mapController = new GSmallMapControl();
    this.map.addControl(this.mapController);

    GEvent.addListener(
      this.map, 
      'addoverlay', 
      this.fnCache.onAddOverlayZoom
    );

    GEvent.addListener(
      this.map, 
      'zoomend', 
      this.fnCache.onZoomEnd
    );

    var self = this;
    window.setTimeout(
      function ()
      {
        self.onResize();
        var latlng = new GLatLng(self.latitude, self.longitude);
        self.map.panTo(latlng);
        self.addMarker(self.latitude, self.longitude);
        self.isInitialized = true;
      }, 
      100
    );

  }
  else
  {
    this.map.panTo(this.markers[(this.markers.length - 1)].getLatLng());
  }
}


DocktabGoogle.prototype.addMarker = function (lat, lng)
{
  var latlng
  if (lat instanceof GLatLng)
  {
    latlng = lat;
  }
  else
  {
    latlng = new GLatLng(lat, lng);
  }
  var marker = this.makeMarker(latlng);
  this.map.addOverlay(marker);
  this.markers[this.markers.length] = marker;
}


DocktabGoogle.prototype.onAddOverlayZoom = function (overlay)
{
  var obj     = overlay.V[0];
  var orig_x  = parseInt(overlay.V[0].style.left);
  var orig_y  = parseInt(overlay.V[0].style.top);
  var orig_w  = parseInt(overlay.V[0].style.width);
  var orig_h  = parseInt(overlay.V[0].style.height);

  obj._width    = orig_w * this.SCALE_ZOOM_ANIME;
  obj._height   = orig_h * this.SCALE_ZOOM_ANIME;
  obj.style.width  = obj._width + 'px';
  obj.style.height = obj._width + 'px';
  obj.style.left   = (orig_x - Math.floor((obj._width  - orig_w) / 2))+ 'px';
  obj.style.top    = (orig_y - Math.floor((obj._height - orig_h) / 2))+ 'px';

  JSTweener.addTween(
    obj,
    {
      'delay'       : 0,
      '_width'      : orig_w,
      '_height'     : orig_h,
      'time'        : .6,
      'transition'  : 'easeOutBounce',
      'onUpdate'    : function () {
        this.target.style.width  = this.target._width + 'px';
        this.target.style.height = this.target._width + 'px';
        this.target.style.left   = (orig_x - Math.floor((this.target._width  - orig_w) / 2))+ 'px';
        this.target.style.top    = (orig_y - Math.floor((this.target._height - orig_h) / 2))+ 'px';
      },
      'onComplete'  : function () {
        this.target.style.width  = orig_w + 'px';
        this.target.style.height = orig_h + 'px';
        this.target.style.left   = orig_x + 'px';
        this.target.style.top    = orig_y + 'px';
      }
    }
  );
}


DocktabGoogle.prototype.onAddOverlayDrop = function (overlay)
{
  var obj     = overlay.V[0];
  var orig_y  = parseInt(overlay.V[0].style.top);

  obj._y = (orig_y - 40);
  obj.style.top = obj._y + 'px';
  JSTweener.addTween(
    obj,
    {
      'delay'       : 0,
      '_y'          : orig_y,
      'time'        : .6,
      'transition'  : 'easeOutBounce',
      'onUpdate'    : function () { this.target.style.top = this.target._y + 'px'; },
      'onComplete'  : function () { this.target.style.top = orig_y + 'px'; }
    }
  );
}

DocktabGoogle.prototype.onDropPin = function ()
{
  var latlng = this.map.getCenter();
  if (this.tempMarker)
  {
    this.map.removeOverlay(this.tempMarker);
  }
  this.tempMarker = this.makeMarker(latlng);
  this.map.addOverlay(this.tempMarker);
}






























// ANIMATION METHODS
// _______________________________________________________________________


DocktabGoogle.prototype.show = function ()
{
  var self = this;
  var obj = this.elm.tab;

  var init_y = (-parseInt(obj.style.height));
  obj.style.bottom = init_y + 'px';
  obj.style.visibility = 'visible';
  obj._y  = init_y;
  JSTweener.addTween(
    obj,
    {
      'delay'       : 0.05,
      '_y'          : -(this.PIX_PADDING_BOTTOM),
      'time'        : this.SEC_TAB_APPEAR,
      'transition'  : 'easeOutElastic',
      'onUpdate'    : function () { obj.style.bottom  = obj._y + 'px'; },
      'onComplete'  : function () 
                      { 
                        self.initMap();
                      }
    }
  );
}


DocktabGoogle.prototype.hide = function ()
{
  var obj = this.elm.tab;

  var goal_y = (-parseInt(obj.style.height));
  obj._y  = -(this.PIX_PADDING_BOTTOM);
  JSTweener.addTween(
    obj,
    {
      'delay'       : 0,
      '_y'          : goal_y,
      'time'        : this.SEC_TAB_DISAPPEAR,
      'transition'  : 'easeInQuart',
      'onUpdate'    : function () { obj.style.bottom  = obj._y + 'px'; },
      'onComplete'  : function () 
                      {
                        obj.style.visibility = 'hidden';
                      }
    }
  );
}


// ACCESS METHODS
// _______________________________________________________________________



// CALLBACK METHODS
// _______________________________________________________________________




// EVENT METHODS
// _______________________________________________________________________


DocktabGoogle.prototype.onClose = function ()
{
  this.hide();
  PinupController.getInstance().reintroduceIcons(this.SEC_TAB_DISAPPEAR);
  if (this.tempMarker)
  {
    var latlng = this.tempMarker.getLatLng();
    this.markers[this.markers.length] = this.tempMarker;
    this.tempMarker = null;
    PinupController.getInstance().accessFetchByGeocode(latlng.lat(), latlng.lng());
  }
}


DocktabGoogle.prototype.onResize = function ()
{
  var max_w = $(document.body).width();
  var max_h = $(document.body).height();
  var w = Math.floor(max_w * this.RATIO_WIDTH);
  if (w < this.PIX_MINIMUM_WIDTH)
  {
    w = this.PIX_MINIMUM_WIDTH;
  }
  this.elm.tab.style.width = w + 'px';
  this.elm.tab.style.left = Math.floor((max_w - w) / 2) + 'px';

  var h = Math.floor(max_h * this.RATIO_HEIGHT);
  if (h < this.PIX_MINIMUM_HEIGHT)
  {
    h = this.PIX_MINIMUM_HEIGHT;
  }
  this.elm.tab.style.height = (h + this.PIX_PADDING_BOTTOM) + 'px';

  this.elm.map.style.width  = (w - (this.PIX_FRAME_WIDTH * 2)) + 'px';
  this.elm.map.style.height = (h - this.PIX_OFFSET_TOP - this.PIX_OFFSET_BOTTOM) + 'px';
}


// INSTANCE UTILITY METHODS
// _______________________________________________________________________




// STATIC UTILITY METHODS
// _______________________________________________________________________



