/* TabbedInfoWindow uses the OverlayView to recreate API v2's tabbed info windows */

function TabbedInfoWindow(opts) {
  //console.log('TabbedInfoWindow Init');
  google.maps.OverlayView.call(this, opts.map);
  this.latlng_ = opts.latlng;
  this.map_ = opts.map;
  this.tabs_ = opts.tabs; 
  this.tailImgSrc = opts.tail || 'img/infowindow-tail.png';
  //this.height_ =  175;
  this.width_ =  320;
  this.paddingTop_ = 50;
  this.paddingRight_ = 50;
  this.paddingBottom_ = 50;
  this.paddingLeft_ = 50;
  this.offsetX_ = 0;
  this.offsetY_ = -80;
  this.visible_ = false;    
      
  if(this.visible)
  {
    this.setMap(this.map_);
  }
      
  var me = this;
  google.maps.event.addListener(this.map_, 'bounds_changed', function() {
    me.draw();
  });
};

/* TabbedInfoWindow extends OverlayView class from the Google Maps API
 */
TabbedInfoWindow.prototype = new google.maps.OverlayView();


/**
 * Called when the overlay is first added to the map.
 */
TabbedInfoWindow.prototype.onAdd = function()
{
  //console.log('TabbedInfoWindow onAdd');
  // Creates the element if it doesn't exist already.
  this.createWindow();
};

TabbedInfoWindow.prototype.onRemove = function() 
{
  //console.log('TabbedInfoWindow onRemove');
  if (this.div_) {
    this.div_.parentNode.removeChild(this.div_);
    this.div_ = null;
  }
};
TabbedInfoWindow.prototype.open = function(map, marker)
{
  //console.log('TabbedInfoWindow Open');
  this.visible_ = true;
  this.panned_ = false;
  this.setMap(map); 
  
  this.maybePanMap();
  
};
TabbedInfoWindow.prototype.close = function()
{
  //console.log('TabbedInfoWindow Close');
  this.visible_ = false; 
  if(typeof this.div_ != "undefined" && this.div_ != null)
  {
    this.div_.style.visibility = "hidden";
  }
  
  this.setMap(null); 

};
TabbedInfoWindow.prototype.updateTabContent = function(tab_id, tab_content)
{
  $('#'+tab_id).html(tab_content);
  for(var i = 0; i < this.tabs_.length; i++)
  {
    var tab = this.tabs_[i];
    if(tab.id == tab_id)
    {
      tab.content = tab_content;  
    }
    
  }
};

/**
 * Creates the DIV representing this TabbedInfoWindow in the floatPane.  If the panes
 * object, retrieved by calling getPanes, is null, remove the element from the
 * DOM.  If the div exists, but its parent is not the floatPane, move the div
 * to the new pane.
 * Called from within draw.  Alternatively, this can be called specifically on
 * a panes_changed event.
 */
TabbedInfoWindow.prototype.createWindow = function()
{
  var panes = this.getPanes();
  var div = this.div_;
  if (!div) {
    // This does not handle changing panes.  You can set the map to be null and
    // then reset the map to move the div.
    div = this.div_ = document.createElement('div');
    div.style.border = '0px none';
    div.style.position = 'absolute';
    div.style.overflow = 'hidden';
    div.style.zIndex = '500';
    div.style.paddingLeft = '20px';
        
    if(!this.tabs_) return;
        
    var tabDiv = document.createElement("div");
    tabDiv.id = "tabs";
    var tabNav = document.createElement("div");
    tabNav.id = "tab_slider_nav";
    for(var i = 0; i < this.tabs_.length; i++)
    {
      var tab = this.tabs_[i];
      var tabA = document.createElement("a");
      tabA.innerHTML = tab.label;
      tabA.href = '#'+tab.id;
      
      tabNav.appendChild(tabA);
    }
    tabDiv.appendChild(tabNav);

    var contentDiv = document.createElement('div');
    contentDiv.id = "tab_slider";
      
    for(var i = 0; i < this.tabs_.length; i++)
    {
      var tab = this.tabs_[i];
      var tabContentDiv =  document.createElement("div");
      tabContentDiv.id = tab.id;
      tabContentDiv.innerHTML = tab.content;
      contentDiv.appendChild(tabContentDiv);
    }
    
    tabDiv.appendChild(contentDiv);

    var closeImg = document.createElement("img");
    closeImg.style.cursor = "pointer";
    closeImg.src = "http://www.google.com/intl/en_us/mapfiles/close.gif";
    closeImg.style.position = "absolute";
    closeImg.style.top = "48px";
    closeImg.style.right = "10px";
    closeImg.style.zIndex = "50";
    
    var tailImg = document.createElement("img");
    tailImg.id = "infowindow-tail";
    tailImg.src =  this.tailImgSrc;
    tailImg.style.position = "absolute";
    tailImg.style.top = "54px";
    tailImg.style.left = "-1px";
    tailImg.style.zIndex = "999";
    
    div.appendChild(tabDiv);
    div.appendChild(closeImg);
    div.appendChild(tailImg);

    function removeTabbedInfoWindow(tiw) {
      return function() { 
        tiw.close();
      };
    }

    google.maps.event.addDomListener(closeImg, 'click', removeTabbedInfoWindow(this));
    
    
    div.style.display = 'none';
    
    panes.floatPane.appendChild(div);
      
  } else if (div.parentNode != panes.floatPane) {
    // The panes have changed.  Move the div.
    div.parentNode.removeChild(div);
    panes.floatPane.appendChild(div);
  } else {
    // The panes have not changed, so no need to create or move the div.
  }                  
};

TabbedInfoWindow.prototype.draw = function()
{
  if (!this.getProjection() || !this.div_) 
  {
    return;
  }

  var pixPosition = this.getProjection().fromLatLngToDivPixel(this.latlng_);
  var centerPosition = this.getProjection().fromLatLngToDivPixel(this.map_.getCenter());
  var centerPositionReal = new google.maps.Point(this.map_.getDiv().offsetWidth/2, this.map_.getDiv().offsetHeight/2);
  // Figure out difference between map div and tiles div, so that we can
  // calculate position in map div
  var centerOffsetX = -centerPosition.x + centerPositionReal.x;
  var centerOffsetY = -centerPosition.y + centerPositionReal.y;
  
  if (!pixPosition) return;

 
  // Now position our DIV based on the DIV coordinates of our bounds
  this.div_.style.width = this.width_ + 'px';
  
  if(this.height_)
  {
    this.div_.style.height = this.height_ + 'px';  
  }
  
  leftPos = (pixPosition.x + this.offsetX_) + centerOffsetX;
  topPos = (pixPosition.y + this.offsetY_) + centerOffsetY;
  this.div_.style.left = (pixPosition.x + this.offsetX_)+ 'px';
  this.div_.style.top = (pixPosition.y + this.offsetY_) + 'px';
  
  this.div_.style.display = 'block';
  
  
  if(this.visible_ == false)
  {
    this.div_.style.visibility = 'hidden';  
  }
  else
  {
    this.div_.style.visibility = 'visible';
   // $(function() {
//      $("#tabs").tabs();
//    });
//    
    $("#tab_slider").cycle(
    {
      fx: 'fade',
      pager: '#tab_slider_nav',
      pagerAnchorBuilder: function(idx, slide)
      {
        return '#tab_slider_nav a:eq(' + idx + ')';
      },
      timeout: 9999999,
      sync: 0,
      pause: 1,
      pauseOnPagerHover: 1
    }
    );
  }
  
  if (!this.panned_) 
  {
    this.panned_ = true;
    this.maybePanMap();
  }

}; 

TabbedInfoWindow.prototype.maybePanMap = function()
{
  // if we go beyond map, pan map 
  var map = this.map_;
  var projection = this.getProjection();
  var bounds = map.getBounds();
  var div = this.div_;
  if (!bounds || !projection || !div) return;

  // The dimension of the infowindow
  var iwWidth = this.width_;
  if(!this.height_)
  {
    var iwHeight = div.offsetHeight;
  }
  else
  {
    var iwHeight = this.height_;  
  }
  

  // The offset position of the infowindow
  var iwOffsetX = this.offsetX_;
  var iwOffsetY = this.offsetY_;
  
  var anchorPixel = projection.fromLatLngToDivPixel(this.latlng_);
  var leftP = anchorPixel.x + iwOffsetX - this.paddingLeft_;
  var bottomP = anchorPixel.y + iwOffsetY + iwHeight + this.paddingBottom_;
  var rightP = anchorPixel.x + iwOffsetX + iwWidth + 30 + this.paddingRight_;
  var topP = anchorPixel.y + iwOffsetY - this.paddingTop_;
  var bl = new google.maps.Point(
      leftP,
      bottomP);
  var tr = new google.maps.Point(
    rightP,
    topP);
  var sw = projection.fromDivPixelToLatLng(bl);
  var ne = projection.fromDivPixelToLatLng(tr);

  // The bounds of the infowindow
  if (!map.getBounds().contains(ne) || !map.getBounds().contains(sw)) {
    map.panToBounds(new google.maps.LatLngBounds(sw, ne));
  }
}


