/*#############################################################
Name: Niceforms
Version: 2.0
Author: Lucian Slatineanu
URL: http://www.emblematiq.com/projects/niceforms/

Feel free to use and modify but please keep this copyright intact.
#################################################################*/

;(function(){
var apply = 'niceform';

var basePath = (function(){
	var scripts = document.getElementsByTagName('script');
	for(var i = 0; i < scripts.length; i++) {
		var script = scripts.item(i);
		var src = script.src;
		
		var separator = src.indexOf('/') > src.indexOf('\\') ? '/' : '\\';
		
		if(src.match(/niceforms.js(\\?)?/i)) {
			var sep = src.split(separator);
			var qp = (src.split('?').length == 1 ? '': src.split('?', 2).last()).toQueryParams();
			if(qp['apply'])
				apply = qp['apply'];
			sep.pop();sep.pop();
			return sep.join(separator) + separator;
		}
	}
})();

var delta = {};
var diff;
delta.gecko = { top: 0, left: 0};
delta.ie = { top: -4, left: 2 };
delta.khtml = {top:-4, left: 0};

if(Prototype.Browser.IE) {
	diff = delta.ie;
} else if (Prototype.Browser.WebKit) {
	diff = delta.khtml;
} else {
	diff = delta.gecko;
}

var DIV = $(document.createElement('div'));
var IMG = $(document.createElement('img'));
var ONE_EM_SIZE = 16;

//Theme Variables - edit these to match your theme
var imagesPath = basePath + "images/";
var selectMaxHeight = 200;
var textareaTopPadding = 10;
var textareaSidePadding = 10;

//Global Variables
var NF = new Array();
var isIE = false;
var resizeTest = 1;

var msieVersion = Prototype.Browser.IE ? parseInt(window.navigator.userAgent.match(/MSIE \d.\d/).toString().replace(/[^0-9.]+/g, '')) : '';


function fixTop(type, value) {
	return diff.top + parseInt(value);
}

function fixLeft(type, value){
	return diff.left + parseInt(value);
}

//Initialization function

function NFInit() {
	try {
		document.execCommand('BackgroundImageCache', false, true);
	} catch(e) {}
	ONE_EM_SIZE = detect1em();
	NFDo('start');
}

function registerEventDispatcher(src, target, eventNames) {
	eventNames = Object.isArray(eventNames) ? eventNames : eventNames.split(',');
	eventNames.each(function(eventName){
		$(src).observe(eventName, function(e){
			Element.fire($(target), eventName, e);
		}.bindAsEventListener());
	});
}


Event.observe(document, 'dom:loaded', NFInit);


function NFDo(what) {
	var niceforms = apply == 'all' ? $A(document.getElementsByTagName('form'))
		: $($(document.body).select('.' + apply));
		
	if (/MSIE (\d+\.\d+);/.test(navigator.userAgent)) {
		var ieversion = new Number(RegExp.$1);
		if(ieversion < 7) 
			return false; //exit script if IE6
		isIE = true;
	}
	
	niceforms.map(function(form, index) {
		if(what == "start") {
			NF[index] = new niceform(form);
			form.start();
		} else {
			form.unload();
			NF[index] = null;
		}
	});
	
}

function NFFix() {
	NFDo('stop');
	NFDo('start');
}

function niceform(nf) {
	var element = $(nf);
	var elements = new Array;
	
	nf.start = function() {
		//Separate and assign elements
		$A(element.select('input, select, textarea, button')).each(function(element){
			elements.push($(element));
			switch(element.tagName.toLowerCase()) {
				case 'input': {
					switch(element.type.toLowerCase()) {
						/*case "text": 
						case "password": 
							return inputText(element);
						case "radio": 
							return inputRadio(element);
						case "checkbox": 
							return inputCheck(element);
						case "file": 
							return inputFile(element);*/
						case "submit": 
						case "reset": 
						case "button": 
							return inputSubmit(element);
					}
					break;
				}
				/*case 'select': 
					return element.getAttribute('size') != '' && element.getAttribute('size') != '1' ? 
						multiSelects(element) : selects(element);
				case 'textarea': 
					return textarea(element);*/
				case 'button':
					return inputSubmit(element);
			}
			elements.pop();
		});
		elements.invoke('init');
	}
	nf.unload = Enumerable.invoke.bind(elements, 'unload');
}

function detect1em(element) {
	element = element || document.body;
	var div = new Element('div').setStyle('margin:0;padding:0px;width:1px;height:1em;visibility:hidden;');
	element.appendChild(div);
	var em = div.clientHeight;
	element.removeChild(div);
	return em;
}

function createImage(src, klass) {
	var element = IMG.cloneNode(false);
	element.src = src;
	element.className = klass;
	return element;
}

function createElement(name, klass) {
	var element = document.createElement(name);
	element.className = klass;
	return $(element);
}

function removeElement(element) {
	if(element.parentNode)
		element.parentNode.removeChild(element);
}

//Get Siblings
function getInputsByName(name) {
	return $(document.body).select('input[name="' + name + '"]');
}

function inputText(el) { //extent Text inputs
	var dummy = createElement('span', "NFTextCenter");
	var left = createImage(imagesPath + "0.png", "NFTextLeft");
	var right = createImage(imagesPath + "0.png", "NFTextRight");
	var element = $(el);
	
	element.onfocus = Enumerable.invoke.bind([dummy, left, right], 'addClassName', 'NFh');
	element.onblur = Enumerable.invoke.bind([dummy, left, right], 'removeClassName', 'NFh');

	element.init = function() {
		this.parentNode.insertBefore(dummy, element);
		appendElements(dummy, left, right, element);
		var display = element.getStyle('display');
		this.addClassName("NFText");
		if(/*@cc_on!@*/false) {
			if(element.offsetWidth == 0) {
			} else {
				dummy.style.width = element.getWidth() + 'px';
			}
		}
	}
	
	element.unload = function() {
		dummy.parentNode.insertBefore(element, dummy);
		removeElement(dummy);
		this.removeClassName("NFText");
	}
}

function radio_dummy_onclick(e) {
	if(!this.ref.checked) {
		var siblings = getInputsByName(this.ref.name);
		for(var q = 0; q < siblings.length; q++) {
			siblings[q].checked = false;
			siblings[q].dummy.className = "NFRadio";
		}
		this.ref.checked = true;
		this.className = "NFRadio NFh";
	}
}

function radio_onclick(e) {
	if(this.checked) {
		var siblings = getInputsByName(this.name);
		for(var q = 0; q < siblings.length; q++) {
			siblings[q].dummy.className = "NFRadio";
		}
		this.dummy.className = "NFRadio NFh";
	}
}

function inputRadio(el) { //extent Radio buttons
	var element = $(el);
	var dummy = createElement('span', 'NFRadio');
	
	el.dummy = dummy;
	dummy.ref = el;
	
	if(el.checked)
		dummy.addClassName("NFh");

	el.dummy.onclick = radio_dummy_onclick.bindAsEventListener(el.dummy, el);
	el.onfocus = Element.addClassName.bind(null, element, 'NFfocused');
	el.onblur = Element.removeClassName.bind(null, element, 'NFfocused');
	el.onclick = radio_onclick.bindAsEventListener(el);
	
	el.init = function() {
		this.parentNode.insertBefore(dummy, this);
		el.addClassName("NFOriginal");
	}
	
	element.unload = function(){
		removeElement(this.dummy);
		element.removeClassName("NFOriginal");
	}
}

function inputCheck(el) { //extend Checkboxes
	var element = $(el);
	var dummy =  createElement('span', 'NFCheck');
	if(el.checked) 
		dummy.addClassName("NFh");
		
	function click(e) {	
		element.fire('click', e);
	}
	
	element.observe('click', function(){
		Element[(element.checked ? 'add' : 'remove') + 'ClassName'].call(null, dummy, 'NFh');
	});
	
	element.onfocus = Element.addClassName.bind(null, dummy, "NFfocused");
	element.onblur = Element.removeClassName.bind(null, dummy, "NFfocused");
	
	element.init = function() {
		this.parentNode.insertBefore(dummy, this);
		registerEventDispatcher(dummy, element, 'mousedown,mouseup');
		el.addClassName("NFOriginal");
	}
	
	dummy.observe('click', function(e){
		if(Prototype.Browser.IE)
			element.checked = !element.checked;
		click(e);
		e.stop();
	}.bindAsEventListener());
	
	element.unload = function(){
		removeElement(this.dummy);
		element.removeClassName("NFOriginal");
	}
}

function inputSubmit(el) { //extend Buttons
	el.oldClassName = el.className;
	el.left = document.createElement('img');
	el.left.className = "NFButtonLeft";
	el.left.src = imagesPath + "0.png";
	el.right = document.createElement('img');
	el.right.src = imagesPath + "0.png";
	el.right.className = "NFButtonRight";
	el.onmouseover = function() {
		this.className = "NFButton NFh";
		this.left.className = "NFButtonLeft NFh";
		this.right.className = "NFButtonRight NFh";
	}
	el.onmouseout = function() {
		this.className = "NFButton";
		this.left.className = "NFButtonLeft";
		this.right.className = "NFButtonRight";
	}
	el.init = function() {
		this.parentNode.insertBefore(this.left, this);
		this.parentNode.insertBefore(this.right, this.nextSibling);
		this.className = "NFButton";
	}
	el.unload = function() {
		removeElement(this.left);
		removeElement(this.right);
		this.className = this.oldClassName;
	}
}

function inputFile(el) { //extend File inputs
	var element = $(el);
	var id = element.identify();
	var dummy = createElement('div', "NFFile");
	var file = createElement('div', "NFFileNew");
	var center = createElement('div', "NFTextCenter");
	var left = createImage(imagesPath + "0.png", "NFTextLeft");
	var clone = document.createElement('input');
	var button = createImage(imagesPath + "0.png", "NFFileButton");
	
	clone.type = "text";
	clone.className = "NFText";
	
	button.onclick = function() {
		if(Prototype.Browser.IE) {
			element.click();
		}else {
			setTimeout('$("' + id + '").click()', 0);
		}
	}
	
	el.init = function() {
		element.parentNode.insertBefore(dummy, element);
		appendElements(dummy, file);
		appendElements(file, center);
		appendElements(center, left, clone, button);
		if(Prototype.Browser.IE && msieVersion == 7){ 
			button.style.position = 'relative';
			button.style.top = '-1px';
		}
		this.style.visibility = 'hidden';
	}
	
	el.unload = function() {
		dummy.parentNode.insertBefore(this, dummy);
		removeElement(dummy);
		this.removeClassName('NFhidden');
	}
	
	el.onchange = el.onmouseout = function() {
		clone.value = this.value;
	}
	
	el.onfocus = Enumerable.invoke.bind([left, center, button], 'addClassName', 'NFh');
	el.onblur = Enumerable.invoke.bind([left, center, button],'removeClassName', 'NFh');
	
	el.onselect = function() {
		clone.select();
		this.value = '';
	}
}

function appendElements(parent) {
	for(var i = 1; i < arguments.length; i++) {
		parent.appendChild(arguments[i]);
	}
}

function textarea(el) { //extend Textareas
	var element = $(el);
	var container = createElement('span', 'NFTextareaContainer');
	var wrapper = createElement('div', 'NFTextareaW');
	var wrapper2 = createElement('div', 'NFTextareaW2');
	var topLeft = createElement('span', "NFTextareaTL");
	var topRight = createElement('span', "NFTextareaTR");
	var bottomLeft = createElement('span', "NFTextareaBL");
	var bottomRight = createElement('span', "NFTextareaBR");
	var left = createElement('div', "NFTextareaL");
	var right = createElement('div', "NFTextareaR");
	var top = createElement('div', "NFTextareaT");
	var bottom = createElement('div', "NFTextareaB");
	var elements = [container, wrapper, topLeft, topRight, bottomLeft, bottomRight, left, right, top, bottom];
	
	var originalDimensions = element.getDimensions();
	
	el.init = function() {
		element.parentNode.insertBefore(container, element);
		
		wrapper2.appendChild(element);
		appendElements(wrapper, wrapper2, left, right);
		appendElements(container, top, topLeft, topRight, wrapper, bottom, bottomLeft, bottomRight);
		
		this.addClassName("NFTextarea");
		if(Prototype.Browser.IE && msieVersion == 7){ 
			container.setStyle({
				width: (originalDimensions.width + 10) + 'px',
				height: (originalDimensions.height + 10) + 'px'
			});
		}
		var dimensions = wrapper2.getDimensions();
		var style = {height: dimensions.height + 'px', marginTop: '-' + dimensions.height + 'px'};
		left.setStyle(style);
		right.setStyle(style);
	}
	
	el.unload = function() {
		container.parentNode.insertBefore(element, container);
		removeElement(container);
	}
	
	el.onfocus = Enumerable.invoke.bind(elements, 'addClassName', 'focus');
	el.onblur = Enumerable.invoke.bind(elements, 'removeClassName', 'focus');
}

function unselect(option){
	option.selected = false;	
}

var singleSelects = [];
function selects(el){
	var visibility = false;
	var spotlight = false;
	var element = $(el);
	var dummy = createElement('span', 'NFSelectContainer');
	var wrapper = createElement('div', 'NFSelectW');
	var center = createElement('div', 'NFSelectC');
	var left = createImage(imagesPath + '0.png', 'NFSelectL');
	var right = createImage(imagesPath + '0.png', 'NFSelectR');
	var dropdown = createElement('div', 'NFSelectVM');
	var optionHolder = createElement('ul', '');
	var options = $A(element.options).map(function(option){return $(option);});
	var replacements = new Array();
	
	function getCurrentIndex() {
		for(var i = 0, len = options.length; i < len; i++)
			if (options[i].selected)
				return i;
		return -1;
	}
	
	function changeSelected(index){
		if(index != -1) {
			replacements.invoke('removeClassName', 'selected');
			replacements[index].addClassName('selected');
			options.each(unselect);
			options[index].selected = 'selected';
			center.innerHTML = options[index].text;
		}
	}
	
	function createOption(parent, option) {
		var li = createElement('li', 'NFSelectOption');
		var label = option.readAttribute('label') || option.textContext || option.innerText;
		
		if(option.tagName == 'optgroup') {
			var group = createElement('ul', 'NFSelectOptGroup');
			appendElements(li, li.ownerDocument.createElement(label), group);
			option.descendants().each(function(element) {
				createOptions(group, element);
			});
		} else {
			var anc = createElement('a', '');
			anc.innerHTML = option.text;
			li.appendChild(anc);
			li.setAttribute('index', replacements.length);
			replacements.push(li);
		}
		parent.appendChild(li);
		li = null;
	}
	
	function opt(element) {
		return element.tagName.toLowerCase() == 'option' || 
			element.tagName.toLowerCase() == 'optgroup';
	}
	
	
	element.init = function() {
		var width = 0;
		if(element.getWidth() > 0)
			width = element.getWidth() - ONE_EM_SIZE - 3;
		
		dummy.appendChild(wrapper);
		appendElements(wrapper, left, right, center);
		element.parentNode.insertBefore(dummy, element);
		
		dropdown.appendChild(optionHolder);
		document.body.appendChild(dropdown);
		
		element.descendants().filter(opt).each(function(elem){
			createOption(optionHolder, elem);
		});
		
		element.addClassName('NFOriginal');
		changeSelected(getCurrentIndex());
		
		
		if(width > 0) {
			wrapper.setStyle({width: (width + ONE_EM_SIZE) + 'px'});
			dropdown.setStyle({width: center.getWidth() + 'px'});
		} else {
			var diff = dropdown.getHeight() < optionHolder.getHeight()? 18 : 8;
			dropdown.setStyle({width: (optionHolder.getWidth() + diff) + 'px'});
			wrapper.setStyle({width: dropdown.getWidth() + 'px'});
		}
		
		//alert(dropdown.getHeight() + ' < ' + optionHolder.getHeight());
		if(dropdown.getHeight() < optionHolder.getHeight()) {
			dropdown.setStyle({width: (center.getWidth() + Element.getScrollbarWidth()) + 'px'});
		}
		
		dropdown.hide();
		element.hide();
		dummy.observe('click', click.bindAsEventListener(null));
		$(document.body).observe('keydown', keydown.bindAsEventListener(null));
		$(document.body).observe('click', document_click.bindAsEventListener());
	}
	
	element.unload = function (){
		removeElement(dummy);
		element.removeClassName('NFOriginal');
		element.show();
	}
	
	
	
	function keydown(ev) {
		if(spotlight) {
			var current = getCurrentIndex();
			switch(ev.keyCode){
				case 40: //down
					if(current < options.length - 1) {
						changeSelected(current + 1);
					}
					break;
				case 38: //up
					if(current > 0) {
						changeSelected(current - 1);
					}
					return false;
					break;
			}
		}
	}
	
	function document_click(ev){
		if(visibility) {
			var elements = ev.element().ancestors();
			elements.unshift(ev.element());
			var element = elements.detect(function(element){
				if(element.hasClassName('NFSelectOption'))
					return element;
			});
			if(element != null) {
				var index = element.getAttribute('index');
				changeSelected(index);
			}
			click(ev);
		} else 
			unfocus();
	}
	
	function click(ev){
		(visibility = !visibility) ? show() : hide();
		ev.stop();
		focus();
	}
	
	function focus(){
		dummy.addClassName('NFFocus');
		spotlight = true;
	}
	
	function unfocus() {
		dummy.removeClassName('NFFocus');
		spotlight = false;
	}
	
	function show(){
		var offset = center.cumulativeOffset();
		dropdown.setStyle({
			left: offset.left + 'px',
			top: (offset.top + center.getHeight()) + 'px'
		});
		dropdown.show();
	}
	
	function hide() {
		dropdown.hide();
	}
}


function multiSelects(element) { //extend Multiple Selects
	element.init = Prototype.K;
	element.unload = Prototype.K;
}

})();