/**
 * Provide a hint box near input as a absolute positioned div.
 * @name InputHintBox
 * @cat Plugins/Forms
 * @type $
 * @param Map options Optional settings
 * @option jQueryDom @div box to show, if this is set then className do not apply
 * @option String @div_sub css selector, use this when you need to write the Dynamic html into a element Inside the @div box,
 							example: .body, this will search for .body in context of @div
 * @option String @className This class will be added to the dynamic created div box. Default: "input_hint_box"
 * @option String @source Source of box message text html: attr | html, Default: "attr"
 * @option String @attr If @source = "attr" then html will be taken from the attribute named @attr. Default: "title"
 * @option String @html If @source = "html" them html will be taken from @html
 * @option Integer @incrementLeft This value will be incremented to the left property of the absolute positioned hint box. Default: 10
 * @option Integer @incrementTop This value will be incremented to the top property of the absolute positioned hint box. Default: 10
 * @option String @attachTo Hint box will be appended to this. Default: "body"
 */

(function($) {
$.fn.inputHintBox = function(options) {
	options = $.extend({}, $.inputHintBoxer.defaults, options);
	
	this.each(function(){
		new $.inputHintBoxer(this,options);
	});
	return this;
}

$.inputHintBoxer = function(input, options) {
	var $guideObject,$input = $guideObject = $(input), box, boxMouseDown = false;
	
	//$guideObject - in left of this object hint box will be positioned
	
	// If @type=radio then it must be inside a label and we should put the hint box in the right side of the label
	if ( ($input.attr('type') == 'radio' || $input.attr('type') == 'checkbox') && $input.parent().is('label') ) {
		$guideObject = $( $input.parent() );
	}
	

	function init() {
		var boxHtml = options.html != ''?options.html:
					  	options.source == 'attr'?$input.attr(options.attr): '';
			
		if (typeof boxHtml === "undefined") boxHtml = '';
		box = options.div != '' ? options.div.clone() : $("<div/>").addClass(options.className);
		box = box.css('display','none').addClass('_hintBox').appendTo(options.attachTo);
		
		if (options.div_sub == '') box.html(boxHtml);
		else $(options.div_sub,box).html(boxHtml);
		
		$input.focus(function() {
			clearTimeout($.inputHintBoxer.mostRecentHideTimer);
			$('._hintBox').stop(true, true).fadeOut('fast');
			$('body').mousedown(global_mousedown_listener);
			show();
		}).blur(function(){
			prepare_hide();
		});
	}
	
	// This is evaluated each time to prevent probs with elements with display none
	function align() {
		var offsets = $guideObject.offset(),
			left = offsets.left + $guideObject.width() + options.incrementLeft,
			top = offsets.top + options.incrementTop;
		box.css({position:"absolute",top:top,left:left});
	}
	
	function show() {
		align();
		box.stop(true, true).fadeIn('normal');
	}
	
	function prepare_hide() {
		// We want to allow user to select and copy/paste content from the box
		// So delay a bit to see where user click
		$('body').click(global_click_listener);
		if (boxMouseDown) return;
		$.inputHintBoxer.mostRecentHideTimer = setTimeout(function(){hide()},300);
	}
	
	var global_click_listener = function(e) {
		var $e = $(e.target),c='._hintBox';
		clearTimeout($.inputHintBoxer.mostRecentHideTimer);
		if ($e.parents(c).length == 0 && $e.is(c) == false) hide();
	};
	
	// Prevent hiding when selecting..
	// When user Select a text to select, a Mousedown is fired BEFORE blur of input
	// This why we need to know when a Mousedown is done to our object
	var global_mousedown_listener = function(e) {
		var $e = $(e.target),c='._hintBox';
		boxMouseDown = ($e.parents(c).length != 0 || $e.is(c) != false);
	}
	
	function hide() {
		$('body').unbind('click',global_click_listener);
		$('body').unbind('mousedown',global_mousedown_listener);
		align();
		box.stop(true, true).fadeOut('normal');
	}
	
	init();
	return {}
};

$.inputHintBoxer.mostRecentHideTimer = 0;

$.inputHintBoxer.defaults = {
	div: '',
	className: 'input_hint_box',
	source: 'attr', // attr or html
	div_sub: '', // Where to write
	attr: 'title',
	html: '',
	incrementLeft: 2,
	incrementTop: 0,
	attachTo: 'body'
}

})(jQuery);
