jQuery( function ($) {

	var StyleSelect = function (elem, tpl, submitOnSelect) {
		if (!StyleSelect.initialized) {
			StyleSelect.initialize();
		}
	
		this.elem = $(elem);
		this.tpl = tpl;
		this.submitOnSelect = submitOnSelect;
		this.parentForm = this.elem.parents('form:first');
		
		this.style().place().bind();
	};
	
	StyleSelect.openSelect = null;
	StyleSelect.initialized = false;
	StyleSelect.delay;
	
	StyleSelect.initialize = function () {
		StyleSelect.initialized = true;
		
		var close = function (e) {
			if (!StyleSelect.openSelect || e.type === 'keydown' && e.keyCode !== 27 || StyleSelect.delay) {
				return;
			}
			
			StyleSelect.delay = true;			
			setTimeout(function () {
				StyleSelect.delay = null;
			}, 100);
			
			var onHeader = e.target !== StyleSelect.openSelect.header[0] && e.target !== StyleSelect.openSelect.elem[0],
				isContained = $.contains(StyleSelect.openSelect.render[0], e.target);
				
			if (!isContained && onHeader || e.type === 'keydown' && e.keyCode === 27) {
				StyleSelect.openSelect.close();
				StyleSelect.openSelect = null;
			}
		}
		
		$( document.body ).bind('click', close);
		$( window ).bind('keydown', close);
	}
	
	StyleSelect.prototype.style = function () {
		var options = this.elem.children(),
			selected = options.filter(':selected'),
			optionsHtml = [],
			i, self, width;
			
		this.realOptions = options;
		
		for (i = 0; i < options.length; i++) {
			self = options.eq(i);

			optionsHtml.push({
				text: self.text(),
				isSelected: self.is(':selected')
			});
		};
				
		this.render = $.tmpl(this.tpl, {
			Selected: selected.text(),
			Options : optionsHtml
		});
		
		this.header = this.render.find('.header');
		this.options = this.render.find('.options');
			
		return this;
	};
	
	StyleSelect.prototype.place = function () {
		this.elem.hide();
		this.render.insertAfter( this.elem );
		
		return this;
	};
	
	StyleSelect.prototype.bind = function () {
		var optionsWrap = $( this.render.find('.options') ),
			self = this;
		
		this.header.bind('click', function (e) {
			var isOpen = self.options.is(':visible');
						
			StyleSelect.openSelect && StyleSelect.openSelect !== self && StyleSelect.openSelect.close();
			
			self[ isOpen ? 'close' : 'open' ]();
			StyleSelect.openSelect = isOpen ? null : self;
		});
		
		this.options.delegate('li', 'click', function (e) {
			var elem = $(this),
				offset = elem.prevAll().length,
				
				newSelect = self.realOptions.eq(offset);

			newSelect.attr('selected', 'selected');
			self.header.text( newSelect.text() );
			
			self.close();
			
			if (self.submitOnSelect) {
				self.parentForm.submit();
			}
		});
		
		return this;
	};
	
	StyleSelect.prototype.open = function () {
		this.options.show();
		this.render.addClass('is-open');

		return this;
	};

	StyleSelect.prototype.close = function () {
		this.options.hide();
		this.render.removeClass('is-open');

		return this;
	};
	
	
	$.fn.styleSelect = function (tpl, submitOnSelect) {
		return this.each( function () {
			return new StyleSelect(this, tpl, submitOnSelect);
		});
	}
	
});
