	function addEvent(element, handler, callback, capture)
	{
		if (window.addEventListener) element.addEventListener(handler, callback, capture);
		else element.attachEvent('on' + handler, callback);
	}
	
	function getOffsetElement(element)
	{
		var top = left = 0;
		while(element)
		{
			top += element.offsetTop;
			left += element.offsetLeft;
			element = element.offsetParent;
		}
		
		var offset = [left, top];
		return offset;
	}
		
	function ObserverComboBox()
	{
		this.current_combo_box = null;
		this.flag_combo_box = false;
		this.dropdown = null;
	}
	
	ObserverComboBox.prototype.initializedDropDown = function()
	{
		var dropdown = document.createElement('div');
			dropdown.className = 'drop_down_combo';
			dropdown.id = 'drop_down_combo';
			dropdown.style.position = 'absolute';
			dropdown.style.zIndex = '99999999';
			dropdown.style.display = 'none';
		document.body.appendChild(dropdown);
		
		ObserverComboBox.dropdown = document.getElementById('drop_down_combo');
		addEvent(document, 'click', ObserverComboBox.hideDropDown, false);
		addEvent(window, 'resize', ObserverComboBox.hideDropDown, false);
	}
	
	ObserverComboBox.prototype.hideDropDown = function()
	{
		if (!ObserverComboBox.current_combo_box || !ObserverComboBox.flag_combo_box)
		{
			ObserverComboBox.flag_combo_box = true;
			return;
		}
		ObserverComboBox.dropdown.style.display = 'none';
		ObserverComboBox.current_combo_box = null;
	}
	
	ObserverComboBox.prototype.showDropDown = function(combo_dom)
	{
		if (combo_dom != this.current_combo_box) this.hideDropDown();

		this.current_combo_box = combo_dom;
		this.dropdown.style.display = (this.dropdown.style.display != 'block') ? 'block' : 'none';
		this.renderOptions();
		this.positionDropDown();
		this.moveSelected(this.dropdown.getElementsByTagName('li')[combo_dom.selectedIndex], combo_dom.selectedIndex);
		
		this.flag_combo_box = false;
	}
	
	ObserverComboBox.prototype.moveSelected = function(sender, index)
	{
		if (sender.className == 'selected') return;
		
		this.dropdown.getElementsByTagName('li')[this.current_combo_box.currentSelected].className = '';
		sender.className = 'selected';
		this.current_combo_box.currentSelected = index;
	}
	
	ObserverComboBox.prototype.setSelectedIndex = function(index)
	{
		if (index == this.current_combo_box.selectedIndex) return;

		this.current_combo_box.selectedIndex = index;
		this.updateTextValue();
		if (this.current_combo_box.onchange_listener) this.current_combo_box.onchange_listener(this.current_combo_box);
	}
	
	ObserverComboBox.prototype.updateTextValue = function()
	{
		var option = this.current_combo_box.options[this.current_combo_box.selectedIndex];
		this.current_combo_box.value = this.current_combo_box.getElementsByTagName('input')[0].value = option.value;
		this.current_combo_box.getElementsByTagName('span')[0].innerHTML = option.text;
	}
	
	ObserverComboBox.prototype.positionDropDown = function()
	{
		var offset = getOffsetElement(this.current_combo_box);
		
		this.dropdown.style.top = offset[1] + this.current_combo_box.offsetHeight + 'px';
		this.dropdown.style.left = offset[0] + 'px';
	}
	
	ObserverComboBox.prototype.renderOptions = function()
	{		
		var html_code = '<ul>';
		for (var i = 0; i < this.current_combo_box.options.length; i++)
		{
			html_code += '<li onclick="ObserverComboBox.setSelectedIndex(' + i + ')" onmouseover="ObserverComboBox.moveSelected(this, '+ i +')">' + this.current_combo_box.options[i].text + '</li>';
		}
		
		this.dropdown.innerHTML = html_code + '</ul>';
		this.dropdown.style.width = (this.current_combo_box.offsetWidth - 2) + 'px';
	}
	
	ObserverComboBox.prototype.parseHtmlSelects = function()
	{
		var selects = document.getElementsByTagName('select');
		var root, combo_box, j, current;
		for (var i = selects.length; --i >= 0;)
		{
			current = selects[i];
			if (!current.multiple && !current.disabled)
			{
				root = document.createElement('div');
				root.id = 'combo_box_' + i;
					
				combo_box = new ComboBox(current.name, current.id, current.className);
				combo_box.setDimension(current.offsetWidth, current.offsetHeight);
				combo_box.setImage('swing_combo.gif');
				
				for (j = 0; j < current.options.length; j++)
				{
					combo_box.addOption(new OptionItem(current.options[j].text, current.options[j].value, current.options[j].selected));
				}
				
				if (selects[i].onchange) combo_box.addOnChangeListener(selects[i].onchange);
				
				selects[i].parentNode.insertBefore(root, selects[i]);
				combo_box.renderComboBox('combo_box_' + i);
				selects[i].parentNode.removeChild(selects[i]);
			}
		}
	}
	var ObserverComboBox = new ObserverComboBox();
	
	
	function OptionItem(text, value, selected)
	{
		this.text = text;
		this.value = (!value) ? this.text : value;
		this.selected = selected;
	}
	
	function ComboBox(name, id, className)
	{
		this.image = 'images/combo_box.gif';
		this.combo_box = document.createElement('div');
		this.combo_box.name = name;
		this.combo_box.id = id;
		this.combo_box.options = new Array();
		this.combo_box.selectedIndex = 0;
		this.combo_box.currentSelected = this.combo_box.selectedIndex;
		this.combo_box.onchange_listener = null;
		//this.combo_box.style.width = 195 + 'px';
		//this.combo_box.style.height = 20 + 'px';
		this.combo_box.style.paddingLeft = 3 + 'px';
		this.combo_box.className = 'combo_box ' + (className != null ? className : '');
		this.combo_box.onclick = function(){ObserverComboBox.showDropDown(this);};
		this.combo_box.setSelectedIndex = function(index)
		{
			if (index < 0 || index >= this.options.length) return;
			
			ObserverComboBox.hideDropDown();
			ObserverComboBox.current_combo_box = this;
			(index == this.selectedIndex) ? ObserverComboBox.updateTextValue() : ObserverComboBox.setSelectedIndex(index);
		}
	}

	ComboBox.prototype.addOption = function(Option)
	{
		this.combo_box.options.push(Option);

		if (Option.selected) this.combo_box.selectedIndex = this.combo_box.options.length - 1;
	}

	ComboBox.prototype.removeOption = function(index)
	{
		this.combo_box.options.splice(index, 1);
	}
	
	ComboBox.prototype.setDimension = function(width, height)
	{
		this.combo_box.style.width = width + 'px';
		this.combo_box.style.height = height + 'px';
	}
	
	ComboBox.prototype.setImage = function(src)
	{
		this.image = src;
	}

	ComboBox.prototype.addOnChangeListener = function(callback)
	{
		if (!(callback instanceof Function))
		{
			throw new Error('Arguments must be Function!!!');
		}

		this.combo_box.onchange_listener = callback;
	}

	ComboBox.prototype.renderComboBox = function(id_element)
	{
		if (!this.combo_box.options.length) this.combo_box.options[0] = new OptionItem('');
		var selectedElement = this.combo_box.options[this.combo_box.selectedIndex];
		this.combo_box.value = selectedElement.value;
		
		this.combo_box.innerHTML = '<img style="height: 100%; float: right;" src="' + this.image + '"><span style="cursor: default;">' + selectedElement.text + '</span><input type="hidden" name="' + this.combo_box.name + '" value="' + selectedElement.value + '">';
		document.getElementById(id_element).appendChild(this.combo_box);
	}
	
	addEvent(window, 'load', ObserverComboBox.initializedDropDown);
	
	
