
//I HATE the standard spelling of this function, so here's a synonym
document.getElementByID = document.getElementById;

function getTag(idOrObj) {
	/* returns an object reference to the tag object
		idOrObj: can be a tag object, the string ID of the object, or an event object
		-- if idOrObj is already the tag, nothing happens
	*/
	if (typeof idOrObj.tagName != 'string') {
		if (typeof idOrObj == 'string') idOrObj = document.getElementById(idOrObj);   //ID was passed
		else if (typeof idOrObj.srcElement == 'object') idOrObj = idOrObj.srcElement; //event object was passed
	}
	return idOrObj;
}

function cleanMyDateField(inputObject) {
	//inputObject must be an INPUT element (or something with the value property)
	//resets the value with the standard date format; on error, fails silently
	try {
		inputObject.value = standardDateFormat(inputObject.value);
	} catch(e) {
		;
	}
}

function standardDateFormat(theDate, doAbbr) {
	/* returns a formatted date string that is standard across the application, client- and server-side
		if theDate is null, returns a 0-length string
		doAbbr -- not required (defaults to true) -- if true, month name is abbreviated
	*/
	
	if (theDate == null) return '';
	dateObj = transformDate(theDate);
	
	if (typeof doAbbr != 'boolean') doAbbr = true;
	
	if (dateObj == false) {
		throw 'Date formatting error.';
	} else {
		//reformat the date
		var year = dateObj.getFullYear();
		
		/* 2-digit years might be interpreted wrongly, like "04" becoming "1904"
			this is tricky, because they may have entered a 4-digit date and we don't want to "correct" it in that case
			so we'll assume it's a 2-digit translation error if the 4-digit form can't be found in the string
		*/ 
		if (year < 1940 && theDate.indexOf(year) < 0) {
			year = '20' + year.toString().substr(2, 2);
		}
		
		return monthFromNum(dateObj.getMonth(), doAbbr) + ' ' + dateObj.getDate() + ' ' + year;
		
		/* this is my preference, but Americans... well, what are you gonna do with us Americans? :-)
			return dateObj.getDate() + ' ' + monthFromNum(dateObj.getMonth(), doAbbr) + ' ' + year;
		*/
	}
}

function roundOff(theNumber, decimalPlaces) {
	//if theNumber is a string, uses parseFloat to convert it, but does NOT catch the possible isNaN error
	
	if (typeof theNumber != 'number') theNumber = parseFloat(theNumber);
	var multiplier = Math.pow(10, Math.abs(decimalPlaces));
	theNumber = Math.round(theNumber * multiplier)/multiplier;
	return theNumber;
}

function monthFromNum(monthNum, doAbbr) {
	//converts the month number (0=January) to the standard textual representation
	if (doAbbr) {
		var	monthName =	new	Array('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
	} else {
		var	monthName =	new	Array('January','February','March','April','May','June','July','August','September','October','November','December');
	}
	return monthName[monthNum];
}

function dayFromNum(dayNum, doAbbr) {
	//converts the day number (0=Sunday) to the standard textual representation
	if (doAbbr) {
		var dayName = new Array('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat');
	} else {
		var dayName = new Array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday');
	}
	return dayName[dayNum];
}

function transformDate(theDate) {
	/* if passed theDate can be a Date instance, an integer representing a date, or a formatted date string
		(if not passed, defaults to now)
		this ftn. returns it as a Date object, or returns false if theDate can't be converted
		
		(taken from my BDS 4 code)
	*/
	
	//default theDate to now
	if (typeof theDate == 'undefined') theDate = new Date();
	
	//on the server side (at least in VBScript), the date might be of subtype "date"
	if (typeof theDate == 'date') {
		/*I know this looks weird, but it guarantees coersion to a string
			the usual technique fails: theDate = theDate.toString();
			probably because theDate as passed from VBScript is not an object in the JScript sense
		*/
		theDate = theDate + '';
	}
	
	if (typeof theDate == 'string') {
		theDate = Date.parse(theDate);
		if (isNaN(theDate)) return false; //ERROR CONDITION return (unparseable string) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
	}
	
	//at this point, theDate can either be a number or a Date
	if (typeof theDate == 'number') {
		theDate = new Date(theDate);
	}
	
	return theDate; //success
}

function isNull(theValue) {
	if (theValue == null || typeof theValue == 'undefined') return true;
	else if (theValue.toString().length < 1) return true;
	else return false;
}

function isNumber(theString, allowFloat, allowNull) {
	//uses a reg exp to test whether the number is either an integer or a float
	var patternOfValids = '0-9\-';
	if (allowFloat) patternOfValids += '.';
	var theRE = new RegExp('[^' + patternOfValids + ']', 'gi');
	
	if (allowNull && isNull(theString)) return true;
	if (theRE.test(theString)) return false;
	if (theString.indexOf('-') > 0) return false;
	if (theString.indexOf('.') != theString.lastIndexOf('.')) return false;
	
	//if we get here, it passed
	return true;
}

//a richer numeric validation
function validateNumeric(theTag, allowFloat, allowNull, lBound, uBound) {
	//other properties are optional; allowFloat and allowNull default to true
	
	if (typeof isNullable == 'undefined') isNullable = true;
	if (typeof allowFloat == 'undefined') allowFloat = true;
	
	var theNum = theTag.value;
	var isValid = isNumber(theNum, allowFloat, allowNull);
	
	if (isValid && !isNull(theNum)) {
		//test boundaries, if provided; clear the display of an earlier error if it's all OK
		theNum = parseFloat(theNum);
		if (typeof lBound != 'undefined') {
			if (theNum < lBound) isValid = false;
		} 
		if (typeof uBound != 'undefined') {
			if (theNum > uBound) isValid = false;
		}
	}
	
	return isValid;
}

function isEmailAddy(theValue) {
	//uses RE to validate e-mail address
	//minimum acceptible value looks like a@b.cc
	
	//check to see that there is only 1 @ symbol in theValue... 
	//could probably work this into the RE but would be it too complicated -- too many character groupings in [ ]
	if (theValue.indexOf('@') != theValue.lastIndexOf('@')) return false;
	
	//the RE below passes glen.ford@yahoo.com, a@b.co.uk, etc.
	//but fails @123.com, glen@ya&$#.com, glen@yahoo.c, glen@yahoo.co.u, etc.
	var reEmail = /^\S+\@[a-zA-Z0-9-]+(\.[a-zA-Z0-9]{2,})+$/
	return reEmail.test(theValue);
}

function validateDate(theTag, canBeBlank) {
	/* checks the date for validity based on JScript's Date.parse method
		if valid, re-formats the date and returns true
		else, sets the validation message and returns false
		
	in immediate validation (onblur), the return actually cancels the blur, 
		meaning the user can not click/tab away from the field until they correct the entry;
		THEREFORE, canBeBlank MUST BE TRUE during immediate validation!
		(I've tried to intercept this situation when resolving theTag, above.)
	*/
	
	theTag = getTag(theTag);
	
	var isValid;
	var theValue = theTag.value.toString();
	
	if (canBeBlank && theValue.length < 1) return true;
	
	var dateInt = Date.parse(theTag.value);
	
	if (isNaN(dateInt)) {
		//setValMsg(theTag, 'Please enter a valid date.');
		isValid = false;
	} else {
		//theTag.value = standardDateFormat(dateInt);
		//clearValMsg(theTag);
		isValid = true;
	}
	
	return isValid;
}

function validateTextAreaLength(theTag, maxLength) {
	//returns false if the text length in a textarea exceeds maxLength
	//needed in addition to showTextAreaLength in non-IE clients
	theTag = getTag(theTag);
	if (theTag.value.length > maxLength) return false;
	else return true;
}

function valScroll(theTag) {
	//scrolls to the validation message displayed in-line in the page -- fails silently if not IE
	try {
		theTag = getTag(theTag);
		theTag.scrollIntoView();
	} catch(e) {
		;
	}
}

function toggleDisplay(tagID) {
	//at this time, this toggles display between INLINE and NONE only
	var theTag = getTag(tagID);
	if (theTag.style.display == 'none') {
		theTag.style.display = 'inline';
	} else {
		theTag.style.display = 'none';
	}
}

function toggleInputClass(theTag, isMouseOut) {
	//call this for mouseOver/Out as well as focus/blur -- attatch to the LABEL too
	//if input is diabled, does nothing
	
	//revised 2003-12-07 to support LABEL tag
	theTag = getTag(theTag);
	var newClass;
	
	if (!theTag.disabled) {
		if (isMouseOut) newClass = 'inactiveInput';
		else 			newClass = 'activeInput';
		
		//append class name if it's a LABEL tag
		if (theTag.tagName.toLowerCase() == 'label') newClass += '_label';
		
		//set the class
		theTag.className = newClass;
	}
}