// JavaScript Document
var xtdForm = Class.create({
	initialize: function(form, ajax){
		this.form = form;
		this.ajax = ajax;
		this.fieldChanged(this.form);
	},
	
	replaceFormElements: function(elms){
		elms.each(function(elm){
			if(elm.match('select')){
				var nwelm = this.getSelectbox(elm);
			} else if(elm.match('input[type=radio]')){
				var nwelm = this.getRadio(elm);
			} else if(elm.match('input[type=checkbox]')){
				var nwelm = this.getCheckbox(elm);
			}
			
			Element.insert(elm, {after: nwelm});
			
			//Event.observe(elm, 'change', this.elementTriggered.bindAsEventListener(this));
			Element.hide(elm);
			
			Event.observe(nwelm, 'click', this.elementTriggered.bindAsEventListener(this));
		}, this);
	},
	
	throwError: function(str){
		document.fire('xtdform:error', { errStr: str });
	},
	
	elementTriggered: function(event, opttrigger){
		if(event){
			var trigger = Event.findElement(event);
		
			// stop all default actions if a link is clicked
			if(trigger.match('a')) Event.stop(event);
		} else {
			var trigger = opttrigger;
		}
		
		// if the trigger is involved with an selectbox do some checks before continuing
		if(trigger.match('div.select a.arrow') || trigger.match('div.select') || trigger.match('div.select span.selecttext')){
			this.toggleSelectOptions(trigger);
			return false;
		} else if(trigger.match('div.select a.option')){
			this.setSelectOption(trigger);
			
			var selectDiv = trigger.up('div.select');
			this.toggleSelectOptions(selectDiv);
			
			var field = selectDiv.previous('select');
			this.fieldChanged(field);
			return false;
		}
		
		// at this point we can be pretty sure this is an legitimate call ;)
		if(trigger.match('input') || trigger.match('select')){
			var field = $(trigger.identify());
		} else if(trigger.hasClassName('option')){
			var field = $(trigger.up('div.select').previous('select').identify());
		} else if(trigger.hasClassName('radio')){
			var field = $(trigger.previous('input').identify());
			this.setRadio(field);
		} else if(trigger.hasClassName('checkbox')){
			var field = $(trigger.previous('input').identify());
			this.toggleCheckbox(field);
		}
		
		this.fieldChanged(field);
	},
	
	fieldChanged: function(field){
		if(!this.ajax) return false;
    	var url = this.form.getAttribute('action');
    	var parameters = $H(this.form.serialize(true));
		parameters.set('type', 'ajax');
		parameters.set('trigger', field.readAttribute('name'));
		
		new Ajax.Request(url, {
    		method: 'get',
    		contentType: 'application/json',
    		parameters: parameters,
    		onSuccess: this.AJAXSucces.bind(this)
    	});
    },
	
	AJAXSucces: function(transport) {
    	var responseArray = $H(transport.responseJSON).get('AJAXResponse');
    			
    	responseArray.each(function(obj){
    		var obj = $H(obj);
    		
    		if(obj.get('action') == 'replace') this.dynamicReplace(obj);
			
			if(obj.get('action') == 'error') this.throwError(obj.get('value'));
    		
    		if(obj.get('action') == 'show') $(obj.get('field')).show();
    		
    		if(obj.get('action') == 'hide') $(obj.get('field')).hide();
    		
    	}, this);
    },
    
    dynamicReplace: function(obj){
    	var field = $(obj.get('field'));
		var id = field.identify();
    	
		if(obj.get('type') == 'select'){
			field.next('div.select').remove();	
			
			field.replace(obj.get('value'));
			
			var elm = this.form.select('#' + id).first();
			elm.hide();
			var nwelm = this.getSelectbox(elm);
			Element.insert(elm, {after: nwelm});
			Event.observe(nwelm, 'click', this.elementTriggered.bindAsEventListener(this));
		} else {
			field.replace(obj.get('value'));
		}
    },
	
	getSelectbox: function(selectbox){
		// loop trough the options and crate an ul of them
		var aOptions = selectbox.select('option');
		var index = 0;
		var optlist = new Element('ul', {
			'class': 'optionsul'
		});
		
		aOptions.each(function(opt, i){
			var optlink = new Element('a', {
				'href': '#',
				'rel': opt.identify(),
				'class': 'option'
			}).update(opt.text);
			
			var optitem = new Element('li', {
				'class': 'optionitem'
			}).update(optlink);
			
			if(opt.selected){
				optlink.addClassName('selected');
				index = i;
			}
			
			Element.insert(optlist, optitem);
		}, this);
		
		// get the text of the selected value
		var text = new Element('span', {
			'class': 'selecttext'
		}).update(aOptions[index].text);
		
		// create a link to trigger the toggling of our optionlist
		var arrow = new Element('a', {
			'href': '#',
			'class': 'arrow'
		}).update('show options');
		
		// create a scrollable element
		var handle = new Element('div', {
			'class': 'scrollbar-handle'
		});
		
		var track = new Element('div', {
			'class': 'scrollbar-track'
		}).insert(handle);
		
		var content = new Element('div', {
			'class': 'scrollbar-content'
		}).insert(optlist);
		
		var container = new Element('div', {
			'class': 'options-container'
		}).insert(content).insert(track).hide();
		
		var nwelm = new Element('div', {
			'class': selectbox.readAttribute('class')
		}).insert(text).insert(container).insert(arrow).addClassName('select').addClassName(selectbox.identify());
		
		return nwelm;
	},
	
	toggleSelectOptions: function(trigger){
		if(trigger.match('a.arrow') || trigger.match('span.selecttext')){
			var selectDiv = trigger.up('div.select');
		} else if(trigger.match('div.select')){
			var selectDiv = trigger;
		}
		
		var container = selectDiv.down('div.options-container');
		container.toggle();
		if(container.visible()){
			var content = container.down('div.scrollbar-content');
			var track = container.down('div.scrollbar-track');
			
			var scrollbar = new Control.ScrollBar(content, track);
			//scrollbar.enable();
		}
	},
	
	getRadio: function(radio){
		var nwelm = new Element('a', {
			'href': '#',
			'rel': radio.identify(),
			'class': radio.readAttribute('class')
		}).update(radio.readAttribute('value'));
		
		nwelm.addClassName(radio.readAttribute('name'));
		
		nwelm.addClassName('radio');
		
		if(radio.checked){
			nwelm.addClassName('checked');
		}
		
		return nwelm;
	},
	
	getCheckbox: function(checkbox){
		var nwelm = new Element('a', {
			'href': '#',
			'rel': checkbox.identify(),
			'class': checkbox.readAttribute('class')
		}).update(checkbox.readAttribute('value'));
		
		nwelm.addClassName(checkbox.readAttribute('name'));
		
		nwelm.addClassName('checkbox');
		
		if(checkbox.checked){
			nwelm.addClassName('checked');
		}
		
		return nwelm;
	},
	
	setSelectOption: function(trigger){
		var relOption = $(trigger.readAttribute('rel'));
		relOption.selected=true;
		
		this.form.select('div.' + relOption.up('select').identify() + ' a.option').invoke('removeClassName', 'selected');
		var selectedElm = relOption.up('select').select('option[value=' + relOption.up('select').getValue() + ']').first();
						
		trigger.addClassName('selected');
			
		this.form.select('div.' + relOption.up('select').identify() + ' span.selecttext').first().update(selectedElm.text);
	},
	
	setRadio: function(field){
		field.checked = true;
		
		this.form.select('a.radio.' + field.readAttribute('name')).invoke('removeClassName', 'checked');
		this.form.select('a.radio[rel=' + field.identify() + ']').first().addClassName('checked');
	},
	
	toggleCheckbox: function(field){
		if(field.checked){
			field.checked = false;
			this.form.select('a.checkbox[rel=' + field.identify() + ']').first().removeClassName('checked');
		} else {
			field.checked = true;
			this.form.select('a.checkbox[rel=' + field.identify() + ']').first().addClassName('checked');
		}
	}
});