	
var FancyForms = {
	initialize: function() {
		
		this.selects = $$("select");
		this.checkboxesAndRadios = $$("input[type='checkbox'], input[type='radio']");
		this.checkboxRadioSpans = [];
		
		// insert spans for each select list
		this.selects.each(function(currentSelect){
			var options = currentSelect.select("option");
			var selectedText = options.find(function(currentOption){
				return currentOption.selected;
			}).childNodes[0].nodeValue;
			var wrapperSpan = new Element("span", {"class": "select-wrapper"});
			var replacementSpan = new Element("span", {"class": "select "+currentSelect.className}).update(selectedText);
			wrapperSpan.insert({top: replacementSpan});
			currentSelect.insert({before: wrapperSpan});
			currentSelect.addClassName("styled");
		});
		
		// insert spans for each radio button and checkbox
		this.checkboxesAndRadios.each(function(currentEl){
			var replacementSpan = new Element("span",{"class": currentEl.type + " " + currentEl.type + (currentEl.checked ? "_checked" : "_unchecked")});
			currentEl.insert({before: replacementSpan});
			this.checkboxRadioSpans.push(replacementSpan);
			currentEl.addClassName("styled");
		}.bind(this));
		
		this.registerEventHandlers();
	},
	registerEventHandlers: function(){
		this.selects.invoke("observe", "change", this.__selectChange.bindAsEventListener(this));
		this.selects.invoke("observe", "keydown", this.__keyboardSelect.bindAsEventListener(this));
		this.checkboxRadioSpans.invoke("observe", "mousedown", this.__push.bindAsEventListener(this));
		this.checkboxRadioSpans.invoke("observe", "mouseup", this.__check.bindAsEventListener(this));
		
		if(isIE){
			/* IE doesn't fire "change" for checkboxes or radio buttons so you need to 
			   observe focus and the spacebar keyup event to fake it. */
			this.checkboxesAndRadios.invoke("observe", "focus", this.__setToCurrentState.bindAsEventListener(this));
			this.checkboxesAndRadios.invoke("observe", "keyup", function(e){
				if (e.keyCode == 32){
					this.__setToCurrentState.bind(this).defer();
				}
			}.bind(this));			
		} else {
			this.checkboxesAndRadios.invoke("observe", "change", this.__setToCurrentState.bindAsEventListener(this));
		}
	},
	__push: function(e) {
		var span = e.element();
		var input = span.next("input");
		span.className = input.type + " " + input.type + (input.checked ? "_checked_pushed" : "_unchecked_pushed");
		
		// in case you mousedown on a checkbox/radiobutton, move your mouse away, and let go
		document.observe("mouseup", function(e){
			span.className = input.type + " " + input.type + (input.checked ? "_checked" : "_unchecked");
		});		
		
	},
	__check: function(e) {
		var span = e.element();
		var input = span.next("input");
		if(input.checked){
			span.className = input.type + " " + input.type + "_unchecked";
			input.checked = false;
		} else {
			span.className = input.type + " " + input.type + "_checked";
			input.checked = true;
		}
		
		/* uncheck all other radio buttons in the same group and
		   make sure you cannot uncheck an already checked radio button */
		if(input.type == "radio"){
			var groupRadios = $$("input[name='"+input.name+"']").without(input);
			groupRadios.each(function(currentRadio){
				currentRadio.previous("span").className = input.type + " " + input.type + "_unchecked";
				currentRadio.checked = false;
			});
			span.className = input.type + " " + input.type + "_checked";
			input.checked = true;
			input.fire('radio:checked');
		} else if (input.type == "checkbox"){
			input.fire('checkbox:checked');
		}
	},
	__setToCurrentState: function(e) {
		var input = e.findElement();

		if (input.type == "radio"){
			input.fire('radio:checked');
		} else if (input.type == "checkbox"){
			input.fire('checkbox:checked');
		}

		this.checkboxesAndRadios.each(function(currentEl){
			if (currentEl.checked) {
				currentEl.previous("span").className = currentEl.type + " " + currentEl.type + "_checked";
			} else {
				currentEl.previous("span").className = currentEl.type + " " + currentEl.type + "_unchecked";			
			}
		});
	},
	__keyboardSelect: function(e){
		var select = e.element();
		var span = select.previous("span").down("span");
		var options = select.select("option");
		var currentOption = options.find(function(currentOption){
			return currentOption.selected;
		});
		if((e.keyCode == Event.KEY_DOWN || e.keyCode == Event.KEY_RIGHT) && currentOption.next("option")){
			span.update(currentOption.next("option").childNodes[0].nodeValue);
		} else if ((e.keyCode == Event.KEY_UP || e.keyCode == Event.KEY_LEFT) && currentOption.previous("option")){
			span.update(currentOption.previous("option").childNodes[0].nodeValue);
		} else if (e.keyCode == Event.KEY_PAGEDOWN || e.keyCode == Event.KEY_END){
			span.update(options[options.length-1].childNodes[0].nodeValue)	;
		} else if (e.keyCode == Event.KEY_PAGEUP || e.keyCode == Event.KEY_HOME){
			span.update(options[0].childNodes[0].nodeValue);
		}
	},
	__selectChange: function(e) {
		var select = e.element();
		var span = select.previous("span").down("span");
		var options = select.select("option");	
		var value = options.find(function(currentOption){
			return currentOption.selected;
		}).childNodes[0].nodeValue;
		span.update(value);
	}
}
/*
document.observe("dom:loaded", function(){
	if (!isIE6) {FancyForms.initialize();}
});
*/
