
function chapOpt(bbook, chap, chap2)
{
   var book = $(bbook).getValue();

   setOptNum( chapters[book], chap );
   if( chap2 ) setOptNum( chapters[book], chap2 );
}

function setOptNum( num, field )
{
   $(field).options.length = 0;
   $(field).options[0] = new Option('','--');
   for( var i=1; i<=num; i++ )
   {
      $(field).options[i] = new Option(i,i);
   }
}

function removeOpt( chap, chap2 )
{
   var chapnum = $(chap).getValue();

   for(var i=0; i<chapnum; i++ )
   {
      $(chap2).options[0] = null;
   }
}

function updateVerses(book,chap,verse, verse2)
{
    var booknum = $(book).getValue();
    var chapnum = $(chap).getValue();

    var url = "/api/getBibleNumVerses.php?id="+booknum+"&c="+chapnum;

    var myAjax = new Ajax(url, {method: 'get',
       onComplete: function () 
         { 
           var numverses = myAjax.response.text;
           setOptNum( numverses, verse );
           if( verse2 ) setOptNum( numverses, verse2 );
         }
    }).request();

}

var InputValidator = new Class({
	initialize: function(className, options){
		this.setOptions({
			errorMsg: 'Validation failed.',
			test: function(field){return true}
		}, options);
		this.className = className;
	},
	test: function(field){
		if($(field)) return this.options.test($(field), this.getProps(field));
		else return false;
	},
	getError: function(field){
		var err = this.options.errorMsg;
		if($type(err) == "function") err = err($(field), this.getProps(field));
		return err;
	},
	getProps: function(field){
		if($(field) && $(field).getProperty('validatorProps')){
			try {
				return Json.evaluate($(field).getProperty('validatorProps'));
			}catch(e){ return {}}
		} else {
			return {}
		}
	}
});
InputValidator.implement(new Options);


var FormValidator = new Class({
	initialize: function(form, options){
		this.setOptions({
			fieldSelectors:"input, select, textarea",
			useTitles:false,
			evaluateOnSubmit:true,
			evaluateFieldsOnBlur: true,
			onFormValidate: function(isValid, form){},
			onElementValidate: function(isValid, field){}
		}, options || {});
		try {
			this.form = $(form);
			if(this.options.evaluateOnSubmit) this.form.addEvent('submit', this.onSubmit.bind(this));
			if(this.options.evaluateFieldsOnBlur) this.watchFields();
		}catch(e){//console.log('error: %s', e);
		}
	},
	watchFields: function(){
		try{
			this.form.getElementsBySelector(this.options.fieldSelectors).each(function(el){
				el.addEvent('blur', this.validateField.pass(el, this));
			}, this);
		}catch(e){//console.log('error: %s', e);
		}
	},
	onSubmit: function(event){
		if(!this.validate()) new Event(event).stop();
	},
	reset: function() {
		this.form.getElementsBySelector(this.options.fieldSelectors).each(this.resetField, this);
	},
	validate : function() {
		var result = this.form.getElementsBySelector(this.options.fieldSelectors).map(function(field) { return this.validateField(field); }, this);
		result = result.every(function(val){
			return val;
		});
		this.fireEvent('onFormValidate', [result, this.form]);
		return result;
	},
	validateField: function(field){
		field = $(field);
		var result = true;
		if(field){
			var validators = field.className.split(" ").some(function(cn){
				return FormValidator.getValidator(cn);
			});
			result = field.className.split(" ").map(function(className){
				var test = this.test(className,field);
				return test;
			}, this);
			result = result.every(function(val){
				return val;
			});
			if(validators){
				if(result) field.addClass('validation-passed').removeClass('validation-failed');
				else field.addClass('validation-failed').removeClass('validation-passed');
			}
		}
		return result;
	},
	getPropName: function(className){
		return '__advice'+className;
	},
	test: function(className, field){
		field = $(field);
		var isValid = true;
		if(field) {
			var validator = FormValidator.getValidator(className);
			if(validator && this.isVisible(field)) {
				isValid = validator.test(field);
				//if the element is visible and it failes to validate
				if(!isValid && validator.getError(field)){
					var advice = this.makeAdvice(className, field, validator.getError(field));
					this.insertAdvice(advice, field);
					this.showAdvice(className, field);
				} else this.hideAdvice(className, field);
				this.fireEvent('onElementValidate', [isValid, field]);
			}
		}
		return isValid;
	},
	showAdvice: function(className, field){
		var advice = this.getAdvice(className, field);
		if(advice && !field[this.getPropName(className)] && (advice.getStyle('display') == "none" || advice.getStyle('visiblity') == "hidden" || advice.getStyle('opacity')==0)){
			field[this.getPropName(className)] = true;
			//if element.cnet.js is present, transition the advice in
			if(advice.smoothShow) advice.smoothShow();
			else advice.setStyle('display','block');
		}
	},
	hideAdvice: function(className, field){
		var advice = this.getAdvice(className, field);
		if(advice && field[this.getPropName(className)]) {
			field[this.getPropName(className)] = false;
			//if element.cnet.js is present, transition the advice out
			if(advice.smoothHide) advice.smoothHide();
			else advice.setStyle('display','none');
		}
	},
	isVisible : function(field) {
		while(field.tagName != 'BODY') {
			if($(field).getStyle('display') == "none") return false;
			field = field.parentNode;
		}
		return true;
	},
	getAdvice: function(className, field) {
		return $('advice-' + className + '-' + this.getFieldId(field))
	},
	makeAdvice: function(className, field, error){
		var errorMsg = this.options.useTitles ? $pick(field.title, error):error;
		var advice = this.getAdvice(className, field);
		if(!advice){
			advice = new Element('div').addClass('validation-advice').setProperty(
				'id','advice-'+className+'-'+this.getFieldId(field)).setStyle('display','none').appendText(errorMsg);
		} else{
			advice.setHTML(errorMsg);
		}
		return advice;
	},
	insertAdvice: function(advice, field){
		switch (field.type.toLowerCase()) {
			case 'radio':
				var p = $(field.parentNode);
				if(p) {
					p.adopt(advice);
					break;
				}
			default: advice.injectAfter($(field));
	  };
	},
	getFieldId : function(field) {
		return field.id ? field.id : field.id = "input_"+field.name;
	},
	resetField: function(field) {
		field = $(field);
		if(field) {
			var cn = field.className.split(" ");
			cn.each(function(className) {
				var prop = this.getPropName(className);
				if(field[prop]) this.hideAdvice(className, field);
				field.removeClass('validation-failed');
				field.removeClass('validation-passed');
			}, this);
		}
	}
});
FormValidator.implement(new Options);
FormValidator.implement(new Events);

Object.extend(FormValidator, {
	validators:[],
	add : function(className, options) {
		this.validators[className] = new InputValidator(className, options);
	},
	addAllThese : function(validators) {
		$A(validators).each(function(validator) {
			this.add(validator[0], validator[1]);
		}, this);
	},
	getValidator: function(className){
		return FormValidator.validators[className] = $pick(FormValidator.validators[className], false);
	}
});


FormValidator.add('IsEmpty', {
	errorMsg: false,
	test: function(element) {
		if(element.type == "checkbox")
                        return !element.checked;
		else if(element.type == "select-one"||element.type == "select")
			return !(element.selectedIndex >= 0 && element.options[element.selectedIndex].value != "");
		else
			return ((element.getValue() == null) || (element.getValue().length == 0));
	}
});


FormValidator.addAllThese([
	['req', {
		errorMsg: function(element){return 'This field is required.'},
		test: function(element) {
			return !FormValidator.getValidator('IsEmpty').test(element);
		}
	}],

	['req-cond', {
		errorMsg: 'This field is required.',
		test: function(element, props) {
			if($type(props.isChecked))
                        {
                           var conditionalField = props.isChecked;
                           if( $(conditionalField).checked )
			      return !FormValidator.getValidator('IsEmpty').test(element);
			   else return true;
                        }
			else if($type(props.hasValue) )
                        {
                           var conditionalField = props.hasValue;
                           var conditionalVal = props.isValue;
                           if( $(conditionalField).getValue()==conditionalVal )
			      return !FormValidator.getValidator('IsEmpty').test(element);
			   else return true;
                        }
                        return true;
		}
	}],

	['minLength-cond', {
		errorMsg: function(element, props){
			if($type(props.minLength))
				return 'Please enter at least ' + props.minLength + ' characters.';
			else return '';
		},
		test: function(element, props) {
			if($type(props.isChecked))
                        {
                           var conditionalField = props.isChecked;
                           if( $(conditionalField).checked )
			      return FormValidator.getValidator('minLength').test(element);
			   else return true;
                        }
			else if($type(props.hasValue) )
                        {
                           var conditionalField = props.hasValue;
                           var conditionalVal = props.isValue;
                           if( $(conditionalField).getValue()==conditionalVal )
			      return !FormValidator.getValidator('minLength').test(element);
			   else return true;
                        }
                        return true;
		}
	}],

	['minLength', {
		errorMsg: function(element, props){
			if($type(props.minLength))
				return 'Please enter at least ' + props.minLength + ' characters.';
			else return '';
		},
		test: function(element, props) {
			if($type(props.minLength)) return (element.getValue().length >= $pick(props.minLength, 0));
			else return true;
		}
	}],
	['maxLength', {
		errorMsg: function(element, props){
			//props is {maxLength:10}
			if($type(props.maxLength))
				return 'Please enter no more than ' + props.maxLength + ' characters (you entered ' + element.getValue().length + ' characters).';
			else return '';
		},
		test: function(element, props) {
			//if the value is <= than the maxLength value, element passes test
			return (element.getValue().length <= $pick(props.maxLength, 10000));
		}
	}],
	['validate-number', {
		errorMsg: 'Please enter a valid number in this field.',
		test: function(element) {
				return FormValidator.getValidator('IsEmpty').test(element) || !/[^\d+$]/.test(element.getValue());
		}
	}],
	['validate-digits', {
		errorMsg: 'Please use numbers only in this field. Please avoid spaces or other characters such as dots or commas.',
		test: function(element) {
			return FormValidator.getValidator('IsEmpty').test(element) ||
				(!/[^a-zA-Z]/.test(element.getValue()) && /[\d]/.test(element.getValue()));
		}
	}],
	['validate-alpha', {
		errorMsg: 'Please use letters only (a-z) in this field.',
		test: function (element) {
			return FormValidator.getValidator('IsEmpty').test(element) ||  /^[a-zA-Z]+$/.test(element.getValue())
		}
	}],
	['validate-alphanum', {
		errorMsg: 'Please use only letters (a-z) or numbers (0-9) only in this field. No spaces or other characters are allowed.',
		test: function(element) {
			return FormValidator.getValidator('IsEmpty').test(element) || !/\W/.test(element.getValue())
		}
	}],
	['validate-date', {
		errorMsg: 'Please use this date format: mm/dd/yyyy. For example 03/17/2006 for the 17th of March, 2006.',
		test: function(element) {
			if(FormValidator.getValidator('IsEmpty').test(element)) return true;
	    var regex = /^(\d{2})\/(\d{2})\/(\d{4})$/;
	    if(!regex.test(element.getValue())) return false;
	    var d = new Date(element.getValue().replace(regex, '$1/$2/$3'));
	    return (parseInt(RegExp.$1, 10) == (1+d.getMonth())) &&
        (parseInt(RegExp.$2, 10) == d.getDate()) &&
        (parseInt(RegExp.$3, 10) == d.getFullYear() );
		}
	}],
	['validate-email', {
		errorMsg: 'Please enter a valid email address. For example fred@domain.com .',
		test: function (element) {
			return FormValidator.getValidator('IsEmpty').test(element) || /\w{1,}[@][\w\-]{1,}([.]([\w\-]{1,})){1,3}$/.test(element.getValue());
		}
	}],
	['validate-url', {
		errorMsg: 'Please enter a valid URL.',
		test: function (element) {
			return FormValidator.getValidator('IsEmpty').test(element) || /^(http|https|ftp):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+)(:(\d+))?\/?/i.test(element.getValue());
		}
	}],

	['validate-url-cond', {
		errorMsg: 'Please enter a valid URL.',
		test: function(element, props) {
			if($type(props.isChecked))
                        {
                           var conditionalField = props.isChecked;
                           if( $(conditionalField).checked )
			      return /^(http|https|ftp):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+)(:(\d+))?\/?/i.test(element.getValue());
			   else return true;
                        }
			else if($type(props.hasValue) )
                        {
                           var conditionalField = props.hasValue;
                           var conditionalVal = props.isValue;
                           if( $(conditionalField).getValue()==conditionalVal )
			      return /^(http|https|ftp):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+)(:(\d+))?\/?/i.test(element.getValue());
			   else return true;
                        }
                        return true;
		}
	}],


	['matches', {
		errorMsg: 'The fields do not match',
		test: function(element, props) {
			if($type(props.matchMe))
                        {
                           var conditionalField = props.matchMe;
                           if( $(conditionalField).getValue() != element.getValue() ) return false;
			   else return true;
                        }
                        return true;
		}
	}],



	['validate-date-au', {
		errorMsg: 'Please use this date format: dd/mm/yyyy. For example 17/03/2006 for the 17th of March, 2006.',
		test: function(element) {
			if(FormValidator.getValidator('IsEmpty').test(element)) return true;
	    var regex = /^(\d{2})\/(\d{2})\/(\d{4})$/;
	    if(!regex.test(element.getValue())) return false;
	    var d = new Date(element.getValue().replace(regex, '$2/$1/$3'));
	    return (parseInt(RegExp.$2, 10) == (1+d.getMonth())) &&
        (parseInt(RegExp.$1, 10) == d.getDate()) &&
        (parseInt(RegExp.$3, 10) == d.getFullYear() );
		}
	}],
	['validate-currency-dollar', {
		errorMsg: 'Please enter a valid $ amount. For example $100.00 .',
		test: function(element) {
			// [$]1[##][,###]+[.##]
			// [$]1###+[.##]
			// [$]0.##
			// [$].##
			return FormValidator.getValidator('IsEmpty').test(element) ||  /^\$?\-?([1-9]{1}[0-9]{0,2}(\,[0-9]{3})*(\.[0-9]{0,2})?|[1-9]{1}\d*(\.[0-9]{0,2})?|0(\.[0-9]{0,2})?|(\.[0-9]{1,2})?)$/.test(element.getValue());
		}
	}],
	['validate-one-required', {
		errorMsg: 'Please select at least one of the above options.',
		test: function (element) {
			var p = element.parentNode.parentNode;
			var options = p.getElements('input');
			return $A(options).some(function(el) {
				return el.getValue();
			});
		}
	}]
]);


