/*
this is a simple modification of original Tips Class
just for make tips stay while mouse IS over the tip.
this behaviour only works when options.fixed=true

also added code made by JustinMs66
http://forum.mootools.net/viewtopic.php?id=3673

to do this i added 2 more options 
showOnClick: true, which shows tip when clicked
showOnMouseEnter: true, which shows tip when mouse enter

for requirements just click on tips http://mootools.net/download and you'll get them

vladimir prieto
http://vladimirprieto.blogspot.com

log :

2007-08-22 v1.3 :
	- fix some problems onmouseleave
	
2007-08-21 v1.2 :
	- added DOM reference on title, wich can be absolute or relative reference ('mydiv' or this. or $(this).  see examples)
	  this one is based on tips made by  (http://www.e-magine.ro/web-dev-and-design/46/tooltips-from-ajax-dom-nodes-or-inline-attributes-contents/)
	- remake of the toolTip.  now it make reference of the tips or creat one if no dom object is passed through title.
	  original Tips class make just one div and copy/paste html values inside of it, making clones of objects.
	
2007-08-13 v1.1 :

- fixed error with onclick event.

*/

/*
Script: Tips.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>
*/

/*
Class: Tips
	Display a tip on any element with a title and/or href.

Note:
	Tips requires an XHTML doctype.

Arguments:
	elements - a collection of elements to apply the tooltips to on mouseover.
	options - an object. See options Below.

Options:
	maxTitleChars - the maximum number of characters to display in the title of the tip. defaults to 30.
	showDelay - the delay the onShow method is called. (defaults to 100 ms)
	hideDelay - the delay the onHide method is called. (defaults to 100 ms)

	className - the prefix for your tooltip classNames. defaults to 'tool'.

		the whole tooltip will have as classname: tool-tip

		the title will have as classname: tool-title

		the text will have as classname: tool-text

	offsets - the distance of your tooltip from the mouse. an Object with x/y properties.
	fixed - if set to true, the toolTip will not follow the mouse.
	
Events:
	onShow - optionally you can alter the default onShow behaviour with this option (like displaying a fade in effect);
	onHide - optionally you can alter the default onHide behaviour with this option (like displaying a fade out effect);

Example:
	(start code)
	<img src="/images/i.png" title="The body of the tooltip is stored in the title" class="toolTipImg"/>
	<script>
		var myTips = new Tips($$('.toolTipImg'), {
			maxTitleChars: 50	//I like my captions a little long
		});
	</script>
	(end)

Note:
	The title of the element will always be used as the tooltip body. If you put :: on your title, the text before :: will become the tooltip title.
*/

var mooTips = new Class({

	options: {
		onShow: function(tip){
			tip.setStyle('visibility', 'visible');
		},
		onHide: function(tip){
			tip.setStyle('visibility', 'hidden');
		},
		showOnClick: false,
		showOnMouseEnter: true,
		showDelay: 100,
		hideDelay: 100,
		offsets: {'x': 16, 'y': 16},
		className: 'tool',
		fixed: false
	},

	initialize: function(elements, options){
		this.setOptions(options);

		$$(elements).each(this.build, this);
		
		if (this.options.initialize) this.options.initialize.call(this);
	},
	build: function(el){
		if (el.title){
			
			if (el.title.test('^DOM:', 'i')) {
				id_string = el.title.split(':')[1].trim();
				//if it is relative reference (if it got "this")
				if (id_string.contains('this'))
					id_string = eval(id_string.replace(/this/, "el"));

				el.domObject = $(id_string);
				el.domObject.setStyles({
					display: '',
					visibility: 'hidden',
					position: 'absolute',
					top: '0',
					left: '0',
					'z-index':99
				});
				
				el.domObject.addClass(this.options.className+'-text');
				
			} else {
				el.$tmp.myTitle = (el.href && el.getTag() == 'a') ? el.href.replace('http://', '') : (el.rel || false);
				//building element.domObject (div)
				internalDiv = new Element('div', {
					'class': this.options.className + '-tip',
					'styles': {
						'position': 'absolute',
						'top': '0',
						'left': '0',
						'visibility': 'hidden',
						'z-index':99
					}
				}).inject(document.body);
				
				//think this wrapper is unnecessary
				wrapper = new Element('div').inject(internalDiv);
				
				el.domObject = internalDiv;
				
				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;
				}
				if (el.$tmp.myTitle && el.$tmp.myTitle.length > this.options.maxTitleChars) el.$tmp.myTitle = el.$tmp.myTitle.substr(0, this.options.maxTitleChars - 1) + "&hellip;";

				if (el.$tmp.myTitle){
					this.title = new Element('span').inject(new Element('div', {'class': this.options.className + '-title'}).inject(wrapper)).setHTML(el.$tmp.myTitle);
				}
				if (el.$tmp.myText){
					this.text = new Element('span').inject(new Element('div', {'class': this.options.className + '-text'}).inject(wrapper)).setHTML(el.$tmp.myText);
				}

			}
			//this ones makes hide tip only when mouseleave it
			//IF fixed=true
			el.domObject.addEvents({
				'mouseenter': function(event){
					el.state = 'mouseenter';
				}.bind(this),
				
				'mouseleave': function(event){
					el.state = 'mouseleave';
					this.end(el);
				}.bind(this)
			});
			
			this.domObject = el.domObject;
			el.removeAttribute('title');
		}
		
		if (el.domObject) {

			if (this.options.showOnClick) {
				el.addEvent('click', function(event){
					this.start(el);
					if (!this.options.fixed) this.locate(event,el);
					else this.position(el);
				}.bindWithEvent(this));
			}
	
			if (this.options.showOnMouseEnter) {
				el.addEvent('mouseenter', function(event){
					this.start(el);
					if (!this.options.fixed) this.locate(event,el);
					else this.position(el);
				}.bind(this));
			}
			
			if (!this.options.fixed) el.addEvent('mousemove', this.locate.create({
													'arguments': [el],
													'bind': this,
													'event': Event
													}));
			
//			var end = this.end.bind(this);
			el.addEvent('mouseleave', this.end.create({
										'arguments': [el],
										'bind': this
										}));
			el.addEvent('trash', this.end.create({
										'arguments': [el],
										'bind': this
										}));
		}
	},

	start: function(el){
		if (el.domObject) {
			//pick up saved domObject element
			this.domObject = el.domObject;

			$clear(el.timer);
			
			//settting initial state of tip
				el.state = 'mouseleave';
			
			el.timer = this.show.delay(this.options.showDelay, this, el);
		}
	},
	
	end: function(el){
		$clear(el.timer);
		el.timer = this.hide.delay(this.options.hideDelay, this, el);
	},

	position: function(element){
		var pos = element.getPosition();
		element.domObject.setStyles({
			'left': pos.x + this.options.offsets.x,
			'top': pos.y + this.options.offsets.y,
			'z-index':99
		});
	},

	locate: function(event,el){
		var win = {'x': window.getWidth(), 'y': window.getHeight()};
		var scroll = {'x': window.getScrollLeft(), 'y': window.getScrollTop()};
		var tip = {'x': el.domObject.offsetWidth, 'y': el.domObject.offsetHeight};
		var prop = {'x': 'left', 'y': 'top'};
		for (var z in prop){
			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];
			el.domObject.setStyle(prop[z], pos);
		};
	},

	show: function(el){
		if (this.options.timeout) el.timer = this.hide.delay(this.options.timeout, this);
		this.fireEvent('onShow', [el.domObject]);
	},

	hide: function(el){
		//if fixed, then it only hide when mouse leave toolTip (the tip itself)
		if ((el.state == 'mouseleave') || (!this.options.fixed))
			this.fireEvent('onHide', [el.domObject]);
	}
});

mooTips.implement(new Events, new Options);

