/*
Copyright (c) 2009, McKesson All rights reserved.
version: 1.0.0
*/

// by convention, yui code uses javadoc comments

/**
 * PersistentTooltip extends YAHOO.widget.Tooltip and adds functionality so that the tooltip
 * will remain visible if the user has positioned the mouse over it.  This allows developers
 * to generate tooltips which are clickable.  The tooltip will close once the mouse is moved
 * outside its border.
 * Unlike YAHOO.widget.Tooltip, this version only accepts an HTMLElement (and not an id String).
 * This will be addressed in a later version.
 * @namespace YAHOO.widget
 * @class PersistentTooltip
 * @extends YAHOO.widget.Tooltip
 * @constructor
 * @param {HTMLElement} el The element representing the Tooltip
 * @param {Object} userConfig The configuration object literal containing 
 * the configuration that should be set for this Overlay/Tooltip. See configuration 
 * documentation for more details.
 */
YAHOO.widget.PersistentTooltip = function ( el, userConfig) { 
     // Chain the constructors 
    this.constructor.superclass.constructor.call(this, el, userConfig); 
}; 


YAHOO.lang.extend(YAHOO.widget.PersistentTooltip, YAHOO.widget.Tooltip, {
        /**
         * Overrides method in YAHOO.widget.Tooltip.
         * This adds three new event listeners for new events in this extended tooltip:
         * onElementMouseOver, onElementMouseOut, and OnPageMouseMove
         * @method configContext
         * @param {String} type The CustomEvent type (usually the property name)
         * @param {Object[]} args The CustomEvent arguments. For configuration 
         * handlers, args[0] will equal the newly applied value for the property.
         * @param {Object} obj The scope object. For configuration handlers,
         * this will usually equal the owner.
        */
    configContext: function (type, args, obj) {
                          YAHOO.widget.PersistentTooltip.superclass.configContext.call(this, type, args, obj);
                          YAHOO.util.Event.on(obj.element, "mouseover", this.onElementMouseOver, obj);
                          YAHOO.util.Event.on(obj.element, "mouseout", this.onElementMouseOut, obj);
                          YAHOO.util.Event.on(document, "mousemove", this.onPageMouseMove, obj);

                          // klugey: code lifted from super.configContext.  need context param value
                          //  for loop over context objects
                          var context = context = this.cfg.getProperty("context");
              
// end code 
                          try {
                          this._context = context;
                          
                          aElements = this._context;
                          
                          if (aElements) {
                              nElements = aElements.length;
                              if (nElements > 0) {
                                  i = nElements - 1;
                                  do {
                                      oElement = aElements[i];
                                      YAHOO.util.Event.on(oElement, "click", this.onContextClick, this);
                                  }
                                  while (i--);
                              }
                          }

                          } catch (e) { YAHOO.log("error adding onContextClick event: " + e.message); }
                          YAHOO.log("added event listeners on " + obj.element.id);
                          
                      },

    initDefaultConfig: function () {
                                      YAHOO.widget.PersistentTooltip.superclass.initDefaultConfig.call(this);
                                      
                                      this.cfg.addProperty('initMsgDiv', { value: '', handler: this.configInitMsgDiv });
                                      this.cfg.addProperty('initMsgText', { value: '' });
                                      

                      },
    configInitMsgDiv: function () {
                          var id = this.cfg.getProperty('initMsgDiv');
                          if (id && id.length > 0) {
                              var div = document.getElementById(id);
                              this._msgDiv = div;
                          }
                      },

     onContextClick: function (e, obj) {
                          var text = obj.cfg.getProperty("text");
                          if (text == YAHOO.widget.PersistentTooltip.loadingMessage) {
                              obj.hide();
                          }
                      },
                          /**
                           * Just tracks the mouse coordinates and stores them in the tooltip object.
                           * onContextMouseMove was just tracking inside the context object. We need to
                           * track the whole page to be able to determine if the mouse is inside the 
                           * tooltip element.
                           * @method onPageMouseMove
                           * @param (DOMEvent) The current DOM event
                           * @param (Object) The persistent tooltip object
                           */
   onPageMouseMove: function (e, obj) {
                          obj.element.fullPageX = YAHOO.util.Event.getPageX(e);
                          obj.element.fullPageY = YAHOO.util.Event.getPageY(e);
                      },
        /**
        * The default event handler fired when the user mouses out of 
        * the context element. We've changed the function for the hideDelay timout.
        * hideDelay won't kick in if the mouse is over obj.element
        * Otherwise, this is an exact copy of onContextMouseOut
        * NOTE: maybe rewrite to call super and then use obj.restartHideDelayTimeout
        * @method onContextMouseOut
        * @param {DOMEvent} e The current DOM event
        * @param {Object} obj The object argument
        */
    onContextMouseOut: function (e, obj) {
                          var el = this;

                          if (obj._tempTitle) {
                              el.title = obj._tempTitle;
                              obj._tempTitle = null;
                          }
                          
                          if (obj.showProcId) {
                              clearTimeout(obj.showProcId);
                              obj.showProcId = null;
                          }
                          
                          if (obj.hideProcId) {
                              clearTimeout(obj.hideProcId);
                              obj.hideProcId = null;
                          }
                          
                          obj.fireEvent("contextMouseOut", el, e);
                          
                          obj.hideProcId = setTimeout(function () { try {
                                                              if (!obj.xyInElement(obj.element.fullPageX, obj.element.fullPageY, obj.element)) {
                                                                  obj.hide();
                                                          } } catch (e) { YAHOO.log('FOOO ' + e.message); }
                                                      }, obj.cfg.getProperty("hidedelay"));
                      },
                          /**
                           * Allows user to restart the hideDelay timeout.  It uses the hidedelay property in obj by default, but you
                           * can set it explicitly to override the config setting.
                           * @method restartHideDelayTimeout
                           * @param (Object) obj The tooltip object
                           * @param (int) delay Milliseconds to override the hidedelay config setting
                           */
    restartHideDelayTimeout: function (  obj, delay ) {
                          if (!delay) {
                              delay = obj.cfg.getProperty("hidedelay");
                          }
                          if (obj.hideProcId) {
                              YAHOO.log("stopping hide timeout");
                              clearTimeout(obj.hideProcId);
                              obj.hideProcId = null;
                          }
                          obj.hideProcId = setTimeout(function () { try {
                                                              if (!obj.xyInElement(obj.element.fullPageX, obj.element.fullPageY, obj.element)) {
                                                                  obj.hide();
                                                              } } catch (e) { YAHOO.log('FOOO ' + e.message); }
                                                      }, delay);
                          
                      },
                          /** 
                           * This allows the tooltip element to know about the context object that was moused over to open the tooltip.
                           * @method onContextMouseOver
                           * @param (DOMEvent) e The current DOM event
                           * @param (Object) obj The context object
                           */
    onContextMouseOver: function ( e, obj ) {
                          obj.element.context = this;
                          YAHOO.widget.PersistentTooltip.superclass.onContextMouseOver.call(this, e, obj);
                      },
                          /**
                           * Default event handler fired when the user mouses over the 
                           * tooltip element.
                           * @method onElementMouseOver
                           * @param (DOMEvent) The current DOM event
                           * @param (Object) obj The tooltip object that was moused over
                           */
    onElementMouseOver: function ( e, obj ) {
                              return true;
                          try {
                              var mouseOverTarget = YAHOO.util.Event.getTarget(e);
                              
                              YAHOO.log("element mouse over");                          
                              YAHOO.log("mouseover element type: " + mouseOverTarget);
                              
                              if (obj.hideProcId) {
                                  YAHOO.log("stopping hide timeout");
                                  clearTimeout(obj.hideProcId);
                                  obj.hideProcId = null;
                              }
                          } catch(e) { YAHOO.log("error in element mouse over: " + e.message ); }
                      },
                          /**
                           * Default event handler fired when the user mouses out of the 
                           * tooltip element.
                           * @method onElementMouseOut
                           * @param (DOMEvent) The current DOM event
                           * @param (Object) obj The tooltip object that was moused out of
                           */
    onElementMouseOut: function ( e, obj ) {
                          try {
                                  var mouseOutTarget = YAHOO.util.Event.getTarget(e);
                                  obj.restartHideDelayTimeout(obj, 50);
                                  // this could be an element deep inside HTML text that has been added to the tooltip element.
                                  YAHOO.util.Event.stopPropagation(e);
                                  return true;
                          } catch(e) {YAHOO.log("element mouse out error: " + e.message + ' ' + e.lineNumber); }
                      },
    init: function (el, userConfig) {
                          YAHOO.widget.PersistentTooltip.superclass.init.call(this, el, userConfig);

                          var id = this.cfg.getProperty('initMsgDiv');
                          if (id && id.length > 0) {
                              var container = document.getElementById(id);
                              if (container) {
                                  container.innerHTML = this.cfg.getProperty('initMsgText');
                              }
                          }

                      }
    });

/**
 * Constant containing message that is displayed when the tooltip is loading
 * @property loadingMessage
 * @public
 * @final
 * @type String
 */
YAHOO.widget.PersistentTooltip.loadingMessage = 'loading ...';

/**
 * Convenience utility method added to determine if the mouse is inside a particular element
 * @method xyInElement
 * @param (int) x The mouse x coordinate
 * @param (int) y The mouse y coordinate
 * @param (DOMElement) el The element we want to test the mouse coordinates against.
 */
YAHOO.widget.PersistentTooltip.prototype.xyInElement = function(x, y, el)
{
    if (!el) {
        return false;
    }
    YAHOO.log("x: " + x + " el.x: " + YAHOO.util.Dom.getX(el) + " y: " + y + " el.y: " + YAHOO.util.Dom.getY(el));
    YAHOO.log("offsetWidth: " + el.offsetWidth + " offsetHeight: " + el.offsetHeight);
    if (x < YAHOO.util.Dom.getX(el)) return false;
    if (x > YAHOO.util.Dom.getX(el)+el.offsetWidth) return false;
    
    if (y < YAHOO.util.Dom.getY(el)) return false;
    if (y > YAHOO.util.Dom.getY(el)+el.offsetHeight) return false;
    YAHOO.log("xyInElement returning true");
    return true;

}
