﻿///////////////////////////////////////////////////////////////////////////////////////////
/// The Date Library Re-Written By Jamil On 17/07/2002.
/// This Library is the most used library in any system we build, so please
/// be careful adding functions to it.  
/// It will be greatly appreciated if you let Jamil know about any add-on to it.
///////////////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////////////////
/// Defining constants that will be used throughout the Library.
//////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////// 
// The Month array indexed by 1 and map numbers to their respective month representation. 
// 1=JAN .......... 12=Dec
//////////////////////////////////////////////////////////////////////////////////////////
var wordedMonth =	new Array();
wordedMonth[0]	=	"";
wordedMonth[1]	=	"January";
wordedMonth[2]	=	"February";
wordedMonth[3]	=	"March";
wordedMonth[4]	=	"April";
wordedMonth[5]	=	"May";
wordedMonth[6]	=	"June";
wordedMonth[7]	=	"July";
wordedMonth[8]	=	"August";
wordedMonth[9]	=	"September";
wordedMonth[10]	=	"October";
wordedMonth[11]	=	"November";
wordedMonth[12]	=	"December";

////////////////////////////////////////////////////////////////////////////////////
// The wordedMonth array map months to their respective index number representation. 
// This Array expect the month in 3 letters in lower case. 
// jan=1 .......... 12=dec
///////////////////////////////////////////////////////////////////////////////////
var idxMonth	=	new Array()
idxMonth["jan"]	=	1;
idxMonth["feb"]	=	2;
idxMonth["mar"]	=	3;
idxMonth["apr"]	=	4;
idxMonth["may"]	=	5;
idxMonth["jun"]	=	6;
idxMonth["jul"]	=	7;
idxMonth["aug"]	=	8;
idxMonth["sep"]	=	9;
idxMonth["oct"]	=	10;
idxMonth["nov"]	=	11;
idxMonth["dec"]	=	12;

////////////////////////////////////////////////////////////////////////////////////
// The wordedWeekDay array map numbers to their respective weekday representation. 
// 1=Sun .......... 7=Sat
///////////////////////////////////////////////////////////////////////////////////
wordedWeekDay		=	new Array();
wordedWeekDay[0]	=	"";
wordedWeekDay[1]	=	"Sunday";
wordedWeekDay[2]	=	"Monday";
wordedWeekDay[3]	=	"Tuesday";
wordedWeekDay[4]	=	"Wednesday";
wordedWeekDay[5]	=	"Thursday";
wordedWeekDay[6]	=	"Friday";
wordedWeekDay[7]	=	"Saturday";

/////////////////////////////////////////////////////////////////////////////////////
// The idxWeekDay array map weekDays to their respective index number representation. 
// This Array expect the weekday in 3 letters in lower case. 
// sun=1 .......... sat=7
////////////////////////////////////////////////////////////////////////////////////
var idxWeekDay		=	new Array()
idxWeekDay["sun"]	=	1;
idxWeekDay["mon"]	=	2;
idxWeekDay["tue"]	=	3;
idxWeekDay["wed"]	=	4;
idxWeekDay["thu"]	=	5;
idxWeekDay["fri"]	=	6;
idxWeekDay["sat"]	=	7;


////////////////////////////////////////////////////////////////////////////////////////////////
/// This function will give the Month in worded form based on an integer passed to it.
/// - If the input cannot be converted to a valid integer OR if the integer is not 
///   in the range 1-12 than the function will return the input.
/// - The Parameter monthFormat is an optional parameter, acceptable value are 
///   1. mmm(Default) return a month in the form Ddec, Jan ....
///   2. mmmm return the full string : December, Jauary.....
/// - The parameter outCase is also optional and and decide on the casing of the output
///   1. U = Uppercase			2. L = Lowercase		3. P = ProperCase (Default)
////////////////////////////////////////////////////////////////////////////////////////////////
function MonthAsWord(intMonth, monthFormat, outCase)
{
	var numMonth, textMonth
	var mFormat, mCase
	// Nothing is passed
	if(!intMonth)
	{
		return "";
	}
	// is it a digit?
	if(!isDigital(intMonth))
	{
		return intMonth;
	}
	else
	{
		numMonth = intMonth - 0;
		if((numMonth<1)||(numMonth>12))
		{
			alert(intWeekDay + " is outside the range [1-12] accepted for a Month.");
			return intMonth;
		}
	}
	
	// Extract The worded Month from the Array
	textMonth = wordedMonth[numMonth];
	if(monthFormat)
	{
		mFormat = monthFormat.toLowerCase();
		if(mFormat=="mmm")
		{
			textMonth = textMonth.substr(0,3)
		}
		else if(mFormat != "mmmm")
		{
			alert(monthFormat + " is not a valid month format.");
			return intMonth;
		}
	}
	else
	{
		textMonth = textMonth.substr(0,3);
	}

	/// Decide on the casing of the worded Month	
	if(outCase)
	{
		mCase = outCase.toLowerCase();
		if(mCase=="u")
		{
			textMonth = textMonth.toUpperCase();
		}
		else if(mCase=="l")
		{
			textMonth = textMonth.toLowerCase();
		}
		else if(mCase!="p")
		{
			alert(outCase + " is not a valid casing format.");
			return intMonth;
		}
	}
	return textMonth;
}

////////////////////////////////////////////////////////////////////////////////////////////////
//  - This a more general Month Formating function.
//	* pMonth could be any valid month representation ex: 1, 01, Feb, Januray
//  * pFormat could be m,mm,mmm,mmmm which will return 8,08,Aug or August.
//  * pCase to determin the casing of the returned value possible value
//    are P (Proper Default), U (Ucase) OR L(LCase)
////////////////////////////////////////////////////////////////////////////////////////////////
function FormatMonth(pMonth, pFormat, pCase)
{
	var re = /m{1,4}/g;
	var recase = /[lup]/;
	var usedCase, usedMonth;
	var newMonth;
	
	// making sure that the function is called properly.
	if((!pMonth)||(pMonth==""))
	{
		alert("Error using the function. Usage : FormatMonth(pMonth, pFormat, [pCase])");
		return ''
	}
	else
	{
		usedMonth = pMonth;
		if(isDigital(usedMonth))
		{
			usedMonth = usedMonth - 0;
			if((usedMonth<1)||(usedMonth>12))
			{
				alert("The month " + " pMonth is invalid.");
				return pMonth;
			}
		}
		else
		{
			usedMonth = usedMonth.substr(0,3);
			usedMonth = usedMonth.toLowerCase();
			if(idxMonth[usedMonth])
			{
				usedMonth = idxMonth[usedMonth];
			}
			else
			{
				alert("The month " + pMonth + " is invalid.");
				return pMonth;
			}
		}
	}
	
	// making sure that the format pattern is present and have a valid value.
	if((!pFormat)||(pFormat=="")||(!re.test(pFormat)))
	{
		alert("Format criteria missing or invalid. Acceptable values 'm','mm','mmm' OR 'mmmm'");
		return pMonth;
	}
	else
	{
		pFormat = pFormat.toLowerCase();
		if(pFormat=="m")
		{
			newMonth = usedMonth;
		}
		else if(pFormat=="mm")
		{
			newMonth = strFill(usedMonth,2,"l","0")
		}
		else 
		{
			// validate the case.
			if(!pCase)
			{
				usedCase = "p";
			}
			else
			{
				usedCase = pCase.toLowerCase();
			}
			// get the Month 
			if(recase.test(usedCase))
			{
				newMonth = MonthAsWord(usedMonth,pFormat,usedCase)
			}
			else
			{
				alert(pCase + " is not a valid casing qualifier.  Acceptable values 'U','L' OR 'P'");
				return pMonth;
			}
		}
	}	
	return newMonth;
}

////////////////////////////////////////////////////////////////////////////////////////////////
/// This function will give the weekday in worded form based on an integer passed to it.
/// - If the input cannot be converted to a valid integer OR if the integer is not 
///   in the range 1-7 than the function will return the input.
/// - The Parameter weekdayFormat is an optional parameter, acceptable value are 
///   1. www(Default) return a weekday in the form Sun, Mon ....
///   2. wwww return the full string : Sunady, Monday.....
/// - The parameter outCase is also optional and and decide on the casing of the output
///   1. U = Uppercase			2. L = Lowercase		3. P = ProperCase (Default)
////////////////////////////////////////////////////////////////////////////////////////////////
function WeekDayAsWord(intWeekDay, weekdayFormat, outCase)
{
	var numWeekDay, textWeekDay
	var wkFormat, wkCase
	
	// Nothing is passed
	if(!intWeekDay)
	{
		return "";
	}
	
	// is it a digit?
	if(!isDigital(intWeekDay))
	{
		return intWeekDay;
	}
	else
	{
		numWeekDay = intWeekDay - 0;
		if((numWeekDay<1)||(numWeekDay>7))
		{
			alert(intWeekDay + " is outside the range [1-7] accepted for a Weekday");
			return intWeekDay;
		}
	}
	
	// Extract The worded Month from the Array
	textWeekDay = wordedWeekDay[numWeekDay];
	if(weekdayFormat)
	{
		wkFormat = weekdayFormat.toLowerCase();
		if(wkFormat=="www")
		{
			textWeekDay = textWeekDay.substr(0,3)
		}
		else if(wkFormat != "wwww")
		{
			alert(weekdayFormat + " is not a valid weekday format.");
			return intWeekDay;
		}
	}
	else
	{
		textWeekDay = textWeekDay.substr(0,3);
	}

	/// Decide on the casing of the worded Month	
	if(outCase)
	{
		wkCase = outCase.toLowerCase();
		if(wkCase=="u")
		{
			textWeekDay = textWeekDay.toUpperCase();
		}
		else if(wkCase=="l")
		{
			textWeekDay = textWeekDay.toLowerCase();
		}
		else if(wkCase!="p")
		{
			alert(outCase + " is not a valid casing format.");
			return intWeekDay;
		}
	}
	return textWeekDay;
}

////////////////////////////////////////////////////////////////////////////////////////////////
//  - This a more general Month Formating function.
//	* pMonth could be any valid month representation ex: 1, 01, Feb, Januray
//  * pFormat could be m,mm,mmm,mmmm which will return 8,08,Aug or August.
//  * pCase to determin the casing of the returned value possible value
//    are P (Proper Default), U (Ucase) OR L(LCase)
////////////////////////////////////////////////////////////////////////////////////////////////
function FormatWeekDay(pWeekDay, pFormat, pCase)
{
	var re = /w{1,4}/g;
	var recase = /[lup]/;
	var usedCase, usedWeekday;
	var newWeekday;
	
	// making sure that the function is called properly.
	if((!pWeekDay)||(pWeekDay==""))
	{
		alert("Error using the function. Usage : FormatWeekDay(pWeekday, pFormat, [pCase])");
		return ''
	}
	else
	{
		usedWeekDay = pWeekDay;
		if(isDigital(usedWeekDay))
		{
			usedWeekDay = usedWeekDay - 0;
			if((usedWeekDay<1)||(usedWeekDay>7))
			{
				alert("The week day " +  pWeekDay + " is invalid.");
				return pWeekDay;
			}
		}
		else
		{
			usedWeekDay = usedWeekDay.substr(0,3);
			usedWeekDay = usedWeekDay.toLowerCase();
			if(idxMonth[usedWeekDay])
			{
				usedMonth = idxWeekDay[usedWeekDay];
			}
			else
			{
				alert("The weekday " + pWeekDay + " is invalid.");
				return pWeekDay;
			}
		}
	}
	
	// making sure that the format pattern is present and have a valid value.
	if((!pFormat)||(pFormat=="")||(!re.test(pFormat)))
	{
		alert("Format criteria missing or invalid. Acceptable values 'w','ww','www' OR 'wwww'");
		return pWeekDay;
	}
	else
	{
		pFormat = pFormat.toLowerCase();
		if(pFormat=="w")
		{
			newWeekDay = usedWeekDay;
		}
		else if(pFormat=="ww")
		{
			newWeekDay = strFill(usedWeekDay,2,"l","0")
		}
		else 
		{
			// validate the case.
			if(!pCase)
			{
				usedCase = "p";
			}
			else
			{
				usedCase = pCase.toLowerCase();
			}
			// get the Month 
			if(recase.test(usedCase))
			{
				newWeekDay = WeekDayAsWord(usedWeekDay,pFormat,usedCase)
			}
			else
			{
				alert(pCase + " is not a valid casing qualifier.  Acceptable values 'U','L' OR 'P'");
				return pWeekDay;
			}
		}
	}	
	return newWeekDay;
}

////////////////////////////////////////////////////////////////////////////////////////////
/// This Function check if the date is a valid date.
/// - Format is d[d][delimiterm][m]delimiter[yyyy] where the delimiter is SPACE - or /
/// - It accept years from 1999 to 2099
/// - validate the days in the month (30 or 31 ) it also validate the leap year for FEB
/// written By jamil 17/07/2002.
////////////////////////////////////////////////////////////////////////////////////////////
function isDate(datetoval)
{
	var datein = datetoval ; 
	var ddmmyyyy = /^(\d?\d)[\/\- ](\d?\d)[\/\- ](\d\d\d\d)$/;
	var theyear;
	var date31 = /^(([0]?[1-9])|([12][\d])|([3][01]))[\/\- ](([0]?[13578])|([1][02]))[\/\- ](([1][19]\d\d)|([2][0]\d\d)|(2100))$/;
	var date30 = /^(([0]?[1-9])|([12][\d])|([3][0]))[\/\- ](([0]?[469])|([1][1]))[\/\- ](([1][19]\d\d)|([2][0]\d\d)|(2100))$/;
	var date28 = /^(([0]?[1-9])|([1][\d])|([2][0-8]))[\/\- ]([0]?[2])[\/\- ](([1][19]\d\d)|([2][0]\d\d)|(2100))$/;		
	var date29 = /^(([0]?[1-9])|([1][\d])|([2][0-9]))[\/\- ]([0]?[2])[\/\- ](([1][19]\d\d)|([2][0]\d\d)|(2100))$/;
		
	if (ddmmyyyy.test(datein))
	{
		theyear = RegExp.$3;
		if( (date31.test(datein)) || (date30.test(datein)) ||(date28.test(datein)))
		{
			return true ;
		}
		else
		{
			if( date29.test(datein))
			{
				if(((theyear % 4 == 0) && (theyear % 100 != 0)) || (theyear % 400 == 0))
				{
					return true
				}
			}
			else
			{
				return false;
			}
		}
	}
	else
	{
		return false;
	}
}
	
////////////////////////////////////////////////////////////////////////////////////////////////
/// This function will extract the day of the week from the passed date. 
/// - If the date is invalid than an empty string will be returned.
/// - The day format will depend on dayFormat :
/// 1. 0 (Sunday) to 6 (Saturday) if dayFormat = "w";
/// 2. 01 (Sunday) to 06 (Saturday) if dayFormat = "ww";
/// 2. Sun ..., Sat if dayFormat = "www";
/// 3. Sunday ..., Staurday  if dayFormat = "wwww".
/// - A date is considered valid if it is of the form dd/mm/yyyy
////////////////////////////////////////////////////////////////////////////////////////////////
function ExtractDayOfWeek(dayDate, dayFormat)
{
	var aday,amonth,ayear;
	var datepieces;
	var wordedDay;
	var theDate;
	var theDay;
	var re  = /[\/ -]/g;
	
	if(isDate(dayDate))
	{
		dayDate    = dayDate + '';
		datepieces = dayDate.split(re);
		
		if(datepieces.length != 3)
		{
			wordedDay = "";
		}
		else
		{
			aday		= datepieces[0] - 0;
			amonth		= datepieces[1] - 1;
			ayear		= datepieces[2] - 0;
			
			theDate		= new Date(ayear,amonth,aday,0,0,0);
			
			theDay		= theDate.getDay();

			if(dayFormat == "wwww")
			{
				theDay	= wordedWeekDay[theDay + 1];
			}
			else if(dayFormat == "www")
			{
				theDay	= wordedWeekDay[theDay + 1];
				theDay	= theDay.substr(0,3);
			}
			else if(dayFormat == "ww")
			{
				theDay = strFill(theDay,2,"l","0")
			}
		}
	}
	else
	{
		alert(dayDate + " is not a valid date.");
		theDay = ""
	}
	return theDay;
}
	
////////////////////////////////////////////////////////////////////////////////////////////////////
/// Written By Jamil On 07/06/2002
/// This function will add to a given date and return the new date.
/// - part is the part of the date you want to add to. d(day), m(month), y(year)
/// - val the number of days,months or years to want to add. (This could be negative).
/// - pdate is the date you want to add to, this date is a string formatted as dd/mm/yyyy.
///
/// - This function does not validate the input data. (will be added later)
/// - A failure in the calculation will return your old date as the newly calculated date.
/// - This function is silent (for the moment) and will not generate any ALERT error messages.
////////////////////////////////////////////////////////////////////////////////////////////////////
function dateAdd(part,val,pdate)
{
	var newdate ;
	var theday,themonth,theyear;
	var pieces;
	var dateStr;
	
	// if the you did not pass the right number of arguments.
	if(arguments.length != 3)
	{
		alert("Error Using dateAdd, Usage dateAdd(part,val,date)");
		return pdate;
	}
	
	// is the date a valid date 
	if((!isDate(pdate)) || (pdate == ""))
	{
		alert("Cannot add the date - Date invalid");
		return pdate;
	}
	else
	{
		pieces = pdate.split("/");
		if(pieces.length != 3)
		{
			newdate = pdate;
			return newdate;
		}
		else
		{
			theday		= pieces[0] - 0;
			themonth	= pieces[1] - 1;
			theyear		= pieces[2] - 0;
			
			if(part == "d")
			{
				theday += val - 0;
			}
			else if(part == "m")
			{
				themonth +=  val - 0;
			}
			else if(part == "y")
			{
				theyear += val - 0;
			}
			else
			{
				alert(part + " is an invalid part of the date. Must be 'd','m' OR 'y'");
			}
			newdate = new Date(theyear, themonth, theday,0,0,0);
			dateStr = newdate.getDate() + "/" + (newdate.getMonth() + 1) + "/" + newdate.getFullYear();
			dateStr = FormatDate(dateStr,"dd/mm/yyyy");
			return dateStr;
		}
	}
}	


//////////////////////////////////////////////////////////////////////////////////////////
//  Written By Jamil 0n 07/06/2002. This Function return the difference in days 
//  between the two dates passed to it.
//  - strDate1 and strDate2 are date strings in the form dd/mm/yyyy.
//////////////////////////////////////////////////////////////////////////////////////////
function getDiffDates(strDate1,strDate2) 
{
	var date1 = Date.parse(FormatDate(strDate1,"dd mmm yyyy"));
	var date2 = Date.parse(FormatDate(strDate2,"dd mmm yyyy"));

	var difference = date2 - date1;
	difference = difference/1000/60/60/24;
	return Math.round(difference)
}

//////////////////////////////////////////////////////////////////////////////////////////
// Written By Jamil 13 Dec 2004. This really similar to getDiffDates 
// but allow the user to format the out put.
// - resFormat is used to format the result.
//		* DD return in days (default)
//		* HH return in hours.
//		* NN return in minutes.
//		* SS return in seconds.
//		* MS return in milliseconds (and also for unknown format).
//	- pSign = 1 return as is, 0 return the absolute value.
//////////////////////////////////////////////////////////////////////////////////////////
function getDiffDatesFormatted(strDate1,strDate2, resFormat, resSigned) 
{
	var diffForm;
	var date1 = Date.parse(FormatDate(strDate1,"dd mmm yyyy"));
	var date2 = Date.parse(FormatDate(strDate2,"dd mmm yyyy"));
	var difference = date2 - date1;

	// should we leave the sign?
	if(resSigned == 0)
	{
		difference = Math.abs(difference);
	}
	
	// Now format it.
	if ((!resFormat) || (isBlank(resFormat)))
	{
		diffForm	= "DD"
	}
	else
	{
		diffForm	= resFormat.toUpperCase();
	}

	if(diffForm == "DD")
	{
		difference = difference/1000/60/60/24;
	}
	else if (diffForm == "HH")
	{
		difference = difference/1000/60/60;
	}
	else if (diffForm == "MM")
	{
		difference = difference/1000/60;
	}
	else if (diffForm == "SS")
	{
		difference = difference/1000;
	}
	else
	{
		difference = difference // not really needed.
	}

	return Math.round(difference)
}


///////////////////////////////////////////////////////////////////////////////////////////
/// - The main purpose of this function is to validate the content of the passed value 
///   to be a time of the form hh:mm am |pm.
/// - The function is not a mere validator it will suggest correction if possible.
///   it will operate on all three tokens passed to it hh,mm and am/pm.
/// - if the mm is missing it will be assumed 00.
/// - if the am/pm is missing it will be generated from the hours.
/// - if the hh is missing then the date is invalid.
///////////////////////////////////////////////////////////////////////////////////////////
function FormatTime(intime,pattern)
{
	var pieces, piecesCount;
	var hpattern, mpattern, spattern, ipattern;
	var htoken,mtoken,stoken, itoken;
	var usedTime, tokens, lasttoken;
	var newTime;
	var re = /[ - / :]/g;
	var varre;
	var hre,mre, sre, ire;
	
	// Making sure that all arguments are present.
	if((arguments.length < 2) || (!intime) || (intime==""))
	{
		alert("Error Using Format Time, Usage \'FormatTime(time,pattern)\'");
		return intime;	
	}
	
	// assign the default pattern
	if((!pattern)||(pattern==""))
	{
		pattern = "hh:nn:ss ampm";
	}

	// Clean the string from trailing and repeated white spaces.
	// make sure that the ampm indicator is not sticked to the number before.
	usedTime = intime;
	usedTime = usedTime.replace(/(am|pm)/i," $1")
	usedTime = SqueezeStr(usedTime);
	if(!isTime(usedTime))
	{
		alert("The time " + usedTime + " cannot be formatted - invalid time.");
		return intime;
	}
	else
	{
		tokens		= usedTime.split(re);
		lasttoken	= tokens[tokens.length-1];
		if(isDigital(lasttoken))
		{
			htoken = tokens[0]&&isDigital(tokens[0])?tokens[0]-0:0;
			mtoken = tokens[1]&&isDigital(tokens[1])?tokens[1]-0:0;
			stoken = tokens[2]&&isDigital(tokens[2])?tokens[2]-0:0;
			itoken = "";
		}
		else
		{
			htoken = tokens[0]&&isDigital(tokens[0])?tokens[0]-0:0;
			mtoken = tokens[1]&&isDigital(tokens[1])?tokens[1]-0:0;
			stoken = tokens[2]&&isDigital(tokens[2])?tokens[2]-0:0;
			itoken = lasttoken;
		}
		
		itoken = itoken.toLowerCase();
		
		// adjust the hours to be in the 24 Hours format.
		htoken = htoken - 0;

		if((itoken=="pm") && (htoken<12))
		{
			htoken += 12;
		}
	}
	
	// set the newTime to the passed pattern
	newTime = pattern;
	
	// Capture the patterns used to format the time.

	// The seconds
	varre = /(s+)/g;
	if(varre.test(pattern))
	{
		spattern = RegExp.$1;
		spattern = spattern.toLowerCase();
		if(spattern=="ss")
		{
			stoken = strFill(stoken,2,"L","0")
		}
	}

	// The minutes
	varre = /(n+)/g;
	if(varre.test(pattern))
	{
		mpattern = RegExp.$1;
		mpattern = mpattern.toLowerCase();
		if(mpattern=="nn")
		{
			mtoken = strFill(mtoken,2,"L","0")
		}
	}

	// The hours 
	varre = /(h+)/g;
	if(varre.test(pattern))
	{
		hpattern = RegExp.$1;
		hpattern = hpattern.toLowerCase();
	}

	// The identifier
	varre = /(ampm)/ig;
	if(varre.test(pattern))
	{
		ipattern = RegExp.$1;
	}

	if(ipattern)
	{
		if(htoken>12)
		{
			htoken = htoken%12;
			itoken = "pm";
		}
		else if(htoken<12)
		{
			itoken = "am";
		}
	}
	else
	{
		
		if(itoken=="am")
		{
			htoken = htoken%12;
		}
	}

	if(hpattern=="hh")
	{
		htoken = strFill(htoken,2,"L","0")
	}
	
	// replace the pattern with the value;
	if(hpattern)
	{
		hre		= new RegExp(hpattern,"gi");
		newTime	= newTime.replace(hre,htoken);
	}

	if(mpattern)
	{
		mre		= new RegExp(mpattern,"gi");
		newTime	= newTime.replace(mre,mtoken);
	}
	
	if(spattern)
	{
		sre		= new RegExp(spattern,"gi");
		newTime	= newTime.replace(sre,stoken);
	}

	if(ipattern)
	{
		if(itoken=="am")
		{
			itoken = ipattern.substr(0,2);
		}
		else if(itoken=="pm")
		{
			itoken = ipattern.substr(2,2);
		}
		ire		= new RegExp(ipattern,"gi");
		newTime	= newTime.replace(ire,itoken);
	}
	
	return newTime;	
}


///////////////////////////////////////////////////////////////////////////////////////////
// This function format the date to the given pattern format.
// - This functions assume that:
// 1. The date could only be seprated by SPACE, / or -
// 2. The year is a four or two digit year and is always the last token of the date.
//    when the year is supplied as yy but required yyyy we will use assume a 19 prefix
//    for a year after 25 and 20 (2K) for a year before 25.
// 3. The month is supplied as mm, mmm or mmmm (could be the first or second).
// 4. When both the day and the month are digital, day will be placed first.
// The Pattern allow for the following at the moment:
// - yyyy , yy for a 4 digits or 2 digits year.
// - m, mm, mmm, mmmm for month formating example : 1, 01, Jan, January.
// - d, dd day formatting e.g. 1, 01.
// This formating function will preserve your pattern and replace the place-holders 
// in your pattern with the correct value.
// e.g. 12 FEB 2002 with a pattern of "yyyy~mmm^dd" will result in 2002~FEB^12.
////////////////////////////////////////////////////////////////////////////////////////////
function FormatDate(indate,pattern)
{
	var day,mth,year;
	var tokens, token1, token2, token3;
	var usedDate, newDate, valDate;
	var re = /[/ -]/g;	// Date delimiers SPACE , / OR -.
	var mtoken, dtoken, ytoken;
	var mvalue, dvalue, yvalue;
	var varre;
	var dre, mre, yre;
	
	
	// Making sure that all arguments are present.
	if((arguments.length < 2) || (!indate) || (indate=="") || (!pattern) || (pattern==""))
	{
		alert("Error Using Format Date, Usage FormatDate(date,Pattern)");
		return indate;	
	}
	
	// eliminate leading and trailing spaces
	usedDate	= indate;
	usedDate	= usedDate.replace(/^(\s+)+|(\s+)$/g,"");
	
	// get the tokens passed in the date.
	tokens = usedDate.split(re)
	
	// insuring tha we have only three tokens in the date.
	if(tokens.length != 3)
	{
		alert("The date " + indate + " cannot be formatted.");
		return indate;
	}
	else
	{
		token1 = tokens[0];
		token2 = tokens[1];
		token3 = tokens[2];

		if((!isDigital(token3)) || ((token3.length!=2) && (token3.length!=4)))
		{
			alert("The date " + indate + " cannot be formatted - Invalid Year.");
			return indate;
		}
		else
		{
			year = token3;
			if(isDigital(token1))
			{
				day = token1 - 0;
				if(isDigital(token2))
				{
					month = token2 - 0;
				}
				else
				{
					month = token2.substr(0,3);
					month = month.toLowerCase();
					if(idxMonth[month])
					{
						month = idxMonth[month];
					}
					else
					{
						alert("The date " + indate + " cannot be formatted - Invalid Month.");
						return indate;
					}
				}
			}
			else
			{
				if(isDigital(token2))
				{
					day		= token2-0;
					month	= token1.substr(0,3);
					month	= month.toLowerCase();
					if(idxMonth[month])
					{
						month = idxMonth[month];
					}
					else
					{
						alert("The date " + indate + " cannot be formatted - Invalid Month.");
						return indate;
					}
				}
				else
				{
					alert("The date " + indate + " cannot be formatted - Invalid Day.");
					return indate;
				}
			}
		}
	}
	
	// Validate if the passed date is valid
	valDate = day + "/" + month + "/" + formatYear(year);
	if(!isDate(valDate))
	{
		alert("The date " + indate + " cannot be formatted - Invalid Date.");
		return indate;
	}

	// capture the passed place-holders and format accordingly.
	newDate = pattern;

	// capture the day pattern if any.
	varre = /(^|$|-|\s|\/)(d+)(^|$|-|\s|\/)/g;
	if(varre.test(pattern))
	{
		 dtoken = RegExp.$2;
		 dvalue = day;
		 if(dtoken=="dd")
		 {
			dvalue = strFill(dvalue,2,"L","0");		 
		 }
	}

	// capture the month pattern if any.
	varre = /(^|$|-|\s|\/)(m+)(^|$|-|\s|\/)/g;
	if(varre.test(pattern))
	{
		 mtoken = RegExp.$2;
		 mvalue = month;
		 if(mtoken=="mm")
		 {
			mvalue = strFill(mvalue,2,"L","0");		 
		 }
		 else if(mtoken=="mmm")
		 {
			mvalue = wordedMonth[mvalue];
			mvalue = mvalue.substr(0,3)
		 }
		 else if(mtoken=="mmmm")
		 {
			mvalue = wordedMonth[mvalue];
		 }
	}

	// capture the month pattern if any.
	varre = /(^|$|-|\s|\/)(y+)(^|$|-|\s|\/)/g;
	if(varre.test(pattern))
	{
		 ytoken = RegExp.$2;
		 yvalue = year;
		 if(ytoken=="yy")
		 {
			if(year.length == 4)
			{
				yvalue = yvalue.substr(2);
			}
		 }
		 else if(ytoken=="yyyy")
		 {
			yvalue = formatYear(yvalue);
		 }
	}
	
	if(dtoken)
	{
		dre		= new RegExp(dtoken,"gi");
		newDate = newDate.replace(dre,dvalue);
	}
	if(mtoken)
	{
		mre		= new RegExp(mtoken,"gi");
		newDate = newDate.replace(mre,mvalue);
	}
	if(ytoken)
	{
		yre	= new RegExp(ytoken,"gi");
		newDate = newDate.replace(yre,yvalue);
	}
	return newDate
}

///////////////////////////////////////////////////////////////////////////////////////////////////
///  This function will merely change a 2 digit year into a four digit one.
///
///
///////////////////////////////////////////////////////////////////////////////////////////////////
function formatYear(pyear)
{
	var nyear;
	var intyear;
	if(pyear.length == 4)
	{
		nyear = pyear;
	}
	else if(pyear.length == 2)
	{
		if(!isDigital(pyear))
		{
			nyear = pyear;
		}
		else
		{
			intyear = pyear - 0;
			if(intyear <= 25)
			{
				nyear = "20" + pyear;
			}
			else
			{
				nyear = "19" + pyear;
			}
		}
	}
	else
	{
		nyear = pyear;	
	}
	return nyear
}

///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
function ReshapeToday(ppattern)
{
	var today = new Date();
	var todayStr;
	
	var day		= today.getDate();	
	var month	= today.getMonth() + 1; 
	var year	= today.getFullYear();
	var hours	= today.getHours(); 
	var minutes = today.getMinutes();
	var seconds = today.getSeconds(); 
	
	
	//Fix length strucure 
	day		= strFill(day,2,'L','0');
	month	= strFill(month,2,'L','0');
	year	= strFill(year,2,'L','0');
	
	hours	= strFill(hours,2,'L','0');
	minutes = strFill(minutes,2,'L','0');
	seconds = strFill(seconds,2,'L','0');
	
	
	todayStr = day + "/" + month + "/" + year + " " + hours + ":" + minutes + ":" + seconds
	
	return FormatDate(todayStr, ppattern)

}

//////////////////////////////////////////////////////////////////////////////
/// This function will return true or false based on if the number passed to
/// it is a valid integer or not.
/////////////////////////////////////////////////////////////////////////////
function isDigital(val)
{
	var regExp = /\D/; // Non- Digital
	if((val=="")||(regExp.test(val)))
	{
		return false;	
	}
	else
	{
		return true;
	}
}

/////////////////////////////////////////////////////////////////////////////////////////
/// Function to validate date passed to it and reformat it to dd/mm/yyyy IF a second
/// parameter is passed then the date is formatted to dd/mmm/yyyy and placed in the field
/// this hidden date will be used on the server to force the server to read it in the correct
/// format
/////////////////////////////////////////////////////////////////////////////////////////
function ValAndHide(elem,tagname)
{
	var indate = elem.value;
	var isgood = true;
	if(indate != "")
	{
		indate = DateReformation(indate)
		if(isDate(indate))
		{
			elem.value = FormatDate(indate,"dd/mm/yyyy");
			if(tagname)
			{
				document.all(tagname).value = FormatDate(indate,"dd/mmm/yyyy");
			}
		}
		else
		{
			elem.focus();
			isgood = false;
			if(tagname)
			{
				document.all(tagname).value = "";
			}
		}
	}
	else
	{
		if(tagname)
		{
			document.all(tagname).value = "";
		}
	}
	return isgood;
}

/////////////////////////////////////////////////////////////////////////////////////////
/// Similar to ValAndHide above but allow the user to choose the format to use on both 
/// the short format and the long format.
/////////////////////////////////////////////////////////////////////////////////////////
function ValFormatAndHide(elem,tagname,shortFormat, longFormat)
{
	var indate = elem.value;
	var isgood = true;
	
	//initialize
	if((!shortFormat) || (shortFormat==""))
	{
		shortFormat = "dd/mm/yyyy";
	}

	if((!longFormat) || (longFormat==""))
	{
		longFormat = "dd/mmm/yyyy";
	}
	
	// format the date both visible and hidden
	if(indate != "")
	{
		indate = DateReformation(indate)
		if(isDate(indate))
		{
			elem.value = FormatDate(indate,shortFormat);
			if(tagname)
			{
				document.all(tagname).value = FormatDate(indate,longFormat);
			}
		}
		else
		{
			elem.focus();
			isgood = false;
			if(tagname)
			{
				document.all(tagname).value = "";
			}
		}
	}
	else
	{
		if(tagname)
		{
			document.all(tagname).value = "";
		}
	}
	return isgood;
}

////////////////////////////////////////////////////////////////////////////////////
/// The Date reformat function is an intermediary function aiming on allowing 
/// some date format which are not generaly accepted by the system and mapping them
/// to a format that is unambigious.
///////////////////////////////////////////////////////////////////////////////////
function DateReformationBirthday(pdate)
{
	var inDate = pdate + '';
	var outDate = pdate + '';
	var pieces;
	var delimiter = / |\/|\-|\t|\./;
	var piecesCount;
	var theDay, theMonth, theYear, intYear
	var today = new Date();
	var century = today.getYear() + '';

	//Trim The Passed Date and and eliminate multiple spaces
	inDate = inDate.replace(/^\s+|\s+$/g,"");
	inDate = inDate.replace(/  /g," ");
	pieces = inDate.split(delimiter);
	piecesCount = pieces.length
	
	if( (piecesCount!=1) && (piecesCount!=2) && (piecesCount!=3))
	{
		outDate = inDate;
		return outDate;
	}
	else
	{
		if(piecesCount==3)
		{
			theDay   = pieces[0];
			theMonth = pieces[1];
			theYear  = pieces[2];
		}
		else if(piecesCount==2)
		{
			theDay   = pieces[0];
			theMonth = pieces[1];
			theYear  = century;
		}
		else if(inDate.length==6)
		{
			theDay   = inDate.substr(0,2);
			theMonth = inDate.substr(2,2);
			theYear  = inDate.substr(4,2);
		}
		else if(inDate.length==4)
		{
			theDay   = inDate.substr(0,2);
			theMonth = inDate.substr(2,2);
			theYear  = century;
		}
		else
		{
			outDate = inDate;
			return outDate;
		}
		
		// Fixing the Day
		theDay = theDay + ''
		if(theDay.length==1)
		{
			theDay = "0" + theDay;
		}
		
		// Fixing the Month 
		theMonth = theMonth + '';
		if(theMonth.length ==1)
		{
			theMonth = "0" + theMonth ;
		}
		else if( theMonth.length > 2)
		{
			theMonth = theMonth.substr(0,3) + '';
			theMonth = theMonth.toLowerCase();
			
			if(idxMonth[theMonth])
			{
				theMonth = idxMonth[theMonth] + '';
				if(theMonth.length ==1)
				{
					theMonth = "0" + theMonth ;
				}
			}
		}
		
		//Fixing the Year
		theYear = theYear + '';
		if(theYear.length <=2)
		{
			intYear = parseInt(theYear,10)
			if(theYear.length ==1)
			{
				theYear = "0" + theYear;
			}
			theYear = century.substr(0,2) + theYear;
		}
		// Compile the new Date
		outDate = theDay + "/" + theMonth + "/" + theYear;
	}
	
	td = new Date();
	dt = new Date(theYear, theMonth, theDay);
	
	if (dt >= td)
	{
	outDate = theDay + "/" + theMonth + "/" + (theYear -100);
	}
	
	return outDate;
}

function DateReformation(pdate)
{
	var inDate = pdate + '';
	var outDate = pdate + '';
	var pieces;
	var delimiter = / |\/|\-|\t|\./;
	var piecesCount;
	var theDay, theMonth, theYear, intYear
	var today = new Date();
	var century = today.getYear() + '';

	//Trim The Passed Date and and eliminate multiple spaces
	inDate = inDate.replace(/^\s+|\s+$/g,"");
	inDate = inDate.replace(/  /g," ");
	pieces = inDate.split(delimiter);
	piecesCount = pieces.length
	
	if( (piecesCount!=1) && (piecesCount!=2) && (piecesCount!=3))
	{
		outDate = inDate;
		return outDate;
	}
	else
	{
		if(piecesCount==3)
		{
			theDay   = pieces[0];
			theMonth = pieces[1];
			theYear  = pieces[2];
		}
		else if(piecesCount==2)
		{
			theDay   = pieces[0];
			theMonth = pieces[1];
			theYear  = century;
		}
		else if(inDate.length==6)
		{
			theDay   = inDate.substr(0,2);
			theMonth = inDate.substr(2,2);
			theYear  = inDate.substr(4,2);
		}
		else if(inDate.length==4)
		{
			theDay   = inDate.substr(0,2);
			theMonth = inDate.substr(2,2);
			theYear  = century;
		}
		else
		{
			outDate = inDate;
			return outDate;
		}
		
		// Fixing the Day
		theDay = theDay + ''
		if(theDay.length==1)
		{
			theDay = "0" + theDay;
		}
		
		// Fixing the Month 
		theMonth = theMonth + '';
		if(theMonth.length ==1)
		{
			theMonth = "0" + theMonth ;
		}
		else if( theMonth.length > 2)
		{
			theMonth = theMonth.substr(0,3) + '';
			theMonth = theMonth.toLowerCase();
			
			if(idxMonth[theMonth])
			{
				theMonth = idxMonth[theMonth] + '';
				if(theMonth.length ==1)
				{
					theMonth = "0" + theMonth ;
				}
			}
		}
		
		//Fixing the Year
		theYear = theYear + '';
		if(theYear.length <=2)
		{
			intYear = parseInt(theYear,10)
			if(theYear.length ==1)
			{
				theYear = "0" + theYear;
			}
			theYear = century.substr(0,2) + theYear;
		}
		// Compile the new Date
		outDate = theDay + "/" + theMonth + "/" + theYear;
	}
	return outDate;
}


////////////////////////////////////////////////////////////////////////////////////
/// cc will return the number of seconds since the beginning of the year.
////////////////////////////////////////////////////////////////////////////////////
function cc()
{
	var jdate = new Date();
	var centdate = new Date(jdate.getFullYear(),0,1,1,1,1,1)

	SinceBeginning = Date.parse(jdate) - Date.parse(centdate);
	if((SinceBeginning % 1000) ==0)
	{
		SinceBeginning = SinceBeginning/1000;
	}	
	return SinceBeginning;
}

// Just another name.
function ck()
{
	return cc();
}
