//##################################
// OPTIONS CLASS
//##################################
optsClass = function(validator) {
	this.validator = validator;
	this.options = new Array();
}

//::::::::::::::::::::::::::::::::::
optsClass.prototype.add_option = function(option) {
	this.options.push(option);
}

//::::::::::::::::::::::::::::::::::
optsClass.prototype.update = function(triggerName) {
	// LEAVE THE SELECTED OPTION TO THE LAST
	var i, j, isSelected, selectedOpt, selectedField, foundTrigger, triggers;
	var optionValue, triggerValue;

	// UPDATE TRIGGERS
	//if (triggers = $(triggerName)) triggers = new Array(triggers);
	triggers = $$('INPUT[name=' + triggerName+ ']');
	if (triggers.length==0) triggers = $$('SELECT[name=' + triggerName+ ']');
	if (triggers.length>0) {
		
		// RESET ALL COLORS
		triggers.each(function(el){el.setStyle('background-color', '');});
		
		for(j=0; j<this.options.length; j++) {
			foundTrigger = false;
			optionValue = this.options[j].value.toString();
			for (i=0; i<triggers.length; i++) {
				triggerValue = triggers[i].value.toString();
				//alert('Option: ' + optionValue + ', Trigger: ' + triggers[i].name + ', value: '+ sender.value);
				if (optionValue==triggerValue) {
					foundTrigger = true;
					isSelected = this.validator.checkSelector(triggers[i], triggerValue);
	
					if (isSelected) {
						//alert('Saving option ' + triggers[i].name + triggers[i].value);
						selectedOpt = this.options[j];
						triggers[i].setStyle('background-color', '#FFDD77');
					} else {
						//alert('Updating trigger ' + triggers[i].name + triggerValue);
						//triggers[i].style.backgroundColor = '#F4F0E8';
						triggers[i].setStyle('background-color', '');
						this.options[j].update(this.validator, isSelected);
					}
					break;
				}
			}
			// IF NOT FOUND A MATCHING TRIGGER
			if (!foundTrigger) {
				//alert('Disabling option (cause trigger not found)' + this.options[j].value);
				this.options[j].update(this.validator, false);
			}
		}
	}


	// AT LAST, UPDATE SELECTED OPTION(to allow one field be repeated in diferent values)
	if (selectedOpt!=undefined) {
		//alert('Updating selected option ' + selectedOpt.value);
		selectedOpt.update(this.validator, true);
	}
}


//##################################
// OPTION CLASS
//##################################
optClass = function() {
	this.value = arguments[0];
	this.hide = arguments[1];
	this.fields = new Array();
	for (var i=2; i<arguments.length;i++) {
		this.add_field(arguments[i]);
	}
}

//::::::::::::::::::::::::::::::::::
optClass.prototype.add_field = function(field_name) {
	this.fields.push(field_name);
}

//::::::::::::::::::::::::::::::::::
optClass.prototype.update = function(validator, isSelected) {
	var fieldName, fields, i, j;
	var display = isSelected ? '' : 'none';
	var disable = isSelected ? false : true;
	var color = disable ? '#D4D0C8': '';

	var selectors = new Array();
	for (i=0; i<this.fields.length; i++) {
		fieldName = this.fields[i];

		// ENABLE DISABLE
		if (!this.hide) {
			if (fields=validator.findFields(fieldName)) {
				for(j=0; j<fields.length; j++) {
					if (fields[j] && fields[j].form) {
						if (!disable && fields[j].optsObj) selectors.push(fields[j]);
						fields[j].disabled = disable;
						if (fields[j].type.indexOf('text')>=0 || fields[j].type.indexOf('select')>=0) {
							fields[j].style.backgroundColor= color;
						}
					} 
				}
			} 

		// HIDE CONTAINER
		} else if (this.hide==1) {
			this.display(fieldName + '_hold', display);

		// HIDE ROW
		} else {
			//if (!this.display(fieldName + '_row', display)) {
				// HIDE HEAD COLUMN AND FIELD COLUMN
				this.display(fieldName + '_header', display);
				this.display(fieldName + '_field', display);
			//}
		}
	}

	// UPDATE NESTED SELECTORS
	for (var i=0; i<selectors.length; i++) {
		selectors[i].optsObj.update(selectors[i]);
	}
}

//::::::::::::::::::::::::::::::::::
optClass.prototype.display = function(name, state) {
	//alert('Canging display of ' + name + ' to state ' + state);
	var obj;
	if (obj = document.getElementById(name)) {
		//alert('Found field to change visibility' + name);
		obj.style.display = state;
		return true;
	} else {
		//alert('Could not found field to change visibility: ' + name);
		return false;
	}
}



//##################################
// VALIDATOR (ADD METHODS)
//##################################
validatorClass.prototype.setSelector = function(triggerName) {
	var triggers, handler;
	var i, j;
	
	triggers = $$('INPUT[name=' + triggerName+ ']');
	if (triggers.length==0) triggers = $$('SELECT[name=' + triggerName+ ']');
	if (triggers.length>0) {
		// Supports a single trigger for several selectors
		//alert('Found triggers ' + fields.length);
		for (i=0; i<triggers.length; i++) {
			if (!triggers[i].optsObj) {
				triggers[i].optsObj = new optsClass(this);
				triggers[i].oldColor = triggers[i].style.backgroundColor;
			}
			for (j=1; j<arguments.length;j++) {
				triggers[i].optsObj.add_option(arguments[j]);
			}
			handler = (triggers[i].type=='radio' || triggers[i].type=='checkbox') ? 'click' : 'change';
			triggers[i].addEvent(handler, function(){this.optsObj.update(triggerName);});
		}
		// update first
		triggers[0].optsObj.update(triggerName);
	} else {
		//alert('Selector triger not found');
	}
}

//::::::::::::::::::::::::::::::::::
validatorClass.prototype.checkTriggers = function(triggers, value) {
	if (triggers = this.findFields(triggers)) {
		for (i=0; i<triggers.length; i++) {
			if (this.checkSelector(triggers[i], value)) return true;
		}
	}
}

//::::::::::::::::::::::::::::::::::
validatorClass.prototype.checkSelector = function(sender, value) {
	if (sender.type=='radio' || sender.type=='checkbox') {
		return sender.checked && (sender.value == value);
	} else {
		return sender.value == value;
	}
}
