
/**
 * Script d'info-bulles
 * 
 * @author Roland Dufour <roland@rentashop.fr> pour Rentashop eCommerce
 */

/**
 * CHANGE LOG
 * 
 * 2010-03-24:
 * Création du script
 */

var RSPlug_Tooltip = function (options, container){
	if (null === options || undefined === options){
		options = {};
	}
	
	this._config = { 
		elementClassName: 'tooltip',
		element: 'a',				// séparer les élements par une pipe |
		tooltipClassName: 'rspt_tooltip',
		contentTooltip: '[content]',
		anchorTooltip: 'tl',		// tl, tr, bl, br
		anchorShiftX: 1,
		anchorShiftY: 21,
		showIfOverFor: 200,
		tooltipCallback: null
	};
	for (var optName in options){
		if (null !== this._config[optName] && undefined !== this._config[optName]){
			this._config[optName] = options[optName];
		} else if (optName == 'tooltipCallback' && typeof(options[optName]) == 'function'){
			this._config[optName] = options[optName];
		}
	}
	if (document.body){		// Si document.body est directement accessible 
		this.init(container);
	} else {				// Si document.body n'est pas encore accessible, on exécute le script via window.onload
		var inst = this;
		window.onload = function (){ inst.init(container) };
	}
};


RSPlug_Tooltip.prototype.init = function (container){
	this.showIfOverForTimer = null;
	this.lastCurPos = { x: 0, y: 0 };
	this.addX = null;
	this.addY = null;

	if (null === container || undefined === container){
		container = document;
	}
	if (typeof container == 'string'){
		container = document.getElementById(container);
	}
	if (!container){
		container = document;
	}
	
	var elementsName = this._config.element.split('|');
	var inst = this;
	for (var i=0; i<elementsName.length; i++){
		var elements = container.getElementsByTagName(elementsName[i]);
		for (var j=0; j<elements.length; j++){
			if (this._config.elementClassName == '' || this.css.hasClassName(elements[j], this._config.elementClassName)){
				if (elements[j].title && elements[j].title != ''){
					this.createTooltip(elements[j], elements[j].title);
				}
			}
		}
	}
};

RSPlug_Tooltip.prototype.getCursorPos = function (e){
	var cursor = {x:0, y:0};
	if (e.pageX || e.pageY) {
		cursor.x = e.pageX;
		cursor.y = e.pageY;
	} else {
		var de = document.documentElement;
		var b = document.body;
		cursor.x = e.clientX + (de.scrollLeft || b.scrollLeft) - (de.clientLeft || 0);
		cursor.y = e.clientY + (de.scrollTop || b.scrollTop) - (de.clientTop || 0);
	}
	return cursor;
};

RSPlug_Tooltip.prototype.createTooltip = function (element, content){
	var tooltip = document.createElement('div');
	tooltip.innerHTML = this._config.contentTooltip.replace('[content]', content);
	tooltip.className = this._config.tooltipClassName;
	tooltip.style.display = 'none';
	tooltip.style.position = 'absolute';
	tooltip.style.zIndex = '50000';
	if ('function' === typeof(this._config.tooltipCallback)){
		this._config.tooltipCallback.call(tooltip, this);
	}
	
	var inst = this;
	element.title = '';
	
	if (null !== element.getAttribute('rel') && element.getAttribute('rel') != ''){
		this.addEvent('mouseover', element, function (e){ inst.showOverTooltip(e, tooltip, element); });
	} else {
		this.addEvent('mousemove', element, function (e){ inst.moveTooltip(e, tooltip, element); });
	}
	this.addEvent('mouseout', element, function (e){ inst.closeTooltip(e, tooltip, element); });
	/* Optimisation: mousemove gère showTooltip automatiquement */
	//this.addEvent('mouseover', element, function (e){ inst.showTooltip(e, tooltip); });
	
	document.body.insertBefore(tooltip, document.body.firstChild);
};

RSPlug_Tooltip.prototype.showOverTooltip = function (event, tooltip, element){
	var inst = this;
	if (null !== this.showIfOverForTimer){
		clearTimeout(this.showIfOverForTimer);
		this.showIfOverForTimer = null;
	}
	if (this._config.showIfOverFor > 0){
		this.showIfOverForTimer = setTimeout(function(){ tooltip.style.display = ''; inst.posTooltipFixed(inst.lastCurPos, tooltip, element); inst.showIfOverForTimer = null; }, this._config.showIfOverFor);
	} else {
		tooltip.style.display = '';
	}
};

RSPlug_Tooltip.prototype.posTooltipFixed = function (event, tooltip, element){
	var options = this.strToOptions(element.rel);
	if (null !== options.position && options.position == 'fixed'){
		var pos = this.getPos(element);
		if (null !== options.top && !isNaN(options.top)){
			pos.y = parseInt(pos.y) + parseInt(options.top);
		} else if (null !== options.bottom && !isNaN(options.bottom)){
			pos.y = parseInt(pos.y) + parseInt(element.offsetHeight) - parseInt(options.bottom);
		}
		if (null !== options.left && !isNaN(options.left)){
			pos.x = parseInt(pos.x) + parseInt(options.left);
		} else if (null !== options.right && !isNaN(options.right)){
			pos.x = parseInt(pos.x) + parseInt(element.offsetWidth) - parseInt(options.right);
		}
		this.posTooltip(pos, tooltip);
	}
};

RSPlug_Tooltip.prototype.getPos = function (obj){
	var pos = {x:0, y:0};
	if (obj.offsetParent){
		while (true){ 
			pos.x += obj.offsetLeft;
			pos.y += obj.offsetTop;
			if (!obj.offsetParent){
				break;
			}
			obj = obj.offsetParent;
        }
	} else {
		if (obj.x) {
			pos.x += obj.x;
		}
		if (obj.y) {
			pos.y += obj.y;
		}
	}
    return pos;
};

RSPlug_Tooltip.prototype.strToOptions = function (string){
	var opts = string.split(';');
	var options = {};
	for (var i=0; i<opts.length; i++){
		var elts = opts[i].split('=');
		if (elts.length == 2){
			options[this.strTrim(elts[0])] = this.strTrim(elts[1]);
		}
	}
	return options;
};

RSPlug_Tooltip.prototype.strTrim = function (string){
	return string.replace(/^\s+/g, '').replace(/\s+$/g, ''); 
};

RSPlug_Tooltip.prototype.moveTooltip = function (event, tooltip, element){
	var cPos = this.getCursorPos(event);
	this.lastCurPos = cPos;
	if (tooltip.style.display != 'none'){
		this.posTooltip(cPos, tooltip);
	} else if (null === this.showIfOverForTimer){
		this.showTooltip(event, tooltip, element);
	}
};

RSPlug_Tooltip.prototype.posTooltip = function (cPos, tooltip){
	var widthTT = tooltip.offsetWidth ? parseInt(tooltip.offsetWidth) : 0;
	var heightTT = tooltip.offsetHeight ? parseInt(tooltip.offsetHeight) : 0;
	
	/* Optimisation du calcul des marges (borders et paddings) */
	if (null === this.addX){
		var bbTT = tooltip.style.borderBottomWidth ? parseInt(tooltip.style.borderBottomWidth) : 0;
		var btTT = tooltip.style.borderTopWidth ? parseInt(tooltip.style.borderTopWidth) : 0;
		var blTT = tooltip.style.borderLeftWidth ? parseInt(tooltip.style.borderLeftWidth) : 0;
		var brTT = tooltip.style.borderRightWidth ? parseInt(tooltip.style.borderRightWidth) : 0;
		
		var pbTT = tooltip.style.paddingBottom ? parseInt(tooltip.style.paddingBottom) : 0;
		var ptTT = tooltip.style.paddingTop ? parseInt(tooltip.style.paddingTop) : 0;
		var plTT = tooltip.style.paddingLeft ? parseInt(tooltip.style.paddingLeft) : 0;
		var prTT = tooltip.style.paddingRight ? parseInt(tooltip.style.paddingRight) : 0;
		
		this.addX = blTT + brTT + plTT + prTT;
		this.addY = bbTT + btTT + pbTT + ptTT;
	}

	if (this._config.anchorTooltip == 'br'){
		tooltip.style.left = (cPos.x - widthTT - this.addX + this._config.anchorShiftX) + 'px';
		tooltip.style.top = (cPos.y - heightTT - this.addY + this._config.anchorShiftY) + 'px';
	} else if (this._config.anchorTooltip == 'bl'){
		tooltip.style.left = (cPos.x + this.addX + this._config.anchorShiftX) + 'px';
		tooltip.style.top = (cPos.y - heightTT - this.addY + this._config.anchorShiftY) + 'px';
	} else if (this._config.anchorTooltip == 'tr'){
		tooltip.style.left = (cPos.x - widthTT - this.addX + this._config.anchorShiftX) + 'px';
		tooltip.style.top = (cPos.y + this.addY + this._config.anchorShiftY) + 'px';
	} else {
		tooltip.style.left = (cPos.x + this.addX + this._config.anchorShiftX) + 'px';
		tooltip.style.top = (cPos.y + this.addY + this._config.anchorShiftY) + 'px';
	} 
};

RSPlug_Tooltip.prototype.showTooltip = function (event, tooltip, element){
	var inst = this;
	if (null !== this.showIfOverForTimer){
		clearTimeout(this.showIfOverForTimer);
		this.showIfOverForTimer = null;
	}
	if (this._config.showIfOverFor > 0){
		this.showIfOverForTimer = setTimeout(function(){ tooltip.style.display = ''; inst.posTooltip(inst.lastCurPos, tooltip, element); inst.showIfOverForTimer = null; }, this._config.showIfOverFor);
	} else {
		tooltip.style.display = '';
	}
};

RSPlug_Tooltip.prototype.closeTooltip = function (event, tooltip, element){
	if (null !== this.showIfOverForTimer){
		clearTimeout(this.showIfOverForTimer);
		this.showIfOverForTimer = null;
	}
	this.addX = null;
	this.addY = null;
	tooltip.style.display = 'none';
};


RSPlug_Tooltip.prototype.addEvent = function (eventName, element, callback){
	if (element.addEventListener){
		element.addEventListener(eventName, callback, false);
	} else if (element.attachEvent){
		element.attachEvent('on' + eventName, callback);
	}
}


RSPlug_Tooltip.prototype.css = {};

RSPlug_Tooltip.prototype.css.hasClassName = function (obj, className){
	var classes = obj.className.split(/\s+/);
	for (var i=0; i<classes.length; i++){
		if (classes[i] == className){
			return true;
		}
	}
	return false;
}
