if (!cx) var cx = {};
if (!cx.controls) cx.controls = {};
cx.controls.instances = [];
cx.controls.ComboBox = Class.create();
cx.controls.ComboBox.prototype = {
	
	classname: 'cx.controls.ComboBox',
		
	rawConfig: {
		handleWidth: 15,
		handleHeight: 15,
		handleSprite: '/_libs/cx/assets/gfx/handles.png',
		label: 'Please select',
		emptyText: 'Please select',
		fontFamily: 'Arial, Verdana, sans-serif',
		labelStyle: {
			fontSize: '11px',
			fontWeight: 'bold',
			color: '#575757',
			textAlign: 'right'
		},
		boxStyle: {
			borderBottom: '2px dotted #2f2f2f'
		},
		listStyle: {
			margin: '0px',
			marginLeft: '3px',
			padding: '0px',
			listStyle: 'none',
			background: '#fff'
		},
		itemStyle: {
			fontSize: '11px',
			lineHeight: '13px',
			padding: '2px',
			fontWeight: 'normal',
			color: '#a5a4a5',
			borderBottom: '1px dotted #575757',
			cursor: 'pointer',
			background: '#fff'
		},
		overStyle: {
			color: '#a8153a',
			borderBottom: '1px dotted #a8153a',
			fontWeight: 'normal'
		},
		selectedStyle: {
			fontWeight: 'bold',
			color: '#a8153a',
			textAlign: 'right'
		}
	},
	usrConfig: {},
	
	initialize: function(element, usrConfig) {
		
		if (usrConfig) this.usrConfig = usrConfig;
		
		this.raw = $(element);
		this._width = (this.usrConfig.width ? this.usrConfig.width : this.raw.getWidth());
		this.render();
		this.setupListeners();
		this.initSelection();
		this.raw.hide();
	},
		
	render: function() {
		
		this.handle = new Element('div').setStyle({
			width: this.rawConfig.handleWidth + "px",
			height: this.rawConfig.handleHeight + "px",
			backgroundImage: 'url('+this.rawConfig.handleSprite+')',
			backgroundPosition: '0px 0px',
			cursor: 'pointer',
			'float': 'left'
		});
		
		var lbl = (this.usrConfig.label ? this.usrConfig.label : (this.raw.readAttribute('label') ? this.raw.readAttribute('label') : this.rawConfig.label));
		this.label = new Element('div').setStyle(
			cx.utils.Helpers.mergeObjects(
				this.rawConfig.labelStyle,
				this.usrConfig.labelStyle, {
					width: this._width - this.rawConfig.handleWidth - 3 + "px",
					marginLeft: '3px',
					overflow: 'hidden',
					'float': 'left',
					MozUserSelect: 'none'
			})
		).update(lbl);

		this.selectedItem = new Element('div').setStyle(
			cx.utils.Helpers.mergeObjects(
				this.rawConfig.itemStyle,
				this.usrConfig.itemStyle,
				this.rawConfig.selectedStyle, {
					width: this._width + "px"
				}
			)
		).update(this.rawConfig.emptyText);
		
		this.box = new Element('div').setStyle({
			width: this._width
		}).insert(
			this.handle
		).insert(
			this.label
		).insert(
			new Element('div').setStyle({clear: 'both'})
		).insert(this.selectedItem);
		
		this.list = new Element('ul').setStyle(
			cx.utils.Helpers.mergeObjects(
				this.rawConfig.listStyle,
				this.usrConfig.listStyle, {
					width: this._width + "px",
					position: 'absolute',
					zIndex: '999',
					display: 'none'
		}));
		
		for (var i = 0; i < this.raw.options.length; i++) {
			
			var text = this.raw.options[i].text;
			this.list.insert(new Element('li', {
				cxComboSelectIndex: i
			}).setStyle(
				cx.utils.Helpers.mergeObjects(
					this.rawConfig.itemStyle,
					this.usrConfig.itemStyle)
			).update(text));
		}
		
		this.wrap = new Element('div').setStyle(
			cx.utils.Helpers.mergeObjects(
				this.usrConfig.wrapStyle, {
					width: this._width,
					fontFamily: (this.usrConfig.fontFamily ? this.usrConfig.fontFamily : this.rawConfig.fontFamily)
			})
		).insert(this.box).insert(this.list);
		this.raw.wrap(this.wrap);
		
		if (this.usrConfig.wrapStyle['float']) {
			$(this.wrap.parentNode).insert(new Element('div').setStyle({clear: 'both'}), {position: 'after'});
		}
	},
	
	setupListeners: function() {
		
		this.handle.observe('click', this.toggleList.bind(this));
		this.selectedItem.observe('click', this.toggleList.bind(this));
		this.list.childElements().each(function(elem) {
			elem.observe('mouseover', this.onItemOver.bind(this));
			elem.observe('mouseout', this.onItemOut.bind(this));
			elem.observe('click', this.onItemClicked.bind(this));
		}.bind(this));
		
		$(document.body).observe('click', this.onBodyClicked.bind(this));
	},
	
	onBodyClicked: function(evt) {
		
		var el = evt.element();
		if (this.wrap.descendants().indexOf(el) != -1) return;
		this.closeList();
	},
	
	onItemOver: function(evt) {
		evt.element().setStyle(cx.utils.Helpers.mergeObjects(this.rawConfig.itemStyle, this.usrConfig.itemStyle, this.rawConfig.overStyle));
	},
	
	onItemOut: function(evt) {
		if (evt.element() == this.selected) return;
		evt.element().setStyle(cx.utils.Helpers.mergeObjects(this.rawConfig.itemStyle, this.usrConfig.itemStyle));
	},
	
	onItemClicked: function(evt) {
		
		try {
			this.selected.setStyle(cx.utils.Helpers.mergeObjects(this.rawConfig.itemStyle, this.usrConfig.itemStyle));
		}
		catch(e) {}
		this.setSelected(evt.element());
	},
	
	setSelectedIndex: function(index, disableRawEvent) {
		
		for (var j = 0; j < this.list.descendants().length; j++) {
			if (this.list.descendants()[j].readAttribute('cxComboSelectIndex') == index) {
				this.setSelected(this.list.descendants()[j], disableRawEvent);
			}
		}
	},
	
	setSelected: function(el, disableRawEvent) {
		
		this.selected = el;
		this.selectedItem.update(this.selected .innerHTML);
		this.selectedItem.observe('click', this.toggleList.bind(this));
		this.selected .setStyle(cx.utils.Helpers.mergeObjects(this.rawConfig.itemStyle, this.usrConfig.itemStyle, this.rawConfig.overStyle));
		this.closeList();
		
		this.raw.selectedIndex = parseInt(this.selected.readAttribute('cxComboSelectIndex'));
		if (disableRawEvent !== false) {
			cx.events.Event.fireEvent(this.raw, 'change');
		}
	},
	
	openList: function() {
		
		if (this.usrConfig.animate != 'undefined' && this.usrConfig.animate == false) {
			this.list.show();
			this.handle.setStyle({
				backgroundPosition: '15px 0px'
			});
			this.state = 'opened';
		}
		else {
			this.state = 'busy';
			Effect.BlindDown(this.list, {
				duration: 0.2,
				afterFinish: function() {
					this.handle.setStyle({
						backgroundPosition: '15px 0px'
					});
					this.state = 'opened';
				}.bind(this)
			});
		}
	},
	
	closeList: function() {
		
		if (this.usrConfig.animate != 'undefined' && this.usrConfig.animate == false) {
			this.list.hide();
			this.handle.setStyle({
				backgroundPosition: '0px 0px'
			});
			this.state = 'closed';
		}
		else {
			this.state = 'busy';
			Effect.BlindUp(this.list, {
				duration: 0.2,
				afterFinish: function() {
					this.handle.setStyle({
						backgroundPosition: '0px 0px'
					});
					this.state = 'closed';
				}.bind(this)
			});
		}
	},
	
	toggleList: function(evt) {

		if (this.state == 'busy') return;		
		if (!this.state || this.state == 'closed') this.openList();
		else if (this.state == 'opened') this.closeList();
	},
	
	initSelection: function() {
		
		for (var i = 0; i < this.raw.options.length; i++) {
			if ($(this.raw.options[i]).readAttribute('selected')) {
				this.setSelectedIndex(i, false);
			}
		}
	}
};
cx.controls.ComboBox.transformSelects = function(className, usrConfig) {
		
	if (!className) className = "cxComboBox";
	if (!cx.controls.instances) cx.controls.instances = new Array();
	
	var selects = $$('.'+className);
	selects.each(function(elem) {
		var cxCombo = new cx.controls.ComboBox(elem, usrConfig);
		cx.controls.instances.push(cxCombo);
	}.bind(this));
};