
// use globals to track mouse position
var hovertipMouseX;
var hovertipMouseY;
function hovertipMouseUpdate(e) {
  var mouse = hovertipMouseXY(e);
  hovertipMouseX = mouse[0];
  hovertipMouseY = mouse[1];
}

// http://www.howtocreate.co.uk/tutorials/javascript/eventinfo
function hovertipMouseXY(e) {
  if( !e ) {
    if( window.event ) {
      //Internet Explorer
      e = window.event;
    } else {
      //total failure, we have no way of referencing the event
      return;
    }
  }
  if( typeof( e.pageX ) == 'number' ) {
    //most browsers
    var xcoorda = e.pageX;
    var ycoorda = e.pageY;
	
	winSize = {
		x: ( document.body.clientWidth ) ? document.body.clientWidth : window.innerWidth ,
		y: ( document.body.clientHeight ) ? document.body.clientHeight : window.innerHeight
	}
	
	
  } else if( typeof( e.clientX ) == 'number' ) {
    //Internet Explorer and older browsers
    //other browsers provide this, but follow the pageX/Y branch
    var xcoorda = e.clientX;
    var ycoorda = e.clientY;
	
	winSize = {
		x: ( document.body.clientWidth ) ? document.body.clientWidth : window.innerWidth ,
		y: ( document.body.clientHeight ) ? document.body.clientHeight : window.innerHeight
	}
	
    var badOldBrowser = ( window.navigator.userAgent.indexOf( 'Opera' ) + 1 ) ||
      ( window.ScriptEngine && ScriptEngine().indexOf( 'InScript' ) + 1 ) ||
      ( navigator.vendor == 'KDE' );
    if( !badOldBrowser ) {
      if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
        //IE 4, 5 & 6 (in non-standards compliant mode)
        xcoorda += document.body.scrollLeft;
        ycoorda += document.body.scrollTop;
		
      } else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
        //IE 6 (in standards compliant mode)
        xcoorda += document.documentElement.scrollLeft;
        ycoorda += document.documentElement.scrollTop;
      }
    }
  } else {
    //total failure, we have no way of obtaining the mouse coordinates
    return;
  }
  
  
	var newTop = ycoorda - 250;//el.offsetHeight;
	var newLeft = xcoorda - ( 160 );
	if( newTop < 0 )
		newTop = ycoorda + 20;
	if( newLeft < 0 )
		newLeft = 0;
	if( ( xcoorda + ( 160 ) ) >= winSize.x - 1 )
		newLeft = winSize.x - 350;
	ycoord = newTop;
	xcoord = newLeft;
  
  
  return [xcoord, ycoord];
}



//// target selectors ////

/**
 * These selectors find the targets for a given tooltip element.  
 * Several methods are supported.  
 * 
 * You may write your own selector functions to customize.
 */

/**
 * For this model:
 * <span hovertip="ht1">target term</span>...
 * <div class="hovertip" id="ht1">tooltip text</div>
 */
 
 /*
targetSelectById = function(el, config) {
  var id;
  var selector;
  if (id = el.getAttribute('id')) {
    selector = '*[@'+config.attribute+'=\''+id+'\']';
    return $(selector);

  }
};*/

/**
 * For this model:
 * <span id="ht1">target term</span>...
 * <div class="hovertip" target="ht1">tooltip text</div>
 */
targetSelectByTargetAttribute = function(el, config) {
  target_list = el.getAttribute('target');
  if (target_list) {
    // use for attribute to specify targets
    target_ids = target_list.split(' ');
    var selector = '#' + target_ids.join(',#');
    return $(selector);
  }
};

/**
 * For this model:
 * <span>target term</span><span class="hovertip">tooltip text</span>
 */



/*eu


targetSelectByPrevious = function(el, config) {
  return $(el.previousSibling);
}

/**
 * Make all siblings targets.  Experimental.
 */

/*targetSelectBySiblings = function(el, config) {
  return $(el).siblings();
}*/

//// prepare tip elements ////

/**
 * The tooltip element needs special preparation.  You may define your own
 * prepare functions to cusomize the behavior.
 */

/*
// adds a close link to clicktips
clicktipPrepareWithCloseLink = function(o, config) {
  return o.append("<a class='clicktip_close'><span>close</span></a>")
  .find('a.clicktip_close').click(function(e) {
      o.hide();
      return false;
    }).end(); 
};*/

// ensure that hovertips do not disappear when the mouse is over them.
// also position the hovertip as an absolutely positioned child of body.

hovertipPrepare = function(o, config) {
  return o.hover(function() {
      hovertipHideCancel(this);
    }, function() {
      hovertipHideLater(this);
    }).css('position', 'absolute').each(hovertipPosition);
};

// do not modify tooltips when preparing
hovertipPrepareNoOp = function(o, config) {
  return o;
}

//// manipulate tip elements /////
/**
 * A variety of functions to modify tooltip elements
 */

// move tooltips to body, so they are not descended from other absolutely
// positioned elements.
hovertipPosition = function(i) {
  document.body.appendChild(this);
}

hovertipIsVisible = function(el) {
  return (jQuery.css(el, 'display') != 'none');
}


hovertipShowUnderMouse = function(el) {
  hovertipHideCancel(el);
  if (!hovertipIsVisible(el)) {
    el.ht.showing = // keep reference to timer
      window.setTimeout(function() {					 
								 				 
          el.ht.tip.css({
              'position':'absolute',
                'top': hovertipMouseY + 'px',
                'left': hovertipMouseX + 'px'})
            .show();
        }, el.ht.config.showDelay);
  }
};



// do not hide
hovertipHideCancel = function(el) {
  if (el.ht.hiding) {
    window.clearTimeout(el.ht.hiding);
    el.ht.hiding = null;
  }  
};

// Hide a tooltip, but only after a delay.
// The delay allow the tip to remain when user moves mouse from target to tooltip
hovertipHideLater = function(el) {
  if (el.ht.showing) {
    window.clearTimeout(el.ht.showing);
    el.ht.showing = null;
  }
  if (el.ht.hiding) {
    window.clearTimeout(el.ht.hiding);
    el.ht.hiding = null;
  }
  el.ht.hiding = 
  window.setTimeout(function() {
      if (el.ht.hiding) {
        // fadeOut, slideUp do not work on Konqueror
        el.ht.tip.hide();
      }
    }, el.ht.config.hideDelay);
};


//// prepare target elements ////
/**
 * As we prepared the tooltip elements, the targets also need preparation.
 * 
 * You may define your own custom behavior.
 */

// when clicked on target, toggle visibilty of tooltip

clicktipTargetPrepare = function(o, el, config) {
  return o.addClass(config.attribute + '_target')
  .click(function() {
      el.ht.tip.toggle();
      return false;
    });
};

// when hover over target, make tooltip appear


hovertipTargetPrepare = function(o, el, config) {
  return o.addClass(config.attribute + '_target')
  .hover(function() {
      // show tip when mouse over target
      hovertipShowUnderMouse(el);
    },
    function() {
      // hide the tip
      // add a delay so user can move mouse from the target to the tip
      hovertipHideLater(el);
    });
};


/**
 * hovertipActivate() is our jQuery plugin function.  It turns on hovertip or
 * clicktip behavior for a set of elements.
 * 
 * @param config 
 * controls aspects of tooltip behavior.  Be sure to define
 * 'attribute', 'showDelay' and 'hideDelay'.
 * 
 * @param targetSelect
 * function finds the targets of a given tooltip element.
 * 
 * @param tipPrepare
 * function alters the tooltip to display and behave properly
 * 
 * @param targetPrepare
 * function alters the target to display and behave properly.
 */
 

jQuery.fn.hovertipActivate = function(config, targetSelect, tipPrepare, targetPrepare) {
  //alert('activating ' + this.size());
  // unhide so jquery show/hide will work.
  return this.css('display', 'block')
  .hide() // don't show it until click
  .each(function() {
      if (!this.ht)
        this.ht = new Object();
      this.ht.config = config;
      
      // find our targets
      var targets = targetSelect(this, config);
      if (targets && targets.size()) {
        if (!this.ht.targets)
          this.ht.targets = targetPrepare(targets, this, config);
        else
          this.ht.targets.add(targetPrepare(targets, this, config));
        
        // listen to mouse move events so we know exatly where to place hovetips
        targets.mousemove(hovertipMouseUpdate);
        
        // prepare the tooltip element
        // is it bad form to call $(this) here?
        if (!this.ht.tip)
          this.ht.tip = tipPrepare($(this), config);
      }
      
    })
  ;
};

/**
 * Here's an example ready function which shows how to enable tooltips.
 * 
 * You can make this considerably shorter by choosing only the markup style(s)
 * you will use.
 * 
 * You may also remove the code that wraps hovertips to produce drop-shadow FX
 * 
 * Invoke this function or one like it from your $(document).ready(). 
 *  
 *  Here, we break the action up into several timout callbacks, to avoid
 *  locking up browsers.
 */
function hovertipInit() {
  // specify the attribute name we use for our clicktips
  var clicktipConfig = {'attribute':'clicktip'};
  
  /**
   * To enable this style of markup (id on tooltip):
   * <span clicktip="foo">target</span>...
   * <div id="foo" class="clicktip">blah blah</div>
   */
 /* window.setTimeout(function() {
    $('.clicktip').hovertipActivate(clicktipConfig,
                                    targetSelectById,
                                    clicktipPrepareWithCloseLink,
                                    clicktipTargetPrepare
									);
  }, 0);*/
  
  /**
   * To enable this style of markup (id on target):
   * <span id="foo">target</span>...
   * <div target="foo" class="clicktip">blah blah</div>
   */
  window.setTimeout(function() {
    if ($('.clicktip') != null)
    {
        $('.clicktip').hovertipActivate(clicktipConfig,
                                        targetSelectByTargetAttribute,
                                        //clicktipPrepareWithCloseLink,
                                        clicktipTargetPrepare
									    );
	}
  }, 0);
  
  // specify our configuration for hovertips, including delay times (millisec)
  var hovertipConfig = {'attribute':'hovertip',
                        'showDelay': 100,
                        'hideDelay': 300};
  
  // use <div class='hovertip'>blah blah</div>
  var hovertipSelect = 'div.hovertip';
  
  // OPTIONAL: here we wrap each hovertip to apply special effect. (i.e. drop shadow):
  /*$(hovertipSelect).css('display', 'block').addClass('hovertip_wrap3').
    wrap("<div class='hovertip_wrap0'><div class='hovertip_wrap1'><div class='hovertip_wrap2'>" + 
         "</div></div></div>").each(function() {
           // fix class and attributes for newly wrapped elements
           var tooltip = this.parentNode.parentNode.parentNode;
           if (this.getAttribute('target'))
             tooltip.setAttribute('target', this.getAttribute('target'));
           if (this.getAttribute ('id')) {
             var id = this.getAttribute('id');
             this.removeAttribute('id');
             tooltip.setAttribute('id', id);
           }
         });
  hovertipSelect = 'div.hovertip_wrap0';*/
  
  // end optional FX section
  
  /**
   * To enable this style of markup (id on tooltip):
   * <span hovertip="foo">target</span>...
   * <div id="foo" class="hovertip">blah blah</div>
   */
  /*window.setTimeout(function() {
    $(hovertipSelect).hovertipActivate(hovertipConfig,
                                       targetSelectById,
                                       hovertipPrepare,
                                       hovertipTargetPrepare
									   );
  }, 0);*/

  /**
   * To enable this style of markup (id on target):
   * <span id="foo">target</span>...
   * <div target="foo" class="hovertip">blah blah</div>
   */
  window.setTimeout(function() {
    if ($(hovertipSelect) != null)
    {
        $(hovertipSelect).hovertipActivate(hovertipConfig,
                                       targetSelectByTargetAttribute,
                                       hovertipPrepare,
                                       hovertipTargetPrepare
									   );
	}
  }, 0);
  
  /**
   * This next section enables this style of markup:
   * <foo><span>target</span><span class="hovertip">blah blah</span></foo>
   * 
   * With drop shadow effect.
   * 
   */
   
  //var hovertipSpanSelect = 'span.hovertip';
  // activate hovertips with wrappers for FX (drop shadow):
  /*$(hovertipSpanSelect).css('display', 'block').addClass('hovertip_wrap3').
    wrap("<span class='hovertip_wrap0'><span class='hovertip_wrap1'><span class='hovertip_wrap2'>" + 
         "</span></span></span>").each(function() {
           // fix class and attributes for newly wrapped elements
           var tooltip = this.parentNode.parentNode.parentNode;
           if (this.getAttribute('target'))
             tooltip.setAttribute('target', this.getAttribute('target'));
           if (this.getAttribute('id')) {
             var id = this.getAttribute('id');
             this.removeAttribute('id');
             tooltip.setAttribute('id', id);
           }
         });
  hovertipSpanSelect = 'span.hovertip_wrap0';*/

 /* window.setTimeout(function() {
    $(hovertipSpanSelect)
      .hovertipActivate(hovertipConfig,
                        targetSelectByPrevious,
                        hovertipPrepare,
                        hovertipTargetPrepare
						);
  }, 0);*/
}
