YUI().use('node', 'overlay', function(Y) {
	Y.all('.HasTooltip').each(function(el) {
		new HoverTooltip(Y, el);
	});
});

function HoverTooltip(Y, el) {
	if (Y.one('body').hasClass('fr'))
		this.i18n = HoverTooltip.i18n.fr;
	else {
		if (window.HoverTooltip_i18n_lang)
			this.i18n = HoverTooltip.i18n[window.HoverTooltip_i18n_lang];
		else
			this.i18n = HoverTooltip.i18n.en;
	}

	if (el.hasClass('TooltipEnabled'))
		return; /* Do nothing.... */
	else
		el.addClass('TooltipEnabled');

	var id = el.get('id');
	this.id = id;

	this.Y = Y;
	this.el = el;
	this.ref_el = Y.one('#' + id + '-ref');
	this.text_el = Y.one('#' + id + '-text');
	
	this.whats_this_visible_by_default = !this.el.hasClass('WhatsThisHideByDefault');
	
	this.CreateWhatsThis();
	this.CreateTooltip();
	
	var self = this; // 'this' doesn't survive the closure.
	this.el.on('mouseover', function() {
		//self.BeginShowTooltipTimer();
		self.ClearHideTooltipTimer();
		self.ClearHideTooltipRefTimer();
		self.ShowTooltipRef();
	});
	this.el.on('mouseout', function() {
		self.ClearShowTooltipTimer();
		self.BeginHideTooltipRefTimer();
		self.BeginHideTooltipTimer();
	});
	
	HoverTooltip.RegisterTooltip(this);
}

HoverTooltip.RegisterTooltip = function(tooltip) {
	if (typeof(HoverTooltip.all) == 'undefined')
		HoverTooltip.all = [];
		
	HoverTooltip.all.push(tooltip);
};
HoverTooltip.HideAll = function() {
	if (typeof(HoverTooltip.all) == 'undefined')
		return;
		
	for (var i = 0; i < HoverTooltip.all.length; i++)
		HoverTooltip.all[i].HideTooltip();
}

HoverTooltip.prototype.CreateTooltip = function() {
	// Re-parent the text element so that onmouseout doesn't fire when we go to "what's this?"
	this.text_el.remove();
	this.el.prepend(this.text_el);
	
	this.text_el.addClass('TooltipHovering');
	var contents = this.text_el.get('innerHTML');
	
	this.text_el.set('innerHTML', '<div class="BubbleTop">&nbsp;</div><div class="BubbleContents"><h1 class="NoTopPadding BottomPadding">' + this.i18n.whats_this + '</h1>' + contents + '</div><div class="BubbleBottom">&nbsp;</div>');
};

HoverTooltip.prototype.CreateWhatsThis = function() {
	var node = this.Y.Node.create('<a href="javascript:">&nbsp;' + this.i18n.whats_this + '</a>');
	var self = this;
	node.on('click', function(e) { e.preventDefault(); self.ShowTooltip(); });
	
	this.ref_el.addClass('TooltipHovering');
	this.ref_el.set('innerHTML', '');
	this.ref_el.prepend(node);
	
	// Re-parent the ref element so that onmouseout doesn't fire when we go to "what's this?"
	this.ref_el.remove();
	this.el.prepend(this.ref_el);
	
	if (this.whats_this_visible_by_default) {
		this.ref_el.addClass('TooltipFaded');
		this.ShowTooltipRef();
	}
}

HoverTooltip.prototype.ShowTooltipRef = function(arg1) {
	this.ref_el.addClass('Shown');
	
	var el_width = parseInt(this.el.getComputedStyle('width'));
	var el_height = parseInt(this.el.getComputedStyle('height'));
	var re_width = parseInt(this.ref_el.getComputedStyle('width'));
	var re_height = parseInt(this.ref_el.getComputedStyle('height'));
	
	var xy = this.el.getXY();
	var el_left = parseInt(xy[0]);
	var el_top = parseInt(xy[1]);
		
	// Position it on the top-right of the item.
	var top_right_above = function() {
		var ref_left = el_left + el_width - re_width;
		var ref_top = el_top - re_height + 1;
		return [ref_left, ref_top];
	};
	var top_right_inside = function() {
		var ref_left = el_left + el_width - re_width;
		var ref_top = el_top;
		
		return [ref_left, ref_top];
	};
	var bottom_right_inside = function() {
		var ref_left = el_left + el_width - re_width;
		var ref_top = el_top + el_height - re_height + 1;
		return [ref_left, ref_top];
	};
	var middles_right_inside = function() {
		var ref_left = el_left + el_width - re_width;
		var ref_top = el_top + el_height/2 - re_height/2 + 1;
		return [ref_left, ref_top];
	};
	
	var call_matrix = {
		'WhatsThisTopRightAbove': top_right_above,
		'WhatsThisTopRightInside': top_right_inside,
		'WhatsThisBottomRightInside': bottom_right_inside,
		'WhatsThisMiddlesRightInside': middles_right_inside
	};
	
	var pos = top_right_above();
	for (var key in call_matrix)
		if (this.el.hasClass(key)) {
			pos = call_matrix[key]();
			break;
		}
	
	this.ref_el.setXY(pos);
};

HoverTooltip.prototype.HideTooltipRef = function(arg1) {
	if (!this.whats_this_visible_by_default)
		this.ref_el.removeClass('Shown');
};


HoverTooltip.prototype.ShowTooltip = function() {

	// Hide all other open tooltips

	this.ClearShowTooltipTimer();
	
	HoverTooltip.HideAll();
	
	this.text_el.addClass('Shown');
	
	var el_width = parseInt(this.el.getComputedStyle('width'));
	var el_height = parseInt(this.el.getComputedStyle('height'));
	var re_width = parseInt(this.ref_el.getComputedStyle('width'));
	var re_height = parseInt(this.ref_el.getComputedStyle('height'));
	var tt_width = parseInt(this.text_el.getComputedStyle('width'));
	var tt_height = parseInt(this.text_el.getComputedStyle('height'));
	
	var xy = this.el.getXY();
	var el_left = parseInt(xy[0]);
	var el_top = parseInt(xy[1]);
	
	
	// Different positioning schemes:
	
	// Align to the bottom right of the element on the right side
	var to_bottom_right_on_right = function() {
		var text_left = el_left + el_width + 20;
		var text_top = el_top + el_height - tt_height;
		return [text_left, text_top];
	};
	
	// Align to teh bottom right of the element below it
	var to_bottom_right_below = function() {
		var text_left = el_left + el_width - tt_width;
		var text_top = el_top + el_height + 10;
		
		return [text_left, text_top];
	};
	
	// Align to the bottom left of the element on the left side
	var to_bottom_left_on_left = function() {
		var text_left = el_left - tt_width - 10;
		var text_top = el_top + el_height - tt_height;
		
		return [text_left, text_top];
	};
	
	var to_top_right_on_right = function() {
		var text_left = el_left + el_width + 10;
		var text_top = el_top;
		
		return [text_left, text_top];
	};
	
	var to_top_left_on_left = function() {
		var text_left = el_left - tt_width - 10;
		var text_top = el_top;
		
		return [text_left, text_top];
	};
	
	// Align align middles above the element.
	var to_middles_top = function() {
		var text_left = el_left - tt_width + tt_width/2 + el_width/2;
		var text_top = el_top - tt_height - 15;
		
		return [text_left, text_top];
	};
	
	var call_matrix = {
		'ToBottomLeftOnLeft': to_bottom_left_on_left,
		'ToBottomRightOnRight': to_bottom_right_on_right,
		'ToBottomRightBelow': to_bottom_right_below,
		'ToTopRightOnRight': to_top_right_on_right,
		'ToTopLeftOnLeft': to_top_left_on_left,
		'ToMiddlesTop': to_middles_top
	};
	
	var pos = to_middles_top();
	for (var key in call_matrix)
		if (this.text_el.hasClass(key)) {
			pos = call_matrix[key]();
			break;
		}
	
	this.text_el.setXY(pos);
};
HoverTooltip.prototype.HideTooltip = function() {
	this.ClearHideTooltipTimer();
	this.text_el.removeClass('Shown');
};



//
// Tooltip timers
//

HoverTooltip.prototype.BeginHideTooltipRefTimer = function() {
	var self = this;
	this.tooltip_ref_hide_timer = setTimeout(function() { self.HideTooltipRef(); }, 800);
}
HoverTooltip.prototype.ClearHideTooltipRefTimer = function() {
	if (!this.tooltip_ref_hide_timer)
		return; // Do nothing.
	
	clearTimeout(this.tooltip_ref_hide_timer);
	this.tooltip_ref_hide_timer = null;
};

HoverTooltip.prototype.BeginShowTooltipTimer = function() {
	var self = this;
	this.tooltip_show_timer = setTimeout(function() { self.ShowTooltip(); }, 300);
};
HoverTooltip.prototype.ClearShowTooltipTimer = function() {
	if (!this.tooltip_show_timer)
		return; // Do nothing.
	
	clearTimeout(this.tooltip_show_timer);
	this.tooltip_show_timer = null;
};


HoverTooltip.prototype.BeginHideTooltipTimer = function() {
	var self = this;
	this.tooltip_timer = setTimeout(function() { self.HideTooltip(); }, 800);
};
HoverTooltip.prototype.ClearHideTooltipTimer = function() {
	if (!this.tooltip_timer)
		return; // Do nothing.
	
	clearTimeout(this.tooltip_timer);
	this.tooltip_timer = null;
};



HoverTooltip.i18n = {
	en: {
		whats_this: 'What\'s this?'
	},
	fr: {
		whats_this: 'Qu\'est-ce?'
	}
};