/**
 * 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;
	
	//Radio buttons
	this.radioButtons = new Array();
	this.radioButtonsDisplay = new Array();

	//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.addRadioButton = function(name, displayString)
{
	this.radioButtons.push(name);
	if(displayString == null)
		displayString = this.deriveDisplayFromId(name);
	
	this.radioButtonsDisplay.push(displayString);

}
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 = "";
	}
		
	//validate check boxes	
	var checkMsg = this.validateCheckBoxes();	
	if(!checkMsg.isEmpty()){
		error = true;
		msg += checkMsg;
	}
	
	//validate radio buttons
	var buttonMsg = this.validateRadioButtons();
	if(! buttonMsg.isEmpty() ){
		error = true;
		msg += buttonMsg;
	}
		
	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.validateRadioButtons  = function()
{
	var msg = "";

	for(var i = 0; i < this.radioButtons.length; i++)
	{				
		var buttons = document.getElementsByName(this.radioButtons[i], "input");
		var bchecked = false;
		for(var b = 0 ; b < buttons.length ; b++)
		{
			if(	buttons[b].checked )
				bchecked = true;										
		}
		
		if(! bchecked )
			msg +=  this.radioButtonsDisplay[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') 	
}

function addEvent(elm, evType, fn, useCapture) {
	try{
		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;
		}
	}
	catch(e)
	{
		console.log(e);
	}
}