///////////////////////////////////////////////////////////////
// File Name: 	library.js
///////////////////////////////////////////////////////////////



/////////////////////////////////////
// popupWindow: To provide consistency in the way popup select windows appear.
/////////////////////////////////////
function popupWindow(windowName,width,height) {
	eval("var " + windowName + " = window.open('','" + windowName + "','width=" + width + ",height=" + height + ",resizable=1,scrollbars=1')");
	eval(windowName + ".focus()");
	return eval(windowName);
}
function popupWindow2(windowName,options) {
	eval("var " + windowName + " = window.open('','" + windowName + "','" + options + "')");
	eval(windowName + ".focus()");
	return eval(windowName);
}

function popupFull(windowName,options) {
	if (options == null) options = "scrollbars=yes,resizable=yes, statusbar=yes,toolbar=yes,menubar=yes,location=yes";
	var top = 0;
	var left = 0;
	var height = screen.availHeight - 100;
	var width = screen.availWidth - 20;
	if (height > 768) {
		height = 768;
	}
	if (width > 1024) {
		width = 1024;
	}
	options = "height=" + height + ",width=" + width + ",top=" + top + ",left=" + left + "," + options;
	return popupWindow2(windowName,options);
}

function upperCase(fieldObj) {
	fieldObj.value = fieldObj.value.toUpperCase();
}

function lowerCase(fieldObj) {
	fieldObj.value = fieldObj.value.toLowerCase();
}

function titleCase(fieldObj) {
	words = fieldObj.value.split(" ");
	for (var i = 0; i < words.length; i ++) {
		words[i] = words[i].substring(0,1).toUpperCase() + words[i].substring(1,words[i].length).toLowerCase()
	}
	fieldObj.value = words.join(" ");
}



///////////////////////////////////////////////////////////////
// Functions for select objects
///////////////////////////////////////////////////////////////

// -------------------------------------------------------------------
// swapOptions(select_object,option1,option2)
//  Swap positions of two options in a select list
// -------------------------------------------------------------------
function swapOptions(obj,i,j) {
	var o = obj.options;
	var i_selected = o[i].selected;
	var j_selected = o[j].selected;
	var temp = new Option(o[i].text, o[i].value, o[i].defaultSelected, o[i].selected);
	var temp2= new Option(o[j].text, o[j].value, o[j].defaultSelected, o[j].selected);
	o[i] = temp2;
	o[j] = temp;
	o[i].selected = j_selected;
	o[j].selected = i_selected;
}
// Move selected options up, if there is room
function moveUp(obj) {
	for (i = 1; i < obj.length; i ++) {
		if (obj[i].selected && !obj[i-1].selected) {
			swapOptions(obj,i,i-1);
		}
	}
}
// Move selected options down, if there is room
function moveDown(obj) {
	// For Netscape 6, keep array of selected options to select afterwards
	selectedArray = new Array();
	for (i = obj.length - 2; i > -1; i --) {
		if (obj[i].selected && !obj[i+1].selected) {
			swapOptions(obj,i,i+1);
			selectedArray.push(i+1);
		}
	}
	for (n = 0; n < selectedArray.length; n ++) {
		obj[selectedArray[n]].selected = true;
	}
}
function selectAll (selectObj) {
	for (i=0; i < selectObj.length; i++) {
		selectObj.options[i].selected = true;
	}
}



///////////////////////////////////////////////////////////////
// Functions for HTML edit
// Author: 	David Hammond
///////////////////////////////////////////////////////////////
function viewingSource(id) {
	return document.f1.elements[id.id + "_Source"].checked;
}
function viewSource(id) {
	id.style.background = "efefef";
	document.all.item(id.id + "_SourceButton").style.background = "FF9999";
	id.innerText = id.innerHTML;
	id.innerText = cleanUp(id.innerText);
	document.f1.elements[id.id + "_Source"].checked = true;
}
function hideSource(id) {
	id.style.background = "ffffff";
	document.all.item(id.id + "_SourceButton").style.background = "cfcfcf";
	id.innerHTML = id.innerText;
	document.f1.elements[id.id + "_Source"].checked = false;
}
function doEdit(id,command,value) {
	if (viewingSource(id)) hideSource(id)
	id.focus();
	id.document.execCommand(command,false,value);
}
function removeFormatting(id) {
	if (viewingSource(id)) hideSource(id);
	// Remove some tags altogether
	id.innerHTML = id.innerHTML.replace(/<\/?(font|span)[^>]*>/gi,"");
	// Remove all attributes from some tags
	id.innerHTML = id.innerHTML.replace(/(<ul|<li) [^>]+>/gi,"$1>");
	// Remove certain attributes
	id.innerHTML = id.innerHTML.replace(/(<[^>]+) style="[^"]+"/gi,"$1");
}
//"
function cleanUp(s) {
	// Strip leading <P> tags
	s = s.replace(/^<P>/i,"");
	// Replace absolute local paths with virtual paths for hyperlinks
	s = s.replace(/(href|src)=\"http:\/\/<%=Request.ServerVariables("HTTP_HOST")%>/gi,"$1=\"");
	// Remove empty paragraphs
	s = s.replace(/<P>&nbsp;<\/P>/gi,"");
	// Insert line breaks
	s = s.replace(/(<br>|<\/p>|<\/ul>)/gi,"$1\n");
	return s;
}

// Simple non-re replace function
function replace(s,subexpr,replacestring) {
	var i = s.indexOf(subexpr);
	if (i > -1) {
		s = s.substring(0,i) + s.substring(i + subexpr.length, s.length)
	}
	return s;
}

///////////////////////////////////////////////////////////////
// VARIABLE DECLARATIONS
///////////////////////////////////////////////////////////////

// regualar expression definitions
var reWhitespace = /^\s+$/
var reEmail = /^.+\@.+\..+$/
var reFloat = /^((\d+(\.\d*)?)|((\d*\.)?\d+))$/

// prompts for "missing" information
var mPrefix = "You did not enter a value into the \""
var mSuffix = "\" field. This is a required field. Please enter it now."
var mPrefix2 = "You did not select a value for \""
var mSuffix2 = "\". This information is required. Please select a value now."

// prompts for "invalid" information
var iEmail = "We have detected an invalid e-mail address. Please review the e-mail address you've entered and try again."


///////////////////////////////////////////////////////////////
// BASIC DATA VALIDATION FUNCTIONS
///////////////////////////////////////////////////////////////

// Check whether string s is empty.
function isEmpty(s) {
	return ((s == null) || (s.length == 0))
}

// Returns true if string s is empty or
// whitespace characters only.
function isWhitespace (s) {
    return (isEmpty(s) || reWhitespace.test(s));
}

// isEmail (STRING s)
function isEmail (s) {
	return reEmail.test(s)
}

// general purpose function to see if a suspected numeric input
// is not empty and is a positive integer
function isNumber(s) {
	return reFloat.test(s)
}

///////////////////////////////////////////////////////////////
// FUNCTIONS TO PROMPT USER
///////////////////////////////////////////////////////////////

// Notify user that required field fieldObj is empty.
// String s describes expected contents of fieldObj.value.
// Put focus in fieldObj and return false.
function warnEmpty (fieldObj, s) {
	if (fieldObj.type != "hidden") {
		fieldObj.focus();
	}
    alert(mPrefix + s + mSuffix);
    return false
}

// Notify user that contents of field fieldObj are invalid.
// String s describes expected contents of fieldObj.value.
// Put select fieldObj, pu focus in it, and return false.
function warnInvalid (fieldObj, s) {
	if (fieldObj.type != "hidden") {
		fieldObj.focus();
	    fieldObj.select()
	}
    alert(s)
    return false
}






///////////////////////////////////////////////////////////////
// FUNCTIONS TO INTERACTIVELY CHECK FIELD CONTENTS
///////////////////////////////////////////////////////////////

// checkText (TEXTFIELD fieldObj, STRING s)
//
// Check that string fieldObj.value is not all whitespace.
function checkText (fieldObj, s) {
	if (isWhitespace(fieldObj.value)) return warnEmpty (fieldObj, s);
    else return true;
}

// checkLength (TEXTAREA fieldObj, INT maxlength, STRING s)
//
// Check length of string fieldObj.value
function checkLength(fieldObj,maxLength,s) {
	if (fieldObj.value.length > maxLength) {
		return warnInvalid (fieldObj, "The value in the \"" + s + "\" field cannot have more than " + maxLength + " characters.\nIt currently has " + fieldObj.value.length + " characters.");
	} else {
		return true;
	}
}


// checkChecked (RADIO|CHECKBOX fieldObj, STRING s)
//
// Check that at least one radio or checkbox is checked
function checkChecked (fieldObj, s) {
	if (fieldObj.length) {
		for (i=0; i < fieldObj.length; i++) {
			if (fieldObj[i].checked) return true;
		}
		fieldObj[0].focus();
	} else {
		if (fieldObj.checked) return true;
		fieldObj.focus();
	}
	alert(mPrefix2 + s + mSuffix2);
	return false;
}

// checkSelected (SELECT fieldObj, STRING s)
//
// Check that at least one option has been selected, and it has a value
function checkSelected (fieldObj, s) {
	for (i=0; i < fieldObj.length; i++) {
		if (fieldObj.options[i].selected && fieldObj.options[i].value.length > 0)	return true;
	}
	fieldObj.focus();
	alert(mPrefix2 + s + mSuffix2);
	return false;
}


// checkEmail (TEXTFIELD fieldObj)
//
// Check that string fieldObj.value is a valid Email.
// It is assumed that empty is okay. Run checkText first if this is required
function checkEmail (fieldObj) {
	if (fieldObj.value != "") {
		if (!isEmail(fieldObj.value)) return warnInvalid (fieldObj, iEmail);
	}
	return true;
}


// checkNumber (TEXTFIELD fieldObj)
//
// Check that string fieldObj.value is a valid number.
// It is assumed that empty is okay. Run checkText first if this is required
function checkNumber(fieldObj, s) {
	// Strip legitimate characters that will cause SQL problems
	var value = fieldObj.value;
	value = value.replace(/[$,]/g,"");
	if (value == "") {
		fieldObj.value = value;
		return true;
	}
	if (!isNumber(value)) {
		return warnInvalid (fieldObj, "The value in field " + s + " must be a number.");
	} else {
		fieldObj.value = value;
		return true;
	}
}

// checkDate (TEXTFIELD fieldObj)
//
// This function accepts a string variable and verifies if it is a
// proper date or not. It validates format matching either
// mm-dd-yyyy or mm/dd/yyyy. Then it checks to make sure the month
// has the proper number of days, based on which month it is.
//
// It is assumed that empty is okay. Run checkText first if this is required
function checkDate(fieldObj, s) {
	dateStr = fieldObj.value;
	if (isEmpty(dateStr)) return true;

	var datePat = /^(\d{1,2})(\/|-)(\d{1,2})(\/|-)((\d{2}|\d{4}))$/;
	var matchArray = dateStr.match(datePat); // is the format ok?
	if (matchArray == null) {
		return warnInvalid (fieldObj,"Value in field " + s + " must be in the form of mm/dd/yyyy.");
	}
	month = matchArray[1]; // parse date into variables
	day = matchArray[3];
	year = matchArray[5];
	if (month < 1 || month > 12) { // check month range
		return warnInvalid (fieldObj,"Month must be between 1 and 12 for field " + s + ".");
	}
	if (day < 1 || day > 31) {
		return warnInvalid (fieldObj,"Day must be between 1 and 31 for field " + s + ".");
	}
	if ((month==4 || month==6 || month==9 || month==11) && day==31) {
		return warnInvalid (fieldObj,"Month "+month+" doesn't have 31 days for field " + s + ".")
	}
	if (month == 2) { // check for february 29th
		var isleap = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
		if (day > 29 || (day==29 && !isleap)) {
			return warnInvalid (fieldObj,"February " + year + " doesn't have " + day + " days for field " + s + ".");
		}
	}
	return true; // date is valid
}

// checkPhone (TEXTFIELD fieldObj)
//
// Check that string fieldObj.value is a valid phone number.
// It is assumed that empty is okay. Run checkText first if this is required
function checkPhone(fieldObj, s) {
	// Strip legitimate characters that will cause SQL problems
	var value = fieldObj.value;
	if (value == "") {
		return true;
	}
	value = value.replace(/\(/g,"");
	value = value.replace(/\)/g,"");
	value = value.replace(/[\s.x-]/g,"");
	if (!isNumber(value)) {
		return warnInvalid (fieldObj, "The value in field " + s + " must be a valid phone number.");
	}
	if (value.length < 10) {
		return warnInvalid (fieldObj, "The value in field " + s + " must be a valid phone number.");
	}
	return true;
}


///////////////////////////////////////////////////////////////
// OTHER UTILITY FUNCTIONS
///////////////////////////////////////////////////////////////


// Get value of checked radio button or checkbox if multiple are present
function getCheckedValue (fieldObj) {
	for (var i = 0; i < fieldObj.length; i++) {
		if (fieldObj[i].checked) { break }
    }
    return fieldObj[i].value
}

// Get value of selected option
function getSelectedValue (fieldObj) {
	for (var i = 0; i < fieldObj.length; i++) {
		if (fieldObj[i].selected) {
			return fieldObj[i].value
		}
    }
    return "";
}


///////////////////////////////////////////////////////////////
// MORE CUSTOM FUNCTIONS
///////////////////////////////////////////////////////////////

function checkZip(x){
	var TrimmedZip=trim(x.value);
	// Zip must be ##### or #####-####
	if (TrimmedZip.length > 0){
		if (TrimmedZip.length != 5 && TrimmedZip.length!=10) {
			alert(ZipAlert);
			x.focus();
			return false;
		}
			
		if (TrimmedZip.length > 5 && TrimmedZip.charAt(5)!='-') {
			alert(ZipAlert); 
			x.focus();
			return false;
		}
		
		if (!allNumAndDash(TrimmedZip)) {
			alert(ZipAlert); 
			x.focus();
			return false;
		}	
			
		for (var i = 0; i < TrimmedZip.length; i++) {
	       	if (TrimmedZip.charAt(i) == '-' && i!=5) {
		   		alert(ZipAlert);
				x.focus();
			 	return false;
		   	}	          
	    } 
	}
	return true;
}

var ZipAlert='Zip codes must be entered as ##### or #####-####.\nFor example: 20001 or 20001-1234'; 

function trim(strText) { 
    // this will get rid of leading spaces 
    while (strText.substring(0,1) == ' ') 
        strText = strText.substring(1, strText.length);

    // this will get rid of trailing spaces 
    while (strText.substring(strText.length-1,strText.length) == ' ')
        strText = strText.substring(0, strText.length-1);

   return strText;
}

function allNumAndDash(string) {
    if (!string) return false;
    var Chars = "0123456789-";

    for (var i = 0; i < string.length; i++) {
       if (Chars.indexOf(string.charAt(i)) == -1)
          return false;
    }
    return true;
}

function checkPhone2(x){
	if (x.value.length > 0 && x.value.slice(0,3)!='011'){
		// Phone number must be ###-###-#### There can be any text added after this, as long as a space precedes it (###-###-####_Ext 55)
		// Numbers starting with 011 are international numbers and are not validated
		
		// Must be at least 12 characters
		if (x.value.length < 12) {
			alert(PhoneAlert);
			x.focus();
			return false;
		}
		//If over 12 characters, 13th character must be a blank (for blank between number and extension info)
		if (x.value.length > 12 && x.value.charAt(12)!=' ') {
			alert(PhoneAlert); 
			x.focus();
			return false;
		}
		// First 12 chars must all be digits or dashes
		var Phone12=x.value.slice(0,12);
		if (!allNumAndDash(Phone12)) {
			alert(PhoneAlert); 
			x.focus();
			return false;
		}	
		// 4th char must be a dash
		if (x.value.charAt(3)!='-') {
			alert(PhoneAlert);
			x.focus();
			return false;
		}	
		// 8th char must be a dash
		if (x.value.charAt(7)!='-') {
			alert(PhoneAlert);
			x.focus();
			return false;
		}	
		//first 12 chars, only 4th and 8th can be dashes
		for (var i = 0; i < Phone12.length; i++) {
	       	if (x.value.charAt(i) == '-' && i!=3 && i!=7) {
		   		alert(PhoneAlert);
				x.focus();
			 	return false;
		   	}	          
	    } 
	}
	return true;
}

var PhoneAlert='Phone numbers must be entered as ###-###-####.\nFor example: 202-555-1212.\nExtension information must be preceded by a blank space.\nFor example: 202-555-1212 ext 15.\nInternational numbers must begin with 011'; 

function textCounter(field, countSpan, maxlimit, addHTMLBRs) {
	// The input parameters are: the field name; field that holds the number of characters remaining; the max. numb. of characters.

	arr = field.value.match(/\n/gi);
	if (arr != null) {
		numNL = arr.length;
	} else {
		numNL = 0;
	}
	if (addHTMLBRs) {
		if (document.all) {
			nlCharCount = 3;
		} else {
			nlCharCount = 4;
		}
	} else {
		nlCharCount = 1;
	}

	maxlimit = maxlimit - (numNL * nlCharCount);
	if (field.value.length > maxlimit) {
		field.value = field.value.substring(0, maxlimit);
	}
	document.getElementById(countSpan).innerHTML  = maxlimit - field.value.length;
}
