/************************************************************************************************************************************************
* Selectbox Skinner																																*
* @author: 	Ferry Brouwer																														*
* @since	15-07-2010																															*
* Example: 																																		*
*			Single implementation by jQuery instance																							*
*			Selectbox: 	$('div placeholder id').selectbox( $('selectbox id') );  																*
* 			Dropdown: 	$('div placeholder id').dropdown( $('div list with anchors') );															*
*																																				*
*			Multiple implementation by class name (NOTE: insert code before the closing body tag)												*
*			var sb = new Selectbox({																											*
*				identifier_class : 'selectbox',																									*
*				classes	: {selected:'selectbox_selected', list:'selectbox_list', text:'selectbox_text', disabled:'selectbox_disabled'},			*
*				max_list_height : 300																											*
*			});																																	*
*																																				*
************************************************************************************************************************************************/

var _selectboxes = [], _dropdowns = [];

//global variables
var isIE7 = (jQuery.browser.msie && Math.floor(jQuery.browser.version) == '7') ? true : false;
var isChrome = ( /chrome/.test(navigator.userAgent.toLowerCase()) ) ? true  : false;
var list_click = false;
var open_selected;

jQuery.fn.extend({ 
	/**
	 * Selectbox jQuery instance
	 * @Param obj_classes : Skinnable selectbox classes {selected, list, text, disabled}
	 */
	selectbox: function(obj_classes){
		if (!clientHasMobileDevice()){
			//set default classes
			obj_classes = (!obj_classes) ? {selected:'selectbox_selected', list:'selectbox_list', text:'selectbox_text', disabled:'selectbox_disabled'} : obj_classes;
			if (!obj_classes.btn) obj_classes.btn = 'btn';
	
			//create placeholder 
			var placeholder = $(document.createElement('div'));
			$.each( getClasses(this), function(i, _class){ placeholder.addClass(_class); });
			$.each( getInline(this), function(i, sp){ placeholder.css(sp.styleName, sp.styleValue); });
			if ( this.attr('tabindex') ) placeholder.attr('tabindex', this.attr('tabindex'));
			placeholder.attr('type', 'selectbox');
			if ( this.css('float') != 'right' ) placeholder.css('float', 'left');
			
			//add to stage
			this.after(placeholder);
			this.hide();
	
			//remove duplicated instance of selectbox
			if (getObject(placeholder)){
				placeholder.html('');
				for(var i=0; i<_selectboxes.length; i++)	{
					if (_selectboxes[i].instance[0] == placeholder[0]) 
						_selectboxes.splice(i, 1);
				}
			}
	
			//create placeholder HTML
			var selected_text = this.find("option:selected").text();
			var html = "<div class='" + obj_classes.selected + "' onclick='toggleList(this);'>" + 
							"<div class='" + obj_classes.text + " noSelect'>" + selected_text + "<\/div>" + 
							"<div class='btn'><\/div>" + 
						"<\/div>" + 
						"<div class='" + obj_classes.list + "' style='display:none; visibility:hidden; position:absolute; z-index:999999999;'>";
						$.each(this.children('option'), function(i, option){
							var font_bold = (selected_text == $(option).text()) ? "font-weight:bold;" : ""; 
							html += "<a href='#' onclick='setSelected(this); return false;' class='selectbox_value_" + $(option).val() + "' style='white-space:nowrap; outline:none;" + font_bold + "'>" + $(option).text() + "<\/a>";
						});
						html += "<\/div>";
			placeholder.html(html);
			
			//add to selectboxes array
			_selectboxes.push({instance:placeholder, selectElement:this, classes:obj_classes});
	
			//btn hover
			placeholder.hover(
				function(){ placeholder.getElement(obj_classes.btn).addClass('hover'); },
				function(){ placeholder.getElement(obj_classes.btn).removeClass('hover'); }
			);
			
			//keyboard arrow event
			placeholder.keydown(function(event){
				//disable window from scrolling
				event.preventDefault();
				switch(event.keyCode){
					case 40: 	setSelectedByKeyEvent(this, 'down'); 	break; //arrow down
					case 38: 	setSelectedByKeyEvent(this, 'up');		break; //arrow up
					case 9:		setNextTabFocus(this);					break; //tab
				}
			});
			
			//add focus class 
			var clickValue = false;
			placeholder.mousedown(function(event){clickValue = true;});
			placeholder.mouseup(function(event){
				setTimeout(function(){
					clickValue = false;						
					clearTimeout(this);
				}, 500);
			});
			placeholder.focus(function(event){
				if (!clickValue) 
					$(this).getElement(obj_classes.selected).addClass('focus');
			});	
	
			//mouseup value check if list is hidden
			placeholder.getElement(obj_classes.selected).mouseup(function(){
				var list = $(this).parent().getElement(obj_classes.list);
				if(!list.is(':hidden')) open_selected = list;
			});
			
			placeholder.truncateText(selected_text);
			placeholder.setListWidth();
			$('.noSelect').disableTextSelect();
			if (this.attr('disabled'))	placeholder.disable();
			
			//set listwidth if isn't set
			if (isNaN( parseInt(this.css('width')) )) 
				($.browser.msie) ? placeholder.width(200) : placeholder.width(this.width());
		}
	}, //end selectbox
	
	/**
	 * Dropdown jQuery instance
	 * @param classes	: Skinnable selectbox classes {selected, list, text, disabled}
	 */
	dropdown: function(obj_classes){
		if (!clientHasMobileDevice()){
			obj_classes = (!obj_classes) ? {selected:'dropdown_selected', list:'dropdown_list', text:'dropdown_text', disabled:'dropdown_disabled'} : obj_classes;
			if (!obj_classes.btn) obj_classes.btn = 'btn';
			
			//create placeholder
			var placeholder = $(document.createElement('div'));
			$.each( getClasses(this), function(i, _class){ placeholder.addClass(_class); });
			$.each( getInline(this), function(i, sp){ placeholder.css(sp.styleName, sp.styleValue); });
			if ( this.attr('tabindex') ) placeholder.attr('tabindex', this.attr('tabindex'));
			placeholder.attr('type', 'dropdown');
			if ( this.css('float') != 'right' ) placeholder.css('float', 'left');
			
			//add to stage
			this.after(placeholder);
			this.hide();
	
			//remove duplicated instance of dropdown
			if (getObject(placeholder)){
				placeholder.html('');
				for (var i=0; z<_dropdowns.length; i++) {
					if (_dropdowns[i].instance[0] == placeholder[0]) 
						_dropdowns.splice(i, 1);
				}
			}
			
			//create placholder HTML
			var selectedText = (this.find('a').length > 0) ? $(this.find('a:first-child')).text() : "";
			if (selectedText != '') this.find('a:first-child').css('font-weight', 'bold');
			var html = 	"<div class='" + obj_classes.selected + "' onclick='toggleList(this);'>" + 
							"<div class='" + obj_classes.text + " noSelect'>" + selectedText + "<\/div>" + 
							"<div class='btn'><\/div>" + 
						"<\/div>" + 
						"<div class='" + obj_classes.list + "' style='display:none; visibility:hidden; position:absolute;'>" + this.html() + "<\/div>";
			placeholder.html(html);
	
			//add to dropdowns array
			_dropdowns.push({instance:placeholder, classes:obj_classes, divElement:this});
			
			//btn hover
			placeholder.hover (
				function(){ placeholder.getElement(classes.btn).addClass('hover'); },
				function(){ placeholder.getElement(classes.btn).removeClass('hover'); }
			);
			
			placeholder.truncateText();
			placeholder.setListWidth();
			$('.noSelect').disableTextSelect();
			
			//mouseup value check if list is hidden
			placeholder.getElement(obj_classes.selected).mouseup( function(){
				var list = $(this).parent().getElement(obj_classes.list);
				if (!list.is(':hidden')) open_selected = list;
			});
			
			var obj = getObject(placeholder);
			obj.instance.getElement(obj_classes.list).find('a').click(function(){
				//set text
				obj.instance.truncateText( $(this).text() );
				
				//delete all style properties 'font-weight:bold'
				$.each($(this).parent().find('a'), function(i, _anchor){
					if ( typeof( $(_anchor).attr('style') ) != 'undefined'){
						var style_properties = $(_anchor).attr('style').split(';');
						
						var new_style_properties = "";
						$.each(style_properties, function(index, property){
							if ($.trim(property) != ""){
								var property_name = property.split(':')[0];
								var property_value = property.split(':')[1];
			
								if (property_name.toUpperCase().replace(" ", "") != "FONT-WEIGHT")
									new_style_properties += property_name + ":" + property_value + ";";
							}
						});
						
						$(_anchor).removeAttr('style');
						$(_anchor).attr('style', new_style_properties);
					}
				});
				
				//add font-weight: bold to selected
				$(this).css('font-weight', 'bold');
				obj.instance.getElement(obj_classes.list).hide();
				$('.noSelect').disableTextSelect();
			});
		}
	}, //end dropdown
	
	/**
	 * Set text only for jQuery dropdown elements
	 * @param text	: The text to display in the selected element
	 */
	selectedText: function(text){
		if (!clientHasMobileDevice()){
			if (this.attr('type') == 'dropdown'){
				var obj = getObject(this);
				
				if (obj){
					//set text
					obj.instance.getElement(obj.classes.text).text(text);
					$.each(obj.instance.getElement(obj.classes.list).find('a'), function(i, _anchor){
						//remove bold
						if ($(this).css('font-weight') == 'bold'){
							if ( typeof( $(_anchor).attr('style') ) != 'undefined'){
								var style_properties = $(_anchor).attr('style').split(';');
								
								var new_style_properties = "";
								$.each(style_properties, function(index, property){
									if ($.trim(property) != ""){
										var property_name = property.split(':')[0];
										var property_value = property.split(':')[1];
					
										if (property_name.toUpperCase().replace(" ", "") != "FONT-WEIGHT")
											new_style_properties += property_name + ":" + property_value + ";";
									}
								});
								
								$(_anchor).removeAttr('style');
								$(_anchor).attr('style', new_style_properties);
							}
						}
						
						//set bold
						if ( $.trim($(this).text()) == $.trim(text) ){
							$(this).css('font-weight', 'bold');
						}
					});
					
					this.truncateText();
				}
			}else if ( $.trim(this[0].tagName.toUpperCase()) == 'DIV' && !this.attr('type') ){
				var instance;
				for (var i=0; i<_dropdowns.length; i++){
					if (_dropdowns[i].divElement[0] == this[0]){
						instance = _dropdowns[0].instance;
						break;
					}
				}
				if (instance.attr('type') == 'dropdown') instance.selectedText(text);
			}
		}
	}, //end selectedText
	
	/**
	* Set value of an element (including dropdown elements
	*/
	val: function(value){
		if (clientHasMobileDevice()){
			this[0].value = value;
		}else{
			if (this.attr('type') == 'dropdown'){
				var obj = getObject(this);
				if (value){
					obj.instance.selectedText(value);
				}else{
					return obj.instance.getElement(obj.classes.text).text();
				}
			}else if (this.attr('type') == 'selectbox'){
				var obj = getObject(this);
				if (value){
					var anchors = obj.instance.getElement(obj.classes.list).children('a');
					for (var i=0; i<anchors.length; i++){
						var val = $.trim( $(anchors[i]).attr('class').replace("selectbox_value_", "") );
						if ( val == $.trim(value.toString()) ){
							setSelected(anchors[i], 'no_submit');
							break;
						}
					}
				}else{
					return obj.selectElement.val();
				}
			}else if ($.trim(this[0].tagName.toUpperCase()) == 'SELECT'){	
				if (value){
					var instance;
					for (var i=0; i<_selectboxes.length; i++){
						if (_selectboxes[i].selectElement[0] == this[0]){
							instance = _selectboxes[i].instance;
							break;
						}
					}
					instance.val(value);
				}else{
					return this[0].value;
				}
			}else if ( $.trim(this[0].tagName.toUpperCase()) == 'DIV' && !this.attr('type') ){
				var instance;
				for (var i=0; i<_dropdowns.length; i++){
					if (_dropdowns[i].divElement[0] == this[0]){
						instance = _dropdowns[i].instance;
						break;
					}
				}
				if (value){
					instance.val(value);
				}else{
					return instance.val();
				}
			}else{
				if (typeof(this[0]) != 'undefined'){
					if (typeof(value) != 'undefined'){
						this[0].value = value;
					}else{
						return this[0].value;
					}
				}
			}
		}
	}, //end value
	 
	/**
	 * Truncate the selected text (text) if it's oversized
	 * @param text : text to truncate and setted to text class
	 */
	truncateText: function(text){
		if (!clientHasMobileDevice()){
			var obj = getObject(this);
			var text_element = obj.instance.getElement(obj.classes.text);
			text_element.text(text);
			text_element.css({'overflow':'hidden', 'white-space':'nowrap'});
			 
			if (isIE7){
				var tmp = obj.instance.clone();
				tmp.css({'visibility':'hidden', 'position':'absolute', 'left':'0', 'top':'0'});
				$('body').append(tmp);
				var selected_width 	= tmp.find('.' + obj.classes.selected).width();
				var btn_width 		= tmp.find('.' + obj.classes.btn).width();
				var padding 		= parseInt(tmp.find('.' + obj.classes.text).css('padding-left')) + parseInt(tmp.find('.' + obj.classes.text).css('padding-right'));				
				var text_element	= tmp.find('.' + obj.classes.text);
				var max_text_width 	= selected_width - btn_width - padding;

				if (max_text_width != 0 && text_element.width() != 0){
					if (text_element.width() > max_text_width){
						while (text_element.width() >= (max_text_width-30)) text_element.text( text_element.text().substr(0, text_element.text().length -1) );
						text_element.text( text_element.text() + "..." );
					}
				}
				obj.instance.getElement(obj.classes.selected).html( tmp.find('.' + obj.classes.selected).html() );
				tmp.remove();
			}else if (isChrome){
				var tmp = obj.instance.clone();
				tmp.css({'visibility':'visible', 'position':'absolute', 'left':'0', 'top':'0'});
				tmp.find('.' + obj.classes.list).css({'display':'block', 'visibility':'visible'});
				$('body').append(tmp);
				var btn = tmp.find('.' + obj.classes.btn);
				btn.css('display', 'inline');
				var detected_width = (btn.width() == 0) ? false : true;
				tmp.remove();
				
				if (detected_width){
					var selected_width 	= obj.instance.getElement(obj.classes.selected).width();
					var btn_width 		= obj.instance.getElement(obj.classes.btn).width();
					var padding 		= parseInt(text_element.css('padding-left')) + parseInt(text_element.css('padding-right'));
					var max_text_width 	= selected_width - btn_width - padding;
					
					if (max_text_width != 0 && text_element.width() != 0){
						if (text_element.width() > max_text_width){
							while (text_element.width() >= (max_text_width-30))
								text_element.text( text_element.text().substr(0, text_element.text().length -1) );
										
							text_element.text( text_element.text() + "..." );
						}
					}	
				}else{
					setTimeout(function(){
						var selected_width 	= obj.instance.getElement(obj.classes.selected).width();
						var btn_width 		= obj.instance.getElement(obj.classes.btn).width();
						var padding 		= parseInt(text_element.css('padding-left')) + parseInt(text_element.css('padding-right'));
						var max_text_width 	= selected_width - btn_width - padding;

						if (max_text_width != 0 && text_element.width() != 0){
							if (text_element.width() > max_text_width){
								while (text_element.width() >= (max_text_width-30))
									text_element.text( text_element.text().substr(0, text_element.text().length -1) );
											
								text_element.text( text_element.text() + "..." );
							}
						}
						clearTimeout(this);
					}, 20);
				}
			}else{
				var selected_width 	= obj.instance.getElement(obj.classes.selected).width();
				var btn_width 		= obj.instance.getElement(obj.classes.btn).width();
				var padding 		= parseInt(text_element.css('padding-left')) + parseInt(text_element.css('padding-right'));
				var max_text_width 	= selected_width - btn_width - padding;
				
				if (max_text_width != 0 && text_element.width() != 0){
					if (text_element.width() > max_text_width){
						while (text_element.width() >= (max_text_width-30))
							text_element.text( text_element.text().substr(0, text_element.text().length -1) );
									
						text_element.text( text_element.text() + "..." );
					}
				}				
			}
		}
	}, //end truncateText
	
	/**
	 * Disable selectbox
	 * Sets disabled class
	 */
	disable: function(){
		if (clientHasMobileDevice()){
			this.attr('disabled', 'disabled');
		}else{
			if (typeof(this[0]) != 'undefined' && $.trim(this[0].tagName.toUpperCase()) == 'SELECT'){
				//get jQuery selectbox object
				var instance;
				for (var i=0; i<_selectboxes.length; i++){
					if (_selectboxes[i].selectElement[0] == this[0]){
						instance = _selectboxes[i].instance;
						break;
					}
				}
				instance.disable();
			}else if ( $.trim(this[0].tagName.toUpperCase()) == 'DIV' && !this.attr('type') ){
				var instance;
				for (var i=0; i<_dropdowns.length; i++){
					if (_dropdowns[i].divElement[0] == this[0]){
						instance = _dropdowns[0].instance;
						break;
					}
				}
				instance.disable();
			}else{
				var obj = getObject(this);
				if (obj.instance.attr('type') == 'selectbox' || obj.instance.attr('type') == 'dropdown') {
					if (isChrome){
						setTimeout(function(){
							if (obj.instance.find('.' + obj.classes.disabled).length == 0){
								//create new disabled div
								var disabled_div = $(document.createElement('div'));
								disabled_div.css({'z-index':'1','position':'absolute','height': obj.instance.height(),'width': obj.instance.width()});
								disabled_div.addClass(obj.classes.disabled);
								obj.instance.unbind('mouseover').unbind('mouseout');
	
								//add to dom structure and set opacity
								var selected = obj.instance.getElement(obj.classes.selected);
								selected.before(disabled_div);
								selected.css({"-moz-opacity":.5, "filter":"alpha(opacity=50)", "opacity":.5});
							}
							clearTimeout(this);
						}, 20);
					}else{
						$(document).ready(function(){
							if (obj.instance.find('.' + obj.classes.disabled).length == 0){
								//create new disabled div
								var disabled_div = $(document.createElement('div'));
								disabled_div.css({'z-index':'1','position':'absolute','height': obj.instance.height(),'width': obj.instance.width()});
								disabled_div.addClass(obj.classes.disabled);
								obj.instance.unbind('mouseover mouseout');
	
								//add to dom structure and set opacity
								var selected = obj.instance.getElement(obj.classes.selected);
								selected.before(disabled_div);
								selected.css({"-moz-opacity":.5, "filter":"alpha(opacity=50)", "opacity":.5});
							}
						});
					}
				}
			}
		}
	}, //end disable
	
	/**
	 * Enable selectbox
	 * Remove the disabled class
	 */
	enable: function(){
		if (clientHasMobileDevice()){
			this.removeAttr('disabled');
		}else{
			if ($.trim(this[0].tagName.toUpperCase()) == 'SELECT'){
				//get jQuery selectbox object
				var instance;
				for (var i=0; i<_selectboxes.length; i++){
					if (_selectboxes[i].selectElement[0] == this[0]){
						instance = _selectboxes[i].instance;
						break;
					}
				}
				instance.enable();
			}else if ( $.trim(this[0].tagName.toUpperCase()) == 'DIV' && !this.attr('type') ){
				var instance;
				for (var i=0; i<_dropdowns.length; i++){
					if (_dropdowns[i].divElement[0] == this[0]){
						instance = _dropdowns[0].instance;
						break;
					}
				}
				instance.enable();
			}else{
				var obj = getObject(this);
				$(document).ready(function(){
					//remove disabled
					obj.instance.find('div.' + obj.classes.disabled).remove();
					
					//collects filtered attributes
					var _selected = obj.instance.getElement(obj.classes.selected);
					if (_selected.attr('style')){
						var inlineStyles = _selected.attr('style').split(";");
						var filteredStyles = [];
						for(var i=0; i<inlineStyles.length; i++){
							var style = inlineStyles[i].split(":");
							if($.trim(style[0]) != ''){
								if(	style[0].toUpperCase().replace(/\s/gi, '') != "OPACITY" && 
									style[0].toUpperCase().replace(/\s/gi, '') != "FILTER" && 
									style[0].toUpperCase().replace(/\s/gi, '') != "-MOZ-OPACITY" && 
									style[0].toUpperCase().replace(/\s/gi, '') != "MOZOPACITY" &&
									style[0].toUpperCase().replace(/\s/gi, '') != "ZOOM")
										filteredStyles.push({styleName:$.trim(style[0]), styleValue:$.trim(style[1])});
							}
						}
						
						//remove all attributes and set the filtered attributes
						_selected.removeAttr('style');
						var newStyle = "";
						$.each(filteredStyles, function(index, style){ newStyle += style.styleName + ":" + style.styleValue + ";"; });	
						if (newStyle != '') _selected.attr('style', newStyle);
						
						//set hover
						obj.instance.bind({
							mouseover: function(){obj.instance.getElement(obj.classes.btn).addClass('hover');},
							mouseout: function(){obj.instance.getElement(obj.classes.btn).removeClass('hover');}
						});
					}
				});
			}
		}
	}, //end enable
	
	/**
	 * Set the width of the list
	 */
	setListWidth: function(){
		if (!clientHasMobileDevice()){
			var obj = getObject(this);
			
			$(document).ready(function(){
				var list = obj.instance.getElement(obj.classes.list);
				
				//remove all width properties from anchors of the list
				var anchors = obj.instance.getElement(obj.classes.list).children('a');
				if (anchors.length > 0){
					$.each(anchors, function(index, _anchor){
						if ( $(_anchor).attr('style') ){
							var style_properties = $(_anchor).attr('style').split(';');
							var new_properties = '';
							$.each(style_properties, function(index, property){
								if ($.trim(property) != ""){
									var property_name 	= property.split(':')[0];
									var property_value 	= property.split(':')[1];
									
									if (property_name.replace(/\s/gi, '').toUpperCase() != 'WIDTH')
										new_properties += property_name + ':' + property_value + ';';
								}
							});
							$(_anchor).removeAttr('style');
							if (new_properties != '') $(_anchor).attr('style', new_properties);
						}
					});
				}	
				
				//check list width
				var list_width;
				var selected_width;
				
				if (isIE7 || list.width() == 0){
					var tmp = obj.instance.clone();
					tmp.css({'visibility':'hidden', 'position':'absolute', 'left':'0', 'top':'0'});
					$('body').append(tmp);
					list_width 	= tmp.find('.' + obj.classes.list).width();
					selected_width = parseInt( tmp.find('.' + obj.classes.selected).width() );
					tmp.remove();
					if (list_width < selected_width) list.width(selected_width);
				}else if (isChrome){
					$(document).ready(function(){
						setTimeout(function(){
							var tmp = obj.instance.clone();
							tmp.css({'visibility':'hidden', 'position':'absolute', 'left':'0', 'top':'0'});
							$('body').append(tmp);
							list_width 	= tmp.find('.' + obj.classes.list).width();
							selected_width = parseInt( tmp.find('.' + obj.classes.selected).width() );
							tmp.remove();
							if (list_width < selected_width) list.width(selected_width);			
							clearTimeout(this);
						}, 100);
					});
				}else{
					list_width = list.width();
					selected_width = obj.instance.getElement(obj.classes.selected).width();	
					if (list_width < selected_width) list.width(selected_width);
				}
			});
		}
	}, //end listWidth
	
	/**
	 * Scrollable functionality 
	 * @param height : height of the list (enable scrolling if content is higher), default height is 200px
	 */
	scrollable: function( height ){
		if (!clientHasMobileDevice()){
			if ($.trim(this[0].tagName.toUpperCase()) == 'SELECT'){
				//get jQuery selectbox object
				var instance;
				for (var i=0; i<_selectboxes.length; i++){
					if (_selectboxes[i].selectElement[0] == this[0]){
						instance = _selectboxes[i].instance;
						break;
					}
				}
				instance.scrollable(height);
			}else if ( $.trim(this[0].tagName.toUpperCase()) == 'DIV' && !this.attr('type') ){
				var instance;
				for (var i=0; i<_dropdowns.length; i++){
					if (_dropdowns[i].divElement[0] == this[0]){
						instance = _dropdowns[0].instance;
						break;
					}
				}
				instance.scrollable(height);
			}else{
				var obj = getObject(this);
				var list = obj.instance.getElement(obj.classes.list);
				var height = (height) ? height : 200;
				
				list.mousedown(function(){list_click = true;});
				
				//get bounding data of list
				var list_bounding = {};
				if (isIE7){
					var tmp = $(document.createElement('div'));
					tmp.css({
						'visibility' 	: 'hidden',
						'position'		: 'absolute',
						'left'			: '0',
						'top'			: '0'
					});
					tmp.html( obj.instance.html() );
					$('body').append(tmp);
					list_bounding.height 	= tmp.find('.' + obj.classes.list).height();
					list_bounding.width 	= tmp.find('.' + obj.classes.list).width();
					tmp.remove();
				}else{
					list_bounding.height 	= list.height();
					list_bounding.width 	= list.width();
				}
				if (list_bounding.height > height){
					if (isIE7 || $.browser.safari) list.css('width', list_bounding.width + 20); //+20 == add scrollbar width (IE 7 and safari)
					list.css('height', height);
					list.css('overflow-y', 'scroll');
				}
			}
		}
	}, //end scrollable
	
	/**
	 * Set error class of selected / list of selectbox
	 */
	setError: function(boolean){
		if (clientHasMobileDevice()){
			this.addClass('error');
		}else{
			if ($.trim(this[0].tagName.toUpperCase()) == 'SELECT'){
				//get jQuery selectbox object
				var instance;
				for (var i=0; i<_selectboxes.length; i++){
					if (_selectboxes[i].selectElement[0] == this[0]){
						instance = _selectboxes[i].instance;
						break;
					}
				}
				instance.setError(boolean);
			}else if ( $.trim(this[0].tagName.toUpperCase()) == 'DIV' && !this.attr('type') ){
				var instance;
				for (var i=0; i<_dropdowns.length; i++){
					if (_dropdowns[i].divElement[0] == this[0]){
						instance = _dropdowns[0].instance;
						break;
					}
				}
				instance.setError(boolean);
			}else{
				var obj = getObject(this);
				var error_classes = obj.instance.find('.error');
				if (boolean){
					if (error_classes.length == 0){
						obj.instance.getElement(obj.classes.selected).addClass('error');
						obj.instance.getElement(obj.classes.list).addClass('error');
					}
				}else{
					$.each(error_classes, function(index, element){
						$(element).removeClass('error');
					});
				}
			}
		}
	}, //end setError
	
	/**
	 * Disable text from being selected
	 */
	disableTextSelect: function() {
		if (!clientHasMobileDevice()){
			return this.each(function(){
				if ($.browser.mozilla){ //mozilla firefox
					$(this).css('MozUserSelect','none');
				}else if ($.browser.msie){ //internet explorer
					$(this).bind('selectstart',function(){
						return false;
					});
				}else{ //all other browsers
					$(this).mousedown(function(){
						return false;
					});
				}
			 });
		}
	}, //end disabledTextSelect
	
	/**
	 * Get element within the instance
	 */
	getElement: function(_class){
		return this.find('.' + _class);
	}
});

/**
 * @return selectbox object
 */
function getObject(element){
	switch (element.attr('type')){
		case 'selectbox':
			for(var i=0; i<_selectboxes.length; i++){
				if (_selectboxes[i].instance[0] == $(element)[0]){
					return _selectboxes[i];
					break;
				}
			}	
		break;
		case 'dropdown':
			for(var i=0; i<_dropdowns.length; i++){
				if (_dropdowns[i].instance[0] == $(element)[0]){
					return _dropdowns[i];
					break;
				}
			}
		break;
	}
	return false;
}

/**
 * Toggle list (hide / show)
 * @param element : element to show / hide
 */
function toggleList(element) {
	if (!clientHasMobileDevice()){
		var obj = getObject($(element).parent());
		
		if (obj){	
			var list = obj.instance.getElement(obj.classes.list);
			
			if (open_selected){
				list.hide();
				list.css('visibility', 'hidden');
				open_selected = null;
			}else{
				if ( list.is(":hidden") ) {
					list.show();
					list.css('visibility', 'visible');
				}
			}
			obj.instance.getElement(obj.classes.selected).removeClass('focus');
		}
	}
}

/**
 * Set selected value for selectbox by a keydown event when selectbox has focus
 * @param instance 	: jQuery instance object
 * @param type 		: 'up' or 'down'
 */
function setSelectedByKeyEvent(instance, type){
	if (!clientHasMobileDevice()){
		var target_anchor;
		var anchors = $(instance).find('a');
		
		
		for(var i=0; i<anchors.length; i++){
			if ($.trim($(anchors[i])[0].style.fontWeight.toUpperCase()) == 'BOLD'){
				if (type == 'down') target_anchor = (i == anchors.length-1) ? anchors[0] : anchors[i+1];
				if (type == 'up')	target_anchor = (i == 0) ? anchors[anchors.length-1] : anchors[i-1];
				break;
			}
		}
		
		if (!target_anchor) {
			if (type == 'down') target_anchor = anchors[0];
			if (type == 'up')	target_anchor = anchors[anchors.length-1];
		}
		
		setSelected(target_anchor);
	}
}

/**
 * When selectbox has focus and tab event is fired, set focus to next element
 */
function setNextTabFocus(instance){
	if (!clientHasMobileDevice()){
		if (!$.browser.opera){
			//get form elementA
			var main_element = $(instance);
			while ( $.trim(main_element[0].tagName.toUpperCase()) != 'FORM'  && 
					$.trim(main_element[0].tagName.toUpperCase()) != 'BODY' ) {
					main_element = $(main_element).parent();
			}
			
			//get next element
			var next_element;
			var main_form_elements = main_element.find("input[type='submit']:visible, input[type='button']:visible, input[type='text']:visible, input[type='checkbox']:visible, input[type='radio']:visible, textarea:visible, div[type='selectbox']:visible, , div[type='dropdown']:visible, select:visible");
			for (var i=0; i<main_form_elements.length; i++){
				if ($(instance)[0] == main_form_elements[i]){
					next_element = (i <= main_form_elements.length-2) ? $(main_form_elements[i+1]) : $(main_form_elements[0]);
					break;
				}
			}
			
			//set focus on next element and remove focus on current element
			if (next_element){
				next_element.focus();
				$(instance).getElement(getObject($(instance)).classes.selected).removeClass('focus');
			}
		}
	}
}

/**
 * Set selectbox value and text
 */
function setSelected(anchorElement){
	if (!clientHasMobileDevice()){
		var obj = getObject( $(anchorElement).parent().parent() );
		var selectElement = obj.selectElement;
		selectElement[0].value = ( $(anchorElement).attr('class').replace("selectbox_value_", "") );
		obj.instance.truncateText( $(anchorElement).text() );	
		
		//remove all bold elements
		$.each($(anchorElement).parent().children('a'), function(index, _anchor){
			if ( typeof( $(_anchor).attr('style') ) != 'undefined'){
				var style_properties = $(_anchor).attr('style').split(';');
				
				var new_style_properties = "";
				$.each(style_properties, function(index, property){
					if ($.trim(property) != ""){
						var property_name = property.split(':')[0];
						var property_value = property.split(':')[1];

						if (property_name.toUpperCase().replace(" ", "") != "FONT-WEIGHT")
							new_style_properties += property_name + ":" + property_value + ";";
					}
				});
				
				$(_anchor).removeAttr('style');
				$(_anchor).attr('style', new_style_properties);
			}
		});
		
		obj.instance.getElement(obj.classes.list).hide();
		obj.instance.getElement(obj.classes.text).disableTextSelect();
		$(anchorElement)[0].style.fontWeight = 'bold';
		if (arguments[1] != 'no_submit'){
			if (selectElement[0].onchange) selectElement[0].onchange();
		}
	}
}

/**
* Collapse all list when mouse is up
*/
$(document).mouseup(function(){
	if (!clientHasMobileDevice()){
		if (list_click && jQuery.browser.mozilla){
			list_click = false;
		}else{
			//selectboxes
			$.each(_selectboxes, function(i, selectbox){
				selectbox.instance.getElement(selectbox.classes.list).hide();
				selectbox.instance.getElement(selectbox.classes.list).css('visibility', 'hidden');
			});
			
			//dropdowns
			$.each(_dropdowns, function(i, dropdown){
				dropdown.instance.getElement(dropdown.classes.list).hide();
				dropdown.instance.getElement(dropdown.classes.list).css('visibility', 'hidden');
			});
		}
		
		//remove focus selectboxes
		$.each(_selectboxes, function(i, selectbox){
			selectbox.instance.getElement(selectbox.classes.selected).removeClass('focus');
		});
	}
});

/**
 * indexOf fix for IE
 */
if(!Array.indexOf) {	
	Array.prototype.indexOf = function(arr) {
		for(var i = 0; i < this.length; i++) if(this[i] == arr) return i;
		return -1;
	}
}

/**
 * Class Selectbox (to generate all javascript selectboxes by class name)
 * @param obj	: Object {indentifier_class, classes, max_list_height[optional]}
 */
function Selectbox(obj){
	if (!clientHasMobileDevice()){
		this.classes = obj.classes;
		$.each( $(document).find("select." + obj.identifier_class), function(i, selectbox){
			$(selectbox).selectbox(obj.classes);
			if (obj.max_list_height) {
				if (isChrome){
					$(document).ready(function(){
						$(selectbox).scrollable(obj.max_list_height);
					});
				}else{
					$(selectbox).scrollable(obj.max_list_height);
				}
			}
		});
	}
}

/**
 * Class Dropdown (to generate all javascrip dropdowns by class name)
 * @param obj	: Object {identifier_class, classes, max_list_height[optional]}
 */
function Dropdown(obj){
	if (!clientHasMobileDevice()){
		this.classes = obj.classes;
		$.each( $(document).find("div." + obj.identifier_class), function(i, dropdown){
			$(dropdown).dropdown(obj.classes);
			if (obj.max_list_height) $(dropdown).scrollable( obj.max_list_height );
		});
	}
}

/**
 * Get inline style properties 
 * @return Array [{styleName, styleValue}]
 */
function getInline(selectbox){
	var inline = [];
	if ($(selectbox).attr('style')){
		$.each( $(selectbox).attr('style').split(';'), function(i, property){
			if ($.trim(property) != ""){
				inline.push({
					styleName	: $.trim( property.split(':')[0].toLowerCase() ), 
					styleValue	: $.trim( property.split(':')[1].toLowerCase() )
				});
			}
		});
	}
	return inline;
}

/**
 * Get Classes
 * @return Array [class]
 */
function getClasses(selectbox){
	var classes = new Array();
	$.each($(selectbox).attr('class').split(' '), function(i, _class){
		if ( $.trim(_class) != '') classes.push(_class);
	});
	return classes;
}

/**
 * Get value of the device mobile type of client
 * Return Boolean
 */
function clientHasMobileDevice(){
	return (navigator.userAgent.indexOf('Mobile') != -1) ? true : false;
}
