(function ($) {
	
    $.select = function (el, options) {
        var self = this,
			node = $(el),
			text = node.find('span span'),
			select = node.find('select');

		node.data('select', this);
		

		/**
		 *	Initializing
		 */
		this.initialized = 1;
        this.init = function () {
            this.options = $.extend({}, $.select.defaultOptions, options);
			
			text.html(select.find('option[value="' + select.val() + '"]').html());
			
			if (this.options.enable) select.attr('disabled', false);
			
			if (this.options.disable) select.attr('disabled', true);
			
			if (select.attr('disabled')) {
				node.unbind('click.selector').find('a').addClass('disabled');
			} else {
				node.unbind('click.selector').bind('click.selector', this._click).find('a').removeClass('disabled');
			}
        };
		
		this._click = function () {
			self.initialized = (self.initialized ? 0 : 1);
			window.select = 1;
			var target = $(this);
			
			if (self.initialized) {
				self.hide();
			} else {
				self.drop = $('<div class="selector-drop"><div class="c"><div class="c-2"><div class="c-3"><ul></ul></div></div></div><div class="b"><div><div></div></div></div>');
				
				var top = $('a', target).offset().top + 20,
					left = $('a', target).offset().left,
					width = $('a', target).width(),
					list = self.drop.find('ul'),
					value = select.val(),
					html = '',
					index = 0;
				
				list.html('');
				select.find('> *').each(function (i) {
					if ($(this).is('optgroup')) {
						html += '<li class="' + (index == 0 ? ' first' : '') + ' group">' + $(this).attr('label') + '</li>';
						$('option', $(this)).each(function () {
							html += '<li class="' + ($(this).val() == value ? ' selected' : '') + ' grouped"><a rel="' + $(this).val() + '">' + $(this).text() + '</a></li>';
						});
					} else if ($(this).val()) {
						html += '<li class="' + (index == 0 ? ' first' : '') + ($(this).val() == value ? ' selected' : '') + '"><a rel="' + $(this).val() + '">' + $(this).text() + '</a></li>';
					}
					index++;
				});
				list.html(html);
				
				list.find('li a').click(self._change).parent().mouseenter(self._enter).mouseleave(self._leave);
				
				self.drop.appendTo('body').css({left: left, top: top, width: width});
				
				self.id = 'selector-' + Math.random();
				node.attr('id', self.id).css({position: 'relative', 'z-index': 50});
			
				$(document).bind('click.' + self.id, self._blur);
				
				$(window).bind('resize.' + self.id, self.hide);
				
				if ($('.selected', list).size()) {
					$(document).bind('keydown.' + self.id, self._key);
					var position = list.find('.selected').position().top;
					list.scrollTop(position);
				}
			}
		};
		
		this._enter = function () {
			$(this).addClass('hover');
		};
		
		this._leave = function () {
			$(this).removeClass('hover');
		};
		
		this._change = function (e) {
			var target = $(this),
				value = target.attr('rel'),
				name = target.text();
			
			text.text(name);
			select.val(value).trigger('change');
			self.hide();
			
			e.preventDefault();
		};
		
		this._blur = function (e) {
			var target = $(e.target);
			if (!target.parents('.selector-drop').size() && self.drop.data('blur') && !target.is('.selector')) self.hide();
			self.drop.data('blur', 1);
		};
		
		this._key = function (e) {
            var key = e.keyCode,
				list = self.drop.find('ul'),
				hover = list.find('.hover'),
				letter = String.fromCharCode(key),
    			LETTERSrus = {
			        'À': 'Ё',
			        'Q': 'Й',
			        'W': 'Ц',
			        'E': 'У',
			        'R': 'К',
			        'T': 'Е',
			        'Y': 'Н',
			        'U': 'Г',
			        'I': 'Ш',
			        'O': 'Щ',
			        'P': 'З',
			        'Û': 'Х',
			        'Ý': 'Ъ',
			        'A': 'Ф',
			        'S': 'Ы',
			        'D': 'В',
			        'F': 'А',
			        'G': 'П',
			        'H': 'Р',
			        'J': 'О',
			        'K': 'Л',
			        'L': 'Д',
			        ';': 'Ж',
			        'Þ': 'Э',
			        'Z': 'Я',
			        'X': 'Ч',
			        'C': 'С',
			        'V': 'М',
			        'B': 'И',
			        'N': 'Т',
			        'M': 'Ь',
			        '¼': 'Б',
			        '¾': 'Ю'
			    },
				scrollTo = function (hover) {
	                pos = hover.position().top + list.scrollTop();
					list.scrollTop(pos);
				};

			$('li', list).filter(function () {
				if (!$(this).hasClass('group')) $(this).addClass('sel');
			});

            if (key == 38) {
                if (hover.size() && hover.prevAll('.sel').eq(0).size()) {
                    hover = hover.removeClass('hover').prevAll('.sel').eq(0).addClass('hover');
                } else {
					hover.removeClass('hover');
                    hover = list.find('li').eq(-1).addClass('hover');
                }
				scrollTo(hover);
            }
            if (key == 40) {
                if (hover.size() && hover.nextAll('.sel').eq(0).size()) {
                    hover = hover.removeClass('hover').nextAll('.sel').eq(0).addClass('hover');
                } else {
					hover.removeClass('hover');
                    hover = list.find('li').eq(0).addClass('hover');
                }
				scrollTo(hover);
            }

            $('li', list).removeClass('sel');
            $('li a', list).each(function () {
                var first = $(this).html().substr(0, 1);
                if (first == letter || first == LETTERSrus[letter]) $(this).parent().addClass('sel');
            });
			
            var selected = list.find('.sel');
            if (selected.size()) {
                if (hover.size() && hover.hasClass('sel') && hover.nextAll('.sel').eq(0).size()) {
                    hover = hover.removeClass('hover').nextAll('.sel').eq(0).addClass('hover');
                } else {
                    hover.removeClass('hover');
                    hover = selected.eq(0).addClass('hover');
                }
				scrollTo(hover);
            }
			
            if (key == 13) $('a', hover).trigger('click');
			if (key == 27) self.hide();
			
			e.preventDefault();
		};
		
		this.hide = function () {
			self.initialized = 1;
			self.drop.data('blur', 0);
			self.drop.remove();
			node.css({position: '', 'z-index': ''});
			$(document)
				.unbind('click.' + self.id)
				.unbind('keydown.' + self.id);
			$(window).unbind('resize.' + self.id);
		};

        this.init();
    };

    $.select.defaultOptions = {
		disabled: false
    };

    $.fn.select = function (options) {
        return this.each(function () {
            (new $.select(this, options));
        });
    };

})(jQuery);
