// String Functions ===============================================================================

function LTrim(inStr)
{
	return ltrim(inStr);
}

function ltrim(inStr)
{
	var newString = "";

	for (var i=0; i<inStr.length; i++)
		if (inStr.charAt(i) != " ")
			break;
	return inStr.substring(i, inStr.length);
}

function Trim(inStr)
{
	return trim(inStr);
}

function trim(inStr)
{
	var tempStr = ltrim(inStr);

	for (var i=tempStr.length-1; i>0; i--)
		if (tempStr.charAt(i) != " ")
			break;
	return tempStr.substring(0, i+1);
}

function TrimLeadingZero(inStr)
{
	return trimLeadingZero(inStr);
}

function trimLeadingZero(inStr)
{
	var newString = "";

	for (var i=0; i<inStr.length; i++)
		if (inStr.charAt(i) != "0")
			break;
	return inStr.substring(i, inStr.length);
}

function ListLen(list, separator)
{
	return listLen(list, separator);
}

function listLen(list, separator)
{
	var oList = list.split(separator ? separator : ",");

	if (trim(list) != "")
		return oList.length;
	else
		return 0;
}

function ListFind(list, inStr, separator)
{
	return listFind(list, inStr, separator);
}

function listFind(list, inStr, separator)
{
	return arrayFind(list.split(separator ? separator : ","), inStr);
}

function ListFindNoCase(list, inStr, separator)
{
	return listFindNoCase(list, inStr, separator);
}

function listFindNoCase(list, inStr, separator)
{
	return arrayFindNoCase(list.split(separator ? separator : ","), inStr);
}

function ListGetAt(list, iPos, separator)
{
	return listGetAt(list, iPos, separator);
}

function listGetAt(list, iPos, separator)
{
	var oList = list.split(separator ? separator : ",");
	return (iPos < oList.length ? oList[iPos] : null);
}

function listAppend(list, inStr, separator)
{
	return ListAppend(list, inStr, separator);
}

function ListAppend(list, inStr, separator)
{
	return (list + (list == "" ? "" : (separator ? separator : ",")) + inStr);
}

function GetURLParam(param, name)
{
	var i;
	
	for (i=0; i<ListLen(param, "&"); i++)
	{
		if (ListGetAt(ListGetAt(param, i, "&"), 0, "=").toUpperCase() == name.toUpperCase())
		{
			if (ListLen(ListGetAt(param, i, "&"), "=") == 2)
				return ListGetAt(ListGetAt(param, i, "&"), 1, "=");
			else
				return "";
		}
	}
}

function SetURLParam(param, name, value)
{
	var i;
	var rpara = "";
	var isFound = false;
	
	for (i=0; i<ListLen(param, "&"); i++)
	{
		if (ListGetAt(ListGetAt(param, i, "&"), 0, "=").toUpperCase() == name.toUpperCase())
		{
			if (rpara.length)
				rpara = rpara + "&" + name + "=" + value;
			else
				rpara = name + "=" + value;
			isFound = true;
		}
		else
		{
			if (rpara.length)
				rpara = rpara + "&" + ListGetAt(param, i, "&");
			else
				rpara = ListGetAt(param, i, "&");
		}
	}
	if (!isFound)
	{
		if (param.length)
			rpara = param + "&" + name + "=" + value;
		else
			rpara = name + "=" + value;
	}
	return rpara;
}

function RemoveURLParam(param, name)
{
	var i;
	var rpara = "";
	
	for (i=0; i<ListLen(param, "&"); i++)
	{
		if (ListFindNoCase(name, ListGetAt(ListGetAt(param, i, "&"), 0, "=")) == -1)
		{
			if (rpara.length)
				rpara += "&" + ListGetAt(param, i, "&");
			else
				rpara = ListGetAt(param, i, "&");
		}
	}
	return rpara;
}

// Array Functions ================================================================================

function arrayFind(oArray, inStr)
{
	var i;
	for (i=0; i<oArray.length; i++)
		if (oArray[i] == inStr)
			return i;

	return -1;
}

function arrayFindNoCase(oArray, inStr)
{
	var i;
	for (i=0; i<oArray.length; i++)
		if (oArray[i].toUpperCase() == inStr.toUpperCase())
			return i;

	return -1;
}


// Date-time Functions ============================================================================

function dateDiff(date1, date2)
{
	return (Date.parse(date2)-Date.parse(date1)) / (24*60*60*1000);
}

function dateSub(date, iDate)
{
	return new Date(Date.parse(date)-(iDate*(24*60*60*1000)));
}

function dateAdd(date, iDate)
{
	return new Date(Date.parse(date)+(iDate*(24*60*60*1000)));
}

function monthAdd(date, iMonth) //Please test carefully before use this function!
{
	var iM = date.getMonth();
	var iY = date.getYear();
	var iD = date.getDate();
	var i;
	var iTotalDate;

	for (i=0; i<iMonth; i++)
	{
		iM++;
		if (iM >= 12)
		{
			iM = 0;
			iY++;
		}
	}
	iTotalDate = dateInMonth(iY, iM+1);
	return new Date(iY, iM, iTotalDate < iD ? iTotalDate : iD);
}


function dateInMonth(iYear, iMonth)
{
	var isLeap;
	var iDay = -1;

	if (iMonth >= 1 && iMonth <= 12)
	{
		iDay = (iMonth == 4 || iMonth == 6 || iMonth == 9 || iMonth == 11) ? 30 : 31;

		if (iMonth == 2)
		{
			isLeap = (((iYear % 4 == 0) && (iYear % 100 != 0)) || iYear % 400 == 0);
			iDay = isLeap ? 29 : 28;
		}
	}

	return iDay;
}

function dateToDMY(date)
{
	return (date.getDate() < 10 ? "0":"") + date.getDate() + "-" + (date.getMonth()+1 < 10 ? "0":"") + (date.getMonth()+1) + "-" + date.getFullYear();
}

function dateToYMD(date)
{
	return date.getFullYear() + "-" + (date.getMonth()+1 < 10 ? "0":"") + (date.getMonth()+1) + "-" + (date.getDate() < 10 ? "0":"") + date.getDate();
}

function dateFromDMY(strDate)
{
	var datePattern;
	var result;
	var iDay, iMonth, iYear;

	if (isDateFormat(strDate, "DMY"))
	{
		datePattern = /^(\d{1,2})(\/|-)(\d{1,2})(\/|-)(\d{4})$/;
		result = strDate.match(datePattern);

		if (result && result[2] == result[4])
		{
			iDay   = parseInt(trimLeadingZero(result[1]));
			iMonth = parseInt(trimLeadingZero(result[3]));
			iYear  = parseInt(trimLeadingZero(result[5]));
			return new Date(iYear, iMonth-1, iDay);
		}
		else
			return false;
	}
	else
		return false;

}

function dateFromYMD(strDate)
{
	var datePattern;
	var result;
	var iDay, iMonth, iYear;

	if (isDateFormat(strDate, "YMD"))
	{
		datePattern = /^(\d{4})(\/|-)(\d{1,2})(\/|-)(\d{1,2})$/;
		result = strDate.match(datePattern);

		if (result && result[2] == result[4])
		{
			iDay   = parseInt(trimLeadingZero(result[5]));
			iMonth = parseInt(trimLeadingZero(result[3]));
			iYear  = parseInt(trimLeadingZero(result[1]));
			return new Date(iYear, iMonth-1, iDay);
		}
		else
			return false;
	}
	else
		return false;
}

function isDate(iYear, iMonth, iDay)
{
	var isLeap;

	if (iMonth >= 1 && iMonth <= 12)
	{
		if (iDay >= 1 && iDay <= ((iMonth == 4 || iMonth == 6 || iMonth == 9 || iMonth == 11) ? 30 : 31))
		{
			if (iMonth == 2)
			{
				isLeap = (((iYear % 4 == 0) && (iYear % 100 != 0)) || iYear % 400 == 0);
				if (iDay > 29 || (iDay == 29 && !isLeap))
					return false;
			}
		}
		else
			return false;
	}
	else
		return false;

	return true;
}

function isDateString(strDate, isSwapDayMonth) // ************** Depreciated, please use isDateFormat instead!
{
	return isSwapDayMonth ? isDateFormat(strDate, "MDY") : isDateFormat(strDate);
}

function isDateFormat(strDate, strFormat, separator)
{
	var datePattern;
	var result;
	var fmt = strFormat ? trim(strFormat.toUpperCase()) : "DMY";

	switch (separator)
	{
		case "-":
			if (fmt == "YMD")
				datePattern = /^(\d{4})(\/|-)(\d{1,2})(\/|-)(\d{1,2})$/;
			else
				datePattern = /^(\d{1,2})(\/|-)(\d{1,2})(\/|-)(\d{4})$/;
		break;
		case "/":
			if (fmt == "YMD")
				datePattern = /^(\d{4})(\/|-)(\d{1,2})(\/|-)(\d{1,2})$/;
			else
				datePattern = /^(\d{1,2})(\/|-)(\d{1,2})(\/|-)(\d{4})$/;
		break;
		default:
			if (fmt == "YMD")
				datePattern = /^(\d{4})(\/|-)(\d{1,2})(\/|-)(\d{1,2})$/;
			else
				datePattern = /^(\d{1,2})(\/|-)(\d{1,2})(\/|-)(\d{4})$/;
	}

	result = strDate.match(datePattern);

	if (result && result[2] == result[4])
	{
		var iDay = parseInt(trimLeadingZero(fmt == "YMD" ? result[5] : (fmt == "MDY" ? result[3] : result[1])));
		var iMonth = parseInt(trimLeadingZero(fmt == "MDY" ? result[1] : result[3]));
		var iYear = parseInt(trimLeadingZero(fmt == "YMD" ? result[1] : result[5]));

		return isDate(iYear, iMonth, iDay);
	}
	else
		return false;
}

function isTime(s, is12Hr) // ********* Private function, please do not use it directly, use isTime12 or isTime24 instead!!!!!!
{
	if (is12Hr)
		var cPattern = /^(\d{1,2})(:)(\d{1,2})(:)(\d{1,2})( )*(AM|PM)?$/;
	else
		var cPattern = /^(\d{1,2})(:)(\d{1,2})(:)(\d{1,2})$/;

	var res = s.toUpperCase().match(cPattern);

	if (res)
	{
		var iHour = parseInt(res[1]) == 0 ? 0 : parseInt(trimLeadingZero(res[1]));
		var iMin = parseInt(res[3]) == 0 ? 0 : parseInt(trimLeadingZero(res[3]));
		var iSec = parseInt(res[5]) == 0 ? 0 : parseInt(trimLeadingZero(res[5]));

		if (iHour <= (is12Hr ? 12 : 23) && iMin <= 59 && iSec <= 59)
			return true;
		else
			return false;
	}
	else
		return false;
}

function isTime12(s)
{
	return isTime(s, true);
}

function isTime24(s)
{
	return isTime(s, false);
}



// Validations Functions ==========================================================================

function IsEmpty(inStr)
{
	return isEmpty(inStr);
}

function isEmpty(inStr)
{
	return trim(inStr) ? false : true;
}

function isDigit(c)
{
	return ((c >= "0") && (c <= "9"));
}

function isLetter(c)
{
	return ((c >= "a") && (c <= "z")) || ((c >= "A") && (c <= "Z"));
}

function isChar(c)
{
	return (isLetter(c) || (c == "-") || (c == "_") || (c == ".") || isDigit(c));
}

function isINT(s)
{
	var cPattern = /^[+|-]?[\d]+$/;

	if (s.match(cPattern))
		return true;
	else
		return false;
}

function isUINT(s)
{
	var cPattern = /^[\d]+$/;

	if (s.match(cPattern))
		return true;
	else
		return false;
}

function isInteger(s)
{
	return isINT(s);
}

function isUnsignedInteger(s)
{
	return isUINT(s);
}


function isFloat(s)
{
	var cPattern = /^[+|-]?[\d]*[.]?[\d]+$/;

	if (s.match(cPattern))
		return true;
	else
		return false;
}

function isUFloat(s)
{
	var cPattern = /^[\d]*[.]?[\d]+$/;

	if (s.match(cPattern))
		return true;
	else
		return false;
}

function isWord(s)
{
	var cPattern = /^[A-Za-z-]+$/;

	if (s.match(cPattern))
		return true;
	else
		return false;
}

function isVarName(s)
{
	var cPattern = /^[\w]+$/;

	if (s.match(cPattern))
		return true;
	else
		return false;
}

/*
function isEmail(s)
{
	var cPattern = /^((\w)+(\.))*(\w)+(@)(\w)+((\.)(\w)+)+$/;

	if (s.match(cPattern))
		return true;
	else
		return false;
}
*/

function isEmail(s)
{
	var cPattern = /^(([\w-])+(\.))*([\w-])+(@)([\w-])+((\.)([\w-])+)+$/;

	if (s.match(cPattern))
		return true;
	else
		return false;
}

function isHKID(idStr)
{
	var iSum = 0;
	var iPos = 0;
	var i;
	var iMod;
	var iVChar;
	idStr = trim(idStr.toUpperCase());


	if (idStr.length == 8 || idStr.length == 9 && (idStr.charAt(0) == " " || idStr.charAt(0) == "X"))
	{
		if (idStr.length == 9)
		{
			if (idStr.charAt(0) == "X")
				iSum += 6;
			iPos++;
		}
		iSum += (idStr.charCodeAt(iPos++) - 64) * 8;

		for (i=0; i<6; i++)
		{
			if (!isDigit(idStr.charAt(iPos)))
				return false;
			else
				iSum += (idStr.charCodeAt(iPos++)-48) * (7-i);
		}

		iMod = 11 - (iSum % 11);
		iVChar = (iMod == 10 ? 65 : (iMod == 11 ? 48 : iMod+48));


		return (iVChar == idStr.charCodeAt(iPos));
	}
	else
		return false;
}




// Convert Functions ==============================================================================

function hexToInteger(hexString)
{
	var intValue = parseInt("0x" + hexString);

	if (!isNaN(intValue))
		return intValue;
	else
		return null;
}

function integerToHex(intValue)
{
	var hexChars = "0123456789ABCDEF";
	var number = intValue;
	var hexString = "";
	var modNum;

	if (intValue > 0)
	{
		while (number > 0)
		{
			modNum = number % 16;
			hexString = hexChars.charAt(modNum) + hexString;
			number = (number - modNum) / 16;
		}
	}
	else
		hexString = "0";

	return hexString;
}




// Cookie Functions ===============================================================================

function setCookie(name, value, expiresTime, path)
{
	if (expiresTime)
	{
		var currentTime = new Date();
		var timeUnit = expiresTime.charAt(expiresTime.length - 1);

		if (timeUnit.toUpperCase() == "D")
			var dTime = parseInt(trimLeadingZero(expiresTime)) * 24 * 3600 * 1000;
		else
		if (timeUnit.toUpperCase() == "H")
			var dTime = parseInt(trimLeadingZero(expiresTime)) * 3600 * 1000;
		else
		if (timeUnit.toUpperCase() == "M")
			var dTime = parseInt(trimLeadingZero(expiresTime)) * 60 * 1000;
		else
			var dTime = parseInt(trimLeadingZero(expiresTime));

		currentTime.setTime(currentTime.getTime() + dTime);
	}

	var cookieExpiresTime = (expiresTime ? "; expires=" + currentTime.toGMTString() : "");
	var cookiePath        = (path ? "; path=" + path : "");

	document.cookie = name + "=" + escape(value) + cookieExpiresTime + cookiePath;

	return getCookie(name);
}

function deleteCookie(name)
{
	if (getCookie(name))
		document.cookie = name + "=; expires=Thu, 01-Jan-70 00:00:01 GMT";
}

function getCookie(name)
{
	if (document.cookie)
	{
		var cookieBegin = document.cookie.indexOf(name + "=");

		if (cookieBegin >= 0)
		{
			cookieBegin += name.length + 1;
			var cookieEnd = document.cookie.indexOf(";", cookieBegin);

			if (cookieEnd == -1)
			{
				cookieEnd = document.cookie.length;
			}
			return unescape(document.cookie.substring(cookieBegin, cookieEnd));
		}
	}
	return null;
}




// Common Form Functions ======================================================

function FormError(oField, errorMsg)
{
	return formError(oField, errorMsg);
}

function formError(oField, errorMsg)
{
	focusField(oField);
	alert(errorMsg);
	return false;
}

function FocusField(oField)
{
	focusField(oField);
}

function focusField(oField)
{
	if (oField)
	{
		oField.focus();

		if (!oField.options)
			oField.select();
	}
}

function GetCheckedRadio(oField)
{
	var i;

	if (oField.length != null)
	{
		for (i=0; i<oField.length; i++)
			if (oField[i].checked)
				return i;
	}
	else
	if (oField.checked)
		return 0;
	
	return -1;	
}



// Other Functions ================================================================================

function msg(message)
{
	window.status = message;
	return true;
}

function addOnLoadFunc(oFunc, pos)
{
	if (!document.onLoadFuncQuery_BEGIN)
	{
		document.onLoadFuncQuery_BEGIN = new Array();
		document.onLoadFuncQuery_END = new Array();
	}

	if (pos && pos.toUpperCase() == "BEGIN")
		document.onLoadFuncQuery_BEGIN[document.onLoadFuncQuery_BEGIN.length] = oFunc;
	else
		document.onLoadFuncQuery_END[document.onLoadFuncQuery_END.length] = oFunc;
}

function processOnLoadFunc(pos)
{
	var i;

	if (document.onLoadFuncQuery_BEGIN)
	{
		if (pos.toUpperCase() == "BEGIN")
		{
			for (i=0; i<document.onLoadFuncQuery_BEGIN.length; i++)
				document.onLoadFuncQuery_BEGIN[i]();
		}
		else
		{
			for (i=0; i<document.onLoadFuncQuery_END.length; i++)
				document.onLoadFuncQuery_END[i]();
		}
	}
}

function addOnUnloadFunc(oFunc, pos)
{
	if (!document.onUnloadFuncQuery_BEGIN)
	{
		document.onUnloadFuncQuery_BEGIN = new Array();
		document.onUnloadFuncQuery_END = new Array();
	}

	if (pos && pos.toUpperCase() == "BEGIN")
		document.onUnloadFuncQuery_BEGIN[document.onUnloadFuncQuery_BEGIN.length] = oFunc;
	else
		document.onUnloadFuncQuery_END[document.onUnloadFuncQuery_END.length] = oFunc;
}

function processOnUnloadFunc(pos)
{
	var i;

	if (document.onUnloadFuncQuery_BEGIN)
	{
		if (pos.toUpperCase() == "BEGIN")
		{
			for (i=0; i<document.onUnloadFuncQuery_BEGIN.length; i++)
				document.onUnloadFuncQuery_BEGIN[i]();
		}
		else
		{
			for (i=0; i<document.onUnloadFuncQuery_END.length; i++)
				document.onUnloadFuncQuery_END[i]();
		}
	}
}
