/**
 * @name NiceJForms
 * @description This a jQuery equivalent for Niceforms ( http://badboy.ro/articles/2007-01-30/niceforms/ ).  All the forms are styled with beautiful images as backgrounds and stuff. Enjoy them!
 * @param Hash hash A hash of parameters
 * @option integer selectRightSideWidth width of right side of the select
 * @option integer selectLeftSideWidth width of left side of the select 
 * @option integer selectAreaHeight
 * @option integer selectAreaOPtionsOverlap
 * @option imagesPath folder where custom form images are stored
 * @type jQuery
 * @cat Plugins/Interface/Forms
 * @author Lucian Lature ( lucian.lature@gmail.com )
 * @credits goes to Lucian Slatineanu ( http://www.badboy.ro )
 * @version 0.1
 */

jQuery.NiceJForms = {
	options : {
		selectRightSideWidth     : 21,
		selectLeftSideWidth      : 8,
		selectAreaHeight 	     : 21,
		selectAreaOptionsOverlap : 2,
		imagesPath               : "css/images/default/"
		// other options here
	},
	
	selectText     : 'please select',
	preloads       : new Array(),
	inputs         : new Array(),
	labels         : new Array(),
	textareas      : new Array(),
	selects        : new Array(),
	radios         : new Array(),
	checkboxes     : new Array(),
	texts          : new Array(),
	buttons        : new Array(),
	radioLabels    : new Array(),
	checkboxLabels : new Array(),
	hasImages      : true,
	
	keyPressed : function(event)
	{
		var pressedKey = event.charCode || event.keyCode || -1;
		
		switch (pressedKey)
		{
			case 40: //down
			var fieldId = this.parentNode.parentNode.id.replace(/sarea/g, "");
			var linkNo = 0;
			for(var q = 0; q < selects[fieldId].options.length; q++) {if(selects[fieldId].options[q].selected) {linkNo = q;}}
			++linkNo;
			if(linkNo >= selects[fieldId].options.length) {linkNo = 0;}
			selectMe(selects[fieldId].id, linkNo, fieldId);
			break;
		
		case 38: //up
			var fieldId = this.parentNode.parentNode.id.replace(/sarea/g, "");
			var linkNo = 0;
			for(var q = 0; q < selects[fieldId].options.length; q++) {if(selects[fieldId].options[q].selected) {linkNo = q;}}
			--linkNo;
			if(linkNo < 0) {linkNo = selects[fieldId].options.length - 1;}
			selectMe(selects[fieldId].id, linkNo, fieldId);
			break;
		default:
			break;
		}
	},
	
	build : function(options)
	{
		if (options)
			jQuery.extend(jQuery.NiceJForms.options, options);	
			
		if (window.event) {
			jQuery('body',document).bind('keyup', jQuery.NiceJForms.keyPressed);
		} else {
			jQuery(document).bind('keyup', jQuery.NiceJForms.keyPressed);
		}
		
		// test if images are disabled or not
		var testImg = document.createElement('img');
		$(testImg).attr("src", jQuery.NiceJForms.options.imagesPath + "blank.gif").attr("id", "imagineTest");
		jQuery('body').append(testImg);
		
		if(testImg.complete)
		{
			if(testImg.offsetWidth == '1') {jQuery.NiceJForms.hasImages = true;}
			else {jQuery.NiceJForms.hasImages = false;}
		}

		$(testImg).remove();
			
		if(jQuery.NiceJForms.hasImages)
		{
			$('form.niceform').each( function()
				{
					el 				= jQuery(this);
					jQuery.NiceJForms.preloadImages();
					jQuery.NiceJForms.getElements(el);
					//jQuery.NiceJForms.replaceRadios();
					//jQuery.NiceJForms.replaceCheckboxes();
					jQuery.NiceJForms.replaceSelects();
					
					if (!$.browser.safari) {
						//jQuery.NiceJForms.replaceTexts();
						//jQuery.NiceJForms.replaceTextareas();
						//jQuery.NiceJForms.buttonHovers();
					}
				}
			);
		}	
	},
	
	preloadImages: function()
	{
		jQuery.NiceJForms.preloads = $.preloadImages(jQuery.NiceJForms.options.imagesPath + "button_left_xon.gif", jQuery.NiceJForms.options.imagesPath + "button_right_xon.gif", 
		jQuery.NiceJForms.options.imagesPath + "input_left_xon.gif", jQuery.NiceJForms.options.imagesPath + "input_right_xon.gif",
		jQuery.NiceJForms.options.imagesPath + "txtarea_bl_xon.gif", jQuery.NiceJForms.options.imagesPath + "txtarea_br_xon.gif", 
		jQuery.NiceJForms.options.imagesPath + "txtarea_cntr_xon.gif", jQuery.NiceJForms.options.imagesPath + "txtarea_l_xon.gif", jQuery.NiceJForms.options.imagesPath + "txtarea_tl_xon.gif", jQuery.NiceJForms.options.imagesPath + "txtarea_tr_xon.gif");
	},
	
	getElements: function(elm)
	{
		el = elm ? jQuery(elm) : jQuery(this);
		
		var r = 0; var c = 0; var t = 0; var rl = 0; var cl = 0; var tl = 0; var b = 0;
		
		jQuery.NiceJForms.inputs = $('input', el);
		jQuery.NiceJForms.labels = $('label', el);
		jQuery.NiceJForms.textareas = $('textarea', el);
		jQuery.NiceJForms.selects = $('select', el);
		jQuery.NiceJForms.radios = $('input[@type=radio]', el);
		jQuery.NiceJForms.checkboxes = $('input[@type=checkbox]', el);
		jQuery.NiceJForms.texts = $('input[@type=text]', el).add($('input[@type=password]', el));		
		jQuery.NiceJForms.buttons = $('input[@type=submit]', el).add($('input[@type=button]', el));
		
		jQuery.NiceJForms.labels.each(function(i){
			labelFor = $(jQuery.NiceJForms.labels[i]).attr("for");
			jQuery.NiceJForms.radios.each(function(q){
				if(labelFor == $(jQuery.NiceJForms.radios[q]).attr("id"))
				{
					if(jQuery.NiceJForms.radios[q].checked)
					{
						$(jQuery.NiceJForms.labels[i]).removeClass().addClass("chosen");	
					}
					
					jQuery.NiceJForms.radioLabels[rl] = jQuery.NiceJForms.labels[i];
					++rl;
				}
			})
			
			jQuery.NiceJForms.checkboxes.each(function(x){
				
				if(labelFor == $(this).attr("id"))
				{
					if(this.checked)
					{
						$(jQuery.NiceJForms.labels[i]).removeClass().addClass("chosen");	
					}
					jQuery.NiceJForms.checkboxLabels[cl] = jQuery.NiceJForms.labels[i];
					++cl;
				}
			})
		});
	},

	
	replaceSelects: function()
	{
		var self = this;
		
		
		jQuery.NiceJForms.selects.each(function(q){
			//create and build div structure
			var selectArea = document.createElement('div');
			var left = document.createElement('div');
			var right = document.createElement('div');
			var center = document.createElement('div');
			var button = document.createElement('a');
			var text = document.createTextNode(jQuery.NiceJForms.selectText);
			var selectWidth = parseInt(this.className.replace(/width_/g, ""));

			if (! selectWidth) {
				selectWidth = 260;				
			}
			
			jQuery(center)
				.attr({id:'mySelectText'+q})
				.css({width: selectWidth - 10 + 'px'});
			jQuery(selectArea)
				.attr({id:'sarea'+q})
				.css({
					width: selectWidth + jQuery.NiceJForms.options.selectRightSideWidth + jQuery.NiceJForms.options.selectLeftSideWidth + 'px'
				})
				.addClass("selectArea");
				
			jQuery(button)
				.css({
				width      : selectWidth + jQuery.NiceJForms.options.selectRightSideWidth + jQuery.NiceJForms.options.selectLeftSideWidth + 'px',
				marginLeft : - selectWidth - jQuery.NiceJForms.options.selectLeftSideWidth + 'px',
				cursor: 'pointer'
				})
				.addClass("selectButton")
				.bind('click', {who:q}, function(e){self.showOptions(e)})
				.keydown(jQuery.NiceJForms.keyPressed);
			
			jQuery(left).addClass("left");	
			jQuery(right).addClass("right").append(button);
			jQuery(center).addClass("center").append(text);	
			
			jQuery(selectArea).append(left).append(right).append(center).insertBefore(this);
			//hide the select field
			$(this).hide();
			//insert select div
			//build & place options div
			var optionsDiv = document.createElement('div');
			selectAreaPos = $(selectArea).offset();
			
			jQuery(optionsDiv)
				.attr({id:"optionsDiv" + q})
				.css({
					width : selectWidth + 1 + 'px', 
					left  : selectAreaPos.left + 'px', 
					top   : selectAreaPos.top + jQuery(center).height() + 7 - jQuery.NiceJForms.options.selectAreaOptionsOverlap + 'px'
				})
				.addClass("optionsDivInvisible");
			
			//get select's options and add to options div
			$(jQuery.NiceJForms.selects[q]).children().each(function(w){
				var optionHolder = document.createElement('p');
				var optionLink = document.createElement('a');
				var optionTxt = document.createTextNode(jQuery.NiceJForms.selects[q].options[w].text);
				
				jQuery(optionLink)
					.attr({href:'#'})
					.css({cursor:'pointer'})
					.append(optionTxt)
					.bind('click', {who: q, id:jQuery.NiceJForms.selects[q].id, option:w, select:q}, function(e){self.showOptions(e);self.selectMe(jQuery.NiceJForms.selects[q].id, w, q);return false;});
				
				jQuery(optionHolder).append(optionLink);
				jQuery(optionsDiv).append(optionHolder);
				
				//check for pre-selected items
				if(jQuery.NiceJForms.selects[q].options[w].selected) {self.selectMe($(jQuery.NiceJForms.selects[q]).attr("id"), w, q);}
			});
			
			jQuery('body').append(optionsDiv);
		});
	},

	selectMe: function(selectFieldId, linkNo, selectNo) {
		selectField = $('#' + selectFieldId);
		sFoptions = selectField.children();
		
		selectField.children().each(function(k){
			if(k == linkNo) {sFoptions[k].selected="selected";}
			else {sFoptions[k].selected = "";}
		});
		
		textVar = $("#mySelectText" + selectNo);
		var newText = document.createTextNode($(sFoptions[linkNo]).text());
		textVar.empty().append(newText);
	}, 

	showOptions: function(e) {
		var self = this;

		selectAreaPos = $("#sarea" +e.data.who).offset().top + $("#sarea" +e.data.who).height();
		$("#optionsDiv"+e.data.who)
			.css({
				top:selectAreaPos
			})
			.toggleClass("optionsDivVisible")
			.toggleClass("optionsDivInvisible")
			.mouseout(function(e){
				self.hideOptions(e);
			});
	},
	
	hideOptions: function(e) {
		if (!e) var e = window.event;
		var reltg = (e.relatedTarget) ? e.relatedTarget : e.toElement;
		if(((reltg.nodeName != 'A') && (reltg.nodeName != 'DIV')) || ((reltg.nodeName == 'A') && (reltg.className=="selectButton") && (reltg.nodeName != 'DIV'))) {
			//$(this).toggleClass('optionsDivInvisible');
		};
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	}
}

jQuery.preloadImages = function()
{
	var imgs = new Array();
	for(var i = 0; i<arguments.length; i++)
	{
		imgs[i] = jQuery("<img>").attr("src", arguments[i]);
	}
	
	return imgs;
}
