/* 
	>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
		CLASS: CustomSelect
	>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
*/
(function($){
	$.CustomSelect = function(sb,options){
		//if (!container) return;
		
	/*****Initialize*******/	
		sb.wrap('<div class="select-parent"></div>');
		this.container = sb.parents("div.select-parent");
		
		this.select = sb;
		if (!this.select.get(0)) return;
		
		var self = this;
		this.isOpen = this.isFocused = 0;
		
		this.settings = $.extend({
			maxHeight: 150,
			zIndex: 10,
			openZIndex: 50000,
			ignoredValue:false, //Options with ignored value will only be processed by javascript
			functions:'',
			submitFunction: false, //Click or enter on an option will submit the form, which calls the submitFunction if it is defined, opts with ignoredValue will not trigger submit
			openCallback : false,
			closeCallback : false,
			truncateDisplay:false,
			customIndex: 1
		},options);
		
		this.locked = false;
		this.parentForm = this.select.parent('form');
		
	/******Create DropDown*******/
		
		this.wrapper = $('<div id="custom-select_'+this.settings.customIndex+'" class="select-wrapper"></div>');
		this.dropDown = $('<div class="select-dropdown"></div>');
		this.listContainer = $('<div class="select-scroller"></div>');
		this.list = $('<ul class="select-list"></ul>');
		
		this.currentIndex = 0;
		this.opts = this.select.find('option');
		
		this.createList();
		
		var currentItem = this.opts[this.currentIndex].innerHTML;
		var wasTruncated = false;
		
		if (this.settings.truncateDisplay && currentItem.length > this.settings.truncateDisplay){
			currentItem = currentItem.substr(0,this.settings.truncateDisplay) + "...";		
			wasTruncated = "true";		
		}
			
		
		this.display = $('<div class="select-display"><span>'+currentItem+'</span></div>');
		this.displaySpan = this.display.find('span');
		if(wasTruncated) {
			this.displaySpan.addClass("truncated");	
		}
		
		this.listContainer.append(this.list);
		this.dropDown.append(this.listContainer);
		this.wrapper.append(this.display);
		this.wrapper.append(this.dropDown);
		this.container.append(this.wrapper);
		
		this.setScrollPane();

	/******Bind Events ******/
		
		$(document).click(function(e){
			if (self.isOpen){
				var parent = '#custom-select_'+self.settings.customIndex;
				if (!$(e.target).parents(parent).get(0) || e.target.nodeName.toLowerCase() == "p"){ //p is to fix the dropdown from not closing on the solutions home page
					self.close();
				}
			}
		}).keyup(function(e){
			if (self.isFocused||self.isOpen){
				self.changeValue();
				if (e.keyCode==9 || e.keyCode==13 || e.keyCode == 27){
					if (e.keyCode == 13){
						self.clickOption();
					}
					self.close();
				}
			}
		});
		
		this.display.click(function(){
			self.select.focus();
			self.isOpen ? self.close() : self.open();
		}).hover(function(){
			$(this).addClass('hovered');
		},function(){
			$(this).removeClass('hovered');
		});
		
		$('#custom-select_'+this.settings.customIndex+' li').live('click',function(e){
			e.preventDefault();
			self.clickOption(e.target);
			self.select.focus();
		});
		
		this.list.find('li').hover(function(e){
			$(this).addClass('hovered');
		},function(e){
			$(this).removeClass('hovered');
		});
		
		this.select.focus(function(e){
			self.isFocused = true;
		}).blur(function(e){
			self.isFocused = false;
		});
	}

	/*******CustomSelect methods ******/
	
		$.CustomSelect.prototype.createList = function(){
			var self = this,
				liString = '';
			
			this.opts.each(function(i){
				var $this = $(this);
				if (this.selected) { self.currentIndex = i; }
				
				var optgroup = $this.parents('optgroup');
				
				if (optgroup.length > 0 && $this.prev().length == 0){
					liString += '<li class="optGroup">'+optgroup.attr('label')+'</li>';				
				}
				
				liString += '<li class="select-opt_' + i +'">'+this.innerHTML+'</li>';			
			});
			
			this.list.html(liString);
			
			this.listItems = this.list.find('li');
			
			this.listItems.eq(0).addClass('first');
			this.listItems.eq(this.listItems.length - 1).addClass('last');
			
			this.selectables = [];
			
			this.listItems.each(function(){
				if (this.className.indexOf('optGroup') == -1){
					self.selectables.push($(this));
				}
			});
			
			this.selectables[this.currentIndex].addClass('selected');
		}
	
		$.CustomSelect.prototype.setScrollPane = function(){
			if (this.listContainer.height()>this.settings.maxHeight){
				this.listContainer.css({height:this.settings.maxHeight});
				this.scrollPane = this.listContainer.jScrollPane({});
			} else if (this.scrollPane){
				this.listContainer.css({height:'auto'}).jScrollPane();
			}
		}
	
		$.CustomSelect.prototype.matchToDisplay = function(){
			var self = this;
			if (this.opts.eq((this.select.get(0).selectedIndex)).html() != this.displaySpan.html()){
				this.opts.each(function(index){
					if (this.innerHTML == self.displaySpan.html()){
						self.select.get(0).selectedIndex = index;
					}
				});
			} 
		}
		
		$.CustomSelect.prototype.matchToIndex = function(){
			this.displaySpan.html(this.opts.eq((this.select.get(0).selectedIndex)).html());
		}
		
		//call after an option has been removed/added/edited
		$.CustomSelect.prototype.updateList = function(){
			this.locked = true;
			this.opts = this.select.find('option');
			this.createList();
			this.setScrollPane();
			this.locked = false;
		}
	
		$.CustomSelect.prototype.open = function(){
			if (this.isOpen || this.locked) return;
			this.container.addClass('active').css({zIndex:1000});
			if (this.scrollPane) {
				this.scrollPane = this.listContainer.jScrollPane({});
				this.scrollPane[0].scrollTo('li.selected');
				
				if (!this.settings.openAtTop){
					this.scrollPane[0].scrollTo('li.selected');
				}
				else {
					this.scrollPane[0].scrollTo('li:first');
				}
			}
			
			this.isOpen = true;
			
			if (typeof this.settings.openCallback == 'function'){
				this.settings.openCallback();
			}
		}

		$.CustomSelect.prototype.close = function(){
			if (!this.isOpen) {
				this.locked = false;
				return;
			}
			
			this.container.removeClass('active').css({zIndex:100});
			this.isOpen = this.locked = false;

			if (typeof this.settings.closeCallback == 'function'){
				this.settings.closeCallback();
			}
		}

		$.CustomSelect.prototype.clickOption = function(tar){
			this.locked = true;
			
			if (tar && tar.className.indexOf('optGroup') != -1) return; //Always ignore optgroup clicks
			
			var select = this.select.get(0);
			var index;
			
			if (tar){
				index = parseInt(tar.className.split('_')[1]);
			} else {
				index = select.selectedIndex;
			}

			var value = select[index].value;
			
			if (this.settings.ignoredValue&&value.search(this.settings.ignoredValue) != -1){	
				
				if (typeof(this.settings.functions[value.replace(this.settings.ignoredValue + " ", "")])=='function'){
					
					this.settings.functions[value.replace(this.settings.ignoredValue + " ", "")]();
				
				}
				
			} else {
				select.selectedIndex = index;
				
				if (typeof(this.settings.submitFunction)=='function'){
					this.settings.submitFunction();
				}
				
				this.changeValue();
			}
			
			this.close();
		}

		$.CustomSelect.prototype.changeValue = function(){
			var index = this.select.get(0).selectedIndex;
			if (index==this.currentIndex) return;
			
			this.selectables[this.currentIndex].removeClass('selected'); //remove selected class from old item
			
			var newItem = this.selectables[index].addClass('selected');
			
			if (this.itemVisible(newItem)==false&&this.scrollPane){
				this.scrollPane[0].scrollTo('li.selected');
			}
			
			var truncated = newItem.html();
			
			this.displaySpan.removeClass("truncated");
			
			if (this.settings.truncateDisplay && newItem.html().length > this.settings.truncateDisplay){
				truncated = newItem.html().substr(0,this.settings.truncateDisplay) + "...";		
				this.displaySpan.addClass("truncated");
			} 
			
			this.displaySpan.html(truncated);
			this.display.data("Value",this.select.val());
			
			
			this.currentIndex = index;
		}

		//returns bool
		$.CustomSelect.prototype.itemVisible = function(item){
			if (!this.isOpen) return true;
			var pos = item.offset().top;
			var top = this.dropDown.offset().top;
			if (pos>top && pos+item.height()<top+this.dropDown.height()){
				return true;
			}
			return false;
		}
		
		$.CustomSelect.prototype.jumpToIndex = function(index){
			if (index<this.opts.length){
			
				this.select.get(0).selectedIndex = index;
				this.changeValue();
			
			}
		}
		
		$.CustomSelect.prototype.jumpToValue = function(value){
			var index = -1;
			
			this.opts.each(function(i){
				if (this.value==value){
					index = i;
					return false;
				}
			});
			
			if (index!=-1){
				this.select.get(0).selectedIndex = index;
				this.changeValue();
			}
			
			return index;
		}
		
		$.CustomSelect.prototype.editOptionText = function(index,text){
			this.opts.eq(index).html(text);
			this.updateList();
		}
		
})(jQuery);

