/**
 * jQuery custom selectboxes
 * 
 * Copyright (c) 2008 Krzysztof Suszyński (suszynski.org)
 * Licensed under the MIT License:
 * http://www.opensource.org/licenses/mit-license.php
 *
 * @version 0.6.1
 * @category visual
 * @package jquery
 * @subpakage ui.selectbox
 * @author Krzysztof Suszyński <k.suszynski@wit.edu.pl>
**/
jQuery.fn.selectbox = function(options){
	/* Default settings */
	var settings = {
		className: 'jquery-selectbox',
		animationSpeed: "normal",
		listboxMaxSize: null,
		replaceInvisible: false,
		selectboxWidth: null,
		dropdownWidth: null
	};
	var currentWidth;
	
	var commonClass = 'jquery-custom-selectboxes-replaced';
	var toggleList = function (listObj, replacement, onBlur, doShow) {
		doShow = (typeof doShow == 'undefined') ? !listObj.isVisible : !!doShow;
		if (doShow) {
			showList(listObj, replacement, onBlur);
		} else {
			hideList(listObj, replacement, onBlur);
		}
		listObj.isVisible = doShow;
	};
	var showList = function(listObj, replacement, onBlur) {
		listObj.slideDown(settings.animationSpeed, function(){
		});
		jQuery(document).bind('click', onBlur);
		replacement.addClass('selecthover');
		return listObj;
	}
	var hideList = function(listObj, replacement, onBlur) {
		listObj.slideUp(settings.animationSpeed, function(){
			replacement.removeClass('selecthover');
		});
		jQuery(document).unbind('click', onBlur);
		return listObj;
	}
	var onBlurHandler = function (listObj, replacement) {
		return function () {
			if (!listObj.isClick) {
				toggleList(listObj, replacement, arguments.callee, false);
			}
			listObj.isClick = false;
		};
	}

	/* Processing settings */
	settings = jQuery.extend(settings, options || {});
	/* Wrapping all passed elements */
	return this.each(function() {
		var _this = jQuery(this);
		if(_this.filter(':visible').length == 0 && !settings.replaceInvisible)
			return;
		currentWidth = settings.selectboxWidth - 22; //fixed IE overflow hidden issue 
		var replacement = jQuery(
			'<div class="' + settings.className + ' ' + commonClass + '">' +
				'<div class="' + settings.className + '-moreButton" />' +
				'<div class="' + settings.className + '-list ' + commonClass + '-list" />' +
				'<div class="' + settings.className + '-currentItem" style="width: ' + currentWidth + 'px;" />' +
			'</div>'
		);
		var list = jQuery('.' + settings.className + '-list', replacement);
		var onBlur = onBlurHandler(list, replacement);
		var html = [];
		jQuery('option', _this).each(function(k, v){
			var v = jQuery(v);
			html.push('<span class="', settings.className, '-item value-', v.val(), ' item-', k, '">', v.text(), '</span>');
		/*
		}).filter(':selected').each(function () {
			jQuery('.'+settings.className + '-currentItem', replacement).text(jQuery(this).text());
		*/
		});
		jQuery('.'+settings.className + '-currentItem', replacement).text(jQuery(this.options[this.selectedIndex]).text());
		list.get(0).innerHTML = html.join('');
		list.click(function(e){
			var target = e.target;
			if (target.nodeType == 3) {
				target = target.parentNode;
			}
			if (target.nodeType != 1 || target.nodeName != 'SPAN') {
				return;
			}

			var thisListElement = jQuery(target);
			var thisIndex = thisListElement[0].className.split(' ');
			for( k1 in thisIndex ) {
				if(/^item-[0-9]+$/.test(thisIndex[k1])) {
					thisIndex = parseInt(thisIndex[k1].replace('item-',''), 10);
					break;
				}
			};
			var thisValue = jQuery('option', _this).eq(thisIndex).val();

			replacement
				.find('.' + settings.className + '-currentItem')
				.text(thisListElement.text());

			replacement
				.find('select')
				.val(thisValue)
				.triggerHandler('change');
			list.isClick = true;
			toggleList( list, replacement, onBlur, false );
		}).mouseover(function(e){
			var target = e.target;
			if (target.nodeType == 3) {
				target = target.parentNode;
			}
			if (target.nodeType != 1 || target.nodeName != 'SPAN') {
				return;
			}
			jQuery(target).addClass('listelementhover');
		}).mouseout(function(e){
			var target = e.target;
			if (target.nodeType == 3) {
				target = target.parentNode;
			}
			if (target.nodeType != 1 || target.nodeName != 'SPAN') {
				return;
			}
			jQuery(target).removeClass('listelementhover');
		});
		replacement.find('.' + settings.className + '-moreButton').click(function(){
			list.isClick = true;
			toggleList( list, replacement, onBlur );
		}).bind('mouseenter',function(){
			jQuery(this).addClass('morebuttonhover');
		}).bind('mouseleave',function(){
			jQuery(this).removeClass('morebuttonhover');
		});
		replacement.find('.' + settings.className + '-currentItem').click(function(){
			list.isClick = true;
			toggleList( list, replacement, onBlur );
		});

		//_this.hide().replaceWith(replacement).appendTo(replacement);
		_this.hide();
		this.parentNode.replaceChild(replacement.get(0), this);
		replacement.get(0).appendChild(this);
		//var thisListBoxSize = list.find('.' + settings.className + '-item').length;
		var thisListBoxSize = settings.listboxMaxSize;
		if(thisListBoxSize == null) {
			thisListBoxSize = 1;
		}
		if(jQuery.browser.safari) {
			thisListBoxSize = thisListBoxSize * 0.94;
		}
		replacement.css('width', settings.selectboxWidth + 'px');
		var ddWidth = settings.dropdownWidth == null ? settings.selectboxWidth : settings.dropdownWidth;
		list.css({
			width: (Math.round(ddWidth)+2) + 'px',
			height: (thisListBoxSize * 1.61) + 'em'
		});
		list.actualHeight = list.css('height');
	});
}
jQuery.fn.unselectbox = function(){
	var commonClass = 'jquery-custom-selectboxes-replaced';
	return this.each(function() {
		var selectToRemove = jQuery(this).filter('.' + commonClass);
		selectToRemove.replaceWith(selectToRemove.find('select').show());		
	});
}


jQuery.fn.resetselectbox = function(){
	var settings = {
		className: 'jquery-selectbox'
	};
	return this.each(function() {
		var thisListElement = jQuery(this);
		var thisReplacment = thisListElement.parents('.'+settings.className);
		var defaultItem = jQuery('option', thisListElement).eq(0);
		thisReplacment
			.find('.' + settings.className + '-currentItem')
			.text(defaultItem.text());
		thisReplacment
			.find('select')
			.val(defaultItem.val())
			.triggerHandler('change');
	});
}