/*
Script: form.js
	Contains <GoBMG_Forms>

Author:
	Alan Roemen
	June 29, 2010

Class: GoBMG_Forms
*/

var GoBMG_Forms = new Class({

	options: {
		dropdown_height: 131,
		zindex_start: 9000
	},

	initialize: function(options) {
		this.boxes = $$('div select[id^=ff_]');
		if (this.boxes.length < 1) return;
		this.setOptions(options);
		this.options.zindex_start += this.boxes.length;

		if (!$chk(window['Scroll'])) {
			var asset_scroll = new Asset.javascript('/scripts/scroll/scroll.js');
			if (window.ie)
				this.setup_scroll.delay(1000, this);
			else asset_scroll.addEvent('load', this.setup_scroll.bind(this));
		} else this.setup_scroll();

		this.select = new Element('div', {'class': 'select'}).adopt(
			new Element('div', {'class': 'fieldbox medium-field'}).adopt([
				new Element('input', {'class': 'dropdown-input'}),
				new Element('span', {'class': 'selected'}),
				new Element('div', {'class': 'dropdown'}).adopt([
					new Element('ul', {'class': 'dropdown-list', 'styles': {'max-height': this.options.dropdown_height}}),
					new Element('div', {'class': 'dropdown-scroll'}).adopt([
						new Element('div', {'class': 'up-arrow'}),
						new Element('div', {'class': 'scroll-bar'}).adopt([
							new Element('div', {'class': 'scroller'})
						]),
						new Element('div', {'class': 'down-arrow'}),
						new Element('div', {'class': 'scroll-bottom'})
					]),
					new Element('div', {'class': 'select-bottom'}).adopt(
						new Element('div', {'class': 'select-bottom-left select-medium'}).adopt(
							new Element('div', {'class': 'select-bottom-right'})
						)
					)
				])
			])
		);
		this.scrolls = [];
		this.to_replace = [];
		this.boxes.each(this.set_field.bind(this));
		this.to_replace.each(function(el){el.removeProperty('class').removeProperty('id');});
	},

	set_field: function(el, j) {
		var i = 0;
		var box = this.select.clone();
		var selected = el.getElement('option');
		var input = new Element('input', {
			'id': el.getProperty('id'),
			'name': el.getProperty('name'),
			'value': '',
			'type': 'hidden'
		});
		el.getProperty('class').split(' ').each(box.addClass.bind(box));
		box.setStyle('z-index', this.options.zindex_start--);
		box.addEvent('click', this.dropdown.bindWithEvent(this, box));
		this.set_input(box.getElement('input.dropdown-input'), box, j);
		
		// populate list
		el.getElements('option').each(function(o){
			if (o.selected) selected = o;
			if (!$chk(o.getProperty('value'))) return;
			var li = new Element('li', {'title': o.getProperty('value')}).setHTML(o.getText());
			if (++i == 1) li.addClass('dropdown-first');
			li.addEvent('click', this.set_selection.bindWithEvent(this, [box, input, li]));
			li.inject(box.getElement('ul.dropdown-list'));
		}.bind(this));

		// do replacement
		if (el.hasClass('small-field')) {
			box.removeClass('small-field');
			box.getElement('div.medium-field').removeClass('medium-field').addClass('small-field');
			box.getElement('div.select-medium').removeClass('select-medium').addClass('select-small');
		} else if (el.hasClass('large-field')) {
			box.removeClass('large-field');
			box.getElement('div.medium-field').removeClass('medium-field').addClass('large-field');
			box.getElement('div.select-medium').removeClass('select-medium').addClass('select-large');
		}
		if (el.getNext() && el.getNext().getTag() == 'select') box.addClass('field-spacer');
		input.setProperty('value', selected.getProperty('value'));
		if (!this.to_replace.contains(el.getParent()))
			this.to_replace.push(el.getParent());
		el.replaceWith(input);

		box.getElement('span.selected').setHTML(selected.getText() + '<span class="select-arrow"></span>');
		box.injectAfter(input);
		this.boxes[j] = box;
	},

	setup_scroll: function() {
		this.boxes.each(function(box, i){
			box.addClass('select-active');
			this.scrolls[i] = new Scroll(box.getElement('ul'), box.getElement('div.scroll-bar div.scroller'), {
				scrollLinks: {
					forward: box.getElement('div.down-arrow'),
					back: box.getElement('div.up-arrow')
				},
				fixedControlSize: 10
			});
			box.removeClass('select-active');
		}.bind(this));
	},

	set_selection: function(e, box, input, li) {
		new Event(e).stop();
		box.getElement('span.selected').setHTML(li.getText() + '<span class="select-arrow"></span>');
		input.setProperty('value', li.getProperty('title'));
		this.dropdown(false, box);
	},

	set_input: function(input, box, i) {
		input.addEvent('keydown', function(e){
			e = new Event(e);
			var alphanum = e.key.length == 1 ? e.key.match(/[a-z0-9]/)[0] : null;
			if (e.key == 'tab') {
				return;
			} else if (e.key == 'esc') {
				if (box.hasClass('select-active'))
					this.dropdown(false, box);
			} else {
				if (e.key == 'space' || alphanum != null) {
					if (!box.hasClass('select-active'))
						this.dropdown(false, box);
				}
				if (alphanum) {
					var el;
					box.getElements('.dropdown-list li').each(function(li){
						if ($chk(el)) return;
						var re = new RegExp("^" + alphanum, "i");
						if (null !== li.getText().match(re)) el = li;
					});

					if ($chk(el)) {
						var up = this.scrolls[i].update.periodical(100, this.scrolls[i]);
						(function(){
							new Fx.Scroll($(box.getElement('.dropdown-list')), {
								wait: false,
								duration: 250,
								onComplete: function(){ $clear(up); }.bind(this)
							}).toElement(el);
						}).delay(100, this);
					}
				}
			}
			e.stop();
		}.bind(this));

		/* CAUSES SCROLLING TO CLOSE DROPDOWN. COMMENTING OUT FOR NOW
		input.addEvent('blur', function(){
			(function(){
				if (box.hasClass('select-active'))
					this.dropdown(false, box);
			}).delay(100, this, [false, box]);
		}.bind(this));
		*/
	},

	dropdown: function(e, box) {
		if (e) {
			e = new Event(e)
			e.target = $(e.target);
			if (e.target.hasClass('select-arrow') || e.target.hasClass('selected'))
				e.stop();
			else return;
		}
		if (box.hasClass('select-active'))
			box.removeClass('select-active');
		else box.addClass('select-active');
		box.getElement('input.dropdown-input').focus();
	}

});

GoBMG_Forms.implement(new Options, new Events);