/**
 * Helps validate a page
 */
function RegistrationValidator(){
	//text fields
	this.fields = new Array();
	this.names = new Array();
	this.decorate = true;

	//CheckBoxes
	this.checkBoxes = new Array();
	this.checkBoxesMinimumChecked = new Array();
	this.checkBoxesMaximumChecked = new Array();
	this.checkBoxesDisplay = new Array();
	_this = this;
	
	//add parse function to window onload event
	addEvent(window,'load',this.getFields,false);

	//gets all input fields with class="validate" 
	//and adds them to the validation
	this.getFieldsViaClass= function()	
	{		
		var f = document.getElementsByClassName("validate", "input");
		
		for(var i = 0; i< f.length; i++)
		{						
			this.addField(f[i].id);
		}
	}
}

//event handler
RegistrationValidator.prototype.getFields = function(){
	_this.getFieldsViaClass();	
}
//Adds an input field for validation
//ID: the id of the text field (if camel case, and name is null, then it will be used as the display name)
//name: teh display name to be shown when in error
RegistrationValidator.prototype.addField = function(id, name)
{
	this.fields.push(id);
	if(name == null)
		name = this.deriveDisplayFromId(id);
		
	this.names.push(name);		
}	

RegistrationValidator.prototype.addCheckbox = function(name, displayString, minChecked, maxChecked)
{
	//name: the name all the checkboxes. in php, you can use name="checkboxname[]"
	//dipslayString: the string to display when in error
	
	this.checkBoxes.push(name);
	if(displayString == null)
		displayString = this.deriveDisplayFromId(name); 

	this.checkBoxesDisplay.push(displayString);
	this.checkBoxesMinimumChecked.push(minChecked);
	this.checkBoxesMaximumChecked.push(maxChecked);
	
}

RegistrationValidator.prototype.deriveDisplayFromId = function(id)
{
	var derivedName = "";
	var cur = 0;
	id = id.charAt(0).toUpperCase() + id.substring(1);
	for(var i = 0; i<id.length; i++)
	{
		if(i != 0 && id.charAt(i).isUpperCase())
		{
			n =id.substring(cur,i).toLowerCase(); 	
			derivedName +=  n.charAt(0).toUpperCase() + n.substring(1) + " ";
			cur = i;
		}				
		if(i == id.length -1)
		{					
			n = id.substring(cur);
			derivedName +=  n.charAt(0).toUpperCase() + n.substring(1) + " ";					
		}
	}
	
	return derivedName.trim();
}

//Called by submit button to validate the fields
RegistrationValidator.prototype.validate = function()
{		
	var error = false;
	var msg = "Please fill out the following required information:\n\n";

	for(var i = 0; i <this.fields.length; i++)
	{
		
		var elem = $(this.fields[i]);
		var label = $(elem.id + "_label");	
		if(isEmpty(elem.value))
		{
			error = true;
			msg += this.names[i]+"\n";
			//decorate label
			if(this.decorate && label != null)
					label.className = "error"
		}
		else if(label != null)
			label.className = "";
	}
		
	var checkMsg = this.validateCheckBoxes();
	
	if(!checkMsg.isEmpty()){
		error = true;
		msg += checkMsg;
	}
	
	if(error)
		alert(msg);
		
	return !error;
}

RegistrationValidator.prototype.validateCheckBoxes = function()
{
	var msg = "";
	for(var i = 0; i<this.checkBoxes.length;i++)
	{
		var curName = this.checkBoxes[i];
		var minChecked = this.checkBoxesMinimumChecked[i];
		var maxChecked = this.checkBoxesMaximumChecked[i];
			
		cb = document.getElementsByName(curName);
		
		//at least x number of boxes must be checked
		var checkedSoFar = 0;
		for(var j = 0; j < cb.length; j++)
		{
			if(cb[j].checked)
				checkedSoFar++;				 
		}

		var error = false;
		if(maxChecked == -1 && checkedSoFar < minChecked)
				error = true;				
		
		else if(maxChecked != -1 && (checkedSoFar < minChecked || checkedSoFar > maxChecked))		
			error = true;			
					
		if(error)
			msg += this.checkBoxesDisplay[i] + "\n";
	}

	return msg;
}

RegistrationValidator.prototype.enableDecorator = function()
{
	this.decorate = true;	
}
RegistrationValidator.prototype.disableDecorator = function()
{
	this.decorate = false;
}

//Global helper function
function $() {
	var elements = new Array();
	for (var i = 0; i < arguments.length; i++) {
		var element = arguments[i];
		if (typeof element == 'string')
			element = document.getElementById(element);
		if (arguments.length == 1)
			return element;
		elements.push(element);
	}
	return elements;
}

function isEmpty(value){
	return value == "";	
}

String.prototype.isEmpty = function(){
	return this == "";	
}
String.prototype.trim = function(){
  sInString = this.replace( /^\s+/g, "" );// strip leading
  return sInString.replace( /\s+$/g, "" );// strip trailing
}
String.prototype.isUpperCase = function(){
	return (this >= 'A') && (this <= 'Z') 	
}

//Tag is optional
Document.prototype.getElementsByClassName = function (searchClass, tag)
{
	var classElements = new Array();	
	node = this;
	if ( tag == null )
		tag = '*';
	var els = node.getElementsByTagName(tag);
	var elsLen = els.length;
	var pattern = new RegExp('(^|\\s)'+searchClass+'(\\s|$)');
	for (i = 0, j = 0; i < elsLen; i++) {
		if ( pattern.test(els[i].className) ) {
			classElements[j] = els[i];
			j++;
		}
	}
	return classElements;		
}

function addEvent(elm, evType, fn, useCapture) {
	if (elm.addEventListener) {
		elm.addEventListener(evType, fn, useCapture);
		return true;
	}
	else if (elm.attachEvent) {
		var r = elm.attachEvent('on' + evType, fn);
		return r;
	}
	else {
		elm['on' + evType] = fn;
	}
}
