jQuery.fn.dropdown = function(config) {
	if (!String.prototype.getFirstLetter) {
		String.prototype.getFirstLetter = function() {
			return (this.length>0)?this[0]:'';
		}
	};
	
	var c = {};
	$.extend(c, {
		alphabetAlign:'left',
		alphabetItemWidth:19,
		defaultText:'All',
		renderOptionCallback:function(option, container) {
			var li = $('<li>' + option.text + '</li>').wrapInner('<a href="#' + option.text + '"></a>').appendTo(container);
			if (option.className != '') li.addClass(option.className);
			if (option.selected) li.addClass('selected');
			$('a', li).get(0).linkedOption = option;
		}
	}, config);
	
	var _getAlphabetFromList = function(list) {
		if (!(list instanceof Array)) return false;
		var l = list.length, result = [], isNumbersInAlphabet = false;
		for (var i=0;i<l;i++) {
			firstLetter = list[i].getFirstLetter();
			if (firstLetter != '' && $.inArray(firstLetter, result) < 0) {
				if (!isNumbersInAlphabet && !isNaN(parseInt(firstLetter))) {
					isNumbersInAlphabet = true;
				}
				else {
					result.push(firstLetter);
				}
			}
		}
		result = result.sort();
		if (isNumbersInAlphabet) {
			result.push('0-9');
		}
		return result;
	};
	
	var _renderItems = function(selectOptions, container) {
		var optionsCount = selectOptions.length, selectBox = selectOptions[0].parentNode;
		if (optionsCount>0 && selectBox.selectedIndex > 0 && $.inArray(selectBox.children[selectBox.selectedIndex], selectOptions)) {
			selectBox.children[selectBox.selectedIndex].selected = true;
		}
		container.empty();
		for (var i=0;i<optionsCount;i++) {
			c.renderOptionCallback(selectOptions[i], container);
		}
	};
	
	var _renderAlphabet = function(alphabet, container) {
		container.empty();
		for (var i=0; i<alphabet.length; i++) {
			$('<li>' + alphabet[i] + '</li>').wrapInner('<a href="#' + alphabet[i] + '"></a>').appendTo(container);
		}
	};
	
	var _hide = function(container) {
		container.animate({height:0}, {duration:200, complete: function() {
			$(this).css({height:'auto', visibility:'hidden'}).removeClass('dd-visible').hide();
		}});
	};
	
	return this.each(function() {
		if (this.tagName.toLowerCase() != 'select') return false;
		var optionsCount = this.length, options = [], alphabet = [], 
			selectedIndex = this.selectedIndex, firstLetter = '', jThis = $(this);
		for (var i=0;i<optionsCount;i++) {
			options.push(this.options[i]);
			alphabet.push(this.options[i].text);
		}
		alphabet = _getAlphabetFromList(alphabet);
		
		jThis.css({
			position:'absolute',
			top:'-10000px'
		});
		
		var thisClass = this.className;
		
		var selectBoxContainer = $('<div class="dd-select ' + thisClass + '"></div>').addClass('dropdown'), 
			selectBoxDropDownContainer = $('<div class="dd-dropdown"><span><a href="#all">' + ((typeof c.defaultText == 'function')?c.defaultText.call(this):c.defaultText) + '</a></span></div>').hide(),
			selectBoxAlphabet = $('<ul class="dd-alphabet"></ul>'),
			closeButton = $('<span class="dd-close">&nbsp;</span>'),
			resetButton = $('<span class="dd-reset">&nbsp;</span>'),
			selectBoxDropDown = $('<ul class="dd-items"></ul>');
		selectBoxDropDownContainer.append(selectBoxAlphabet);
		selectBoxDropDownContainer.append(closeButton);
		selectBoxDropDownContainer.append(selectBoxDropDown);
		
		selectBoxContainer.append(resetButton);
		
		_renderItems(options, selectBoxDropDown);
		_renderAlphabet(alphabet, selectBoxAlphabet);
		
		resetButton.click(function(e) {
			if (selectBoxContainer.hasClass('selected')) {
				jThis.trigger('dropdown-reset');
				e.stopImmediatePropagation();
				return false;
			}
		});
		
		selectBoxContainer.click(function(e) {
			var _this = $(this), o = _this.offset(), h = selectBoxDropDownContainer.height(), css = {};
			
			if (selectBoxDropDownContainer.hasClass('dd-visible')) {
				_hide(selectBoxDropDownContainer);
				selectBoxContainer.removeClass('opened');
				jThis.trigger('dropdown-close');
			}
			else {
				selectBoxContainer.addClass('opened');
				$.extend(css, o, {
					top:o.top + _this.outerHeight() + 1,
					left:(c.left)?c.left:o.left + _this.outerWidth() - selectBoxDropDownContainer.width(),
					height:0
				});
				selectBoxDropDownContainer.css(css).show().css('visibility', 'visible').animate({height:h}, {duration:200, complete: function() {
					$(this).addClass('dd-visible').css('height', 'auto');
					jThis.trigger('dropdown-open');
				}});
			}
		});
		
		$(document).click(function(e){
			if (selectBoxDropDown.get(0) == e.target || selectBoxContainer.get(0) == e.target || selectBoxAlphabet.get(0) == e.target) return false;
			if (selectBoxDropDownContainer.hasClass('dd-visible')) {
				_hide(selectBoxDropDownContainer);
				selectBoxContainer.removeClass('opened');
				jThis.trigger('dropdown-close');
			}
		});
		
		closeButton.click(function() {
			if (selectBoxDropDownContainer.hasClass('dd-visible')) {
				_hide(selectBoxDropDownContainer);
				selectBoxContainer.removeClass('opened');
				jThis.trigger('dropdown-close');
			}
			return false;
		});
		
		jThis.after(selectBoxContainer);
		$(document.body).append(selectBoxDropDownContainer);
		
		$.swap(selectBoxDropDownContainer.get(0), {visibility:'hidden',display:'block'}, function() {
			var alphabetItems = $('a', selectBoxAlphabet), l = 0, _paddingLeft = _paddingRight = 0,
				_defaultAlphabetItemWidth = _alphabetItemWidth = c.alphabetItemWidth;
			switch (c.alphabetAlign) {
				case 'center':
					_paddingLeft = _paddingRight = (selectBoxAlphabet.width() - _alphabetItemWidth * alphabetItems.length) / 2;
					break;
				case 'justify':
					_alphabetItemWidth = Math.floor(selectBoxAlphabet.width() / alphabetItems.length);
					break;
				case 'right':
					_paddingLeft = selectBoxAlphabet.width() - _alphabetItemWidth * alphabetItems.length;
					break;
				case 'left':
				default:
					break;
			}
			if (_paddingLeft > 0 || _paddingRight > 0) {
				var css = {width:'auto'};
				if (_paddingLeft > 0) css['padding-left'] = _paddingLeft + 'px';
				if (_paddingRight > 0) css['padding-right'] = _paddingRight + 'px';
				selectBoxAlphabet.css(css);
			}
			alphabetItems
				.width(_alphabetItemWidth)
				.click(function(e) {
						var parentLi = $(this).parent(), letterIndex = parentLi.index(), letter = $(this).text(), _filteredOptions = [];
						if (parentLi.hasClass('selected')) {
							parentLi.removeClass('selected');
							_filteredOptions = options;
							letterIndex = -1;
							letter = '';
						}
						else {
							$('li.selected', selectBoxAlphabet).removeClass('selected');
							parentLi.addClass('selected');
							for (var i=0; i<optionsCount; i++) {
								if (options[i].text.getFirstLetter() == letter || (letter == '0-9' && !isNaN(parseInt(options[i].text.getFirstLetter())))) {
									_filteredOptions.push(options[i]);
								}
							}
						}
						_renderItems(_filteredOptions, selectBoxDropDown);
						jThis.trigger('dropdown-alphabet-click', [letterIndex, letter]);
						e.stopImmediatePropagation();
						return false;
					});
		});
		
		$('span a', selectBoxDropDownContainer).click(function(e) {
			$('.selected', selectBoxAlphabet).removeClass('selected');
			_renderItems(options, selectBoxDropDown);
			jThis.trigger('dropdown-alphabet-click', [-1, '']);
			e.stopImmediatePropagation();
			return false;
		});
		
		var links = $('a', selectBoxDropDown);
		if (!links.context) links.context = selectBoxDropDown;
		links.live('click', function(e) {
			if (this.linkedOption) {
				jThis.get(0).selectedIndex = this.linkedOption.index;
				$('li.selected', selectBoxDropDown).removeClass('selected');
				$(this).parent().addClass('selected');
				_hide(selectBoxDropDownContainer);
				selectBoxContainer.removeClass('opened').addClass('selected');
				jThis.trigger('change');
			}
			return false;
		});
		
		this.dd_BoxContainer = selectBoxContainer;
		this.dd_DropDown = selectBoxDropDown;
		this.dd_Alphabet = selectBoxAlphabet;
		
		jThis.trigger('dropdown-render');
		
		return jThis;
	});
};