/**
 * SelectsManager.js (SelectsManager, Select, SelectBaseItemRenderer classes)
 *
 * @version: 1.0
 * @author: WGU Team (www.web-go-up.com)
 *
 * @TODO: Redesign without Mootools
 * @TODO: more robust testing!!!
 */

var SelectsManager = new Class({
	Implements: [Options, Events],

	options: {
		'id':				'select',
		'selector':			'select',
		'cssClass':			'select'
	},

	initialize: function(options) {
		this.setOptions(options);

		this.onItemSelectInternalBound	= this.onItemSelectInternal.bind(this);
		this.onWindowResizeBound		= this.onWindowResize.bind(this);

		this.selects					= [];

		this.attachDefaultSelects();

		window.addEvent('resize', this.onWindowResizeBound);
	},

	attach: function(options) {
		if (options.select) {
			options		= $merge(this.options, options);
			delete options.selector;

			var id		= ($type(options.select) == 'string') ? options.select : $(options.select).get('id') || this.selects.length.toString();
			options.id	= options.id + '-' + id;

			var slct	= new SelectsManager.Select(options);
			slct.addEvent('itemSelectInternal', this.onItemSelectInternalBound);

			this.selects.push(slct);

			id			= null;
			slct		= null;
		}

		return this;
	},

	detach: function(select) {
		if (select) {
			var slct	= $(select).retrieve('select');

			if (slct) {
				this.selects.splice(this.selects.indexOf(slct), 1);

				slct.destroy();

				slct	= null;
			}
		}

		return this;
	},

	getSelectBySelect: function(select) {
		return $(select).retrieve('select');
	},

	attachDefaultSelects: function() {
		$$('select.' + this.options.selector).each(function(el) {
			if (!el.retrieve('select')) {
				this.attach({ 'select': el });
			}
		}, this);

		return this;
	},

	getId: function() {
		return this.options.id;
	},

	setId: function(value) {
		this.options.id	= value;

		this.selects.each(function(el) {
			el.setId(value);
		});

		return this;
	},

	getSelector: function() {
		return this.options.selector;
	},

	setSelector: function(value) {
		this.options.selector = value;

		return this;
	},

	getCSSClass: function() {
		return this.options.cssClass;
	},

	setCSSClass: function(value) {
		this.options.cssClass	= value;

		this.selects.each(function(el) {
			el.setCSSClass(value);
		});

		return this;
	},

	/**
	 * Private function! React on item selecting
	 */
	onItemSelectInternal: function(select, params) {
		this.fireEvent('itemSelect', [select, params]);
	},

	/**
	 * Private function!
	 */
	onWindowResize: function() {
		this.selects.each(function(el) {
			el.replace();
		});
	}
});

SelectsManager.Select = new Class({
	Implements: [Options, Events],

	options: {
		'select':			null,
		'id':				'select',
		'cssClass':			'select'
	},

	initialize: function(options) {
		this.setOptions(options);

		this.options.select						= $(this.options.select);

		this.contWidth							= this.options.select.getSize().x + 25;
		this.options.select.setStyle('width', ((this.options.select.getSize().x < 462) ? (this.options.select.getSize().x + 25) : 462) + 'px');
		this.options.select.store('select', this);

		// private properties

		this.shown								= false;
		this.container							= null;
		this.handler							= null;
		this.handlerText						= null;
		this.list								= null;
		this.items								= [];
		this.onContainerMouseOutBound			= this.onContainerMouseOut.bind(this);
		this.onHandlerPressBound				= this.onHandlerPress.bind(this);
		this.onItemSelectInternalBound			= this.onItemSelectInternal.bind(this);
		this.onItemMouseOverBound				= this.onItemMouseOver.bind(this);
		this.onItemMouseOutBound				= this.onItemMouseOut.bind(this);

		// visual components

		this.createContainer();
		this.createHandler();
		this.createList();
	},

	destroy: function() {
		this.items.each(function(el) {
			el.removeEvents();
			el.destroy();
		});
		this.items.empty();

		this.list.removeEvents();
		this.list.destroy();

		this.handler.removeEvents();
		this.handler.destroy();

		this.options.select.setStyle('visibility', 'visible');

		this.options.select.store('select', null);

		this.list							=
		this.items							=
		this.handlerText					=
		this.onItemSelectInternalBound		=
		this.onItemMouseOverBound			=
		this.onItemMouseOutBound			= null;

		return this;
	},

	show: function() {
		if (!this.shown) {
			this.list.setStyle('visibility', 'visible');
            this.list.setStyle('height', '190px');
            this.list.setStyle('white-space', 'normal');
            this.list.setStyle('overflow', 'auto');

			this.shown	= true;
		}

		return this;
	},

	hide: function() {
		if (this.shown) {
			this.list.setStyle('visibility', 'hidden');

			this.shown	= false;
		}

		return this;
	},

	replace: function() {
		var selectPos	= this.options.select.getPosition();

		this.container.setStyles({
			'left':	selectPos.x + 'px',
			'top':	selectPos.y + 'px'
		});

		selectPos		= null;

		return this;
	},

	getId: function() {
		return this.options.id;
	},

	setId: function(value) {
		this.container.set('id', value + '-container');
		this.list.set('id', value + '-list');
		this.items.each(function(el) {
			var id		= el.get('id').split('-');
			id[0]		= value;

			el.set('id', id.join('-'));

			id			= null;
		});

		this.options.id	= value;

		return this;
	},

	getCSSClass: function() {
		return this.options.cssClass;
	},

	setCSSClass: function(value) {
		this.list.set('class', value + '_list');
		this.items.each(function(el) {
			var clss			= el.get('class').split('_');
			clss[0]				= value;

			el.set('class', clss.join('_'));

			clss				= null;
		});

		this.options.cssClass	= value;

		return this;
	},

	/**
	 * Private function!
	 */
	createContainer: function() {
		var selectPos	= this.options.select.getParent().getPosition();

		this.container	= new Element('div', {
			'id':				this.options.id + '-container',
			'class':			this.options.cssClass + '_container',
			'styles': {
				'position':		'absolute',
				'width':		this.contWidth + 'px',
				'left':			selectPos.x + 'px',
				'top':			selectPos.y + 'px'
			},
			'events': {
				'mouseleave':	this.onContainerMouseOutBound
			}
		});

		this.options.select.setStyle('visibility', 'hidden');

		$(document.body).grab(this.container, 'top');

		selectPos		= null;

		return this;
	},

	/**
	 * Private function!
	 */
	createHandler: function() {
		var selectedOpt	= this.options.select.getSelected()[0];

		this.handler	= new Element('div', {
			'id':				this.options.id + '-handler',
			'class':			this.options.cssClass + '_handler',
			'events': {
				'mousedown':	this.onHandlerPressBound
			}
		}).adopt([
			new Element('div', {
				'class': 		this.options.cssClass + '_handler_left'
			}),
			this.handlerText	= new Element('div', {
				'class':		this.options.cssClass + '_handler_text',
				'styles': {
					'width':	(this.options.select.getSize().x - 4 - 34 - 14) + 'px' // width - _handler_left width - _handler_right width - _handler_text padding-left
				},
				'text':			selectedOpt.get('text').substr(0, 65) + ((selectedOpt.get('text').length > 65) ? '...' : '')
			}),
			new Element('div', {
				'class': 		this.options.cssClass + '_handler_right'
			}),
			new Element('div', {
				'class':		'clear'
			})
		]);

		this.container.grab(this.handler);

		selectedOpt		= null;

		return this;
	},

	/**
	 * Private function!
	 */
	createList: function() {
		this.list	= new Element('ul', {
			'id':				this.options.id + '-list',
			'class':			this.options.cssClass + '_list',
			'styles': {
				'width':		this.contWidth-27 + 'px',
				'visibility':	'hidden'
			}
		});

		var selectedOpt		= this.options.select.getSelected()[0];
		var opts			= this.options.select.getElements('option');
		var newItem			= null;

		for (var i = opts.length - 1; i >= 0; --i) {
			newItem			= new Element('div', {
				'id':				this.options.id + '-item-' + i,
				'class':			this.options.cssClass + '_item' + ((opts[i] == selectedOpt) ? ' current' : ''),
				'events': {
					'click':		this.onItemSelectInternalBound,
					'mouseenter':	this.onItemMouseOverBound,
					'mouseleave':	this.onItemMouseOutBound
				}
			}).adopt([
				new Element('div', {
					'class':		this.options.cssClass + '_item_left'
				}),
				new Element('div', {
					'class':		this.options.cssClass + '_item_text',
					'styles': {
						'width':	(this.contWidth - 87 + 'px')
					},
					'text':			opts[i].get('text')
				}),
				new Element('div', {
					'class':		this.options.cssClass + '_item_right'
				}),
				new Element('div', {
					'class':		'clear'
				})
			]).store('value', opts[i].get('value'));

			this.list.grab(newItem, 'top');

			this.items.unshift(newItem);
		}

		//this.list.getFirst().removeClass(this.options.cssClass + '_item').addClass(this.options.cssClass + '_item_first');
		//this.list.getLast().removeClass(this.options.cssClass + '_item').addClass(this.options.cssClass + '_item_last');

		this.container.grab(this.list);

		selectedOpt		= null;
		opts			= null;
		newItem			= null;

		return this;
	},

	/**
	 * Private function!
	 */
	onContainerMouseOut: function() {
		this.hide();
	},

	/**
	 * Private function!
	 */
	onHandlerPress: function() {
		if (this.showed) {
			this.hide();
		} else {
			this.show();
		}
	},

	/**
	 * Private function!
	 */
	onItemSelectInternal: function(evt) {
		var item	= (evt.target.hasClass('select_item') || evt.target.hasClass('select_item_first') || evt.target.hasClass('select_item_last')) ? evt.target : (evt.target.getParent('.select_item') || evt.target.getParent('.select_item_first') || evt.target.getParent('.select_item_last'));

		this.options.select.set('value', item.retrieve('value'));

		this.handlerText.set('text', item.get('text').substr(0, 65) + ((item.get('text').length > 65) ? '...' : ''));

		this.fireEvent('itemSelectInternal', [this.options.select]);

		this.options.select.fireEvent('itemSelect',  [this.options.select]);
		this.options.select.fireEvent('change');
		if (this.options.select.hasClass('filter_form')) {
			$('filter-form').submit();
		}
		this.hide();

		item		= null;
	},

	/**
	 * Private function! Reacts on selecting (highlighting) some item
	 */
	onItemMouseOver: function(evt) {
		var item	= (evt.target.hasClass('select_item') || evt.target.hasClass('select_item_first') || evt.target.hasClass('select_item_last')) ? evt.target : (evt.target.getParent('.select_item') || evt.target.getParent('.select_item_first') || evt.target.getParent('.select_item_last'));

		item.getFirst().setStyle('background-position', 'left bottom').getNext().setStyle('background-color', '#F8F8F8').getNext().setStyle('background-position', 'left bottom');

		item		= null;
	},

	/**
	 * Private function! Reacts on loosing select (highlight) of some item
	 */
	onItemMouseOut: function(evt) {
		var item	= (evt.target.hasClass('select_item') || evt.target.hasClass('select_item_first') || evt.target.hasClass('select_item_last')) ? evt.target : (evt.target.getParent('.select_item') || evt.target.getParent('.select_item_first') || evt.target.getParent('.select_item_last'));

		item.getFirst().setStyle('background-position', 'left top').getNext().setStyle('background-color', '#FEFEFE').getNext().setStyle('background-position', 'left top');

		item		= null;
	}
});

window.addEvent('load', function() {
	var IE6 = false /*@cc_on || @_jscript_version < 5.7 @*/
	if (IE6) {
	} else {
		window.Selects = new SelectsManager();
	}
});

