// Global functions

function getFirstForm(formName) {
	var form = document.forms[formName];
	if (form) {
		return $(isArray(form) ? form[0] : form);
	}
	return null;
}

function getForm(formName) {
	return $(document.forms[formName]);
}

function isArray(obj) {
	return (obj.length) && (!obj.elements);
}

function loadPage(url) {
	window.location = url;
}

// Display functions

function ImageInfo(imageId,imageOnSrc,imageOffSrc) {
	this.imageId = imageId;
	this.imageOnSrc = imageOnSrc;
	this.imageOffSrc = imageOffSrc;
}

function swapTabs(imageInfos,id) {
	imageInfos.each(function(imageInfo) {
		var imageId = $(imageInfo.imageId);

		if(imageId != null) {
			if(imageInfo.imageId==id) {
				imageId.src=imageInfo.imageOnSrc;
			}
			else {
				imageId.src=imageInfo.imageOffSrc;
			}
		}
	});

	return true;
}

function DISPLAY_hideAllForClass(className) {
	$$(className).each(function(value) {
		Element.hide(value);
	});
}

function DISPLAY_showAllForClass(className) {
	$$(className).each(function(value) {
		Element.show(value);
	});
}

function DISPLAY_showIdOnlyForClass(className, id) {
	$$(className).each(function(value) {
		Element.hide(value);
	});

	if(id) {
		Element.show(id);
	}
}

function DISPLAY_toggleAllForClass(className) {
	$$(className).each(function(value) {
		Element.toggle(value);
	});
}

function DISPLAY_toggleIdOnlyForClass(className, id) {
	$$(className).each(function(value) {
		if (value.id == id) {
			Element.toggle(value);
		}
	});
}

// Image functions

function IMAGE_create(src) {
	var image = new Image();
	image.src = src;
	return image;
}

function IMAGES_showImageAllForClass(className, img) {
	$$(className).each(function(value) {
		value.src = img;
	});
}

function IMAGES_toggle(id, first_img, second_img) {
	imageElement = $(id);
	imageElement.src = imageElement.src.match(first_img) ? second_img : first_img;
}

function IMAGES_toggleAllForClass(className, first_img, second_img) {
	$$(className).each(function(value) {
		value.src = value.src.match(first_img) ? second_img : first_img;
	});
}

function IMAGES_toggleIdOnlyForClass(className, id, first_img, second_img) {
	$$(className).each(function(value) {
		if (value.id == id) {
			value.src = value.src.match(first_img) ? second_img : first_img;
		}
	});
	return true;
}

// Number functions

function NUMBER_formatDollar(number){
	//???   Work around for IE.  Theory being that when toFixed(2)
	//is called on a negative float in IE, the sign of the Float remains
	//the same even if the result is 0.00.  There must be a more eloquent
	//way around this, but this seems to work and hopefully this will improve
	//during the code review process.
	var roundedNumber  = Math.round(100*number.toFixed(2))/100;
	var roundedNumberString  = "" + roundedNumber.toFixed(2);

	//add commas if neccessary.
	var regExpression = /(-?\d+)(\d{3})/;

	while(regExpression.test(roundedNumberString)){
		roundedNumberString = roundedNumberString.replace(regExpression, "$1,$2");
	}

	return roundedNumberString;
}

function NUMBER_isDivisibleBy(num1,num2) {
	return ((num1 % num2) == 0);
}

// Date functions

function DATE_isLeapYear(year) {
	return (NUMBER_isDivisibleBy(year,4) && (!NUMBER_isDivisibleBy(year,100) || NUMBER_isDivisibleBy(year,400)));
}

function DATE_isValid(year,month,day) {
	if ((year >= 0) && (year <= 9999)) {
		if ((month >= 0) && (month <= 11)) {
			daysInMonth = 0;
			switch (month) {
				case  0: daysInMonth = 31; break; // Jan
				case  1: daysInMonth = DATE_isLeapYear(year) ? 29 : 28; break; // Feb
				case  2: daysInMonth = 31; break; // Mar
				case  3: daysInMonth = 30; break; // Apr
				case  4: daysInMonth = 31; break; // May
				case  5: daysInMonth = 30; break; // Jun
				case  6: daysInMonth = 31; break; // Jul
				case  7: daysInMonth = 31; break; // Aug
				case  8: daysInMonth = 30; break; // Sep
				case  9: daysInMonth = 31; break; // Oct
				case 10: daysInMonth = 30; break; // Nov
				case 11: daysInMonth = 31; break; // Dev
			}
			if ((day >=0) && (day <= daysInMonth)) {
				return true;
			}
		}
	}
	return false;
}

// String functions

function STRING_repeatChar(ch,len) {
	var str = '';
	for (var i = 0; i < len; i++) {
		str += ch;
	}
	return str;
}

// Note: Parameter ch defaults to a space.
function STRING_padLeft(str,len,ch) {
	if (arguments.length < 3) { ch = ' '; };
	return STRING_repeatChar(ch,len-str.length,ch) + str;
}

function STRING_countLeadingChars(str,ch) {
	for (var i = 0; i < str.length; i++) {
		if (str.charAt(i) != ch) {
			return i;
		}
	}
	return str.length;
}

function STRING_countTrailingChars(str,ch) {
	for (var i = 0; i < str.length; i++) {
		if (str.charAt(str.length-1-i) != ch) {
			return i;
		}
	}
	return str.length;
}

function STRING_trimChars(str,ch) {
	var lchars = STRING_countLeadingChars(str,ch);
	var rchars = STRING_countTrailingChars(str,ch);
	return str.substring(lchars,str.length-rchars);
}

function STRING_trimLeadingChars(str,ch) {
	var lchars = STRING_countLeadingChars(str,ch);
	return str.substring(lchars,str.length);
}

function STRING_trim(str) {
	return STRING_trimChars(str,' ');
}

function STRING_trimLeadingZeros(str) {
	return STRING_trimLeadingChars(str,'0');
}

function STRING_equalIgnoreCase(str1,str2) {
	var stric1 = str1.toLowerCase();
	var stric2 = str2.toLowerCase();
	return (stric1 == stric2);
}

function STRING_parseInt(str) {
	var trimmedStr = STRING_trim(str);
	if (trimmedStr != '') {
		trimmedStr = STRING_trimLeadingZeros(trimmedStr);
		if (trimmedStr == '') { trimmedStr = '0'; }
	}
	return parseInt(trimmedStr);
}

function STRING_formatInt(i) {
	return i + '';
}

function STRING_formatZeroPaddedInt(i,len) {
	return STRING_padLeft(STRING_formatInt(i),len,'0');
}

function STRING_formatDateMMsDDsYY(date,separator) {
	if (!separator) { separator = '/'; }
	return STRING_formatZeroPaddedInt(date.getMonth()+1,2) +
	       separator +
	       STRING_formatZeroPaddedInt(date.getDate(),2) +
	       separator +
	       STRING_formatInt(date.getFullYear()).substr(2,2);
}

function STRING_isValidDateMsDsYY(str) {
	var good = /^\d{1,2}([\/\-\.])\d{1,2}\1\d{2}$/;
	return (str.match(good) != null);
}

function STRING_isValidDateMsDsYYYY(str) {
	var good = /^\d{1,2}([\/\-\.])\d{1,2}\1\d{4}$/;
	return (str.match(good) != null);
}

function STRING_parseDateMsDsYY(str) {
	if (STRING_isValidDateMsDsYY(str)) {
		separator = str.substr(str.length-3,1);
		index1 = str.indexOf(separator);
		index2 = str.indexOf(separator,index1+1);
		month = STRING_parseInt(str.substring(0,index1))-1;
		day = STRING_parseInt(str.substring(index1+1,index2));
		year = STRING_parseInt(str.substring(index2+1));
		year += (year < 50) ? 2000 : 1900;
		if (DATE_isValid(year,month,day)) {
			return new Date(year,month,day);
		}
	}
	return null;
}

function STRING_parseDateMsDsYYYY(str) {
	if (STRING_isValidDateMsDsYYYY(str)) {
		separator = str.substr(str.length-5,1);
		index1 = str.indexOf(separator);
		index2 = str.indexOf(separator,index1+1);
		month = STRING_parseInt(str.substring(0,index1))-1;
		day = STRING_parseInt(str.substring(index1+1,index2));
		year = STRING_parseInt(str.substring(index2+1));
		if (DATE_isValid(year,month,day)) {
			return new Date(year,month,day);
		}
	}
	return null;
}

function STRING_parseDateInput(str) {
	if (STRING_isValidDateMsDsYY(str)) {
		return STRING_parseDateMsDsYY(str);
	}
	if (STRING_isValidDateMsDsYYYY(str)) {
		return STRING_parseDateMsDsYYYY(str);
	}
	return null;
}

// Select functions

function SELECT_getSelectedValue(select) {
	var index = select.selectedIndex;
	if ((index >= 0) && (index < select.length)) {
		return select.options[index].value;
	}
	return '';
}

function SELECT_selectOptionByValue(select,value) {
	for (var i = 0; i < select.length; i++ ) {
		if (select.options[i].value == value) {
			select.selectedIndex = i;
			return true;
		}
	}
	select.selectedIndex = -1;
	return false;
}

function SELECT_submit(select) {
	var value = SELECT_getSelectedValue(select);
	if (value != '') {
		select.form.submit();
	}
	return false;
}

// Radio functions

function $RF(element, radioGroup) {
	if($(element).type == 'radio') {
		element = $(element).form;
		radioGroup = $(element).name;
	} else if ($(element).tagName.toLowerCase() != 'form') {
		return null;
	}

	return $F($(element).getInputs('radio', radioGroup).find(
		function(re) {return re.checked;}
	));
}

function RADIO_GROUP_setValue(radioGroup,value) {
	for (var i = 0; i < radioGroup.length; i++) {
		if (radioGroup[i].value == value) {
			radioGroup[i].checked = true;
		}
	}
}

// Element functions

function ELEMENT_clearFormErrors() {
	$$('.error').each(function(value) {
		value.innerHTML = '';
	});
}

function ELEMENT_clearFormFields(element){
	var inputElements  = $A(element.getElementsByTagName('input'));
	var selectElements = $A(element.getElementsByTagName('select'));

	var elements = inputElements.concat(selectElements);

	for( var i = 0; i < elements.length; i++ ) {
		elements[i].value = '';
	}
}

function ELEMENT_isHidden(element) {
	return ELEMENT_isType(element,'hidden');
}

function ELEMENT_isType(element,typeName) {
	return (element.type) && STRING_equalIgnoreCase(element.type,typeName);
}

// Form functions

function FORM_focusFirstElement(form) {
	var elements = form.elements;
	for (var i = 0; i < elements.length; i++) {
		if (!ELEMENT_isHidden(elements[i]) && (elements[i].focus) && !elements[i].disabled) {
			elements[i].focus();
			return true;
		}
	}
	return false;
}

// Deprecated - use "form.elements[elementName]"
function FORM_getField(form,elementName) {
	if (form) {
		var elements = form.elements;
		for (var i=0; i < elements.length; i++) {
			if ((elements[i].name) && (elements[i].name == elementName)) {
				return elements[i];
			}
		}
	}
	return null;
}

// NOTE: We need to loop through the source form rather than the destination form in the following method because if
//       we call srcForm.elements['stringName'] for a radio element we will get an array not a form element.
function FORM_copyCommonValues(destForm, srcForm) {
	for (var i = 0; i < srcForm.elements.length; i++) {
		var srcElement  = srcForm.elements[i];
		var destElement = destForm.elements[srcElement.name];

		if (destElement) {
			FORM_copyElementValue(destElement, srcElement);
		}
	}
}

function FORM_copyElementValue(destElement, srcElement)
{
	var srcType  = srcElement.type.toLowerCase();
	var srcValue = FORM_getElementValue(srcElement);

	if (srcType == 'radio') {
		if (srcElement.checked) {
			destElement.value = srcValue;
		}
	} else {
		destElement.value = srcValue;
	}
}

function FORM_getElementValue(element) {
	var type = element.type.toLowerCase();

	if (type == 'radio') {
		if (element.checked) {
			return element.value;
		} else {
			return null;
		}
	} else {
		return element.value;
	}
}

// Onload functions

var ONLOAD_events = new Array();

function ONLOAD_addEvent(func) {
	ONLOAD_events.push(func);
	window.onload = ONLOAD_do;
}

// Deprecated - use "doOnLoad(func)"
function ONLOAD_do() {
	for (var i = 0; i < ONLOAD_events.length; i++) {
		ONLOAD_events[i]();
	}
}

function doOnLoad(func) {
	Event.observe(window, 'load', func);
}

function doOnUnload(func) {
	Event.observe(window, 'unload', func);
}

function doOnReady(func) {
	document.observe('dom:loaded', func);
}

// Helper Text

var HelperText = {
	_CSS_CLASS_NAME: 'helpertext',

	hide: function(element) {
		element = $(element);
		if (element.helperText) {
			if (element.hasClassName(HelperText._CSS_CLASS_NAME)) {
				element.removeClassName(HelperText._CSS_CLASS_NAME);
				if (element.value == element.helperText) {
					element.value = '';
				}
			}
		}
	},

	show: function(element) {
		element = $(element);
		if (element.helperText) {
			if (element.value == '') {
				element.addClassName(HelperText._CSS_CLASS_NAME);
				element.value = element.helperText;
			}
		}
	},

	getRealValue: function(element) {
		element = $(element);
		var value = element.value;
		if (element.hasClassName(HelperText._CSS_CLASS_NAME)) {
			if (value == element.helperText) {
				value = '';
			}
		}
		return value;
	},

	decorate: function(element, helperText) {
		element = $(element);

		element.helperText = helperText;

		Event.observe(
			element,
			'focus',
			(function() { HelperText.hide(this); }).bindAsEventListener(element)
		);

		Event.observe(
			element,
			'blur',
			(function() { HelperText.show(this); }).bindAsEventListener(element)
		);

		if (element.form) {
			Event.observe(
				element.form,
				'submit',
				(function() { HelperText.hide(this); }).bindAsEventListener(element)
			);
		};

		HelperText.show(element);
	},

	decorateForm: function(form, infos) {
		form = $(form);
		infos.each(
			function(info) {
				HelperText.decorate(form.elements[info.element], info.text);
			}
		);
	}
};
