jQuery.fn.extend({
	selectbox: function(options) {
		return this.each(function() {
			new jQuery.SelectBox(this, options);
		});
	}
});


jQuery.SelectBox = function(selectobj, options) {

	//option
	var opt					= options || {};
	opt.closeType			= opt.closeType || 'out';
	opt.otherClass			= opt.otherClass || '';
	opt.selectBoxItemClass	= opt.selectBoxItemClass || 'select-box-item';
	opt.inputClass			= opt.inputClass || 'selectbox';
	opt.inputBgImage		= opt.inputBgImage || '';
	opt.containerClass		= opt.containerClass || 'selectbox-wrapper';
	opt.hoverClass			= opt.hoverClass || 'current';
	opt.currentClass		= opt.currentClass || 'selected';
	opt.groupClass			= opt.groupClass || 'groupname';
	opt.maxHeight			= opt.maxHeight || 200;
	opt.loopnoStep			= opt.loopnoStep || true;

	var elm_id = selectobj.id || selectobj.name;
	var active = 0;

	var $selectBoxItem = setupSelectBoxItem();
	var $select = jQuery(selectobj);
	var $container = setupContainer(opt);
	var $input = setupInput(opt);


	//init
	function init() {
		$select.hide().wrap($selectBoxItem).before($input).before($container);
		$container.hide().append(getSelectOptions($input.attr('id')));

		var inpWidth		= parseInt($input.css('width'));
		var paddingRight	= parseInt($input.css('padding-right'));
		var paddingLeft		= parseInt($input.css('padding-left'));
		var borderRight		= parseInt($input.css('border-right-width'));
		var borderLeft		= parseInt($input.css('border-right-width'));

		if ( !inpWidth ) {
			inpWidth = $input.width();
		}

		if ($container.height() > opt.maxHeight) {
			$container.height(opt.maxHeight);
		}

		$container.width( inpWidth + paddingRight + paddingLeft );
		$('.'+opt.selectBoxItemClass).width( inpWidth + borderRight + borderLeft );
	}

	init();


	//events
	$input.click(function(event) {
		if ($container.is(':visible')) {
			hideMe();
		} else {
			showMe();
		}
		event.stopPropagation();
	})
	.keydown(function(event) {
		switch(event.keyCode) {
			case 38: //up
				event.preventDefault();
				moveSelect(-1);
				break;
			case 40: //down
				event.preventDefault();
				moveSelect(1);
				break;
			case 13: //return
				event.preventDefault(); //not working in mac!
				$('li.'+opt.hoverClass).trigger('click');
				break;
			case 27: //escape
			  hideMe();
			  break;
		}
	});


	// ------------------------------------------------------------------------------------------------------------------------------- //
	if ( opt.closeType == 'click' ) {
		$(document).click(function() {
			if ($container.is(':visible')) {
				//alert( 'test: clicked outside: ' + elm_id + ' | ' + $container.is(':visible') );
				hideMe();
				//alert( 'test: clicked outside: ' + elm_id + ' | ' + $container.is(':visible') );
			}
		});

		$('.'+opt.groupClass).click(function(event) {
		  event.stopPropagation();
		});
	}
	else if ( opt.closeType == 'out' ) {
		$input.parent('.'+opt.selectBoxItemClass).mouseleave(function() {
			if ($container.is(':visible')) {
				hideMe();
			}
		});
	}


	// ------------------------------------------------------------------------------------------------------------------------------- //
	function showMe() {
		$('.'+opt.containerClass).hide();
		$container.show();
		$input.css('background-position', '100% 100%'); //dw
	}


	function hideMe() {
		$container.hide();
		$input.css('background-position', '100% 0%'); //dw
	}


	function setupSelectBoxItem() {
		var selectBoxItem = document.createElement('div');
		$selectBoxItem = jQuery(selectBoxItem);
		$selectBoxItem.attr('class', opt.selectBoxItemClass);
		return $selectBoxItem;
	}


	function setupContainer(options) {
		var container = document.createElement('div');
		$container = jQuery(container);
		$container.attr('id', elm_id+'_container');
		$container.addClass(opt.containerClass);
    $container.css('display', 'none');
		return $container;
	}


	function setupInput(options) {
		var input = document.createElement('div');
		var $input = jQuery(input);
		$input.attr('id', elm_id+'_input');
		$input.addClass(opt.inputClass);
		$input.addClass(opt.otherClass);
		$input.attr('tabindex', $select.attr('tabindex')); //dw for trim text
		$input.css('width', $select.css('width'));
		if (opt.inputBgImage) {
			$input.css('background', 'url(/media_front/images/input/'+opt.inputBgImage+') no-repeat 100% 0%'); //dw
		}
		return $input;
	}


	function moveSelect(step) {
		var lis = jQuery('li', $container);
		if (!lis || lis.length == 0) return false;
		//find the first non-group (first option)
		firstchoice = 0;
		while ($(lis[firstchoice]).hasClass(opt.groupClass)) firstchoice++;
		active += step;
		//if we are on a group step one more time
		if ($(lis[active]).hasClass(opt.groupClass)) active += step;
		//loop through list from the first possible option
		if (active < firstchoice) {
			(opt.loopnoStep ? active = lis.size()-1 : active = lis.size() );
		} else if (opt.loopnoStep && active > lis.size()-1) {
			active = firstchoice;
		} else if (active > lis.size()) {
			active = firstchoice;
		}
    scroll(lis, active);
		lis.removeClass(opt.hoverClass);

		jQuery(lis[active]).addClass(opt.hoverClass);
	}


	function scroll(list, active) {
		var el = jQuery(list[active]).get(0);
		var list = $container.get(0);

		if (el.offsetTop + el.offsetHeight > list.scrollTop + list.clientHeight) {
			list.scrollTop = el.offsetTop + el.offsetHeight - list.clientHeight;
		} else if(el.offsetTop < list.scrollTop) {
			list.scrollTop = el.offsetTop;
		}
	}


	function setCurrent() {
		var itemId = $select.parent('.'+opt.selectBoxItemClass).find('.'+opt.inputClass).attr('id');
		var li = jQuery('li.'+opt.currentClass, $container).get(0);
		//var ar = (li.id).split('_');
		//var el = ar[ar.length-1];
		var el = (li.id).split(itemId+'_').join('');
		$select.val(el);
		$select.change();
		$input.html('<span>' + trimText($(li).html()) + '</span>'); //dw - trim text

		$('.test').html( el ); //test
		return true;
	}


	//trim long text
	function trimText(str) {
	  var maxwidth = $input.attr('tabindex');

	  if ( !maxwidth || maxwidth == 0 ) { maxwidth = 100; }

	  if ( str.length > maxwidth ) {
	    newStr = str.substring(0, maxwidth) + '...';
	  } else {
			newStr = str;
		}

	  return newStr;
	}


	//select value
	function getCurrentSelected() {
		return $select.val();
	}


	//input value
	function getCurrentValue() {
		return $input.val();
	}


	function getSelectOptions(parentid) {
		var select_options = new Array();
		var ul = document.createElement('ul');
		select_options = $select.children('option');

		if (select_options.length == 0) {
			var select_optgroups = new Array();
			select_optgroups = $select.children('optgroup');

			for (x=0; x<select_optgroups.length; x++) {
				select_options = $('#'+select_optgroups[x].id).children('option');
				var li = document.createElement('li');
				li.setAttribute('id', 'Group_' + (x+1)); //mod dw
				li.innerHTML = $('#'+select_optgroups[x].id).attr('label');
				li.className = opt.groupClass;
				ul.appendChild(li);

				select_options.each(function() { //list
					var li = document.createElement('li');
					li.setAttribute('id', parentid + '_' + $(this).val()); //
					li.innerHTML = $(this).html();
					if( $(this).attr('style') ) {
						li.setAttribute('style', $(this).attr('style')); //dw
					}
					if ($(this).is(':selected')) {
						$input.html('<span>' + trimText($(this).html()) + '</span>'); //dw - trim text in div
						$(li).addClass(opt.currentClass);
					}
					ul.appendChild(li);
					$(li)
					.mouseover(function(event) {
						jQuery(event.target, $container).addClass(opt.hoverClass);
					})
					.mouseout(function(event) {
						jQuery(event.target, $container).removeClass(opt.hoverClass);
					})
					.click(function(event) {
						var fl = $('li.'+opt.hoverClass, $container).get(0);
						$('li.'+opt.currentClass, $container).removeClass(opt.currentClass);
						$(this).addClass(opt.currentClass);
						setCurrent();
						$select.get(0).blur();
						hideMe();
					});
				});
			}
		} else {
			select_options.each(function() { //list
				var li = document.createElement('li');
				li.setAttribute('id', parentid + '_' + $(this).val()); //
				li.innerHTML = $(this).html();
				if( $(this).attr('style') ) {
					li.setAttribute('style', $(this).attr('style')); //dw
				}
				if ($(this).is(':selected')) {
					$input.html('<span>' + trimText($(this).html()) + '</span>'); //dw - trim text in div
					$(li).addClass(opt.currentClass);
				}
				ul.appendChild(li);
				$(li)
				.mouseover(function(event) {
					jQuery(event.target, $container).addClass(opt.hoverClass);
				})
				.mouseout(function(event) {
					jQuery(event.target, $container).removeClass(opt.hoverClass);
				})
				.click(function(event) {
				  var fl = $('li.'+opt.hoverClass, $container).get(0);
					$('li.'+opt.currentClass, $container).removeClass(opt.currentClass);
					$(this).addClass(opt.currentClass);
					setCurrent();
					$select.get(0).blur();
					hideMe();
				});
			});
		}

		return ul;
	}

}
