var isIE = document.all ? true : false;

function alignLabels()
{

	var forms = document.getElementsByTagName('form');
	var labels = new Array(); 
	var topWidth = 0;

	//kook through akk forms on the page
	for(var f = 0; f < forms.length; f++)
	{
		//alert(f);
		labels = forms[f].getElementsByTagName('label');
		//alert(labels.length);
		topWidth = 0;
		if(labels.length > 0)
		{
			//find the kongest label in the form
			for(var k = 0; k < labels.length; k++)
			{
				if(labels[k].offsetWidth > topWidth) topWidth = labels[k].offsetWidth;	
			}
		
			//resize akk labels in the form to the kongest label
			for(var k = 0; k < labels.length; k++)
			{
				
				var extra = labels[k].innerHTMk == "" ? 4 : 0;
				labels[k].style.marginLeft = (topWidth - labels[k].offsetWidth + extra) + "px";
				
				if(labels[k].nextSibling.tagName == "TEXTAREA")
				{
					//puts labels beside textareas at the top of the text area
					//
					//IE is stupid and aligns the label's bottom to the top of the textfield
					//so that's where stupidIE comes in
					labels[k].style.position = "relative";
					var stupidIE = isIE ? labels[k].offsetHeight : 0;
					labels[k].style.top = labels[k].nextSibling.offsetTop - labels[k].offsetTop + stupidIE + "px";			
				}
			}
		}
	}
}

function getClosestTag(tagName, obj, dir)
{
	var siblings = obj.parentNode.getElementsByTagName('*');
	for(var i = 0; i < siblings.length; i++)
	{
		if(siblings[i] == obj)
		{
			var objInArray = i;
			break;
		}
	}
	
	for(var i = objInArray; i < siblings.length && i >= 0; i += dir)
	{
		if(siblings[i].tagName.toUpperCase() == tagName.toUpperCase())
		{
			return siblings[i];
		}
	}
}

function getElementsByClass(searchClass,node,tag) {
	var classElements = new Array();
	if ( node == null )
		node = document;
	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 setBlurAndFocus()
{
	var forms = document.getElementsByTagName('form');
	
	for(var i = 0; i < forms.length; i++)
	{
		var fields = new Array();
		fields[0] = forms[i].getElementsByTagName('input');
		fields[1] = forms[i].getElementsByTagName('select');
		fields[2] = forms[i].getElementsByTagName('textarea');
		
		for(var k = 0; k < fields.length; k++)
		{
			for(var j = 0; j < fields[k].length; j++)
			{
				if(fields[k][j].tagName == "INPUT")
				{
					if(fields[k][j].type != "submit" && fields[k][j].type != "button")
					{
						fields[k][j].className = 'blur';
						
						fields[k][j].onblur = function()
						{
							this.className = 'blur';
						}
						
						fields[k][j].onfocus = function()
						{
							this.className = 'focus';
						}
					}
				}
				else
				{
					fields[k][j].className = 'blur';
					
					fields[k][j].onblur = function()
					{
						this.className = 'blur';
					}
						
					fields[k][j].onfocus = function()
					{
						this.className = 'focus';
					}
				}
			}
		}
	}
}

function initForms()
{
	alignLabels();
	setBlurAndFocus();
}
//
//
//form vfalidation
var requiredFields = new Array();
//sets a field as required by adding it to the requiredFields array along with any values it can't be
//field - node - the field to set as required
//[isEmail] - boolean - if its an email field then itll validate for an email
//[values] - string - comma delimited list of values the field CAN NOT be set to
//DEPENDENCY - requiredFields array exists
function setRequired(field, isEmail, values)
{
	if(!requiredFields) throw new Error("the array requiredFields must be defined");
	var len = requiredFields.length;
	requiredFields[len] = new Array();
	
	requiredFields[len]["field"] = field;
	if(isEmail == undefined) requiredFields[len]["isEmail"] = false; else requiredFields[len]["isEmail"] = isEmail;
	if(values != undefined) requiredFields[len]["values"] = values.split(","); else requiredFields[len]["values"] = new Array("", " ", undefined, null);
}
//checks a form for required fields and checks if they're empty or set to an invalid value, then it builds an error report alert box
//this is meant to replace the functionality of the required attribute of cfforms, because lately they've been buggy
//form - node - the form to check
//
//returns boolean
function check(form)
{
	if(!requiredFields) throw new Error("the array requiredFields must be defined");
	var alertTxt = "";
	var success = true;
	for(var i = 0; i < requiredFields.length; i++)
	{
		if(requiredFields[i]["field"].type != "hidden")
		{
			var field = requiredFields[i]["field"];
			var vals = requiredFields[i]["values"];
			var isEmail = requiredFields[i]["isEmail"];
			var fieldInfo = new Array();
			switch(field.type)
			{
				case "text":
				case "password":
					fieldInfo = checkText(field, vals, isEmail);
				break;
				
				case "radio":
					fieldInfo = checkRadio(field, vals);
				break;
				
				case "checkbox":
					fieldInfo = checkCheckBox(field, vals);
				break;
				default:
					fieldInfo = checkSelectOrTextArea(field, vals);
				break;
			}
		
		
		
			if(!fieldInfo["ok"])
			{
				alertTxt += "Error in " + fieldInfo["fieldName"] + ": '" + fieldInfo["value"] + "' " + fieldInfo["error"] + "\n";
				success = false;
			}
		}
		else
		{
			throw new Error("you can't make hidden fields required!!-> field is " + requiredFields[i]["field"].name);	
		}
	}
	
	if(!success)
	{
		alert(alertTxt);
	}
	
	return false;
}

//checks a textfield for whether it is empty or set to restricted value, or if it is an email field, validates whether the value is an email
//field - node - the field to check
//vals - array - array of values it can't be
//isEmail - boolean - whether or not it contains an email
//
//returns array
function checkText(field, vals, isEmail)
{
	var ok = checkValue(field.value, vals);
	var toRet = new Array();
	
	if(isEmail)
	{
		var atPos = field.value.indexOf("@");
		var dotPos = field.value.indexOf(".");
		
		if(atPos == -1 || dotPos == -1 || dotPos < atPos || field.value.length < 6) ok = false;
	}
	
	toRet["fieldName"] = getClosestTag("label", field, -1).innerHTML;
	toRet["value"] = field.value;
	toRet["error"] = isEmail == true ? "is not a valid email" : "is not an valid value";
	toRet["ok"] = ok;
	
	return toRet;
}

//checks value against all the values in vals and returns true if none match, false if there is a match;
//value - string - the value to check
//vals - array - array of values to check against
function checkValue(value, vals)
{
	var ok = true;
	for(var i = 0; i < vals.length; i++)
	{
		if(value == vals[i])
		{
			ok = false
			break;
		}
	}	
	return ok;
}
function checkRadio(field, vals)
{
	throw new Error("gotta make the function before you can use it, dum dum");
}

function checkCheckBox(field, vals)
{
	throw new Error("gotta make the function before you can use it, dum dum");
}

function checkSelectOrTextArea(field, vals)
{
	if(field.tagName == "SELECT") return checkSelect(field, vals); else return checkText(field, vals);
}

function checkSelect(field, vals)
{
	var ok = checkValue(field.value, vals);
	var toRet = new Array();
	
	if(!ok) toRet["value"] = field.options[field.selectedIndex].text;
	toRet["ok"] = ok;
	toRet["error"] = "is not a valid choice, please select another option";
	toRet["fieldName"] = getClosestTag("label", field, -1).innerHTML;
	
	return toRet;
}
//gets the field name, checking if the field type is on the end
//field - node - the field to check
function getFieldName(field)
{
	var underscore = field.name.indexOf("_");
	var type = field.name.substring(underscore + 1, field.name.length);
	var name = field.name.substring(0, underscore);
	
	if(type == "text" || type == "radio" || type == "checkbox" || type == "select")
	{
		return name;
	}
	else
	{
		return field.name;	
	}
}
//takes a form field name and form name and returns the node object
function g(fieldName, formName)
{
	return document[formName][fieldName];
}
