function ComboBox(element) {
	if (!(this.element = $(element))) {
		throw 'assertion(element != null) failed!';
	}

	// set an id for the element
	if (!(this.id = this.element.id)) {
		this.element.id = this.id = 'combobox_' + parseInt((new Date()).getTime() / 1000).toString(16) + '_' + parseInt(Math.random()*65535).toString(16);
	}

	// check registered instances
	if (ComboBox._instances[this.id]) {
		return ComboBox._instances[this.id].reset();
	}

	// register and initialize
	ComboBox._instances[this.id] = this.reset();
}

ComboBox.prototype = {
	reset: function() {
		// destroy previous one if any
		this.destroy();

		// build replacement html
		this.label = new Element('label');
		disable_text_selection(this.label);
		this.replacement = new Element('div', { id: 'ComboBox_' + this.id, className: 'combo_box' });
		this.replacement.appendChild(new Element('span', { className: 'dd_arrow' }));
		this.replacement.appendChild(this.label);

		// insert it after the select and hide
		this.element.addClassName('hidden_component');
		this.element.insert({ after: this.replacement });

		// build option list
		this.options = new Element('div', { className: 'dropdown_combobox scrollbar_container' });

		// build more shits to go
		this.outer = new Element('div', { className: 'wrap_outer' });
		this.inner = new Element('div', { className: 'wrap_inner' });

		this.track = new Element('div', { className: 'scrollbar_track' });
		this.handle = new Element('div', { className: 'scrollbar_handle' });
		this.content = new Element('div', { className: 'scrollbar_content' });

		this.track.appendChild(this.handle);
		this.options.appendChild(this.track);
		this.options.appendChild(this.content);

		this.inner.appendChild(this.options);
		this.outer.appendChild(this.inner);

		// hide and set width
		this.outer.setStyle({
			display: 'none',
			width: this.replacement.getDimensions().width - 2 + 'px' // padding :-(
		});

		// set selected index for future use
		this.selectedIndex = this.element.selectedIndex;

		// build "options"
		var x = 0, xx = this.element.options.length;
		for (; x < xx; ++x) {
			var option = this.element.options[x],
				replacement = new Element('label', { id: 'ComboBox_' + this.id + '_Option_' + x }).update(option.innerHTML);

			if (x == this.element.selectedIndex) {
				this.label.update(option.innerHTML);
			}

			replacement.onmouseover = function() {
				this.className = 'selected_index';
			}
			replacement.onmouseout = function() {
				this.className = '';
			}

			this.content.appendChild(replacement);
		}

		// ensure we have a "selected" "option"
		if (!this.label.innerHTML && this.element.options[0]) {
			this.selectedIndex = 0;
			this.label.update(this.element.options[0].innerHTML);
		}

		// create scrollbar
		this.scrollbar = new Control.ScrollBar(this.content, this.track);

		// append "options"
		this.replacement.insert({ after: this.outer });

		// done?
		return this;
	},
	destroy: function() {
		if (this.outer && this.replacement) {
			this.outer.remove();
			this.replacement.remove();
			this.element.removeClassName('hidden_component');
		}
	}
};

ComboBox._instances = [];

document.ready(function() {
	for(var selects = document.getElementsByTagName('select'), z = selects.length; z--;){
		selects[z]._combobox = new ComboBox(selects[z]);
	}
});

document.on('click', function(event) {
	if (!Event.isLeftClick(event) && !Prototype.Browser.IE) {
		return;
	}

	var element, instance;

	if (element = event.findElement('div.scrollbar_handle')) {
		return event.stop();
	}

	if (ComboBox._instance) {
		if (element = event.findElement('div.dropdown_combobox label')) {
			var index = element.id.replace('ComboBox_' + ComboBox._instance.id + '_Option_', '');
			if (index != ComboBox._instance.element.selectedIndex) {
				ComboBox._instance.label.update(element.innerHTML);
				ComboBox._instance.element.selectedIndex = index;
				ComboBox._instance.element.fire('change');	// hell, yeah!
			}
		}

		ComboBox._instance.outer.hide();
		ComboBox._instance = null;
		return event.stop();
	}

	if (element = event.findElement('div.combo_box')) {
		ComboBox._instance = ComboBox._instances[element.id.replace('ComboBox_', '')];
		ComboBox._instance.outer.show();
		setTimeout(function() {
			ComboBox._instance.scrollbar.recalculateLayout();
		}, 0);
		return event.stop();
	}
});

