var Tip = Class.create();
Tip.prototype = {

	initialize: function(){
		this.tooltip	= false;
		this.element	= false;
		this.trigger	= false;
		this.effects	= false;

		Event.observe(window, 'load', function(){
			// Build the tooltip
			Tip.build();
		});
	},

	// Create HTML
	html: function() {
		/*var table 						= document.createElement('table');
		table.cellpadding 				= '0';
		table.cellspacing 				= '0';
		table.className 				= 'tooltip_container';
		table.style.display				= 'none';
		table.id 						= 'tooltip_balloon';

		var tr 							= document.createElement('tr');

		var td 							= document.createElement('td');

		var tooltip_topleft 			= document.createElement('div');
		tooltip_topleft.className		= 'tooltip_topleft';

		var tooltip_topright 			= document.createElement('div');
		tooltip_topright.className		= 'tooltip_topright';

		var tooltip_top 				= document.createElement('div');
		tooltip_top.className			= 'tooltip_top';

		var tooltip 					= document.createElement('div');
		tooltip.className				= 'tooltip';

		var tooltip_left 				= document.createElement('div');
		tooltip_left.className			= 'tooltip_left';

		var tooltip_right 				= document.createElement('div');
		tooltip_right.className			= 'tooltip_right';
		tooltip_right.id				= 'tooltip_balloon_inner';

		var tooltip_bottomleft 			= document.createElement('div');
		tooltip_bottomleft.className	= 'tooltip_bottomleft';

		var tooltip_bottomright 		= document.createElement('div');
		tooltip_bottomright.className	= 'tooltip_bottomright';

		var tooltip_bottom 				= document.createElement('div');
		tooltip_bottom.className		= 'tooltip_bottom';

		var clearer 					= document.createElement('div');
		clearer.style.clear				= 'both';
		clearer.style.width				= '10px';

		table.appendChild(tr);
			tr.appendChild(td);
				td.appendChild(tooltip_topleft);
				td.appendChild(tooltip_topright);
				td.appendChild(tooltip_top);
				td.appendChild(tooltip);
					tooltip.appendChild(tooltip_left);
					tooltip_left.appendChild(tooltip_right);
				td.appendChild(tooltip_bottomleft);
				td.appendChild(tooltip_bottomright);
				td.appendChild(tooltip_bottom);
				td.appendChild(clearer);

		document.body.appendChild(table);*/

		var tooltip_balloon				= $(document.createElement('div'));
		tooltip_balloon.style.position	= 'absolute';
		tooltip_balloon.style.display	= 'inline-block';
		tooltip_balloon.style.display	= 'none';
		tooltip_balloon.id 				= 'tooltip_balloon';
		tooltip_balloon.style.zIndex 	= 990;

		balloon_topborder	= $(document.createElement('div'));
		balloon_topborder.setStyle({
			background: 'url(images/tooltip_border.gif) repeat-x bottom'
		});


		balloon_top	= $(document.createElement('div'));
		balloon_top.id = 'balloon_top';
		balloon_top.setStyle({
			background: 'url(images/tooltip_top_left.gif) no-repeat'
		});

		// Stupid IE fix
		balloon_top.update('<img style="width: 10px; height: 11px;" src="images/spacer.gif" alt="" />');

		balloon_main = $(document.createElement('div'));
		balloon_main.id = 'tooltip_balloon_inner';
		balloon_main.setStyle({
			padding: 		'4px',
			borderLeft: 	'1px solid #D5C900',
			borderRight: 	'1px solid #D5C900',
			background: 	'#FFFFE0'
		});

		balloon_botborder = $(document.createElement('div'));
		balloon_botborder.setStyle({
		//	fontSize:		'1px',
			background: 'url(images/tooltip_border.gif) repeat-x top'
		});

		balloon_bot	= $(document.createElement('div'));
		balloon_bot.id = 'balloon_bot';
		balloon_bot.setStyle({
			background: 'none'
		});

		// Stupid IE fix
		balloon_bot.update('<img style="width: 10px; height: 1px;" src="images/spacer.gif" alt="" />');

		tooltip_balloon.appendChild(balloon_topborder);
			balloon_topborder.appendChild(balloon_top);

		tooltip_balloon.appendChild(balloon_main);

		tooltip_balloon.appendChild(balloon_botborder);
			balloon_botborder.appendChild(balloon_bot);

		document.body.appendChild(tooltip_balloon);
	},


	// Position the tooltip
	position: function(){

		// Element's width
		var elm_width = Tip.element.getWidth();
		var elm_height = Tip.element.getHeight();

		var width = parseFloat(Tip.tooltip.getWidth() || '0');
		var height = parseFloat(Tip.tooltip.getHeight() || '0');

		// Clone the position
		Position.clone(Tip.element, Tip.tooltip, {setWidth: false, setHeight: false});

		// Get the tooltip's position & width
		var left 	= parseFloat(Tip.tooltip.getStyle('left') || '0');
		var top 	= parseFloat(Tip.tooltip.getStyle('top')  || '0');

		// Get the viewport
		var scroll = Tip.getScrollOffsets();
		var viewport = Tip.viewportSize();

		var balloon_top = $('balloon_top');
		var balloon_bot = $('balloon_bot');

		// Is it too far down?
		if (top + height + 30 > (viewport['height'] + scroll['top'])){

			// Position it to the bottom
			top = top - height;

			// Hide the top arrow
			balloon_top.setStyle({
				background: 'none'
			});

			$(balloon_top.firstDescendant()).setStyle({
				height: '1px'
			});

			// Use the bottom arrow
			$(balloon_bot.firstDescendant()).setStyle({
				height: '11px'
			});

			// Is it too far over the right side?
			if (left + width + 30 > (viewport['width'] + scroll['left'])){

				balloon_bot.setStyle({
					background: 'url(images/tooltip_bot_right.gif) no-repeat right'
				});

				// Align it to the right side now
				left = left + (elm_width - width) - 3;

			}
			else {

				balloon_bot.setStyle({
					background: 'url(images/tooltip_bot_left.gif) no-repeat left'
				});
			}

		}
		else {

			// Position it to the bottom
			top = top + elm_height;

			// Hide the top arrow
			balloon_bot.setStyle({
				background: 'none'
			});

			$(balloon_bot.firstDescendant()).setStyle({
				height: '1px'
			});

			// Use the bottom arrow
			$(balloon_top.firstDescendant()).setStyle({
				height: '11px'
			});

			// Is it too far over the right side?
			if (left + width + 30 > (viewport['width'] + scroll['left'])){

				balloon_top = $('balloon_top');
				balloon_top.setStyle({
					background: 'url(images/tooltip_top_right.gif) no-repeat right'
				});

				// Align it to the right side now
				left = left + (elm_width - width) - 3;

			}
			else {
				balloon_top = $('balloon_top');
				balloon_top.setStyle({
					background: 'url(images/tooltip_top_left.gif) no-repeat left'
				});
			}

		}


		// Set the position
		Tip.tooltip.setStyle({
			position: 'absolute',
			top: top + 'px',
			left: left + 'px'
		});
	},

	build: function(){

		// Re-use the old one?
		if (Tip.tooltip){
			return true;
		}

		// Create the html
		Tip.html();

		// Make life easier
		Tip.tooltip = $('tooltip_balloon');
		Tip.tooltip_inner = $('tooltip_balloon_inner');
	},

	// Show tooltip
	show: function(element, message, trigger, hide_self){

		// Already got a previous tooltip open?
		//if (Tip.tooltip && Tip.tooltip.visible() && Tip.element != element){

			// Show it again
			/*
			var show_again = function(event, element, message, trigger){
								Tip.show(element, message, trigger);
							 }.bindAsEventListener(null, element, message, trigger);

			if (this.effects){
				Effect.Queues.get('tooltip').each(function(e){ e.cancel(); e.options.afterFinish = null; });
				new Effect.Fade(Tip.tooltip, {duration: 0.1, afterFinish: show_again, queue: {position: 'end', limit: 1, scope: 'tooltip'}});
			}
			else {
				Tip.tooltip.hide();
			}

			return;
			*/

			if (Tip.tooltip == false){
				return;
			}

			if ($(Tip.tooltip).visible()){
				$(Tip.tooltip).hide();
			}
		//}

		// Save the element
		Tip.element = element;

		// Save the element's ID
		Tip.elementid = Tip.getElmID(element);

		// Set default hide trigger
		if (!trigger){
			trigger = 'mouseout';
		}

		// Set the trigger
		Tip.trigger = trigger;

		Tip.element.hide_bind = Tip.hide.bindAsEventListener(Tip, Tip.elementid);

		// Observe the hide trigger
		Event.observe(Tip.element, Tip.trigger, Tip.element.hide_bind);

		// Set the position
		Tip.tooltip.setStyle({
			top: '0px',
			left: '0px'
		});

		// Set the inner HTML
		Tip.tooltip_inner.update(message);

		// Position the tooltip
		Tip.position();

		if (this.effects){
			Effect.Queues.get('tooltip').each(function(e){ e.cancel(); });
			new Effect.Appear(Tip.tooltip, {duration : 0.5, queue: {position: 'end', limit: 1, scope: 'tooltip'}});
		}
		else {
			Tip.tooltip.show();
		}

		// - improve me

		// Let the tooltip hide itself?
		if (hide_self){

			Tip.hideSelfOn = hide_self;

			Event.observe(Tip.tooltip, Tip.hideSelfOn, Tip.hideSelf);
		}

	},

	// Hide tooltip
	hide: function(event, id){
		// Hide the tooltip
		//Tip.tooltip.hide();

		if (event){
			var elm = Event.element(event);
		}
		else if (id){
			var elm = $(id);
		}
		else {
			var elm = Tip.element;
		}

		if (Tip.elementid && id && Tip.elementid != id){
			return;
		}

		/*if (this.effects){
			Effect.Queues.get('tooltip').each(function(e){ e.cancel(); });
			new Effect.Fade(Tip.tooltip, {duration: 0.5, queue: {position: 'end', limit: 1, scope: 'tooltip'}});
		}
		else {*/
			Tip.tooltip.hide();
		//}

		// Stop observing the element?
		if (Tip.element && Tip.trigger && elm && elm.hide_bind){
			Event.stopObserving(Tip.element, Tip.trigger, elm.hide_bind);
		}

	},

	// Let tooltip hide itself
	hideSelf: function(){

		if (this.effects){
			Effect.Queues.get('tooltip').each(function(e){ e.cancel(); });
			new Effect.Fade(Tip.tooltip, {duration: 0.5, queue: {position: 'end', limit: 1, scope: 'tooltip'}});
		}
		else {
			Tip.tooltip.hide();
		}

		// Stop observing self
		Event.stopObserving(Tip.tooltip, Tip.hideSelfOn, Tip.hideSelf);

		// Start observing to showself
		//Event.observe(Tip.tooltip, Tip.hideSelfOn, Tip.hideSelf);
	},

	// Start observing the show trigger
	// Use this if you're not using the usual method of showing them
	create: function(element, message, show, hide, hide_self){

		element = $(element);

		// Set default show trigger
		if (!show){
			show = 'mouseover';
		}

		element.show_bind = function(e, element, message, hide, hide_self){ if (!Tip){ return; } Tip.show(element, message, hide, hide_self); var nout = null; }.bindAsEventListener(null, element, message, hide, hide_self);

		Event.observe(element, show, element.show_bind);
	},

	// Destroy a tooltip
	destroy: function(element, show){

		element = $(element);

		// Hide it if it's visible
		if (Tip.tooltip && Tip.tooltip.visible()){
			var func = Tip.hide.bindAsEventListener(Tip, element, Tip.getElmID(element));

			func();
		}

		// Set default show trigger
		if (!show){
			show = 'mouseover';
		}

		// Stop observing the event
		Event.stopObserving(element, show, element.show_bind);
	},

  viewportWidth: function() {
    return self.innerWidth || (document.documentElement.clientWidth || document.body.clientWidth);
  },

  viewportHeight: function() {
    return self.innerHeight || (document.documentElement.clientHeight || document.body.clientHeight);
  },

  viewportSize: function() {
    return { width: this.viewportWidth(), height: this.viewportHeight() };
  },

	getScrollLeft: function(){
		return window.pageXOffset || document.documentElement.scrollLeft;
	},

	getScrollTop: function(){
		return window.pageYOffset || document.documentElement.scrollTop;
	},

	getScrollOffsets: function(){
		return {'left': Tip.getScrollLeft(), 'top': Tip.getScrollTop()}
	},

	getElmID : function(elm) {
		return elm.id ? elm.id : elm.name;
	}
}

// Singleton approach
var Tip = new Tip();

// We'll stick the alerts in here too as they're related
// and share a few functions
var alert_count = 0;
var alert_timeout = 0;

function update_alert_button(alert_id, i){

	clearTimeout(alert_timeout);

	if (i == 0){
		Effect.Fade('alertbox', {duration: 0.3});

		return;
	}

	$('close_alert_' + alert_id).innerHTML = 'Close this message (' + i + ')';

	i--;

	alert_timeout = setTimeout('update_alert_button("' + alert_id + '", ' + i + ')', 1000);
}

function show_alert(message){

	if (typeof(Draggable) == 'undefined'){
		alert(message);
		return;
	}

	if (!$('alertbox')){
		new Insertion.Top(document.body,  '<div id="alertbox" class="alertbox" style="padding: 2px;">'
									+ '<div class="alert_tleft"></div>'
									+ '<div class="alert_tright"></div>'
									+ '<div class="alert_top"></div>'
									+ '<div class="alert_left">'
									+ '<div class="alert_right">'
									+ '	<div class="alert_main">'
									+ 		message
									+ '		<div class="alert_button"><button name="close_alert_' + alert_count + '" id="close_alert_' + alert_count + '" onclick="Effect.Fade(\'alertbox\', {duration: 0.3});">Close this message</button></div>'
									+ '	</div>'
									+ '</div>'
									+ '</div>'
									+ '<div class="alert_bleft"></div>'
									+ '<div class="alert_bright"></div>'
									+ '<div class="alert_bottom"></div>'
									+ '</div>');

	//var dimensions = Validation.viewportSize();//Element.getDimensions(document.body);
//	var body_width = self.innerWidth;
//	var body_height = self.innerHeight;
		new Draggable('alertbox');
	}
	else {
		$('alertbox').setOpacity(1);
		$('alertbox').show();

		clearTimeout(alert_timeout);
	}

	// Get the viewport
	var scroll = Tip.getScrollOffsets();
	var viewport = Tip.viewportSize();

	var dimensions = Element.getDimensions($('alertbox'));
	var width = dimensions.width;
	var height = dimensions.height;

	$('alertbox').style.left = scroll['left'] + (viewport['width'] / 2) - (width / 2) + 'px';
	$('alertbox').style.top = scroll['top'] + (viewport['height'] / 2) - (height / 2) + 'px';

	new Effect.Highlight('alertbox', {startcolor: '#FF6666'});

	update_alert_button(alert_count, 10);
}

// Set the resize function
//Event.observe(window, 'resize', Tip.hide.bind(Tip));