var SelectCustomList = [];
/* Remove references */
$(window).unload(function () {
	for(var i in SelectCustomList)
		if (SelectCustomList.hasOwnProperty(i))
			SelectCustomList[i] = null;
	
	SelectCustomList = null;
});

/**
 * Select element replacement
 * @param {HTMLElement} element
 * @param {Object} config
 */
function SelectCustom (element, config) {
	if (!config) config = {};
	if (!element) return null;

	this.config = $.extend({
		onchange: null,
		onblur: null,
		select_classname: 'select',
		dropdown_classname: 'select-dropdown',
		show_empty_value: false,					//Show options which value is ''
		show_dropdown_if_one_option: true,			//Drop down can be triggered also if there is only one option
		max_dropdown_height: 250,
		listTypeHref: false
	}, config);
	
	this.values = {};
	this.element = $(element);
	this.unique_id = Math.random();
	
	SelectCustomList[this.unique_id] = this;
	
	this.init();
};
/* Unique id */
SelectCustom.prototype.unique_id = null;
/* Disabled */
SelectCustom.prototype.disabled = false;
/* Configuration */
SelectCustom.prototype.config = {};
/* SELECT element */
SelectCustom.prototype.element = null;
/* Dropdown elements (popup) */
SelectCustom.prototype.dropdown = null;
/* Dropdown state */
SelectCustom.prototype.dropdownState = 0;	//1 - open, 0 - closed
/* Hover state */
SelectCustom.prototype.hoverState = 0;		//1 - hovered, 0 - not hovered
/* Custom select root element */
SelectCustom.prototype.custom = null;
/* Options for SELECT, values are references to the OPTION elements*/
SelectCustom.prototype.values = {};
/* Currently select value */
SelectCustom.prototype.value = "";
/**
 * Select value 
 * @param {String} value
 */
SelectCustom.prototype.selectItem = function (value, fireOnChange) {
	if (fireOnChange === undefined || fireOnChange === null) fireOnChange = true;
	
	if (this.value != value)
	{
		this.values[this.value].selected = false;
		this.values[value].selected = true;
		this.value = value;

		$('a span', this.custom).eq(0).html(this.values[this.value].innerHTML);
		if (this.config.onchange)
		{
			this.config.onchange.call(this.element);
		}
		
		/* Removed due to the bug in IE6
		if (this.values[value].click)
		{
			this.values[value].click();
		}
		*/
		if (fireOnChange)
			this.element.change();
	}
	this.closeDropdown();
};
/**
 * Open dropdown
 */
SelectCustom.prototype.openDropdown = function () {
	if (this.disabled) return;
	
	for(var i in SelectCustomList)
		if (SelectCustomList.hasOwnProperty(i) && i != this.unique_id)
			SelectCustomList[i].closeDropdown();
	
	var w = this.custom.width() + parseInt(this.custom.css('paddingLeft')) + parseInt(this.custom.css('paddingRight'));
	this.dropdown.css({width: w + 'px'});
	this.dropdown.slideDown('fast');
	this.dropdownState = 1;
};
/**
 * Close dropdown
 */
SelectCustom.prototype.closeDropdown = function () {
	var self = this;
	this.dropdown.slideUp('fast', function () {
		self.dropdownState = 0;
		if (!self.hoverState)
		{
			$(this).parent().removeClass('hover');
		}
	});
	
	if (this.config.onblur)
		this.config.onblur.call(this.element);
};
SelectCustom.prototype.disable = function () {
	this.disabled = true;
	this.element[0].disabled = true;
	this.custom.addClass('disabled');
	
	return this;
};
SelectCustom.prototype.enable = function () {
	this.disabled = false;
	this.element[0].disabled = false;
	this.custom.removeClass('disabled');
	
	return this;
};
/**
 * Class constructor
 */
SelectCustom.prototype.init = function () {
	var list_options = $('option', this.element);
	var html_options = '';
	var self = this;

	for(var i=0,j=list_options.length; i<j; i++)
	{
		var item_val = list_options[i].value;
		if (item_val == '') item_val = '_';
		
		this.values[item_val] = list_options[i];
		if (list_options[i].selected)
		{
			this.value = item_val;
		}
		if (item_val != '_' || this.config.show_empty_value)
		{
			if (this.config.listTypeHref)
				html_options += '<li><a href="' + $(list_options[i]).attr('href') + '" data="' + item_val + '">' + list_options[i].innerHTML + '</a></li>';
			else
				html_options += '<li><a href="#" data="' + item_val + '">' + list_options[i].innerHTML + '</a></li>';
		}
	}
	
	var html_drop_down = '<div class="' + this.config.dropdown_classname + '"><ul>' + html_options + '</ul><span class="l"><!-- --></span><span class="r"><!-- --></span></div>';
	var html_select = '<div class="' + this.config.select_classname + '"><a href="#"><span>' + (this.values[this.value] ? this.values[this.value].innerHTML : '') + '</span></a>' + html_drop_down + '</div>';
	
	this.custom = $(html_select);
	this.custom.insertAfter(this.element);
	this.element.addClass('off-screen');
	this.dropdown = $('div.' + this.config.dropdown_classname, this.custom);
	
	/* If original select value changes, then show changes */
	this.element.change(function () {
		self.selectItem($(this).val(), false);
	});
	
	/* Scrollable drop down if height exceeds the limit */
	if (this.dropdown.height() > this.config.max_dropdown_height)
	{
		this.dropdown.addClass('scrollable');
	}
	
	/* Click on dropdown item */
	$('a', this.dropdown).click(function () {
		if (this.disabled) return;
		self.selectItem(this.getAttribute('data'));
	});
	
	/* Click on select element */
	if (list_options.length > 1 || this.config.show_dropdown_if_one_option)
	{
		$('a', this.custom).eq(0).click(function () {
			if (this.disabled) return;
			
			if (self.dropdownState)
			{
				self.closeDropdown();	
			}else{
				self.openDropdown();
			}
		});
	
	
		/* Click inside select - used to stop event bubbling */
		this.custom.click(function () { return false; });
		if (this.config.listTypeHref)
		{
			$('a', this.custom).click(function (e) {
				stopEventPropagation(e);
				return true;
			});
		}
		
		/* Click outside select element */
		$(document).click(function () {
			if (self.dropdownState)
			{
				self.closeDropdown();
			}
		});
	}
	else
	{
		this.custom.addClass('empty');
	}
	
	/* Hover */
	this.custom.hover(function () {
		$(this).addClass('hover');
		self.hoverState = 1;
	}, function () {
		self.hoverState = 0;
		if (!self.dropdownState)
			$(this).removeClass('hover');
	});
	
	/* Unload, clear object references */
	$(window).unload(function () {
		self.element = null;
		self.dropdown = null;
		self.config.onchange = null;
		self.config = null;		
		
		for (i in self.values)
			self.values[i] = null;
			
		self.values = null;
	});
};