/*
 * UPDATED: 11.26.08
 *
 * jNice
 * by Sean Mooney (sean@whitespace-creative.com) 
 *
 * To Use: place in the head 
 *  <link href="inc/style/jNice.css" rel="stylesheet" type="text/css" />
 *  <script type="text/javascript" src="inc/js/jquery.jNice.js"></script>
 *
 * And apply the jNice class to the form you want to style
 *
 * To Do: Add textareas, Add File upload
 *
 ******************************************** */
(function(J){
	J.fn.jNice = function(options){
		var self = this;
		var safari = J.browser.safari; /* We need to check for safari to fix the input:text problem */
		/* Apply document listener */
		J(document).mousedown(checkExternalClick);
		/* each form */
		return this.each(function(){
			J('input:submit, input:reset, input:button', this).each(ButtonAdd);
			J('button').focus(function(){ J(this).addClass('jNiceFocus')}).blur(function(){ J(this).removeClass('jNiceFocus')});
			J('input:text:visible, input:password', this).each(TextAdd);
			/* If this is safari we need to add an extra class */
			if (safari){J('.jNiceInputWrapper').each(function(){J(this).addClass('jNiceSafari').find('input').css('width', J(this).width()+11);});}
			J('input:checkbox', this).each(CheckAdd);
			J('input:radio', this).each(RadioAdd);
			J('select', this).each(function(index){ SelectAdd(this, index); });
			/* Add a new handler for the reset action */
			J(this).bind('reset',function(){var action = function(){ Reset(this); }; window.setTimeout(action, 10); });
			J('.jNiceHidden').css({opacity:0});
		});		
	};/* End the Plugin */

	var Reset = function(form){
		var sel;
		J('.jNiceSelectWrapper select', form).each(function(){sel = (this.selectedIndex<0) ? 0 : this.selectedIndex; J('ul', J(this).parent()).each(function(){J('a:eq('+ sel +')', this).click();});});
		J('a.jNiceCheckbox, a.jNiceRadio', form).removeClass('jNiceChecked');
		J('input:checkbox, input:radio', form).each(function(){if(this.checked){J('a', J(this).parent()).addClass('jNiceChecked');}});
	};

	var RadioAdd = function(){
		var Jinput = J(this).addClass('jNiceHidden').wrap('<span class="jRadioWrapper jNiceWrapper"></span>');
		var Jwrapper = Jinput.parent();
		var Ja = J('<span class="jNiceRadio"></span>');
		Jwrapper.prepend(Ja);
		/* Click Handler */
		Ja.click(function(){
				var Jinput = J(this).addClass('jNiceChecked').siblings('input').attr('checked',true);
				/* uncheck all others of same name */
				J('input:radio[name="'+ Jinput.attr('name') +'"]').not(Jinput).each(function(){
					J(this).attr('checked',false).siblings('.jNiceRadio').removeClass('jNiceChecked');
				});
				return false;
		});
		Jinput.click(function(){
			if(this.checked){
				var Jinput = J(this).siblings('.jNiceRadio').addClass('jNiceChecked').end();
				/* uncheck all others of same name */
				J('input:radio[name="'+ Jinput.attr('name') +'"]').not(Jinput).each(function(){
					J(this).attr('checked',false).siblings('.jNiceRadio').removeClass('jNiceChecked');
				});
			}
		}).focus(function(){ Ja.addClass('jNiceFocus'); }).blur(function(){ Ja.removeClass('jNiceFocus'); });

		/* set the default state */
		if (this.checked){ Ja.addClass('jNiceChecked'); }
	};

	var CheckAdd = function(){
		var Jinput = J(this).addClass('jNiceHidden').wrap('<span class="jNiceWrapper"></span>');
		var Jwrapper = Jinput.parent().append('<span class="jNiceCheckbox"></span>');
		/* Click Handler */
		var Ja = Jwrapper.find('.jNiceCheckbox').click(function(){
				var Ja = J(this);
				var input = Ja.siblings('input')[0];
				if (input.checked===true){
					input.checked = false;
					Ja.removeClass('jNiceChecked');
				}
				else {
					input.checked = true;
					Ja.addClass('jNiceChecked');
				}
				return false;
		});
		Jinput.click(function(){
			if(this.checked){ Ja.addClass('jNiceChecked'); 	}
			else { Ja.removeClass('jNiceChecked'); }
		}).focus(function(){ Ja.addClass('jNiceFocus'); }).blur(function(){ Ja.removeClass('jNiceFocus'); });
		
		/* set the default state */
		if (this.checked){J('.jNiceCheckbox', Jwrapper).addClass('jNiceChecked');}
	};

	var TextAdd = function(){
		var Jinput = J(this).addClass('jNiceInput').wrap('<div class="jNiceInputWrapper"><div class="jNiceInputInner"></div></div>');
		var Jwrapper = Jinput.parents('.jNiceInputWrapper');
		Jinput.focus(function(){ 
			Jwrapper.addClass('jNiceInputWrapper_hover');
		}).blur(function(){
			Jwrapper.removeClass('jNiceInputWrapper_hover');
		});
	};

	var ButtonAdd = function(){
		var value = J(this).attr('value');
		J(this).replaceWith('<button id="'+ this.id +'" name="'+ this.name +'" type="'+ this.type +'" class="'+ this.className +'" value="'+ value +'"><span><span>'+ value +'</span></span>');
	};

	/* Hide all open selects */
	var SelectHide = function(){
			J('.jNiceSelectWrapper ul:visible').hide();
	};

	/* Check for an external click */
	var checkExternalClick = function(event) {
		if (J(event.target).parents('.jNiceSelectWrapper').length === 0) { SelectHide(); }
	};

	var SelectAdd = function(element, index){
		var Jselect = J(element);
		index = index || Jselect.css('zIndex')*1;
		index = (index) ? index : 0;
		/* First thing we do is Wrap it */
		Jselect.wrap(J('<div class="jNiceWrapper"></div>').css({zIndex: 100-index}));
		var width = Jselect.width();
		Jselect.addClass('jNiceHidden').after('<div class="jNiceSelectWrapper"><div><span class="jNiceSelectText"></span><span class="jNiceSelectOpen"></span></div><ul></ul></div>');
		var Jwrapper = J(element).siblings('.jNiceSelectWrapper').css({width: width +'px'});
		J('.jNiceSelectText, .jNiceSelectWrapper ul', Jwrapper).width( width - J('.jNiceSelectOpen', Jwrapper).width());
		/* IF IE 6 */
		if (J.browser.msie && jQuery.browser.version < 7) {
			Jselect.after(J('<iframe src="javascript:\'\';" marginwidth="0" marginheight="0" align="bottom" scrolling="no" tabIndex="-1" frameborder="0"></iframe>').css({ height: Jselect.height()+4 +'px' }));
		}
		/* Now we add the options */
		SelectUpdate(element);
		/* Apply the click handler to the Open */
		J('div', Jwrapper).click(function(){
			var Jul = J(this).siblings('ul');
			if (Jul.css('display')=='none'){ SelectHide(); } /* Check if box is already open to still allow toggle, but close all other selects */
			Jul.slideToggle();
			var offSet = (J('a.selected', Jul).offset().top - Jul.offset().top);
			Jul.animate({scrollTop: offSet});
			return false;
		});
		/* Add the key listener */
		Jselect.keydown(function(e){
			var selectedIndex = this.selectedIndex;
			switch(e.keyCode){
				case 40: /* Down */
					if (selectedIndex < this.options.length - 1){ selectedIndex+=1; }
					break;
				case 38: /* Up */
					if (selectedIndex > 0){ selectedIndex-=1; }
					break;
				default:
					return;
					break;
			}
			J('ul a', Jwrapper).removeClass('selected').eq(selectedIndex).addClass('selected');
			J('span:eq(0)', Jwrapper).html(J('option:eq('+ selectedIndex +')', Jselect).attr('selected', 'selected').text());
			return false;
		}).focus(function(){ Jwrapper.addClass('jNiceFocus'); }).blur(function(){ Jwrapper.removeClass('jNiceFocus'); });
	};

	var SelectUpdate = function(element){
		var Jselect = J(element);
		var Jwrapper = Jselect.siblings('.jNiceSelectWrapper');
		var Jul = Jwrapper.find('ul').find('li').remove().end().hide();
		J('option', Jselect).each(function(i){
			Jul.append('<li><a href="#" index="'+ i +'">'+ this.text +'</a></li>');
		});
		/* Add click handler to the a */
		Jul.find('a').click(function(){
			J('a.selected', Jwrapper).removeClass('selected');
			J(this).addClass('selected');	
			/* Fire the onchange event */
			if (Jselect[0].selectedIndex != J(this).attr('index') && Jselect[0].onchange) { Jselect[0].selectedIndex = J(this).attr('index'); Jselect[0].onchange(); }
			Jselect[0].selectedIndex = J(this).attr('index');
			J('span:eq(0)', Jwrapper).html(J(this).html());
			Jul.hide();
			return false;
		});
		/* Set the defalut */
		J('a:eq('+ Jselect[0].selectedIndex +')', Jul).click();
	};

	var SelectRemove = function(element){
		var zIndex = J(element).siblings('.jNiceSelectWrapper').css('zIndex');
		J(element).css({zIndex: zIndex}).removeClass('jNiceHidden');
		J(element).siblings('.jNiceSelectWrapper').remove();
	};

	/* Utilities */
	J.jNice = {
			SelectAdd : function(element, index){ 	SelectAdd(element, index); },
			SelectRemove : function(element){ SelectRemove(element); },
			SelectUpdate : function(element){ SelectUpdate(element); }
	};/* End Utilities */

	/* Automatically apply to any forms with class jNice */
	J(function(){J('form.jNice').jNice();	});
})(jQuery);