/*
 * gStyle v.1.0 beta
 * Copyright (c) 2009 Gilles Cochez
 * Dual licensed under the MIT and GPL licenses.
 */
 
// closure
;(function(jQuery) 
{	
	// declaration
	jQuery.fn.gStyle = function(settings, callback) 
	{		
		// cache this
		var self = this;
		
		// defaults
		var defaults = {
			prefix: 'gStyle', // css class prefix
			checkbox: true, // false to disable
			button: true, // false to disable
			select: true, // false to disable
			radio: true, // false to disable 
			file: true, // false to disable
			tag: 'span' // building html tag
		};
		
		// if 'settings' callback no option
		if ('function' == typeof settings) var callback = settings, settings = {};
		
		// options
		var o = jQuery.extend({}, defaults, settings);
		
		// button styling
		if (o.button)
		{
			
		};
		
		// checkbox styling
		if (o.checkbox) 
		{		
			jQuery(self).find(':checkbox').each(function(i) 
			{
				// cache parent and element
				var parent = jQuery(this).parent().eq(0),
					e = jQuery(this);
				
				// parent set to relative
				parent.css('position','relative');
				
				// cache element position
				var p = e.position();
				
				// hide checkbox and add/style tag
				e.fadeTo(1,0).css({
					position:'absolute',
					top:p.top,
					left:p.left
				})
				.after('<'+o.tag+' class="'+o.prefix+'Checkbox"></'+o.tag+'>').next().css({
					position:'absolute',
					top:p.top,
					left:p.left
				});
				
				// cache div
				var f = e.next();
				
				// already checked?
				if (e.attr('checked')) f.removeClass(o.prefix+'Checkbox').addClass(o.prefix+'CheckboxChecked');
				
				// tag event handler
				f.click(function() 
				{
					var e = jQuery(this).prev();
					if (e.attr('checked')) 
					{
						e.removeAttr('checked');
						f.removeClass(o.prefix+'CheckboxChecked').addClass(o.prefix+'Checkbox');
					}
					else
					{
						e.attr('checked','checked');
						f.removeClass(o.prefix+'Checkbox').addClass(o.prefix+'CheckboxChecked');
					}
				})
				.prev().focus(function() {
					/*
						Check for checked focused element
					*/
				
					f.addClass(o.prefix+'CheckboxFocused');
				})
				.blur(function() {
					f.removeClass(o.prefix+'CheckboxFocused');
				})
				.change(function()
				{
					if (jQuery(this).is(':checked')) f.removeClass(o.prefix+'Checkbox').addClass(o.prefix+'CheckboxChecked');
					else f.removeClass(o.prefix+'CheckboxChecked').addClass(o.prefix+'Checkbox');
				});
			});
		};
		
		// radio styling
		if (o.radio) 
		{		
			jQuery(self).find(':radio').each(function(i) 
			{
				// cache parent and this
				var parent = jQuery(this).parent().eq(0),
					e = jQuery(this);				
				
				// parent set to relative
				parent.css('position','relative');
				
				// cache element position, dimension and next position
				var p = e.position(),
					nleft = e.height()*i+p.left;
				
				// hide checkbox and add/style tag
				e.fadeTo(1,0).css({
					position:'absolute',
					display:'inline',
					top:p.top,
					left:nleft
				})
				.after('<'+o.tag+' class="'+o.prefix+'Radio"></'+o.tag+'>').next().css({
					position:'absolute',
					display:'inline',
					top:p.top,
					left:nleft
				});
				
				// cache div
				var f = e.next();
				
				// tag event handler
				f.click(function() 
				{
					f.siblings(o.tag).removeClass(o.prefix+'RadioChecked').addClass(o.prefix+'Radio')
						.prev().removeAttr('checked');
					f.removeClass(o.prefix+'Radio').addClass(o.prefix+'RadioChecked')
						.prev().attr('checked','checked');
				})
				.prev().focus(function()
				{
					/*
						Check for checked focused element
					*/
					f.addClass(o.prefix+'RadioFocused');
				})
				.blur(function()
				{					
					f.removeClass(o.prefix+'RadioFocused');
				})
				.change(function()
				{
					jQuery('input[name='+jQuery(this).attr('name')+']').next().removeClass(o.prefix+'RadioChecked').addClass(o.prefix+'Radio')
					.siblings(':checked').next().removeClass(o.prefix+'Radio').addClass(o.prefix+'RadioChecked')
				});
			});
		};
		
		// select styling
		if (o.select) 
		{		
			
			jQuery(self).find('select').each(function() 
			{				
				// cache parent and element
				var parent = jQuery(this).parent().eq(0),
					e = jQuery(this);
				
				// parent set to relative
				parent.css('position','relative');
				
				// store position
				var p = e.position();
				
				// invisible select and add tag
				e.fadeTo(1,0).css({
					position:'absolute',
					top:p.top,
					left:p.left
				})
				.prev().after('<'+o.tag+' class="'+o.prefix+'Select"></'+o.tag+'>').next().css({
					position:'absolute',
					top:p.top,
					left:p.left
				})
				.text(jQuery('option:selected', this).text());
				
				// cache tag and sort padding/margin if any				
				var f = e.prev();
				
				// select restyling and event
				e.css({
					width:f.css('width'),
					height:f.css('height')
				})
				.change(function()
				{
					f.text(jQuery('option:selected', this).text());
				})
				.focus(function()
				{
					f.addClass(o.prefix+'SelectFocused');
				})
				.blur(function()
				{
					f.removeClass(o.prefix+'SelectFocused');
				})
				.keypress(function() 
				{
					f.text(jQuery('option:selected', this).text());
				});
			});
			
		};
		
		// file styling
		if (o.file) 
		{		
			jQuery(self).find(':file').each(function() 
			{
				// cache parent
				var parent = jQuery(this).parent().eq(0);
				
				// parent set to relative
				parent.css('position','relative');
				
				// select position stored
				var p = jQuery(this).position();
				
				// invisible select and add tag
				jQuery(this).fadeTo(1,0).css({
					position:'absolute',
					top:p.top,
					left:p.left
				})
				.prev().after('<'+o.tag+' class="'+o.prefix+'File"></'+o.tag+'>');
				
				// cache tag
				var e = jQuery(this).prev();
				
				// tag position
				e.css({
					position:'absolute',
					top:p.top,
					left:p.left
				});	
				
				// select restyling and event handlers
				jQuery(this).css({
					width:e.css('width'),
					height:e.css('height')
				})
				.change(function()
				{
					// get the path
					var val = jQuery(this).val();
					
					// extract the file name if needed (for older browser)
					if (val.indexOf('/') > -1) var f = val.substring(val.lastIndexOf('/')+1,val.length);
					else var f = val.substring(val.lastIndexOf('\\')+1,val.length);
					
					// update the display
					e.text(f);
				})
				.focus(function()
				{
					e.addClass(o.prefix+'FileFocused');
				})
				.blur(function()
				{
					e.removeClass(o.prefix+'FileFocused');
				});
			});
		};
	};
})(jQuery);