/*
Script: TipsX3.js
	Tooltips, BubbleTips, whatever they are, they will appear on mouseover

License:
	MIT-style license.

Credits:
	The idea behind Tips.js is based on Bubble Tooltips (<http://web-graphics.com/mtarchive/001717.php>) by Alessandro Fulcitiniti <http://web-graphics.com>
	TipsX3.js is based on Tips.js, with slight modifications, by razvan@e-magine.ro
*/
var Tooltips = new Class({

	options: { // modded for X3
		'parseDom': true,
		'onShow': function(tip){
			if(this.flag == true) {
				tip.setStyle('visibility', 'visible');
			}
		},
		'onHide': function(tip){
			if(this.flag == false) {
				tip.setStyle('visibility', 'hidden');
			}
		},
		'maxTitleChars': 30,
		'showDelay': 100,
		'hideDelay': 500,
		'className': 'tool',
		'offsets': {'x': 16, 'y': 16},
		'fixed': true,
		'loading': {
			'title': 'Lade Tooltipp&hellip;',
			'content': 'Tooltipp wird geladen.'
		},
		'error': {
			'title': 'Fehler&hellip;',
			'content': 'Leider konnte der Tooltipp nicht erfolgreich geladen werden.'
		},
		'closeText': 'Tooltipp schließen.'
	},
	
	initialize: function(elements, options){
		this.setOptions(options);
		this.triggerTimer = false;
		this.toolTip = new Element('div', {
			'class': this.options.className + '-tip',
			'styles': {
				'position': 'absolute',
				'top': '0',
				'left': '0',
				'visibility': 'hidden'
			}
		}).inject(document.body);
		this.toolTip.addEvent('mouseenter', this.show);
		this.toolTip.addEvent('mouseleave', this.triggerHide);
		
		this.flag = false;
		
		this.wrapper = new Element('div').inject(this.toolTip);
		if(this.options.parseDom) {
			$$(elements).each(this.build, this);
		}
		if (this.options.initialize) this.options.initialize.call(this);
	},

	build: function(el){ // modded for X3
		el.addEvent('mouseenter', function(event){
			this.mouseover(el, event);
		}.bind(this));
/*
		if (!this.options.fixed) el.addEvent('mousemove', this.locate.bindWithEvent(this));
*/
		el.addEvent('mouseleave', function(event) {
			this.mouseout(el, event);
		}.bind(this));
		el.addEvent('trash', function(event) {
			this.mouseout(el, event);
		}.bind(this));
	},
	
	getText: function(el) {
		el.$tmp.myTitle = (el.href && el.getTag() == 'a') ? el.href.replace('http://', '') : (el.rel || false);
		if (el.title){
		
			// check if we need to extract contents from a DOM element
			if (el.title.test('^DOM:', 'i')) {
				el.title = $(el.title.split(':')[1].trim()).innerHTML;				
			}
			
			// check for an URL to retrieve content from
			if (el.title.test('^AJAX:', 'i')) {
				el.title = this.options.loadingText + '::' + el.title;
			}
					
			var dual = el.title.split('::');
			if (dual.length > 1) {
				el.$tmp.myTitle = dual[0].trim();
				el.$tmp.myText = dual[1].trim();
			} else {
				el.$tmp.myText = el.title;
			}
					
			el.removeAttribute('title');
		} else {
			el.$tmp.myText = false;
		}
		if (el.$tmp.myTitle && el.$tmp.myTitle.length > this.options.maxTitleChars) el.$tmp.myTitle = el.$tmp.myTitle.substr(0, this.options.maxTitleChars - 1) + "&hellip;";
	},

	start: function(el){ // modded for X3
		this.wrapper.empty();
		this.el = el;
		// check if we have an AJAX request - if so, show a loading animation and launch the request		
		if (el.$tmp.myText && el.$tmp.myText.test('^AJAX:', 'i')) {
			this.ajax = new Ajax (el.$tmp.myText.replace(/AJAX:/i,''), {
				onComplete: function (responseText, responseXML) {
					el.$tmp.myText = responseText;
					el.$tmp.loaded = true;
					//this.getText(this.el);
					this.displayTooltip(this.el);
					}.bind(this),
				onFailure: function () {
					el.title = this.options.error.title + '::' + this.options.error.text;
					var end = this.end.bind(this);
					el.addEvent('mouseleave', end);
					this.getText(this.el);
					this.displayTooltip(this.el);
					}.bind(this),
				method: 'get'
				}).request();				
			el.$tmp.myText = '<div class="' + this.options.className + '-loading">&nbsp;</div>';			
		} else {
			this.displayTooltip(this.el);
		}
	},
	
	displayTooltip:	function(el) {

		if (el.$tmp.myTitle) {
			this.title = new Element('span').inject(
				new Element('div', {'class': this.options.className + '-title'}).inject(this.wrapper)
			).setHTML(el.$tmp.myTitle);
		}
		if (el.$tmp.myText) {
			this.text = new Element('span').inject(
				new Element('div', {'class': this.options.className + '-text'}).inject(this.wrapper)
			).setHTML(el.$tmp.myText);
		}
		if (el.$tmp.myText != '<text response="emulation"></text>') {
			$$('span.tool-close').setProperty('title', this.options.closeText).addEvent('click', function(event) {
				this.flag = false;
				this.hide();
			}.bind(this));
			this.triggerShow(el);
		}
	},

	end: function(event){
		$clear(this.timer);
		this.timer = this.hide.delay(this.options.hideDelay, this);
	},

	position: function(element){
		var pos = element.getPosition();
		this.toolTip.setStyles({
			'left': pos.x + this.options.offsets.x,
			'top': pos.y + this.options.offsets.y
		});
	},

	locate: function(event){
		var win = {'x': window.getWidth(), 'y': window.getHeight()};
		var scroll = {'x': window.getScrollLeft(), 'y': window.getScrollTop()};
		var tip = {'x': this.toolTip.offsetWidth, 'y': this.toolTip.offsetHeight};
		var prop = {'x': 'left', 'y': 'top'};
		for (var z in prop){
			if(event.page[z]) {
				var pos = event.page[z] + this.options.offsets[z];
				if ((pos + tip[z] - scroll[z]) > win[z]) pos = event.page[z] - this.options.offsets[z] - tip[z];
				this.toolTip.setStyle(prop[z], pos);
			}
		};
	},

	show: function(){
		$clear(this.triggerDelayHide);
		this.fireEvent('onShow', [this.toolTip]);
	},

	hide: function(){
		this.fireEvent.delay(0, this, ['onHide', [this.toolTip]]);
	},
	triggerShow: function(el, event) {
		if(this.flag == false) {
			this.flag = true;

			if(el.$tmp.loaded) {} else { this.getText(el); }

			this.start(el);
/* 
			if (!this.options.fixed) this.locate(event);
			else this.position(el);
*/
			this.position(el);
			this.show();
		}
	},
	triggerHide: function(el, event) {
		if(this.flag == true) {
			this.flag = false;
			this.hide();//.delay(this.options.hideDelay, this);
		}
	},
	mouseover: function(el, event) {
		if(this.triggerTimer == false) {
			this.triggerDelayShow = this.triggerShow.delay(this.options.showDelay, this, [el, event]);
			$clear(this.triggerDelayHide)
			this.triggerHide();
			if(this.ajax) {
				this.ajax.cancel();
			}
			this.triggerTimer = true;
		}
	},
	mouseout: function(el, event) {
		// delete the triggerTimer
		this.triggerTimer = false;
		$clear(this.triggerDelayShow);
		// check if the tooltips is displayed
		if(this.flag == true) {
			this.triggerDelayHide = this.triggerHide.delay(this.options.hideDelay, this, [el, event]);
		}
	}

});

Tooltips.implement(new Events, new Options);