/*
 * 	 styleSelect - apply style to a select box
 *   (http://www.8stream.com/blog/entry/styleselect)
 *
 * 	 Copyright (c) 2010 Siim Sindonen, <siim@8stream.com>
 *   Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 * 
 *   Requires qsalva version: >= 1.3.2
 * 	 Version: 2.0.0 | 15.10.2010
 */
(function(qsalva){

	qsalva.fn.styleSelect = function(options){
		
		var tabindex = 1;
		
		var opts = qsalva.extend({}, qsalva.fn.styleSelect.defaults , options);
		
		//set tabindex		
		qsalva('input,select,textarea,button').each(function() {
			
			var input = qsalva(this);
				
			if (!input.attr('tabindex')){
				
				input.attr('tabindex', tabindex);
				tabindex++;
			}
		});
		
		return this.each(function(){

			mainSelect = qsalva(this);
			var orgSelectbox = mainSelect.attr('name');
			var mainId = orgSelectbox.replace(/\[.*\]/, '');
			
			var styledTabIndex = mainSelect.attr('tabindex');
			
			var date = new Date;
			var selectId = 'selectbox_'+mainId+date.getTime();
			
			//Hidde select box
			mainSelect.hide();
	
			//Main container 
			var mainContainer = qsalva('<div tabindex="'+styledTabIndex+'"></div>')
					.css({position : 'relative', 'z-index' : parseInt(1000 - styledTabIndex)})
					.addClass(opts.styleClass)
					.attr('id', selectId)
					.insertBefore(mainSelect);
					
			qsalva('<div class="styleSelect_item"></div>')
				.appendTo(mainContainer)
				.css({'position' : 'absolute', 'z-index' : '' + parseInt(500 - styledTabIndex) + '', 'top' : opts.optionsTop, 'left' : opts.optionsLeft})
				.hide();
			
			qsalva('<div class="styleSelect_item_start"></div><div class="styleSelect_item_content"></div><div class="styleSelect_item_end">').appendTo(qsalva('#'+selectId + ' .styleSelect_item'));
			
			//Options container
			var subContainer = qsalva('<ul></ul>').appendTo(qsalva('#'+selectId + ' .styleSelect_item_content'));
				
			//Generate options list
			var optionsList = "";
			
			mainSelect.find('option').each(function(){
			
				optionsList += '<li id="'+qsalva(this).val()+'"';
				if(qsalva(this).attr('class')) optionsList += ' class="'+qsalva(this).attr('class')+'" ';
				optionsList += '>';
				optionsList += '<span style="display: block;"';
				if (qsalva(this).attr('selected')) optionsList += ' class="selected" ';
				optionsList += '>';
				optionsList += qsalva(this).text();
				optionsList += '</span>';
				optionsList += '</li>';
				
			});

			subContainer.append(optionsList);
			
			checkSelected(opts.styleClass,opts.optionsWidth);
				
			//Show otions   
			qsalva('#'+selectId).click(function(event){
				
				var eitem = qsalva(event.target);
				
				if (!eitem.parents(".jspVerticalBar").attr('class')){ 
				
					qsalva(this).find('.styleSelect_item').slideToggle(opts.speed, function(){ 
						
						if (qsalva(this).css('display') != 'none' && opts.jScrollPane == 1){
						
							//Use jScrollPane
							qsalva(this).find(".styleSelect_item_content").jScrollPane(opts.jScrollPaneOptions);

							//jScrollPane api
							var api = qsalva('.styleSelect_item_content').data('jsp');
							var container_height = qsalva(".styleSelect_item_content").height();
							var active_item_position = qsalva('.styleSelect_item_content .selected').position();
							
							if (active_item_position.top && api != null && active_item_position.top > container_height){
							
								api.scrollTo(0, parseInt(active_item_position.top - container_height/2));
								
							} else if (active_item_position.top && active_item_position.top < container_height){
							
								api.scrollTo(0, parseInt(active_item_position.top - container_height));
							
							} else if (api != null){
						
								api.scrollTo(0, 0);
							}
						}
					});
				}
			});

			//On click
			qsalva('#'+selectId+' li').click(function(){
				
				doSelection(qsalva(this));
			});
			
			//Keyboard support
			qsalva('#'+selectId).keydown(function(event){
				
				var active = qsalva(this).find('.selected').parent();
				
				//jScrollPane api
				if (opts.jScrollPane == 1){ 
					
					var api = qsalva('.styleSelect_item_content').data('jsp');
					var container_height = qsalva(".styleSelect_item_content").height();
				}
				
				//Next item
				if (event.keyCode == 40 || event.keyCode == 39 ){ 
				
					var next_item = active.next();
					
					if (next_item.index() > 0 && api != null && qsalva('#'+selectId).find('.styleSelect_item').css('display') != 'none'){
					
						var position_next = next_item.position();
					
						if (position_next.top != null && position_next.top > container_height){
							
							api.scrollTo(0, parseInt(position_next.top));
						}
					}
					
					doSelection(next_item); 
				}
				
				//Prev item
				if (event.keyCode == 37 || event.keyCode == 38 ){ 
				
					var prev_item = active.prev();
					var prev_item_index = prev_item.index();
					
					if (api != null && opts.jScrollPane == 1 && qsalva('#'+selectId).find('.styleSelect_item').css('display') != 'none'){
						
						if (prev_item_index > 0){
						
							var position_prev = prev_item.position();
						
							if (position_prev.top-container_height < container_height){
								
								api.scrollTo(0, parseInt(position_prev.top));
							}
							
						} else {
							
							api.scrollTo(0, 0);
						}
					}
				
					doSelection(prev_item); 
				}
				

				if (event.keyCode == 13 || event.keyCode == 0 || event.keyCode == 32){ 
				
					qsalva(this).find('.styleSelect_item').slideToggle(opts.speed,function(){ 
						
						var eitem = qsalva(event.target);
						
						//Use jScrollPane
						if (!eitem.find(".jspContainer").attr('class') && opts.jScrollPane == 1){
						
							qsalva(this).find(".styleSelect_item_content").jScrollPane(opts.jScrollPaneOptions);
						}
					});
					
					return false;
				}
				
				if (event.keyCode == 9){ qsalva(this).find('.styleSelect_item').hide(opts.speed); }
				
			});
			
			//Do selection
			var doSelection = function(item){
				
				item.siblings().find("span").removeClass('selected');
				item.find("span").addClass('selected');
		
				var selectedItem = item.attr('id');

				var realSelector = qsalva('select[name="'+orgSelectbox+'"]');
				realSelector.siblings().selected = false;
				realSelector.find('option[value="'+selectedItem+'"]').attr('selected','selected');
				realSelector.trigger(opts.selectTrigger);
		
				checkSelected(opts.styleClass,opts.optionsWidth);
			}
			
			qsalva('#'+selectId).click(function(event){
			
				event.stopPropagation();
			});
			
			qsalva(document).click(function() {
			
				qsalva('#'+selectId+' .styleSelect_item').hide();
			});
		});	
	}
		
		//Selected items check
		function checkSelected(mainClass,mainWidth){
				
				qsalva('.'+mainClass).each(function(){
				
					var elementList = qsalva(this).find('.styleSelect_item');
					
					qsalva(this).find('span').each(function(){
					
						var spanClass = qsalva(this).attr("class");
						if (spanClass == "passiveSelect" || spanClass == "activeSelect") qsalva(this).remove();
					
					});
					
					var selectedName = qsalva(this).find('.selected');
					
					qsalva('<span></span>').text(selectedName.text())
							.attr('id', selectedName.parent().attr('id'))
							.addClass('passiveSelect')
							.appendTo(qsalva(this));
					
					if (mainWidth === 0){
						qsalva(this).css({'width' :  elementList.width()});
					}
					
				});
				
				qsalva('.'+mainClass+' span').each(function(){
					if (qsalva(this).attr('id')){
						qsalva(this).removeClass();
						qsalva(this).addClass('activeSelect');
					}
				});
		}	
	
		qsalva.fn.styleSelect.defaults = {
		
			optionsTop: '26px',
			optionsLeft: '0px',
			optionsWidth: 0,
			styleClass: 'selectMenu',
			speed: 0,
			selectTrigger: 'change',
			jScrollPane: 0,
			jScrollPaneOptions: ''
		};
		
})(jQuery);

