/**
 * Automatically manages default values for input elements.
 * 
 * @author Ewen Elder <ewen@jainaewen.com> <glomainn@yahoo.co.uk>
 * @copyright (c)Copyright 2011 Ewen Elder
 * @version 0.3 Alpha
 * @todo Improve at lunch time :)
 */
;(function ($)
{
	$.fn.defaultInputValues = function (options)
	{
		var defaultInputValues = 
		{
			/**
			 * Positions the clone.
			 * 
			 * This method attempts to position the clone where the original is. 
			 * The reason I did this instead of simply inserting it after the 
			 * original element is so that it doesn't screw up the use of CSS nth
			 * type selectors.
			 * 
			 * @param {Object} element The element to position
			 * @return {Object} This class
			 */
			position : function (element)
			{
				var clone = $('#' + element.attr('id') + options.passwordCloneId),
					offset = element.offset();
				
				
				clone
					.css('position', 'absolute')
					.offset({
						top : offset.top, 
						left : offset.left
					});
				
				return this;
			},
			
			
			/**
			 * The focus event actions.
			 * 
			 * Check whether to clear the input value or not, also hides any password
			 * clones and shows the original password element.
			 * 
			 * @param {Object} element The element to check
			 * @return {Object} This class
			 */
			focus : function (element)
			{
				if (element.data(options.isPasswordFieldCloneDataName))
				{
					element.hide();
					
					$('#' + element.attr('id').replace(options.passwordCloneId, ''))
						.css('visiblity', 'visible')
						.focus();
				}
				
				if (element.val() === element.data(options.defaultValueDataName))
				{
					element.val('');
				}
				
				return this;
			},
			
			
			/**
			 * The blur event actions.
			 * 
			 * Check whether to reinstate the default value or not, also shows any
			 * password clones and hides the original password element.
			 * 
			 * @param {Object} element The element to check
			 * @return {Object} This class
			 */
			blur : function (element)
			{
				if (element.val().replace(/ /g, '').length)
				{
					return null;
				}
				
				
				if (element.data(options.isPasswordFieldDataName))
				{
					element
						.val('')
						.css('visiblity', 'hidden');
					
					$('#' + element.attr('id') + options.passwordCloneId).show();
				}
				
				else
				{
					element.val(element.data(options.defaultValueDataName));
				}
				
				return this;
			},
			
			
			/**
			 * Attach event listeners.
			 * 
			 * Attatches the required event listeners and delegates any actions to
			 * the appropriate method.
			 * 
			 * @param {Object} element The element to attach the listeners to
			 * @return {Object} This class
			 */
			listeners : function (element)
			{
				var self = this;
				
				element
					.bind('focus.' + options.namespace, function ()
					{
						self.focus($(this));
					})
					.bind('blur.' + options.namespace, function ()
					{
						self.blur($(this));
					});
				
				return this;
			}
		};
		
		
		options = $.extend({}, $.defaultInputValues.defaults, options);
		
		return $(this).each(function ()
		{
			var clone;
			
			$(this).data(options.defaultValueDataName, $(this).val());
			defaultInputValues.listeners($(this));
			
			
			// If we want to show the password field as plain text when showing default value.
			if (options.showPasswordFields && $(this).attr('type') === 'password')
			{
				clone = $(document.createElement('input'));
				clone
					.data(options.isPasswordFieldCloneDataName, true)
					.attr({
						type : 'text',
						name : $(this).attr('name') + options.passwordCloneId,
						id : $(this).attr('id') + options.passwordCloneId,
						className : $(this).attr('className'),
						maxlength : $(this).attr('maxlength'),
						size : $(this).attr('size'),
						readonly : $(this).attr('readonly'),
						value : $(this).attr('value'),
						style : $(this).attr('style')
					});
				
				
				$('body').append(clone);
				
				defaultInputValues
					.position($(this))
					.listeners(clone);
				
				
				$(this)
					.data(options.isPasswordFieldDataName, true)
					.css('visiblity', 'hidden');
			}
		});
	};
	
	
	$.defaultInputValues = 
	{
		version : 'alpha',
		defaults : {
			namespace : 'defaultInputValues',
			showPasswordFields : false,
			passwordCloneId : 'defaultInputValues',
			defaultValueDataName : 'defaultInputValues',
			isPasswordFieldDataName : 'isPassword',
			isPasswordFieldCloneDataName : 'isClone'
		}
	}
})(jQuery);
