/**
 * NOTE: To use this file you need jScrollPane.js, jquery.mousewheel.js (these are required for scrollable dropdowns)
 * and jquery.livequery.js (for styling selects that are dynamically added to the page (or hidden to begin with))
 * 
 * It is recommended that you set selects to display: none in your CSS as correct width values are only picked up
 * properly (from the CSS file) when selects are hidden
 * 
 * When creating styled selects we assume that:
 * - The select element has a width applied in the CSS
 * - The majority of CSS for the look and feel of the styled selects will be done in a CSS file based on the classes
 *   we apply to each element
 */

var styledSelects = new Array();

jQuery(document).click(function(event) {
	for (var i = 0; i < styledSelects.length; i++) {
		if (!styledSelects[i].mouseIn && styledSelects[i].open) {
			styledSelects[i].closeSelect();
		}
	}
});

function StyledSelectField(element, index) {

	this.init = function() {
		this.index = index;
		
		this.selectElement = element;

		this.optionElements = this.selectElement.children();
		
		//this.selectElementWidth = this.selectElement.css('width').substr(0, this.selectElement.css('width').length-2);
		this.selectElementWidth = this.selectElement.width();
		
		this.styledSelectOptionFocus = 0;
		
		this.open = false;
		this.mouseIn = false;
		this.optionsMouseIn = false;
		this.textInputTimeout = null;
		
		this.buildStyledSelect();
		this.applyStyles();
		this.addEventHandlers();
		this.addScrollbar();

	}
	
	
	
	this.buildStyledSelect = function() {
		var styledSelectWrapper = jQuery('<div></div>').addClass('selectWrapper');
		var styledSelectHolder = jQuery('<div></div>').addClass('styledSelect');
		var styledSelectSelected = jQuery('<div></div>').addClass('selectedOption');
		var styledSelectOptionHolder = jQuery('<div></div>').addClass('optionHolder').hide();
		var styledSelectArrow = jQuery('<div></div>').addClass('selectArrow');
		var styledSelectBottom = jQuery('<div></div>').addClass('selectFooter').hide();
		var styledSelectBottomRight = jQuery('<div></div>').addClass('selectFooterRight');
		
		this.selectElement.wrap(styledSelectWrapper);
		
		styledSelectHolder.append(styledSelectArrow);
		styledSelectHolder.append(styledSelectSelected);
		styledSelectHolder.append(styledSelectOptionHolder);
		styledSelectBottom.append(styledSelectBottomRight);
		styledSelectHolder.append(styledSelectBottom);
		
		this.styledSelectWrapper = this.selectElement.parent();
		
		this.styledSelectWrapper.append(styledSelectHolder);

		//This is added to stop the window from moving on keydown
		this.styledSelectWrapper.prepend(jQuery("<input/>").attr('name', "Dummy_"+this.selectElement.attr('name')).addClass('dummy').css({'opacity': '0', 'position': 'absolute', 'left': '-9999px'}));
		
		// get all dom elements
		this.styledSelectHolder = jQuery('.styledSelect', this.styledSelectWrapper);
		this.styledSelectSelected = jQuery('.selectedOption', this.styledSelectWrapper);
		this.styledSelectOptionHolder = jQuery('.optionHolder', this.styledSelectWrapper);
		this.styledSelectArrow = jQuery('.selectArrow', this.styledSelectWrapper);
		
		var that = this;

		var styledOptionsHtml = '';

		// build options html
		this.optionElements.each(function(i) {
			var optionElement = jQuery(this);
			var value = optionElement.val();
			var text = optionElement.text();

			styledOptionsHtml += '<div class="option"><span class="optionValue" style="display: none;">' + value + '</span><span class="optionText">' + text + '</span></div>';

			// check if this option is selected
			if (that.selectElement.val() == value) {
				that.styledSelectSelected.html('<span>' + text + '</span>');
			} else if (i == 0) {
				that.styledSelectSelected.html('<span>' + text + '</span>');
			}
		});
		
		this.styledSelectOptionHolder.append(styledOptionsHtml);

		this.styledSelectOptions = this.styledSelectOptionHolder.children();

		if ( this.selectElement.attr('id') == 'CreateWine_Variety' ) {

			var $other = jQuery('<div></div>').attr('class','other');
			
			$other.append(jQuery('<span></span>').text('Other'));

			this.styledSelectHolder.append($other);

		}
	}



	this.applyStyles = function() {
		this.styledSelectWrapper.css({
			'z-index': (7777 - this.index),
			'width': this.selectElementWidth + 'px'
		});

		this.styledSelectHolder.css({
			'width': this.selectElementWidth + 'px'
		});

		this.styledSelectSelected.css({
			'width': parseInt(this.selectElementWidth)-(parseInt(this.styledSelectArrow.css('width').substr(0, this.styledSelectArrow.css('width').length-2))) + 'px'
		});

		this.styledSelectOptionHolder.css({
			'width': parseInt(this.selectElementWidth) + 'px'
		});
	}



	this.addEventHandlers = function() {
		var that = this;
		
		jQuery('input.dummy', this.styledSelectWrapper).focus(function(){
			if (!that.open) {
				that.openSelect();
			}
		});
		
		this.styledSelectHolder.click(function(event) {
			event.stopPropagation();
			if (that.open && !that.optionsMouseIn) {
				that.closeSelect();
			} else {
				that.closeAllSelects();
				jQuery('input.dummy', that.styledSelectWrapper).focus();
			}
	 	});
		
		this.styledSelectHolder.bind('mouseenter', function() {
			that.mouseIn = true;
			that.styledSelectWrapper.addClass('selectHover');
		}).bind('mouseleave', function() {
			that.mouseIn = false;
			that.styledSelectWrapper.removeClass('selectHover');
		});

		this.styledSelectOptionHolder.delegate('.option', 'mouseenter', function () {
			that.setFocus(jQuery(this));
		}).delegate('.option', 'mouseleave', function () {
			jQuery(this).removeClass('optionHover');
		}).delegate('.option', 'click', function (event) {
			event.stopPropagation();
			if (that.open) {
				that.setFocus(jQuery(this));
				that.closeSelect();
				that.setSelected(this);

				if ( that.selectElement.attr('id') == 'CreateWine_Variety' ) {

					jQuery('#Form_CreateWine_OtherVariety').hide();

				}

			}
		});

		if ( this.selectElement.attr('id') == 'CreateWine_Variety' ) {

			jQuery('div.other span', this.styledSelectHolder).hover(function () {
				
				jQuery(this).addClass('otherHover');

			}, function () {

				jQuery(this).removeClass('otherHover');
				
			});

			jQuery('div.other span', this.styledSelectHolder).click(function () {
				
				jQuery('#Form_CreateWine_OtherVariety').show();
				
			});

		}

	}

	this.addScrollbar = function() {
		if (this.styledSelectOptionHolder.outerHeight() > 150) {
			this.styledSelectOptionHolder.css({ height: '150px' });
			this.styledSelectOptionHolder.jScrollPane({
				showArrows: true,
				wheelSpeed: 5,
				scrollbarWidth: 9
			});
			
			jQuery(this.styledSelectHolder).find('div.jScrollPaneContainer').css({ position: 'relative', overflow: 'hidden' }).hide();
			this.styledSelectOptionHolder.css({ paddingRight: '0' });
		}
	}

	this.setFocus = function(element, jumpToSelected) {
		if (this.styledSelectOptions.index(element) != this.styledSelectOptionFocus) {
			this.removeFocus(jQuery(this.styledSelectOptions[this.styledSelectOptionFocus]));
		}
		element.addClass('optionHover');
		
		// if the dropdown has a scrollbar we need to keep the focused element in view
		if (jQuery('div.jScrollPaneTrack2', this.styledSelectHolder).length) {
			var scrollContainerHeight = jQuery('div.jScrollPaneContainer', this.styledSelectHolder).height();
			var optionHeight = element.height();
			var optionOffset = element.position();
			var optionHolderPosition = this.styledSelectOptionHolder.position();
			
			var maxViewablePosition = scrollContainerHeight - optionHeight;
			var currentPosition = optionOffset.top + optionHolderPosition.top;
			if (jumpToSelected) {
				if (currentPosition > maxViewablePosition) {
					jQuery('div.jScrollPaneContainer', this.styledSelectHolder).trigger('mousewheel', -0.75);
					this.setFocus(element, true);
				} else if (currentPosition < 0) {
					jQuery('div.jScrollPaneContainer', this.styledSelectHolder).trigger('mousewheel', 0.75);
					this.setFocus(element, true);
				}
			}
		}
		
		this.styledSelectOptionFocus = this.styledSelectOptions.index(element);
	}



	this.removeFocus = function(element) {
		element.removeClass('optionHover');
	}



	this.attachKeyPressHandler = function() {
		var that = this;
		this.downArrowInterval = null;
		this.upArrowInterval = null;
		if (this.open) {
			this.styledSelectWrapper.bind('keydown', function(event) {
				switch (event.keyCode) {
					case 38:
						// up
						that.setFocusUp();
						if (!jQuery.browser.safari) {
							that.upArrowInterval = setInterval(function() {
								that.setFocusUp();
							}, 150);
						}
						break;
					case 40:
						// down
						that.setFocusDown();
						if (!jQuery.browser.safari) {
							that.downArrowInterval = setInterval(function() {
								that.setFocusDown();
							}, 150);
						}
						break;
					case 13:
						// enter
						event.preventDefault();
						that.setSelected(jQuery(that.styledSelectOptions[that.styledSelectOptionFocus]));
						that.closeSelect();
						break;
					case 9:
						// tab
						that.closeSelect();
						break;
				}
			}).bind('keyup', function(event) {
				switch (event.keyCode) {
					case 38:
						// up
						clearInterval(that.upArrowInterval);
						break;
					case 40:
						// down
						clearInterval(that.downArrowInterval);
						break;
					default:
						that.checkForTextInput(event.keyCode);
						break;
				}
			}).bind('keypress', function(event) {
				switch(event.keyCode) {
					case 9:
						// tab
						that.closeSelect();
						break;
				}
			});
		}
	}



	this.checkForTextInput = function(keyCode) {
		if ((keyCode >= 65 && keyCode <= 90)) {
			clearTimeout(this.textInputTimeout);
			this.textInputTimeout = setTimeout(function() {
				jQuery('input.dummy', this.styledSelectWrapper).val('');
			}, 1000);
			jQuery('input.dummy', this.styledSelectWrapper).trigger('textEntry');
		}
	}



	this.setFocusUp = function() {
		if (this.styledSelectOptionFocus != 0) {
			this.removeFocus(jQuery(this.styledSelectOptions[this.styledSelectOptionFocus]));
			this.setFocus(jQuery(this.styledSelectOptions[this.styledSelectOptionFocus-1]), true);
		}
	}



	this.setFocusDown = function() {
		if ((this.styledSelectOptionFocus + 1) < this.styledSelectOptions.length) {
			this.removeFocus(jQuery(this.styledSelectOptions[this.styledSelectOptionFocus]));
			this.setFocus(jQuery(this.styledSelectOptions[this.styledSelectOptionFocus+1]), true);
		}
	}



	this.detachKeyPressHandler = function() {
		this.styledSelectWrapper.unbind('keydown');
	}



	this.addScrollbarListener = function() {
		var that = this;
		var scrollbar = jQuery('div.jScrollPaneTrack2', this.styledSelectHolder);
		if (jQuery(scrollbar).length) {
			scrollbar.bind('mouseenter', function() {
				that.optionsMouseIn = true;
			}).bind('mouseleave', function() {
				that.optionsMouseIn = false;
			});
		}
	}



	this.removeScrollbarListener = function() {
		var scrollbar = jQuery('div.jScrollPaneTrack2', this.styledSelectHolder);
		if (jQuery(scrollbar).length) {
			scrollbar.unbind('mouseenter').unbind('mouseleave');
		}
	}



	this.closeSelect = function() {
		jQuery('.selectFooter', this.styledSelectHolder).hide();
		this.styledSelectOptionHolder.parent('div.jScrollPaneContainer').hide();
		this.styledSelectWrapper.css({'background-position':'left top'});
		this.styledSelectWrapper.removeClass('selectOpen');
		this.styledSelectOptionHolder.hide();
		this.open = false;
		this.detachKeyPressHandler();
		this.removeScrollbarListener();
		clearInterval(this.upArrowInterval);
		clearInterval(this.downArrowInterval);
	}



	this.openSelect = function() {
		this.styledSelectOptionHolder.show();
		this.styledSelectOptionHolder.parent('div.jScrollPaneContainer').show();
		this.styledSelectWrapper.removeClass('selectHover').addClass('selectOpen');
		jQuery('.selectFooter', this.styledSelectHolder).show();
		this.open = true;
		this.setFocus(jQuery(this.styledSelectOptions[this.styledSelectOptionFocus]));
		this.attachKeyPressHandler();
		this.addScrollbarListener();
	}



	this.closeAllSelects = function() {
		for (var i = 0; i < styledSelects.length; i++) {
			styledSelects[i].closeSelect();
		}
	}



	this.setSelected = function(optionElement) {
		var value = jQuery('.optionValue', optionElement).text();
		var text  = jQuery('.optionText', optionElement).text();
		
		this.selectElement.val(value);
		
		this.styledSelectSelected.find('span').text(text);
		this.selectElement.change();
	}



	this.searchSelect = function() {
		var that = this;
		var searchVal = jQuery('input.dummy', this.styledSelectWrapper).val();
		var results = jQuery("span.optionText", this.styledSelectOptionHolder);
		var regexp = new RegExp("^" + searchVal);
		if (results.length) {
			results.each(function(i) {
				if (regexp.test(jQuery(this).text().toLowerCase())) {
					that.setFocus(jQuery(this).parent(), true);
					return false;
				}
			});
		}
	}



	this.init();
}


if (!(jQuery.browser.msie && jQuery.browser.version == '6.0')) {
	
	jQuery(window).load(function() {
		var zIndex = 0;
		jQuery("select:not(.notready select, #VerifyAge_Day, #VerifyAge_Month, #VerifyAge_Year, #VerifyAge_Country)").livequery(function() {
			var element = jQuery(this);
			styledSelects[zIndex] = new StyledSelectField(element, zIndex);
			zIndex++;
		});
	});

}
