if (!(typeof loadFirebugConsole == "undefined")) {
	loadFirebugConsole();
}

/**
 * SkinFormElements is a toolkit for skinning form elements, primarily
 * select-boxes. It uses the jQuery ready-event to initialize all form elements.
 * It wraps each form element inside a div, so other scripts that traverses the
 * DOM should take special notice. <b>Required libs:</b>
 * <ul>
 * <li>jQuery</li>
 * </ul>
 * <p>
 * NOTE: Currently only select boxes are supported. NOTE: SkinFormElements is
 * packer-safe
 * </p>
 * 
 * @author Daniel Skantze
 * @version %I%, %G%
 * @since 1.5
 */

function SkinFormElements() { };

// -----------------------------------------------------------------------
// STATIC DECLARATIONS
// -----------------------------------------------------------------------
/**
 * Adds w3c methods to an event so it can be treated the same in IE and Firefox
 * 
 * @param event
 *            the event that should be standardized
 * @return the event
 */

SkinFormElements.prototype.standardizeEvent = function(event) {
	if (!event.target) {
		event.target = event.srcElement;
		event.stopPropagation = function() {
			this.cancelBubble = true; // note, this-scope is the event
		};
		event.preventDefault = function() {
		};
	}
	return event;
};

SkinFormElements.prototype.TEXT_CLASS_INTERNAL = "__skin_form_elements_text";

// -----------------------------------------------------------------------
// MAIN CLASS
// -----------------------------------------------------------------------

/**
 * Skins elements. Uses specified jQuery pattern to find the elements to
 * skin. Each form element is wrapped inside a div. The class name of the
 * div follows the following pattern: type_wsuffix. E.g. select_holder or
 * radio_holder. Each holder must have its corresponding css rules that
 * directs the skinning.
 * 
 * @param selector
 *            e.g. 'select' - pattern to find the elements to skin.
 * @param wsuffix
 *            the div-wrapper suffix.
 */

SkinFormElements.prototype.skinElementType = function(selector, wsuffix) {
	var elements = jQuery(selector);
	var traceStr = "";
	for ( var i = 0; i < elements.length; i++) {
	  traceStr = traceStr + "element: " + i;
		var element = elements[i];
		var wrapperClass = this.getWrapperClass(element, wsuffix);
		if (!this.hasWrapper(element, wrapperClass)) {
			this.createWrapper(element, wrapperClass);
		}
		this.attachEventListeners(element);
	}
};

/**
 * @return true if element has a wrapper, false otherwise
 */

SkinFormElements.prototype.hasWrapper = function(element, wrapperClass) {
	return (jQuery(element.parentNode).hasClass(wrapperClass));
}

/**
 * Wraps a form element inside a div-tag setting wrapperClass as class on
 * the div-tag. In case of a select box, a text div container is also
 * created.
 */

SkinFormElements.prototype.createWrapper = function(element, wrapperClass) {
	var origW = jQuery(element).width();
	var parent = element.parentNode;
	var wrapperDiv = jQuery(document.createElement("div")).addClass(wrapperClass);
	var formElement = jQuery(element).wrap(wrapperDiv);
	wrapperDiv = jQuery(formElement[0].parentNode);

	// select needs an extra text fiekds that holds its selected value
	if (element.tagName.toLowerCase() == "select") {
		var text = jQuery(element.options[element.selectedIndex]).text();
		var textDiv = jQuery(document.createElement("div"));
		textDiv.append(text);
		textDiv.addClass(this.getTextClass(wrapperClass));
		textDiv.addClass(SkinFormElements.prototype.TEXT_CLASS_INTERNAL);
		formElement.before(textDiv);
		var wh = formElement.width();
		formElement.width("100%");
		wrapperDiv.width(origW);
		wrapperDiv.css("float", "inherit");
	}
}

/**
 * Attaches event listeners regarding skinning for a form element Although
 * not implemented, the idea is that the various input elements should have
 * their type determined by input type.
 * 
 * @param element
 *            the element that gets the event handler
 */

SkinFormElements.prototype.attachEventListeners = function(element) {
	if (element.tagName.toLowerCase() == "select") {
		this.safeAddEventListener(element, "change", "select");
		this.safeAddEventListener(element, "mouseout", "select");
		this.safeAddEventListener(element, "mouseover", "select");
		this.safeAddEventListener(element, "mousedown", "select");
		this.safeAddEventListener(element, "mouseup", "select");
	}
	// add other form elements as needed, input type radio, checkbox etc
};

// -----------------------------------------------------------------------
// SELECT handlers
// -----------------------------------------------------------------------

SkinFormElements.prototype.change_select = function(event) {
	var select = SkinFormElements.prototype.standardizeEvent(event).target;
	var container = select.parentNode;
	var text = jQuery(select.options[select.selectedIndex]).text();
	// note wrapperClass property is added on each wrapped element
	jQuery("." + SkinFormElements.prototype.TEXT_CLASS_INTERNAL, container)
			.text(text);
};

SkinFormElements.prototype.mouseover_select = function(event) {
	var container = SkinFormElements.prototype.standardizeEvent(event).target.parentNode;
	jQuery(container).addClass("over");
	jQuery(container).removeClass("press");
};
SkinFormElements.prototype.mouseout_select = function(event) {
	var container = SkinFormElements.prototype.standardizeEvent(event).target.parentNode;
	jQuery(container).removeClass("over");
	jQuery(container).removeClass("press");
};
SkinFormElements.prototype.mousedown_select = function(event) {
	var container = SkinFormElements.prototype.standardizeEvent(event).target.parentNode;
	jQuery(container).addClass("press");
	jQuery(container).removeClass("over");
};
SkinFormElements.prototype.mouseup_select = function(event) {
	var container = SkinFormElements.prototype.standardizeEvent(event).target.parentNode;
	jQuery(container).removeClass("press");
	jQuery(container).addClass("over");
};

// -----------------------------------------------------------------------
// HELPER METHODS
// -----------------------------------------------------------------------

/**
 * Adds an event listener regardless of browser type The event listener
 * added has the form: mouseover_select, i.e. event-name followed by handler
 * type. The event handler must be present inside the SkinFormElements
 * class.
 * 
 * @param element
 *            the element
 * @param evt
 *            the event (NOTE firefox notation, e.g. "click", 'mouseover'
 *            etc., NOT "onclick")
 * @param type
 *            the handler type, e.g. "select" etc.
 * @return the event
 */

SkinFormElements.prototype.safeAddEventListener = function(element, evt, type) {
	var handler = this[evt + "_" + type];
	if (element.addEventListener) {
		element.addEventListener(evt, handler, false);
	} else {
		element.attachEvent('on' + evt, handler);
	}
};

/**
 * Gets the text class name for a specific wrapper class (note, it generates
 * the name, it does not traverse the dom). Currently only used by select
 * boxes.
 * 
 * @param the
 *            wrapper class name
 * @return the class name
 */

SkinFormElements.prototype.getTextClass = function(wrapperClass) {
	return wrapperClass + "_text";
}

/**
 * Gets the wrapper class name for a specific element (note, it generates
 * the name, it does not traverse the dom).
 * 
 * @return the class name
 */

SkinFormElements.prototype.getWrapperClass = function(element, wsuffix) {
	return this.getTypeFromElement(element) + "_" + wsuffix;
}

/**
 * Extracts the type from a form element. Note that select and textarea has
 * their tagName as type (i.e. select or textarea)
 * 
 * @return the element type
 */

SkinFormElements.prototype.getTypeFromElement = function(element) {
	if (element.tagName.toLowerCase() == "input") {
		return jQuery(element).attr('type').toLowerCase();
	}
	return element.tagName.toLowerCase();
}
