
// Must be global for use with setTimeout ( damm js :( )
var  GLOBAL_itt_last_objectName = null;

/**
* Bs_InstantToolTip class
* 
* dependencies: Bs_InstantHelpClient, Bs_Misc.lib.js
* 
* @author     andrej at arn dot li
* @copyright  blueshoes.org
* @package    javascript_plugins
* @subpackage instanthelp
*/
function Bs_InstantToolTip() {
  
  /**
  * set in init(), so look there.
  * @access private
  * @var    string _objectName
  */
  this._objectName = '';
  
  /**
  * instance of Bs_InstantHelp.
  * gets set in the constructor.
  * @access private
  * @var    object _ih
  */
  this._ih = null;
  
  /**
  * if we're in tooltip mode or not.
	* @see alwaysActive
  */
  this.mode = false;
  
	/**
	* @var bool alwaysActive
	*/
	this.alwaysActive = false;
	
  /**
  * @var int eventX
  */
  this.eventX = false;
  
  /**
  * @var int eventY
  */
  this.eventY = false;
  
	/**
	* defines what cursor should be used when the mouse moves over something for what
	* a tooltip is available. 
	* by default it is set to 'help' (css 2).
	* can also be set to 'hand' (ie uses 'hand', for mozilla the property 'pointer' will be used).
	* @access public
	* @var    string cursor
	* @since  bs4.3
	*/
	this.highlightCursor = 'help';
	
	/**
	* defines the default highlight mode.
	* can be a string or a hash.
	* possible options are: 'border' (default), 'background', 'raster'.
	* 
	* example 1: obj.highlightMode = 'raster';
	* 
	* example 2: obj.highlightMode = new Array();
	*            obj.highlightMode['border'] = true;
	*            obj.highlightMode['raster'] = true;
	* 
	* check the howto to see how they look.
	* note that this default can be overwritten for each element that defines a tooltip. 
	* again, check the howto.
	* 
	* @access public
	* @var    string highlightMode
	* @sinde  bs4.3
	*/
	this.highlightMode = 'border';
	
	/**
	* if this.highlightMode is set to 'raster' then this raster image will be used.
	* @access public
	* @var    string rasterImage
	* @since  bs4.3
	*/
	this.rasterImage = '/_bsImages/plugins/instanthelp/raster/yellow400.gif';
	
  /**
  * the id of the tooltip layer. you may change this if needed. for example 
  * if you want to use 2 different (looking) tooltips on the same page. but 
  * normally there's no need.
  * @var string toolTipLayerId
  */
  this.toolTipLayerId = 'tthLayer';
  this.toolTipLayerContentId = 'tthLayerContent';
  
  
	/**
	* html string of the layer in "right down" mode.
	* @access private
	* @var    string _layerRightDown
	* @see    this._initLayerRightDown
	*/
	this._layerRightDown;
	this._layerLeftDown;
	this._layerRightUp;
	this._layerLeftUp;
	
  /**
  * @access public
  * @param  string objectName (name of this object, eg 'itt'. note: needs to be in the global scope so everyone can call it.)
  * @param  object ih (instance of Bs_InstantHelp)
  * @return void
  */
  this.init = function(objectName, ih) {
    this._objectName  = objectName;
		if (typeof(ih) !== 'undefined') {
	    this._ih          = ih;
		}
  }
  
  
  /**
  * start the tool tip help. that means: 
  * make the elements (words, icons, whatever) marked as tooltipable. 
	* (yellow border, whatever)
	* this is the opposite of release().
	* if alwaysActive is on then this is not needed.
  * @access public
  * @return void
  * @see    release()
  */
  this.start = function() {
		if (this.mode == true) {
			//toggle
			this.release();
			return;
		}
		
    this.mode = true;
    //document.style.cursor = "help";
    var e = document.getElementsByTagName("span");
    for (var i=0; i<e.length; i++) {
      if (typeof(e[i]['dictName']) != 'undefined') { //internet explorer
				var dictName = e[i]['dictName'];
			} else { //mozilla
				var dictName = e[i].getAttribute('dictName');
				if (typeof(dictName) == 'undefined') continue;
				if (dictName == null) continue;
			}
			
			//highlight:
			if (typeof(this.highlightMode) == 'string') {
				var highlightMode = new Array();
				highlightMode[this.highlightMode] = true;
			} else {
				var highlightMode = this.highlightMode;
			}
			if (typeof(highlightMode['background']) != 'undefined') {
				e[i].style.background = "yellow";
			}
			if (highlightMode['raster']) {
				for (var z=0; z<1; z++) {
					var elmWidth  = parseInt(e[i].clientWidth);
					var elmHeight = parseInt(e[i].clientHeight);
					if (elmWidth <= 0) { //mozilla
						elmWidth  = parseInt(e[i].offsetWidth);
						elmHeight = parseInt(e[i].offsetHeight);
					}
					
					var rasterId = this._getRasterId(e[i]);
					var rasterElm = document.getElementById(rasterId);
					if (!rasterElm) {
			      try {
			        var divTagStr = '<div id="' + rasterId + '" style="display:none; overflow:hidden;"><img src="' + this.rasterImage + '" border="0"></div>';
			        var bodyTag = document.getElementsByTagName('body');
			        bodyTag = bodyTag[0];
			        bodyTag.insertAdjacentHTML('beforeEnd', divTagStr);
			      } catch (e) {
			        //alert('webmaster: please add the layer named ' + rasterId + ' to your html code.');
							//return;
							break;
			      }
						var rasterElm = document.getElementById(rasterId);
					}
					rasterElm.style.width    = elmWidth;
					rasterElm.style.height   = elmHeight;
					rasterElm.style.position = 'absolute';
					rasterElm.style.left     = getAbsolutePos(e[i]).x; //bs_fullOffsetLeft(e[i]); //e[i].offsetLeft;
					rasterElm.style.top      = getAbsolutePos(e[i]).y; //bs_fullOffsetTop(e[i]);  //e[i].offsetTop;
					GLOBAL_itt_last_objectName      = this._objectName; //hack using global var, i see no other way to do that.
					rasterElm.onmouseover    = function () { this.style.display = 'none'; window.setTimeout("if (" + GLOBAL_itt_last_objectName + ".mode) document.getElementById('" + this.id + "').style.display = 'block';", 3000); };
					rasterElm.style.zIndex   = 10000;
					rasterElm.style.display  = 'block';
					
					/*
					return;
					alert(elmWidth); 73
					alert(elmHeight); 16
					alert(e[i].offsetLeft); 0
					alert(e[i].offsetTop); 0
					alert(e[i].clientLeft);
					*/
				}
			}
			if (highlightMode['border']) {
				e[i].style.border = "1px solid yellow";
			}
      
			if (this.highlightCursor == 'help') {
				e[i].style.cursor = 'help';
			} else {
				e[i].style.cursor = (typeof(e[i]['dictName']) != 'undefined') ? "hand" : 'pointer';
			}
      //e[i].onClick = "alert('hi'); ih.getText('" + e[i]['dictName'] + "', '" + e[i]['strKey'] + "', '" + e[i]['lang'] + "', 'localSetHelpText()');";
      //e[i].onMouseOver = "alert('hi');";
    }
  }
  
  /**
  * release the tool tip help. that means: 
  * hide the tool tip, and make the elements (words, icons, whatever) 
  * not marked as tooltipable anymore. (yellow border, whatever)
	* this is the opposite of start().
  * @access public
  * @return void
  * @see start()
  */
  this.release = function() {
    this.mode = false;
    document.onclick = null;
    var l = document.getElementById(this.toolTipLayerId);
		if (l) l.style.display = "none";
    
    var e = document.getElementsByTagName("span");
    for (var i=0; i<e.length; i++) {
      if (typeof(e[i]['dictName']) != 'undefined') { //internet explorer
				var dictName = e[i]['dictName'];
			} else { //mozilla
				var dictName = e[i].getAttribute('dictName');
				if (typeof(dictName) == 'undefined') continue;
				if (dictName == null) continue;
			}
			
			//highlight:
			if (typeof(this.highlightMode) == 'string') {
				var highlightMode = new Array();
				highlightMode[this.highlightMode] = true;
			} else {
				var highlightMode = this.highlightMode;
			}
			if (typeof(highlightMode['background']) != 'undefined') {
				e[i].style.background = "";
			}
			if (highlightMode['raster']) {
				var rasterId = this._getRasterId(e[i]);
				var rasterElm = document.getElementById(rasterId);
				if (rasterElm) rasterElm.style.display = 'none';
			}
			if (highlightMode['border']) {
				e[i].style.border = "none";
			}
			
      e[i].style.cursor     = "default";
    }
  }
  
  /**
  * executes a query (if we're in query mode or alwaysActive is on).
	* 
	* we return false if the query has been done because you can use that value in your 
	* code to return it too. then other events won't fire because of the return false. 
	* you may not understand this if you're not a web crack, just accept that it works like that.
	* 
  * @access public
  * @param  object obj
  * @param  object event (event object, msie)
  * @return bool (false if query has been done, true if not. see above.)
  */
  this.query = function(obj, event) {
    var ret = false;
    if (this.mode || this.alwaysActive) {
      this.eventX = event.clientX; //event.offsetX;
      this.eventY = event.clientY; //event.offsetY;
			
			if (typeof(obj['dictName']) != 'undefined') {
				var dictName = obj['dictName'];
			} else {
				var dictName = obj.getAttribute('dictName');
			}
			if (typeof(obj['strKey']) != 'undefined') {
				var strKey = obj['strKey'];
			} else {
				var strKey = obj.getAttribute('strKey');
			}
			if (typeof(obj['lang']) != 'undefined') {
				var lang = obj['lang'];
			} else {
				var lang = obj.getAttribute('lang');
			}
			
      this._ih.getText(dictName, strKey, lang, this._objectName + '.fireToolTip()');
			try {
				//only ie supports that. mozilla does not seem to complain.
	      event.cancelBubble = true; //stop the event, don't fire release() on a document click.
			} catch (e) {
			}
			ret = true;
    }
		return ret;
  }
  
  
  /**
  * fires when the text from instanthelp came back from the server.
  * @access ?
  * @param  string value
	* @param  object event
  * @return void
  */
  this.fireToolTip = function(value, event) {
    //alert('fireToolTip');
		
		this.release(); //hacky. this fixes a bug. when already open and firing directly another one before closing the first one, it didn't work.
    
    this._addLayer(); //make sure the layer is ready to use
    var l = document.getElementById(this.toolTipLayerId);
    
    if (!l) {
      alert('Error: please add the layer named ' + this.toolTipLayerId + ' to your html code.');
      return;
    }
    
		if (typeof(event) != 'undefined') {
			this.eventX = event.clientX; //event.offsetX;
			this.eventY = event.clientY; //event.offsetY;
		}
		
		var cursorWidth  = 22;
		var windowWidth  = (window.innerWidth)  ? window.innerWidth  : document.body.offsetWidth;  //first is ns, 2nd is ie
		var windowHeight = (window.innerHeight) ? window.innerHeight : document.body.offsetHeight; //first is ns, 2nd is ie
		var tipWidth     = parseInt(l.style.width);
		var tipHeight    = parseInt(l.style.height);
		
		//at first try down-right:
		var posX = this.eventX -cursorWidth;
		var posY = this.eventY;
		
		if ((tipWidth + posX > windowWidth) && (posX - tipWidth >= 0)) {
			//ups, not enough space on the right, but enough space on the left.
			posX = posX - tipWidth + (2 * cursorWidth);
			this._fireToolTipTo('down-left', posX, posY, value);
			var doOnRight = false;
		} else {
			this._fireToolTipTo('down-right', posX, posY, value);
			var doOnRight = true;
		}
		
    var l = document.getElementById(this.toolTipLayerId);
		tipHeight = parseInt(l.clientHeight);
		if (tipHeight <= 0) { //mozilla
			tipHeight = parseInt(l.offsetHeight);
		}
		if (tipHeight + posY + 20 > windowHeight) { //20 is some extra-space for scrollbars.
			do {
				//ups, not enough space at the bottom, now that we've rendered it.
				posY -= tipHeight;
				if (posY < 0) {
					//not enough space at the top aswell, so it's better we leave it at the bottom. page is scrollable.
					break;
				}
				if (doOnRight) {
					this._fireToolTipTo('up-right', posX, posY, value);
				} else {
					this._fireToolTipTo('up-left', posX, posY, value);
				}
			} while (false);
		}
		
    
    //if you already have an onclick event and don't want to drop it, see here:
    //http://216.239.51.100/search?q=cache:_m2onoERVesC:www.tek-tips.com/gfaqs.cfm/lev2/4/lev3/32/spid/216/sfid/1063+document.onclick+%3D+&hl=en&ie=UTF-8
		if (typeof(event) == 'undefined') {
    	document.onclick = new Function(this._objectName + '.release()');
		} else {
			//very stupid. if we call this function in the onclick and show the layer, and register 
			//a document.onclick here that goes and hides the layer, this onclick is called right 
			//away! in both browsers. i think this object model is fucked. with the setTimeout it works.
			//2005-05-02 --andrej
			var onc = "document.onclick = new Function('" + this._objectName + ".release()');"
			setTimeout(onc, 10);
		}
  }
	
	/**
	* @access private
	* @return void
	*/
	this._fireToolTipTo = function(where, posX, posY, value) {
		if (document.body) {
			if (document.body.scrollTop  > 0) posY += document.body.scrollTop;
			if (document.body.scrollLeft > 0) posX += document.body.scrollLeft;
		}
		
		switch (where) {
			case 'down-right':
				this._initLayerRightDown();
				break;
			case 'down-left':
				this._initLayerLeftDown();
				break;
			case 'up-right':
				this._initLayerRightUp();
				break;
			case 'up-left':
				this._initLayerLeftUp();
				break;
		}
		var d = document.getElementById(this.toolTipLayerId);
		switch (where) {
			case 'down-right':
				d.innerHTML = this._layerRightDown;
				break;
			case 'down-left':
				d.innerHTML = this._layerLeftDown;
				break;
			case 'up-right':
				d.innerHTML = this._layerRightUp;
				break;
			case 'up-left':
				d.innerHTML = this._layerLeftUp;
				break;
		}
		
    var l = document.getElementById(this.toolTipLayerId);
    l.style.left    = posX;
    l.style.top     = posY;
    l.style.display = "block";
		
    var lc = document.getElementById(this.toolTipLayerContentId);
    lc.innerHTML = value; //innerText
	}
	
	
	/**
	* @access private
	* @param  object elm
	* @return string
	*/
	this._getRasterId = function(elm) {
		if (typeof(elm.id) != 'undefined' && (elm.id != '')) {
			var rasterId = elm.id;
		} else {
			if (elm.getAttribute) { //mozilla
				var rasterId = elm.getAttribute('dictName') + "_" + elm.getAttribute('strKey') + "_";
				var lang = elm.getAttribute('lang');
				if ((typeof(lang) != 'undefined') && (lang != null)) rasterId += lang;
			} else { //ie
				var rasterId = elm.dictName + "_" + elm.strKey + "_";
				if (typeof(elm.lang) != 'undefined') rasterId += elm.lang;
			}
		}
		rasterId += '_raster';
		rasterId = rasterId.replace(/[^a-zA-Z0-9_-]/g, '');
		return rasterId;
	}
	
  
	/**
	* @access private
	* @return void
	*/
  this._addLayer = function() {
    var d = document.getElementById(this.toolTipLayerId);
    if (!d) {
      //coder forgot to add the tag looking like
      //<div id="tthLayer"></div>
      //into the page. maybe we can add it to the end, right before the </body> page.
      try {
        var divTagStr = '<div id="' + this.toolTipLayerId + '"></div>';
        var bodyTag = document.getElementsByTagName('body');
        bodyTag = bodyTag[0];
        bodyTag.insertAdjacentHTML('beforeEnd', divTagStr);
        d = document.getElementById(this.toolTipLayerId);
      } catch (e) {
        alert('webmaster: please add the layer named ' + this.toolTipLayerId + ' to your html code.');
				return;
      }
    }
    
    if (d.innerHTML == '') {
      d.style.display    = 'none';
      d.style.position   = 'absolute';
      d.style.width      = '200px';
      d.style.height     = '40px';
      d.style.overflow   = 'visible';
      d.style.zIndex     = '999999';
      d.style.fontFamily = 'Arial,Helvetica,sans-serif';
      d.style.fontSize   = '12px';
      //d.style = 'display:none; position:absolute; width:200; height:40; overflow:visible; zIndex:999999; font-family:Arial,Helvetica,sans-serif; font-size:12px;';
			this._initLayerRightDown();
      d.innerHTML = this._layerRightDown;
    }
  }
	
	this._initLayerRightDown = function() {
    var content = '';
    content += '<table width="100%" height="100%" border="0" cellspacing="0" cellpadding="0">';
    content += '  <tr height="16">';
    content += '    <td height="16" width="3"><img src="/_bsImages/plugins/instanthelp/layerCornerTopLeft.gif" width="3" height="16"></td>';
    content += '    <td height="16"><table width="100%" height="100%" border="0" cellspacing="0" cellpadding="0"><tr><td width="19" height="16"><img src="/_bsImages/plugins/instanthelp/layerPointer.gif" width="19" height="16"></td><td background="/_bsImages/plugins/instanthelp/layerLineTop.gif"><div><font size="1">&nbsp;</font></div></td></tr></table></td>';
    content += '    <td height="16" width="4"><img src="/_bsImages/plugins/instanthelp/layerCornerTopRight.gif" width="4" height="16"></td>';
    content += '  </tr>';
    content += '  <tr>';
    content += '    <td width="3"><img src="/_bsImages/plugins/instanthelp/layerLineLeft.gif" width="3" height="100%"></td>';
    content += '    <td bgcolor="#FFFFCE"><div id="tthLayerContent" style="padding:10px;"></div></td>';
    content += '    <td width="4" background="/_bsImages/plugins/instanthelp/layerLineRight.gif"></td>';
    content += '  </tr>';
    content += '  <tr height="4">';
    content += '    <td height="4" width="3"><img src="/_bsImages/plugins/instanthelp/layerCornerBottomLeft.gif" width="3" height="4"></td>';
    content += '    <td height="4" background="/_bsImages/plugins/instanthelp/layerLineBottom.gif"></td>';
    content += '    <td height="4" width="4"><img src="/_bsImages/plugins/instanthelp/layerCornerBottomRight.gif"></td>';
    content += '  </tr>';
    content += '</table>';
		this._layerRightDown = content;
	}
	
	this._initLayerLeftDown = function() {
    var content = '';
    content += '<table width="100%" height="100%" border="0" cellspacing="0" cellpadding="0">';
    content += '  <tr height="16">';
    content += '    <td height="16" width="3"><img src="/_bsImages/plugins/instanthelp/layerCornerTopLeft.gif" width="3" height="16"></td>';
    content += '    <td height="16"><table width="100%" height="100%" border="0" cellspacing="0" cellpadding="0"><tr><td background="/_bsImages/plugins/instanthelp/layerLineTop.gif"><div><font size="1">&nbsp;</font></div></td><td width="19" height="16"><img src="/_bsImages/plugins/instanthelp/layerPointerLeftUp.gif" width="19" height="16"></td></tr></table></td>';
    content += '    <td height="16" width="4"><img src="/_bsImages/plugins/instanthelp/layerCornerTopRight.gif" width="4" height="16"></td>';
    content += '  </tr>';
    content += '  <tr>';
    content += '    <td width="3"><img src="/_bsImages/plugins/instanthelp/layerLineLeft.gif" width="3" height="100%"></td>';
    content += '    <td bgcolor="#FFFFCE"><div id="tthLayerContent" style="padding:10px;"></div></td>';
    content += '    <td width="4" background="/_bsImages/plugins/instanthelp/layerLineRight.gif"></td>';
    content += '  </tr>';
    content += '  <tr height="4">';
    content += '    <td height="4" width="3"><img src="/_bsImages/plugins/instanthelp/layerCornerBottomLeft.gif" width="3" height="4"></td>';
    content += '    <td height="4" background="/_bsImages/plugins/instanthelp/layerLineBottom.gif"></td>';
    content += '    <td height="4" width="4"><img src="/_bsImages/plugins/instanthelp/layerCornerBottomRight.gif"></td>';
    content += '  </tr>';
    content += '</table>';
		this._layerLeftDown = content;
	}
  
	this._initLayerRightUp = function() {
    var content = '';
    content += '<table width="100%" height="100%" border="0" cellspacing="0" cellpadding="0">';
    content += '  <tr height="4">';
    content += '    <td height="4" width="3"><img src="/_bsImages/plugins/instanthelp/layerCornerBottomLeft_Flipped.gif" width="3" height="4"></td>';
    content += '    <td height="4" background="/_bsImages/plugins/instanthelp/layerLineBottom_Flipped.gif"></td>';
    content += '    <td height="4" width="4"><img src="/_bsImages/plugins/instanthelp/layerCornerBottomRight_Flipped.gif"></td>';
    content += '  </tr>';
    content += '  <tr>';
    content += '    <td width="3"><img src="/_bsImages/plugins/instanthelp/layerLineLeft.gif" width="3" height="100%"></td>';
    content += '    <td bgcolor="#FFFFCE"><div id="tthLayerContent" style="padding:10px;"></div></td>';
    content += '    <td width="4" background="/_bsImages/plugins/instanthelp/layerLineRight.gif"></td>';
    content += '  </tr>';
    content += '  <tr height="16">';
    content += '    <td height="16" width="3"><img src="/_bsImages/plugins/instanthelp/layerCornerTopLeft_Flipped.gif" width="3" height="16"></td>';
    content += '    <td height="16"><table width="100%" height="100%" border="0" cellspacing="0" cellpadding="0"><tr><td width="19" height="16"><img src="/_bsImages/plugins/instanthelp/layerPointerRightDown.gif" width="19" height="16"></td><td background="/_bsImages/plugins/instanthelp/layerLineTop_Flipped.gif"><div><font size="1">&nbsp;</font></div></td></tr></table></td>';
    content += '    <td height="16" width="4"><img src="/_bsImages/plugins/instanthelp/layerCornerTopRight_Flipped.gif" width="4" height="16"></td>';
    content += '  </tr>';
    content += '</table>';
		this._layerRightUp = content;
	}
	
	this._initLayerLeftUp = function() {
    var content = '';
    content += '<table width="100%" height="100%" border="0" cellspacing="0" cellpadding="0">';
    content += '  <tr height="4">';
    content += '    <td height="4" width="3"><img src="/_bsImages/plugins/instanthelp/layerCornerBottomLeft_Flipped.gif" width="3" height="4"></td>';
    content += '    <td height="4" background="/_bsImages/plugins/instanthelp/layerLineBottom_Flipped.gif"></td>';
    content += '    <td height="4" width="4"><img src="/_bsImages/plugins/instanthelp/layerCornerBottomRight_Flipped.gif"></td>';
    content += '  </tr>';
    content += '  <tr>';
    content += '    <td width="3"><img src="/_bsImages/plugins/instanthelp/layerLineLeft.gif" width="3" height="100%"></td>';
    content += '    <td bgcolor="#FFFFCE"><div id="tthLayerContent" style="padding:10px;"></div></td>';
    content += '    <td width="4" background="/_bsImages/plugins/instanthelp/layerLineRight.gif"></td>';
    content += '  </tr>';
    content += '  <tr height="16">';
    content += '    <td height="16" width="3"><img src="/_bsImages/plugins/instanthelp/layerCornerTopLeft_Flipped.gif" width="3" height="16"></td>';
    content += '    <td height="16"><table width="100%" height="100%" border="0" cellspacing="0" cellpadding="0"><tr><td background="/_bsImages/plugins/instanthelp/layerLineTop_Flipped.gif"><div><font size="1">&nbsp;</font></div></td><td width="19" height="16"><img src="/_bsImages/plugins/instanthelp/layerPointerLeftDown.gif" width="19" height="16"></td></tr></table></td>';
    content += '    <td height="16" width="4"><img src="/_bsImages/plugins/instanthelp/layerCornerTopRight_Flipped.gif" width="4" height="16"></td>';
    content += '  </tr>';
    content += '</table>';
		this._layerLeftUp = content;
	}
	
}

