﻿// instantiation
JSAPI = new Object();
// declarations
JSAPI.IsIE = function()
{
    if (document.all) return true;
    else return false;
}

JSAPI.IsNull = function(obj)
{
    if (!obj) return true;
    else return false;
}

JSAPI.GetElementById = function(name)
{
    var obj = document.getElementById(name);
    if (JSAPI.IsNull(obj)) return null;
    
    return obj;
}

JSAPI.Length = function(string)
{  
    if (JSAPI.IsNull(string)) return 0;
    return string.length;
}

JSAPI.IsEmpty = function(string)
{ 
	if (JSAPI.IsNull(string)) return true; // if null, return true
    string = JSAPI.Trim(string);
    if (JSAPI.Length(string) == 0) return true;
    
    return false;
}

// note: pass for instance \\w, \w won't work
JSAPI.RegexTest = function(string, pattern)
{
    var regex = new RegExp(pattern, "gi");
    return regex.test(string);
}

JSAPI.FoundInString = function(string, searchString)
{
    return (string.indexOf(searchString) > -1);
}

function getYear(d) // private
{
	return (d < 1000) ? d + 1900 : d;
}
JSAPI.IsDate = function(strDate)
{
	var arr = strDate.split("/");
	var m = arr[0];
	var d = arr[1];
	var y = arr[2];
	m = m - 1;
	var testDate = new Date(y, m, d);
	
	if ( getYear(testDate.getYear()) == y && testDate.getMonth() == m && testDate.getDate() == d )
	{
		return true;
	}
	else
	{
		return false;
	}
}

JSAPI.IsNumber = function(val)
{
    return (!isNaN(val));
}
JSAPI.Asc = function(ch)
{
    return ch.charCodeAt(0);
}
JSAPI.Chr = function(code)
{
    return String.fromCharCode(code);
}
JSAPI.ConvertToInt32 = function(number)
{
    return parseInt(number);
}

JSAPI.ConvertToDate = function(dateToConvert)
{
	if (JSAPI.IsDate(dateToConvert))
	{
		var arr = dateToConvert.split("/");
		var m = arr[0];
		var d = arr[1];
		var y = arr[2];
		m = m - 1;		
		
		return new Date(y, m, d);
	}
	return null;
}

JSAPI.Mid = function(string, start, end)
{
    if (!start) start = 0;
    if (!end || end > string.length) end = string.length;
    if (end != string.length) end = start + end;
    
    return string.substring(start, end);
}
JSAPI.Replace = function(string, replace_this, replace_with)
{
    while(string.indexOf(replace_this) > -1)
    {
        string = string.replace(replace_this, replace_with);
    }
    return string;
}

JSAPI.Right = function(string, character_count)
{
    return string.substring((string.length - character_count), string.length);
}

JSAPI.Split = function(string, character)
{
    return string.split(character);
}

// #################################### TRIM FUNCTIONS #####################################
JSAPI.Trim = function(string)
{
	if (!string)
	{
		return string;	
	}
	
    string = JSAPI.LTrim(string);
    return JSAPI.RTrim(string);
}
JSAPI.RTrim = function(string)
{
	if (!string)
	{
		return string;	
	}
	
    while (string.charAt((string.length -1)) == " ")
    {
        string = string.substring(0, string.length - 1);
    }
    return string;
}
JSAPI.LTrim = function(string)
{
	if (!string)
	{
		return string;	
	}
	
    while (string.charAt(0) == " ")
    {
        string = string.replace(string.charAt(0), "");
    }
    return string;
}
// ################################## END TRIM FUNCTIONS ###################################

// ############################# ARRAY MANIPULATION FUNCTIONS ##############################
JSAPI.GetArrayValue = function(arr, name, value, text)   
{
    if (JSAPI.IsNull(arr)) return "";
    name = JSAPI.Trim(name);
    if (JSAPI.IsEmpty(name)) return "";
    value = JSAPI.Trim(value);
    if (JSAPI.IsEmpty(value)) return "";
    text = JSAPI.Trim(text);
    if (JSAPI.IsEmpty(text)) return ""; 
        
    // based on name, value array of objects
    var x = 0;
    var item = null;
    for (x = 0; x < arr.length; x++)
    {
        item = arr[x];
        if (item.name == text)
        {
            return item.value;
        }        
    }
    
    return "";
} 

JSAPI.GetArrayLength = function(arr)
{
    if (!arr) return -1;
    return arr.length;
}

// ######################## END ARRAY MANIPULATION FUNCTIONS ###############################

// #################################### CONTROL MANIPULATION FUNCTIONS #####################
JSAPI.GetSelectedValue = function(dropDownList)   
{
    var ddl = document.forms[0][dropDownList];
    var selectedValue = "";
    if (ddl)
    {
        selectedValue = ddl.options[ddl.selectedIndex].value;
    }  
    return selectedValue;
} 

JSAPI.SetValue = function(dropDownList, newValue)   
{
    var ddl = document.forms[0][dropDownList];
    if (ddl)
    {
        ddl.options.value = newValue;
    }  
} 

JSAPI.SetText = function(controlName, text)   
{
    var ctl = document.getElementById(controlName);

    if (JSAPI.IsEmpty(text)) return;
    if (ctl)
    {
        if (JSAPI.IsIE())
        {
            ctl.innerText = text;
        }
        else
        {
            ctl.innerHTML = text;
        }
    }  
} 

// #################################### END CONTROL MANIPULATION FUNCTIONS #################

// #################################### FORM VALIDATION FUNCTIONS ##########################

JSAPI.IsValidEmail = function(email)
{
	var regx = /^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
	if (email.match(regx))
	{
		return true;
	}
	return false;
}

JSAPI.IsValidPhoneNumber = function(phone)
{
	var regx = /^\s*\d?-?\(?\d{3}\)?[\- ]?\s*\d{3}[\- ]\s*\d{4}.*$/;
	if (phone.match(regx))
	{
		return true;
	}
	return false;
}

JSAPI.IsNumber = function(number)
{
    return (!isNaN(number));
}

JSAPI.IsBlank = function(string)
{
	// checks for empty string or string made up of all whitespaces
	if (JSAPI.IsEmpty(string))
	{
		return true;
	}
	var foundValidChar = false;
	var x;
	for(x = 0; x < string.length; x++)
	{
		if(string[x] != "")
		{
			foundValidChar = true;
			break;
		}
	}
	return (!foundValidChar);
}

JSAPI.ValidateFields = function(formName, arrFields, singleFieldValidation, highlightField, color, errorSummaryFieldName) 
{
	// accepts array of objects of following format:
	// {fieldName:"Phone", friendlyName:"Day time phone", required:true, type:"phone", initialValue:"na", checkType:false}
	
	// fieldName = field reference to a field on form to be validated
	// friendlyName = used in error message returned
	// required = if true than field is checked for empty value, otherwise, field is only validated if something's entered in it
	// type = data type in field - possible values: "string", "number", "phone", "email", "email_confirm", "list", "radio"
	// initialValue = only used with "list" data type (dropdown list) - it's the value assigned to initial element so that script knows if a valid element's been selected
	// checkType = if true then type is checked for validity, i.e. if "numeric" used and set to false, the type is not checked, default value is true
	
    // pass true for singleFieldValidation if you want to throw error for every invalid field	
	// pass errorSummaryField as reference to <div> or any other element where you want errors to be written to - innerHTML used
	// otherwise passed null or empty string if you want errors to be displayed in javascript alert box
	
	var errMsgTemplateRequiredField = "Please enter a value for {0}.";
	var errMsgTemplateInvalidField = "Please enter a valid value for {0}.";	
	var errMsgTemplateInvalidRadio = "Please select an option for {0}.";
	var errMsgTemplateInvalidCheckbox = "Please select at least one option for {0}.";	
	
	var field = "";
	var fieldValue = "";
	var fieldInitialValue = "";		
	var fieldFriendlyName = "";
	var fieldType = "";
	var isRequired = true;
	var isCheckType = true;
	var stringBuilder = "";
	var emailField = "";
	var emailConfirmField = "";
	var lineBreak = "\n";
	
	if (JSAPI.IsEmpty(formName))
	{
		return false;	
	}
	var form = document.forms[formName];
	if (JSAPI.IsNull(form))
	{
		return false;	
	}
	
	var htmlErrorDisplay = false;
	var htmlErrorField = null;
	if (JSAPI.IsEmpty(errorSummaryFieldName))
	{
		htmlErrorDisplay = false;
	}
	else
	{
		var errSummaryField = document.getElementById(errorSummaryFieldName);
		if (!JSAPI.IsNull(errSummaryField))
		{
			htmlErrorField = errSummaryField;
			lineBreak = "<br />";
		}
	}
	
	// reset border colors of all elements		
	if(highlightField)
	{
		var i; 
		for(i = 0; i < arrFields.length; i++)
		{
			resetBGColor(arrFields[i].fieldName);
		}
	}

	var x;
	for(x = 0; x < arrFields.length; x++)
	{
		field = arrFields[x].fieldName;
		fieldType = arrFields[x].type;
		if (fieldType != "checkboxlist")
		{
			if (!form.elements[field]) // invalid field
			{
				continue;	
			}
			fieldValue = form.elements[field].value;
		}
		isRequired = arrFields[x].required;	
		
		if (fieldType == "radio")
		{
			// iterate through radio buttons, if any checked, then set dummy value to "checked"
			var radioCounter = 0;
			for(radioCounter = 0; radioCounter < form.elements[field].length; radioCounter++)
			{
				if (form.elements[field][radioCounter].checked)
				{
					fieldValue = "checked";
				}
			}
		}

		if(typeof(arrFields[x].checkType) != "undefined")		
		{		
			isCheckType = arrFields[x].checkType;
		}
		else
		{
			isCheckType = true; // default to check type
		}
			
		if(typeof(arrFields[x].initialValue) != "undefined")	
		{			
			fieldInitialValue = arrFields[x].initialValue;		
		}		
			
		if(JSAPI.IsBlank(arrFields[x].friendlyName))
		{
			fieldFriendlyName = field;
		}
		else
		{
			fieldFriendlyName = arrFields[x].friendlyName;
		}
			
		// if text field is empty, throw a message
		if (isRequired) // field is required
		{
			if ( (JSAPI.IsBlank(fieldValue) || (fieldType == "list" && JSAPI.Equals(fieldValue, fieldInitialValue))) &&
					fieldType != "checkboxlist")
			{
				// iterate through all fields to validate constructing a global error message
				if (fieldType == "radio")
				{
					stringBuilder += constructErrorMessage(errMsgTemplateInvalidRadio, fieldFriendlyName) + lineBreak;	
				}
				else
				{
					stringBuilder += constructErrorMessage(errMsgTemplateRequiredField, fieldFriendlyName) + lineBreak;
				}
				
				if (highlightField) 
				{
				    setBGColor(field, color);
				}
			}
			else
			{
				if (isCheckType)
				{
					switch(fieldType)
					{
					    // TODO: create different phone number formats for coder to choose from
						case "phone":
							if(!JSAPI.IsValidPhoneNumber(fieldValue))
							{
								stringBuilder += constructErrorMessage(errMsgTemplateInvalidField, fieldFriendlyName) + lineBreak;
								if (highlightField) 
								{
								    setBGColor(field, color);
								}
							}
						break;
						case "email":
							if (!JSAPI.IsValidEmail(fieldValue))
							{
								stringBuilder += constructErrorMessage(errMsgTemplateInvalidField, fieldFriendlyName) + lineBreak;
								if (highlightField) 
								{
								    setBGColor(field, color);
								}
							}
							// set email field
							emailField = field;
						break;		
					    case "email_confirm":
						    if (!JSAPI.IsValidEmail(fieldValue))
						    {
							    stringBuilder += constructErrorMessage(errMsgTemplateInvalidField, fieldFriendlyName) + "\n";
							    if (highlightField) 
							    {
							        setBGColor(field, color);
							    }
						    }
						    emailConfirmField = field;							
					    break;											
						case "number":
							if (!JSAPI.IsNumber(fieldValue))
							{
								stringBuilder += constructErrorMessage(errMsgTemplateInvalidField, fieldFriendlyName) + lineBreak;
								if (highlightField) 
								{
								    setBGColor(field, color);
								}
							}
						break;	
						
						case "checkboxlist":
						
							// get all checkboxes with this prefix
							var inputs = document.getElementsByTagName("input");
							var checked = false;
							var ident = "";
							
							var index = 0;
							for (index = 0; index < inputs.length; index++)
							{
								if (inputs[index].type == "checkbox") // inspect checkbox
								{
									ident = inputs[index].name;
									if (JSAPI.IsEmpty(ident))
									{
										ident = inputs[index].id;	
									}
																	
									if (ident.indexOf(field) > -1) // found checkbox of series to validate
									{
										if (inputs[index].checked)
										{
											checked = true; // at least 1 checked, then break
											break;
										}
									}
								}
							}
						
							if (!checked)
							{
								stringBuilder += constructErrorMessage(errMsgTemplateInvalidCheckbox, fieldFriendlyName) + lineBreak;
								if (highlightField) 
								{
								    setBGColor(field, color);
								}
							}

						break;
					}
				}			
			}
		}
		else
		{
			if (isCheckType)
			{
				switch (fieldType)
				{
					case "phone":
						if (!isValidPhoneNumber(fieldValue))
						{
							stringBuilder += constructErrorMessage(errMsgTemplateInvalidField, fieldFriendlyName) + "\n";
							if (highlightField) 
							{
							    setBGColor(field, color);
							}
						}
					break;
					case "email":
						if (!isValidEmail(fieldValue))
						{
							stringBuilder += constructErrorMessage(errMsgTemplateInvalidField, fieldFriendlyName) + lineBreak;
							if(highlightField) setBGColor(field, color);
						}
						emailField = field;						
					break;		
					case "email_confirm":
						if (!isValidEmail(fieldValue))
						{
							stringBuilder += constructErrorMessage(errMsgTemplateInvalidField, fieldFriendlyName) + lineBreak;
							if (highlightField) 
							{
							    setBGColor(field, color);
							}
						}
						emailConfirmField = field;							
					break;							
					case "number":
						if (!isNumber(fieldValue))
						{
							stringBuilder += constructErrorMessage(errMsgTemplateInvalidField, fieldFriendlyName) + lineBreak;
							if (highlightField) 
							{
							    setBGColor(field, color);
							}
						}
					break;		
					
					case "checkboxlist":
						// get all checkboxes with this prefix
						var inputs = document.getElementsByTagName("input");
						var checked = false;
						var ident = "";
						
						var index = 0;
						for (index = 0; index < inputs.length; index++)
						{
							if (inputs[index].type == "checkbox") // inspect checkbox
							{
								ident = inputs[index].name;
								if (JSAPI.IsEmpty(ident))
								{
									ident = inputs[index].id;	
								}								
								
								if (ident.indexOf(field) > -1) // found checkbox of series to validate
								{
									if (inputs[index].checked)
									{
										checked = true; // at least 1 checked, then break
										break;
									}
								}
							}
							
						}
					
						if (!checked)
						{
							stringBuilder += constructErrorMessage(errMsgTemplateInvalidCheckbox, fieldFriendlyName) + lineBreak;
							if (highlightField) 
							{
								setBGColor(field, color);
							}
						}

						break;					
				}
			}
		}
		
		if (singleFieldValidation) // display error immediately
		{
			if (!JSAPI.IsEmpty(stringBuilder)) // some invalid field detected
			{
				if (htmlErrorDisplay)
				{
					alert(stringBuilder);	
				}
				else
				{
					if (!JSAPI.IsNull(htmlErrorField))
					{
						htmlErrorField.innerHTML = stringBuilder;
					}
					else
					{
						alert(stringBuilder);
					}
				}

				form.elements[field].focus();
				
				return false;
			}
		}
	} // end for
	
	// if there's email confirmation field, check that it matches with email field
	if (!JSAPI.IsBlank(emailField) && !JSAPI.IsBlank(emailConfirmField))
	{
		if (typeof(form.elements[emailField]) != "undefined" && typeof(form.elements[emailConfirmField]) != "undefined")
		{
			if (!JSAPI.Equals(form.elements[emailField].value, form.elements[emailConfirmField].value))
			{
				stringBuilder += "The Confirm Email field must match the Email field." + lineBreak;
				if (highlightField) 
				{
				    setBGColor(emailConfirmField, color);	
				}				
			}
		}
	}		

	if (!JSAPI.IsEmpty(stringBuilder))
	{
		if (htmlErrorDisplay)
		{
			alert(stringBuilder);	
		}
		else
		{
			if (!JSAPI.IsNull(htmlErrorField))
			{
				htmlErrorField.innerHTML = stringBuilder;
			}
			else
			{
				alert(stringBuilder);
			}
		}
		
		return false;
	}
	else
	{
		return true;
    }
}

// private
function regexReplace(pattern, replaceString, replaceWith)
{
	return replaceString.replace(pattern, replaceWith);
}

// private
function constructErrorMessage(errMsgTemplate, fieldFriendlyName)
{
	var regXpr = /\{0\}/gi;
	return regexReplace(regXpr, errMsgTemplate, fieldFriendlyName);
}	

JSAPI.Equals = function(string1, string2)
{
	var s1 = string1 + "";
	var s2 = string2 + "";
	
	return (s1 == s2);
}

JSAPI.SetBGColor = function(fieldID, color)
{
	if (document.getElementById(fieldID))
	{		
		document.getElementById(fieldID).style.backgroundColor = color;
    }
}

JSAPI.ResetBGColor = function(fieldID)
{
	if (document.getElementById(fieldID))
	{
		document.getElementById(fieldID).style.backgroundColor = "";
    }
}

// #################################### END FORM VALIDATION FUNCTIONS ##########################