/*--------------------------------------------------------------
 * Find a Hotel Map Tooltips
 *------------------------------------------------------------*/

var currMapTip;     // Track the currently open MapTip
var mapTips = [];   // Array of all our MapTips

/*--------------------------------------------------------------
 * Function: attachMapTips
 *
 * Creates MapTips for any element with the class name mapCity.
 * Stores the MapTips in a global array.
 *
 * Parameters:
 * None
 *
 * Return:
 * None
 *------------------------------------------------------------*/
function attachMapTips() {
  // Get all elements with class name mapCity
  var mapCities = $$('.mapCity');
  
  // Create a new MapTip for each element and store the MapTip
  // in our global mapTips array.
  for (var i = 0; i < mapCities.length; i++) {
    mapTips[i] = new MapTip(mapCities[i]);
  }
}

/*--------------------------------------------------------------
 * Class: MapTip
 *
 * Represents a custom tooltip for client-side find-a-hotel image
 * map.
 *
 * Assumes the tooltip and image map area have ids related as
 * follows:
 * <tooltip id> = '<area id>Overlay'
 *------------------------------------------------------------*/
var MapTip = Class.create();

MapTip.prototype = {

  /*--------------------------------------------------------------
   * Function: initialize
   *
   * Creates a new MapTip instance and assigns event handlers.
   *
   * Parameters:
   * pEl   object reference  Reference to the image map area.
   *
   * Return:
   * None
   *------------------------------------------------------------*/
  initialize: function(pEl) {
    this.mapPt = pEl;                   // image map area element
    this.id = pEl.id;                   // id of the MapTip
    this.tip = $(this.id + 'Overlay');  // tooltip
    
    // Assign event handlers
    this.mapPt.onmouseover = this.mouseOverHandler.bindAsEventListener(this);
    this.mapPt.onmouseout = this.mouseOutHandler.bindAsEventListener(this);

    // Cancel the hide timer if we mouse back over the tooltip.
    this.tip.onmouseover = this.cancel.bindAsEventListener(this);
    this.tip.onmouseout = this.mouseOutHandler.bindAsEventListener(this);
  },
  
  /*--------------------------------------------------------------
   * Function: show
   *
   * Displays the tooltip
   *
   * Parameters:
   * None
   *
   * Return:
   * None
   *------------------------------------------------------------*/
  show: function() {
    // Only display one MapTip at a time.
    // Hide any MapTips already open.
    if (currMapTip) {
      currMapTip.hide();
    }

    // Display the tooltip.
    this.tip.style.display = 'block';
    
    // Update currMapTip to this MapTip
    currMapTip = this;
    
    // Save status
    this.shown = true;
  },
  
  /*--------------------------------------------------------------
   * Function: hide
   *
   * Hides the tooltip
   *
   * Parameters:
   * None
   *
   * Return:
   * None
   *------------------------------------------------------------*/
  hide: function() {
    // Hide the tooltip.
    this.tip.style.display = 'none';
    
    // Save status.
    this.shown = false;
    
    // Update currMapTip.
    currMapTip = null;
    
    // Cancel the timer to hide if any.
    this.cancel();
  },
  
  /*--------------------------------------------------------------
   * Function: isShown
   *
   * Returns true if the MapTip is showing, false if hidden.
   *
   * Parameters:
   * None
   *
   * Return:
   * boolean   true if the MapTip is showing, false if hidden.
   *------------------------------------------------------------*/
  isShown: function() {
    return this.shown;
  },
  
  /*--------------------------------------------------------------
   * Function: move
   *
   * Moves the tooltip to the given coordinates
   *
   * Parameters:
   * pX  integer   The x coordinate to move to
   * pY  integer   The y coordinate to move to
   *
   * Return:
   * None
   *------------------------------------------------------------*/
  move: function(pX, pY) {
    this.tip.style.top = pY + 'px';
    this.tip.style.left = pX + 'px';
  },
  
  /*--------------------------------------------------------------
   * Function: mouseOverHandler
   *
   * Event handler for when the pointer mouses over the image map
   * area.  Positions and displays the tooltip if not already shown.
   *
   * Parameters:
   * pEvt  event   The event object
   *
   * Return:
   * None
   *------------------------------------------------------------*/
  mouseOverHandler: function(pEvt) {
    // Don't move if we're already showing.
    // Avoids having the tooltip slide as the pointer drags over
    // the image map area.
    if (!this.shown) {
      // Display the tooltip slightly offset from the pointer.
      var x = Event.pointerX(pEvt) + 2;
      var y = Event.pointerY(pEvt) + 2;
    
      // Position and display the tooltip.
      this.move(x, y);
      this.show();
    }
  },
  
  /*--------------------------------------------------------------
   * Function: mouseOutHandler
   *
   * Event handler for when the pointer mouses out of the tooltip.
   * Hides the tooltip after a short delay.
   *
   * Parameters:
   * pEvt  event   The event object
   *
   * Return:
   * None
   *------------------------------------------------------------*/
  mouseOutHandler: function(pEvt) {
    var eventEl = Event.element(pEvt);
    var x = Event.pointerX(pEvt);
    var y = Event.pointerY(pEvt);
    // The event handler will fire if we mouse over and out of
    // any links contained in the tooltip.  Only hide if the
    // mouse has trully left the area of the tooltip.
    if ((eventEl == this.mapPt) || !Position.within(this.tip, x, y)) {
      // Set a timer to hide the tooltip after half a second.
      this.timer = setTimeout(this.hide.bind(this), 250);
    }
  },
  
  /*--------------------------------------------------------------
   * Function: cancel
   *
   * Cancels the hide timer.
   *
   * Parameters:
   * None
   *
   * Return:
   * None
   *------------------------------------------------------------*/
  cancel: function() {
    clearTimeout(this.timer);
    this.timer = null;
  }
}