/* 	Tooltip Class */
var Tooltip = Class.create();
Tooltip.prototype = ({
	
	//CONSTRUCTOR
	initialize: function (str_tiplayer_id, str_class_name, str_xml_url, int_offset_top, int_offset_left, bool_use_cursor)
	{
		this._str_tiplayer_id 	= str_tiplayer_id;
		this._regex_class_name	= str_class_name;
		this._str_xml_url		= str_xml_url;
		this._int_offset_top	= int_offset_top;
		this._int_offset_left	= int_offset_left;
		this._bool_use_cursor	= bool_use_cursor;

		this._arr_contents		= new Array();
		this._elem_tip 			= this.createTip();
		this._int_tip_id		= false;
		this._last_tip			= false;
		this._target			= false;
		this._in_target			= false;
		
		this._arr_targets		= this.getTargets();
		
		this.handleEventsObserver=this.handleEvents.bindAsEventListener(this);
		
		this.attachTriggers();
	},
	
	//METHODS
	createTip: function()
	{
		var tip_id = this._str_tiplayer_id;
		if(tip_id)
		{	
			//does tip elem exist
			var tip_elem = $(tip_id) ? $(tip_id) : false;
			
			//tip elem not found so add to body
			if(!tip_elem)
			{
				tool_tip_layer 						= document.createElement( 'dl' );
				tool_tip_layer.id 					= tip_id;
				tool_tip_layer.onmouseover			= function(){Element.show(this);};
				tool_tip_layer.onmouseout			= function(){Element.hide(this);};
				
				var tip_elem = document.body.insertBefore( tool_tip_layer, document.body.firstChild );
			}
			//tip elem found or successfully added to body				
			return tip_elem;
		}
		//not able to find or create tip elem
		return false;
	},
	
	getTargets: function()
	{
		var targets = document.getElementsBySelector('.tooltip');
		return targets;
	},
	
	attachTriggers: function ()
	{
		if(!this._arr_targets)
			this._arr_targets = this.getTargets();
				
		for (var i=0; i<this._arr_targets.length; i++)
		{
			Event.observe(this._arr_targets[i], 'mouseover', this.handleEventsObserver);
			Event.observe(this._arr_targets[i], 'mouseout', this.handleEventsObserver);
		}
	},
	
	removeTriggers: function ()
	{
		for (var i=0; i<this._arr_targets.length; i++)
		{
			Event.stopObserving(this._arr_targets[i], 'mouseover', this.handleEventsObserver);
			Event.stopObserving(this._arr_targets[i], 'mouseout', this.handleEventsObserver);
		}
		this._arr_targets = false;
	},
	
	handleEvents: function(event)
	{
		this._target		= Event.element(event);
		this._int_tip_id 	= this.getCurrentTipId();
		
		if(event.type=='mouseover')
		{
			this._in_target = true;
			this.getTipContent();
		}
		else if(event.type=='mousemove' && this._in_target && this._arr_contents[this._int_tip_id]!='')
		{
			this.positionTip();
		}
		else if(event.type=='mouseout')
		{
			this._in_target = false;
			Element.hide(this._elem_tip);
			//new Effect.DropOut(this._elem_tip);
		}
	},
	
	getTipContent: function()
	{
		if(!this._arr_contents[this._int_tip_id])
		{
			var pars = 'tooltip='+this._int_tip_id;
			var request_url = this._str_xml_url;
			
			this.ajax = new Ajax.Request( request_url, 
					{
						method: 'get',
						parameters: pars,
						onComplete:this.saveResponse.bind(this)
					}
			);
		}
		//use saved content
		else
		{
			this._last_tip = this._int_tip_id;
			Element.update(this._elem_tip, this._arr_contents[this._int_tip_id]);
			this.positionTip();
		}
	},

	saveResponse: function (originalRequest)
	{
		//save response
		this._arr_contents[this._int_tip_id] = originalRequest.responseText;		
		Element.update(this._elem_tip, originalRequest.responseText);
		
		this._last_tip = this._int_tip_id;
		this.positionTip();
	},

	positionTip: function()
	{
		//Position.prepare();
		if (this._bool_use_cursor)
		{
			//get cursor position
			var int_x_pos = Event.pointerX(e.evnt);
			var int_y_pos = Event.pointerY(e.evnt);

			//apply user defined offset
			int_x_pos += this._int_offset_left;
			int_y_pos += this._int_offset_top;
		}
		else
		{
			//get position of mouseover element
			var arr_offsets = Position.cumulativeOffset(this._target);
			var int_x_pos = arr_offsets[0] + this._target.offsetWidth + this._int_offset_left;
			var int_y_pos = arr_offsets[1] + this._int_offset_top;
		}
		//keep tip within visible page area
		var tip_dimensions 	= Element.getDimensions(this._elem_tip);

		var tip_position	= new Object();	
		tip_position.x=Number(int_x_pos+tip_dimensions.width)
		tip_position.y=Number(int_y_pos+tip_dimensions.height);
		
		//if all of tip is visible then both x and y will have negative values
		var visibility = this.isVisible(tip_position);
		
		//off screen width
		if(visibility.x > 0)
		{
			if (!this._bool_use_cursor)
			{
				int_x_pos -= this._target.offsetWidth;
				int_x_pos -= tip_dimensions.width;
			}
			else
			{
				int_x_pos -= tip_dimensions.width;
				int_x_pos -= 2*this._int_offset_left;
			}
		}
		//off screen height
		if(visibility.y > 0)
		{
			if (!this._bool_use_cursor)
			{
				int_y_pos -= visibility.y;
			}
			else 
			{
				int_y_pos -= tip_dimensions.height;
				int_y_pos -= 2*this._int_offset_top;
			}
		}

		if(int_x_pos && int_x_pos)
		{	
			this._elem_tip.style.left		= int_x_pos +'px';
			this._elem_tip.style.top		= int_y_pos + 'px';

			Element.show(this._elem_tip);
		}
	},

	isVisible: function(elem)
	{
		var xdiff;
		var ydiff;
		
		var real_area	= new Object();
		
		var viewable 	= this.viewableArea();
		var scroll_area	= this.scrollArea();
		
		real_area.x		= viewable.x+scroll_area.x;
		real_area.y		= viewable.y+scroll_area.y;


		//subtract viewport height and width from tooltip bottom and right coords
		xdiff	 = elem.x - real_area.x;
		ydiff	 = elem.y - real_area.y;
	
		return {x:xdiff,y:ydiff};
	},

	viewableArea: function()
	{
		var x,y;
		
		if (self.innerHeight) // all except Explorer
		{
			x = self.innerWidth;
			y = self.innerHeight;
		}
		else if (document.documentElement && document.documentElement.clientHeight)
			// Explorer 6 Strict Mode
		{
			x = document.documentElement.clientWidth;
			y = document.documentElement.clientHeight;
		}
		else if (document.body) // other Explorers
		{
			x = document.body.clientWidth;
			y = document.body.clientHeight;
		}
		return {x:x,y:y};
	},
	
	scrollArea: function()
	{
		var x,y;
		
		if (this.pageYOffset) // all except Explorer
		{
			x = this.pageXOffset;
			y = this.pageYOffset;
		}
		else if (document.documentElement && document.documentElement.scrollTop)
			// Explorer 6 Strict
		{
			x = document.documentElement.scrollLeft;
			y = document.documentElement.scrollTop;
		}
		else if (document.body) // all other Explorers
		{
			x = document.body.scrollLeft;
			y = document.body.scrollTop;
		}
		return {x:x,y:y};
	},

	getCurrentTipId: function()
	{
		var regex_tip_id = this._regex_class_name;		

		if(regex_tip_id)
		{
			//attempt to find tip id
			regex_tip_id.test(this._target.className );
			var int_tip_id = (RegExp.$1 != '') ?  RegExp.$1 : false;
			
			return int_tip_id;
		}
		return false;
	}
});


