
//**************************************************************************
//		Copyright  Sybase, Inc. 1998-2006
//						 All Rights reserved.
//
//	Sybase, Inc. ("Sybase") claims copyright in this
//	program and documentation as an unpublished work, versions of
//	which were first licensed on the date indicated in the foregoing
//	notice.  Claim of copyright does not imply waiver of Sybase's
//	other rights.
//
//	 This code is generated by the PowerBuilder HTML DataWindow generator.
//	 It is provided subject to the terms of the Sybase License Agreement
//	 for use as is, without alteration or modification.  
//	 Sybase shall have no obligation to provide support or error correction 
//	 services with respect to any altered or modified versions of this code.  
//
//       ***********************************************************
//       **     DO NOT MODIFY OR ALTER THIS CODE IN ANY WAY       **
//       ***********************************************************
//
//       ***************************************************************
//       ** IMPLEMENTATION DETAILS SUBJECT TO CHANGE WITHOUT NOTICE.  **
//       **            DO NOT RELY ON IMPLEMENTATION!!!!		      **
//       ***************************************************************
//
// Use the public interface only.
//**************************************************************************

//
// Date management code
//

// Added to determine if dates are being processed in client side JavaScript.
bDateTimeProcessingEnabled = true;

var DW_dayTable = new Array();
DW_dayTable[0] = new Array(0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
DW_dayTable[1] = new Array(0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);

var DW_cumDayTable = new Array();
DW_cumDayTable[0] = new Array(0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365);
DW_cumDayTable[1] = new Array(0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366);

function DW_daysInCentury(year)
{
    return ((((year) / 100) % 4 ? 24 : 25) + 36500);
}

function DW_isLeap(year)
{
    return ((year%4 == 0 && year%100 != 0) || year%400 == 0);
}

function DW_dayOfYear(year, month, day)
{
	var i, aleap;

	aleap = DW_isLeap(year) ? 1 : 0;
	for (i = 1; i < month; i++)
		day += DW_dayTable[aleap][i];
	return day;                   // Offset from 0
}

function DW_dayOfCentury(year, month, day)
{
	var days, leaps;
	var years_in_century;

	/* Get number of years in the century. */
	years_in_century = Math.floor(year % 100);

	/* Get the number of days in year */
	days = DW_dayOfYear(year, month, day);;

	/* Add number of days in previous years */
	if (years_in_century != 0)
		{
		leaps = Math.floor((years_in_century - 1) / 4);  /* num of inclusive leap years */
		leaps += (Math.floor(year / 100) % 4 ? 0 : 1); /* + 1 every 4 centuries */
		days += leaps * 366;
		days += (years_in_century - leaps) * 365;
		}
	return days;
}

function DW_daysDiff(year1, mon1, day1, year2, mon2, day2)
{
	var days = 0;
	var no_centuries;
	var temp;
	var sign = 1;
	var i;

	// Swap dates if date1 < date2
	if ( year1 < year2 || 
			(year1 == year2 && (mon1 < mon2 || 
									(mon1 == mon2 && day1 < day2) ) ) )
		{
		temp = year1; year1 = year2; year2 = temp;
		temp = mon1;  mon1 = mon2;   mon2 = temp;
		temp = day1;  day1 = day2;   day2 = temp;
		sign = -1;
		}

	// Calculate difference in dates.
	no_centuries = Math.floor(year1 / 100) - Math.floor(year2 / 100);
	for (i = 0; i < no_centuries; i++)
		days += DW_daysInCentury (year2 + i * 100);
	days += DW_dayOfCentury (year1,mon1,day1) - DW_dayOfCentury (year2,mon2,day2); 

	// Set sign of days
	days *= sign;

	return (days);
}

// Notes   :  Jan 1, 1899 was a Sunday.
function DW_dayOfWeek(year, month, day)
{
	var days_from_1899;
	var weekday;

	// Get number of days since 01/01/1899.
	days_from_1899 = DW_daysDiff (year, month, day, 1899, 1, 1);

	// Mod by 7 to get day of week.
   	weekday = days_from_1899 % 7;
	// CR 184356 - make sure we deal properly with dates less than 01/01/1899
	if (weekday < 0)
        weekday += 7;
        
	return (weekday);
}

function DW_daysInYear(year)
{
	return DW_isLeap(year) ? 366 : 365;
}

function initDateSeq()
{
	var inString = DW_shortDateFormat;
	var currChar;
	var charIndex;
	var strLen = inString.length;
	var section;

	section = 0;            // start at first section
    for (charIndex = 0; charIndex < strLen;)
		{
		currChar = inString.charAt (charIndex);
		if (currChar == '-' ||     // New section
				currChar == '/' ||
				currChar == ',' ||
				currChar == '.' ||
				currChar == ':')
			{
				section++;
			}
		else if (currChar == 'm' || currChar == 'M')
			DW_PARSEDT_monseq = section;
		else if (currChar == 'd' || currChar == 'D')
			DW_PARSEDT_dayseq = section;
		else if (currChar == 'y' || currChar == 'Y')
			DW_PARSEDT_yearseq = section;
		charIndex++;
		}
}

function DW_DateToString()
{
    var outStr = "";
	initDateSeq();
    // format based on current localized order from constants
    for (var i=0; i<3; i++)
    {
        if (i==DW_PARSEDT_yearseq)
            outStr += (this.year + 1900);
        else if (i==DW_PARSEDT_monseq)
            outStr += (this.month + 1);
        else if (i==DW_PARSEDT_dayseq)
            outStr += this.day;
        if (i<2)
            outStr += "/";
    }
    return outStr;
}

function DW_DatetimeToString()
{
    var outStr = "";
	initDateSeq();
    // format based on current localized order from constants
    for (var i=0; i<3; i++)
    {
        if (i==DW_PARSEDT_yearseq)
            outStr += (this.year + 1900);
        else if (i==DW_PARSEDT_monseq)
            outStr += (this.month + 1);
        else if (i==DW_PARSEDT_dayseq)
            outStr += this.day;
        if (i<2)
            outStr += "/";
    }
    outStr += " " + this.hour + ":" + this.min + ":" + this.sec + ":";
    var tempStr = ""+ this.msec;
    var i = tempStr.length;
    while(i<6)
    {
        outStr += "0";
        i++;
    }
    return outStr + this.msec;
}

function DW_TimeToString()
{
    var outStr = this.hour + ":" + this.min + ":" + this.sec + ":";

    var inStr = "" + this.msec;
    var i = inStr.length;    
    while(i<6) 
    {
     outStr = outStr +"0";
     i++;
    } 

    outStr = outStr+inStr;
    return outStr;  
}

function DW_EqualsDatetime(dt)
{
    if (this.year == dt.year &&
        this.month == dt.month &&
        this.day == dt.day &&
        this.hour == dt.hour &&
        this.min == dt.min &&
        this.sec == dt.sec &&
        this.msec == dt.msec)
        return true;
    else
        return false;
}

function DW_DateClass(year, month, day)
{
    if (arguments.length == 0)
        {
        year = 0;
        month = 0;
        day = 0;
        }
        
    this.year = year;
    this.month = month;
    this.day = day;
    this.hour = 0;
    this.min = 0;
    this.sec = 0;
    this.msec = 0;

    this.toString = DW_DateToString;
    this.equals = DW_EqualsDatetime;
}

function DW_TimeClass(hour, min, sec, msec)
{
    if (arguments.length == 0)
        {
        hour = 0;
        min = 0;
        sec = 0;
        msec = 0;
        }

    this.hour = hour;
    this.min = min;
    this.sec = sec;
    this.msec = msec;
    this.year = 0;
    this.month = 0;
    this.day = 0;

    this.toString = DW_TimeToString;
    this.equals = DW_EqualsDatetime;
}

function DW_DatetimeClass(year,month,day,hour,min,sec,msec)
{
	if (arguments.length == 0)
		{
		year = 0;
        month = 0;
        day = 0;		
        hour = 0;
        min = 0;
        sec = 0;
        msec = 0;
        }
        
     this.year = year;
     this.month = month;
     this.day = day;
     this.hour = hour;
     this.min = min;
     this.sec = sec;
     this.msec = msec;
     
     this.toString = DW_DatetimeToString;
     this.equals = DW_EqualsDatetime;
}

function DW_DatetimeClass2(date, time)
{
     this.year = date.year;
     this.month = date.month;
     this.day = date.day;
     this.hour = time.hour;
     this.min = time.min;
     this.sec = time.sec;
     this.msec = time.msec;
     
     this.toString = DW_DatetimeToString;
     this.equals = DW_EqualsDatetime;
}

// These constants are used by the date parsing code
var DW_PARSEDT_DATE = 0;
var DW_PARSEDT_TIME = 1;
var DW_PARSEDT_DATETIME = 2;

// these three are dependent on localization settings
//var DW_PARSEDT_monseq = 0;
//var DW_PARSEDT_dayseq = 1;
//var DW_PARSEDT_yearseq = 2;
var DW_PARSEDT_hourseq = 3;
var DW_PARSEDT_minseq = 4;
var DW_PARSEDT_secseq = 5;
var DW_PARSEDT_msecseq = 6;

function DW_monthSearch(inMonthName)
{
    var index;
    var inMonthLC = inMonthName.toLowerCase();
    
    // check short month names
    for (index=0; index < 12; index++)
        {
        if (DW_shortMonthNames[index].toLowerCase() == inMonthLC)
            return index + 1;
        }

    // check long month names
    for (index=0; index < 12; index++)
        {
        if (DW_longMonthNames[index].toLowerCase() == inMonthLC)
            return index + 1;
        }

   // if we get here, we couldn't find the name
   return -1;
}

// The function validates data against the following masks only.
// yy, yyyy, m, mm, mmm, mmmm, d, dd, h, hh, m, mm, s, ss, f to ffffff, a/p, A/P, am/pm, AM/PM
// Validates standard formats, i.e. [SHORTDATE], [LONGDATE], [TIME], [GENERAL]
// Accepts only the following 6 delimiters as legal separator
// '-', '/', ',', '.', ' ', ':'
// The function does not do any validation against illegal masks

function DW_parseDatetimeStringAgainstMask(inString, outDatetime, parseType, Mask)
{
    // Get encoded format against mask
	var format = new DW_DateEncodingClass(Mask);

    // if invald mask, return false
	if (! format.bValid) return false;
	var StringAllZero = true;
    // Create a new date class
    var dt = new DW_DateClass(0,0,1);

	var STATESECTION = 0;
	var STATENUMBER = 1;
	var STATEMONSTRING = 2;
	var STATESEPARATOR = 3;

	var currChar;
	var nextChar; 
	var charIndex = 0;
	var state;

	var key;			// To hold number and strings
	var nVal;			// To store integer value
	
    var index = 0;
    var encodedFormat = format.encodedFormat;
    var action;

	while (charIndex < inString.length && index < encodedFormat.length)
	{
		currChar = inString.charAt (charIndex);
		if (DW_parseIsDigit(currChar) && currChar !='0')
		{
			StringAllZero = false;
		}
		charIndex++;
	}
	if(StringAllZero)
	{
	    if (typeof(goEditMaskManager) == "object")
	        return true;
	    else
		    return false;
	}
	
	if (typeof(goEditMaskManager) == "object")
	{
		if (inString == "12:00 AM") inString = "12:00 PM";
		if (inString == "12:00 am") inString = "12:00 pm";
	}
	
	charIndex = 0;
	while (charIndex < inString.length && index < encodedFormat.length)
	{
		// Now extract one token from encode string
		
		action = 0;

		if( index < encodedFormat.length)
		{
            action = encodedFormat[index];
			index++;
		}

		// Initialize
		state = STATESECTION;

		key = "";
		nVal = 0;

		// Extract one token from inString
		do{
			
			currChar = inString.charAt (charIndex);
			if (state == STATESECTION)
			{
				if (action == DWFMT_apCaps || action == DWFMT_apNCaps || action == DWFMT_ampmCaps || action == DWFMT_ampmNCaps) 
				{
					if (currChar == 'a' || currChar == 'A')
					{
						if((inString.charAt (charIndex+1) == 'm') || (inString.charAt (charIndex+1) == 'M'))
						{
							key = currChar + inString.charAt (charIndex+1);
							charIndex += 2;
						}
						else
						{
							key = currChar;
							charIndex ++;
						}
					
						state = STATESECTION;

					}
					else if ((currChar == 'p') || (currChar == 'P'))
					{
						if(inString.charAt (charIndex+1) == 'm' || inString.charAt (charIndex+1) == 'M')
						{
							key = currChar + inString.charAt (charIndex+1);
							charIndex += 2;
						}
						else
						{
							key = currChar;
							charIndex ++;
						}
					
						state = STATESECTION;

					}
					else
						return false;
				}

				else if (currChar == '-' ||     // New section
				currChar == '/' ||
					currChar == ',' ||
					currChar == '.' ||
					currChar == ' ' ||
					currChar == ':')
					state = STATESEPARATOR;
				
				else if (DW_parseIsDigit(currChar))
					state = STATENUMBER;
				
				else if (DW_parseIsAlpha(currChar))
					state = STATEMONSTRING;
				
				else if (currChar == action)
					state = STATESEPARATOR; 				else
					return false;
			
			}
			
			else if(state == STATENUMBER)
			{
				key += currChar;
				charIndex++;

				// accumulate until next char is not a digit
				if (!DW_parseIsDigit(inString.charAt (charIndex)))
				{
					state = STATESECTION;       // Change state for next char
					
					nVal = key - 0;
				}
			}

			else if (state == STATEMONSTRING)
			{
				key += currChar;
				charIndex++;
				if (!DW_parseIsAlpha(inString.charAt (charIndex)))
				{
					nVal = DW_monthSearch(key);
					if (nVal == -1)
						return false;
					state = STATESECTION;
				}
			}

			else if (state == STATESEPARATOR) 
			{
				key += currChar;  
				charIndex++;
				nextChar = inString.charAt (charIndex);
				if (!(nextChar == '-' ||     // New section
					nextChar == '/' ||
					nextChar == ',' ||
					nextChar == '.' ||
					nextChar == ' ' ||
					nextChar == ':'))
					state = STATESECTION;
			}

			else
			{
				return false;        // Unspecified error
			}

		}while(charIndex < inString.length && state != STATESECTION)


		// If both the tokens are matching - update date class and continue.

        if (typeof action == "string")
		{
			if (key != action)
				return false;
		}
		else if(action == DWFMT_2digityear)
		{
			if(nVal < 0 || key.length != 2)
				return false;
			else if (nVal >= 50)
				nVal += 1900;
			else
				nVal += 2000;

			dt.year = nVal;
		}
        else if (action == DWFMT_4digityear)
		{
			if(nVal < 0 || (key.length != 4 && key.length != 2))
				return false;
			if (key.length == 2)
			{
				if (nVal >= 50) 
					nVal += 1900
				else
					nVal += 2000;
			}
			else if(nVal == 0)
				return false;
				

			dt.year = nVal;
		}
        else if (action == DWFMT_monthz || action == DWFMT_monthnz)
		{
			if(nVal < 1 || nVal > 12 || key.length > 2)
				return false;

			dt.month = nVal;
		}
		else if (action == DWFMT_monthshortname)
        {
			if(nVal < 0 || key.length != 3)
				return false;

			dt.month = nVal;
        }
        else if (action == DWFMT_monthlongname)
        {
			if(nVal < 0)
				return false;

			if(key.length == 3 && nVal != 5) // May is only exception
				return false;

			dt.month = nVal;
        }
        else if (action == DWFMT_dayz || action == DWFMT_daynz)
		{
			if(nVal < 1 || nVal > 31 || key.length > 2)
				return false;

			dt.day = nVal;
		}
		//The following masks are invalid input mask
        else if (action == DWFMT_dayshortname || action == DWFMT_daylongname)
        {
			return false;
        }
        else if (action == DWFMT_hourz || action == DWFMT_hournz)
		{
			if(nVal < 0 || nVal > 23 || key.length > 2)
				return false;

			dt.hour = nVal;
		}
        else if (action == DWFMT_minz || action == DWFMT_minnz)
		{
			if(nVal < 0 || nVal > 59 || key.length > 2)
				return false;

			dt.min = nVal;
		}
        else if (action == DWFMT_secz || action == DWFMT_secnz)
		{
			if(nVal < 0 || nVal > 59 || key.length > 2)
				return false;

			dt.sec = nVal;
		}
        else if (action == DWFMT_msec)
		{
			if(nVal < 0 || nVal > 999999)
				return false;

			// Retreive next action
			action = 0;

			if( index < encodedFormat.length)
			{
				action = encodedFormat[index];
				index++;
			}
			else return false;

			if((action > 6) || (key.length != action))
				return false;

            var tempStr = key + "000000";
            dt.msec = tempStr.substring(0, 6) - 0;
		}
        else if (action == DWFMT_apCaps)
        {
			if ((key != "A") && (key != "P"))
				return false;
			if ((dt.hour > 12) || (dt.hour == 0))
				return false;
			
			if (key == "A")
			{
				if (dt.hour == 12)
					dt.hour = 0;
			}
			else 
			{
				if(dt.hour < 12)
					dt.hour += 12;
			}
        }
        else if (action == DWFMT_apNCaps)
        {
			if ((key != "a") && (key != "p"))
				return false;
			if ((dt.hour > 12) || (dt.hour == 0))
				return false;
			if (key == "a")
			{
				if (dt.hour == 12)
					dt.hour = 0;
			}
			else 
			{
				if(dt.hour < 12)
					dt.hour += 12;
			}
        }
        else if (action == DWFMT_ampmCaps)
        {
			if ((key != "AM") && (key != "PM"))
				return false;
			if ((dt.hour > 12) || (dt.hour == 0))
				return false;
			if (key == "AM")
			{
				if (dt.hour == 12)
					dt.hour = 0;
			}
			else 
			{
				if(dt.hour < 12)
					dt.hour += 12;
			}
        }
        else if (action == DWFMT_ampmNCaps)
        {
			if ((key != "am") && (key != "pm"))
				return false;
			if ((dt.hour > 12) || (dt.hour == 0))
				return false;
			if (key == "am")
			{
				if (dt.hour == 12)
					dt.hour = 0;
			}
			else 
			{
				if(dt.hour < 12)
					dt.hour += 12;
			}
        }
		else return false
	}

	// whether we have reached at the end of both the string
	if (charIndex < inString.length)
		return false;


	// Do additional validation of the day against month and year
	if (parseType != DW_PARSEDT_TIME)
	    {
    		var leapYear = DW_isLeap(dt.year) ? 1 : 0;
			if (dt.day > DW_dayTable[leapYear][dt.month])
				return false;
    	}

    if (outDatetime != null)
    {
    	if (parseType == DW_PARSEDT_DATE || parseType == DW_PARSEDT_DATETIME)
    	{
    		outDatetime.day = dt.day;
    		outDatetime.month = dt.month - 1;
    		outDatetime.year = dt.year - 1900;
    	}
    	if (parseType == DW_PARSEDT_TIME || parseType == DW_PARSEDT_DATETIME)
    	{
    		outDatetime.sec = dt.sec;
    		outDatetime.min = dt.min;
    		outDatetime.hour = dt.hour;
    		outDatetime.msec = dt.msec;
    	}
    }

	return true;
}

function DW_parseDatetimeString(inString, outDatetime, parseType)
{
    var result;
	if (gMask != "")
		result = DW_parseDatetimeStringAgainstMask(inString, outDatetime, parseType, gMask);
	if (result)
	    return result;

	var STATESECTION = 0;
	var STATENUMBER = 1;
	var STATEMONSTRING = 2;

	var dt = new Array();            // date time array
	var key;           // To hold number and strings
	var currChar;
	var charIndex;
	var strLen = inString.length;
	var state;
	var seq;
	var bIllegal= false;
	var section;
	var i;

	// Initialize date/time array
	for (var i=0; i<= DW_PARSEDT_msecseq; i++)
		dt[i] = -1;

	if (parseType == DW_PARSEDT_TIME)
		{
		section = DW_PARSEDT_hourseq;      // start at time section
		lastseq = DW_PARSEDT_msecseq;
		}
	else if (parseType == DW_PARSEDT_DATETIME)
		{
		section = 0;
		lastseq = DW_PARSEDT_msecseq;
		}
	else
		{
		section = 0;            // start at first section
		lastseq = 2;            // end after date segments
		}
	state = STATESECTION;

    for (charIndex = 0; charIndex < strLen && ! bIllegal;)
		{
		currChar = inString.charAt (charIndex);
		if (state == STATESECTION)
			{
			if (DW_parseIsSpace(currChar))
				charIndex++;          // skip white space
			else if ((currChar == 'a' || currChar == 'A') &&
					 (inString.charAt (charIndex+1) == 'm' || inString.charAt (charIndex+1) == 'M'))
				{
				if (dt[DW_PARSEDT_hourseq] != -1)
					{
					if (dt[DW_PARSEDT_hourseq] == 0 &&
						dt[DW_PARSEDT_minseq] <= 0)
						bIllegal = true;
					else
						{
						if (dt[DW_PARSEDT_hourseq] == 12)  // 12 a.m. = 00
							dt[DW_PARSEDT_hourseq] = 0;
						charIndex += 2;
						section = lastseq;
						}
					}
				else
					bIllegal = true;
				}
			else if ((currChar == 'p' || currChar == 'P') &&
					 (inString.charAt (charIndex+1) == 'm' || inString.charAt (charIndex+1) == 'M'))
				{
				if (dt[DW_PARSEDT_hourseq] != -1)
					{
					charIndex += 2;
					if (dt[DW_PARSEDT_hourseq] != 12)
						{
						dt[DW_PARSEDT_hourseq] += 12;
						if (dt[DW_PARSEDT_hourseq] > 23)
							bIllegal = true;
						else
							section = lastseq;
						}
					}
				else
					bIllegal = true;
				}
			else if (section > lastseq) // too many sections
				bIllegal = true;
			else if (currChar == '-' ||     // New section
					 currChar == '/' ||
					 currChar == ',' ||
					 currChar == '.' ||
					 currChar == ':')
				{
				if (section == 0 ||                 // Never done a section?
					dt[section-1] == -1)        // Missed a section?
					bIllegal = true;
				else
					charIndex++;
				}
			else if (DW_parseIsDigit(currChar))
				{
				key = "";
				state = STATENUMBER;
				}
			else if (DW_parseIsAlpha(currChar))
				{
				if (section != DW_PARSEDT_monseq)
					bIllegal = true;
				else
					state = STATEMONSTRING;
				key = "";
				}
			else
				bIllegal = true;
			}
		else if(state == STATENUMBER)
			{
			key += currChar;
			charIndex++;
			// accumulate until next char is not a digit
			if (!DW_parseIsDigit(inString.charAt (charIndex)))
				{
				state = STATESECTION;       // Change state for next char
				var n = key - 0;
                var keyLength = key.length;
                
				if (section == 0 &&  keyLength == 4)
					{           // year obviously first; force new format
					DW_PARSEDT_yearseq = 0;
					DW_PARSEDT_monseq = 1;
					DW_PARSEDT_dayseq = 2;
					}

				if (section == DW_PARSEDT_monseq)
					{
					if (n < 1 || n > 12)
					bIllegal = true;
					}
				else if (section == DW_PARSEDT_yearseq)
					{       // valid size of year

					if (n < 0 || !(keyLength == 2 || keyLength == 4))
						bIllegal = true;
					// e.g. if 01/01/50 then year is 1950
					else if (n >= 50 && keyLength == 2)
						n += 1900;
					// e.g. if 01/01/49 then year is 2049
					else if (n < 50 && keyLength == 2)
						n += 2000;
					}
				else if (section == DW_PARSEDT_dayseq)
					{
					if (n < 1 || n > 31)        // Do more validation later
						bIllegal = true;
					}
				else if (section == DW_PARSEDT_hourseq)
					{
					if (n < 0 || n > 23)
						bIllegal = true;
					}
				else if (section == DW_PARSEDT_minseq)
					{
					if (n < 0 || n > 59)
						bIllegal = true;
					}
				else if (section == DW_PARSEDT_secseq)    // seconds
					{
					if (n < 0 || n > 59)
						bIllegal = true;
					}
				else        // Micro seconds
					{
					if (n < 0 || n > 999999)
						bIllegal = true;
					else if (keyLength == 1)
						n *= 100000;
					else if (keyLength == 2)
						n *= 10000;
					else if (keyLength == 3)
						n *= 1000;
					else if (keyLength == 4)
						n *= 100;
					else if (keyLength == 5)
						n *= 10;
					}
				if (!bIllegal)
					{
					dt[section] = n;
					section++;
					}
				}
			}
        else if (state == STATEMONSTRING)
            {
			key += currChar;
			charIndex++;
			if (!DW_parseIsAlpha(inString.charAt (charIndex)))
				{
				var m;

				m = DW_monthSearch(key);
				if (m == -1)
					bIllegal = true;
				else
					dt[section] = m;
				state = STATESECTION;
				section++;
				if (inString.charAt (charIndex) == '.' &&  // Check for possible
					key.length == 3 &&  // abbreviation of month
					m != 5)         // "May" has no abbreviation
					charIndex++;
				}
			}
		else
		    {
			bIllegal = true;        // Unspecified error
			}
		}

	if (bIllegal)
		return false;


	if (parseType != DW_PARSEDT_TIME)
		{   // We require month and day and year
		if (dt[DW_PARSEDT_monseq] == -1 ||
			dt[DW_PARSEDT_yearseq] == -1 ||
			dt[DW_PARSEDT_dayseq] == -1)
			return false;
		}
	else if (dt[DW_PARSEDT_hourseq] == -1 )     // We require at least the hour
		return false;

	// Zero out uninitialized fields
	for (i=0; i <= DW_PARSEDT_msecseq; i++)
		if (dt[i] == -1)
			dt[i] = 0;

	// Do additional validation of the day and year
	if (parseType != DW_PARSEDT_TIME)
	    {
    	var leapYear = DW_isLeap(dt[DW_PARSEDT_yearseq]) ? 1 : 0;
		if (dt[DW_PARSEDT_dayseq] > DW_dayTable[leapYear][dt[DW_PARSEDT_monseq]])
    		return false;
		if (dt[DW_PARSEDT_yearseq] > 9999)
			return false;
    	}

    if (outDatetime != null)
        {
    	if (parseType == DW_PARSEDT_DATE || parseType == DW_PARSEDT_DATETIME)
    		{
    		outDatetime.day = dt[DW_PARSEDT_dayseq];
    		outDatetime.month = dt[DW_PARSEDT_monseq]-1;
    		outDatetime.year = dt[DW_PARSEDT_yearseq]-1900;
    		}
    	if (parseType == DW_PARSEDT_TIME || parseType == DW_PARSEDT_DATETIME)
    		{
    		outDatetime.sec = dt[DW_PARSEDT_secseq];
    		outDatetime.min = dt[DW_PARSEDT_minseq];
    		outDatetime.hour = dt[DW_PARSEDT_hourseq];
    		outDatetime.msec = dt[DW_PARSEDT_msecseq];
    		}
    	}

	return true;
}

function DW_DateParse(inString)
{
    var result = new DW_DateClass();
    
    if (DW_parseDatetimeString (inString, result, DW_PARSEDT_DATE))
    {
		if(result.equals(new DW_DateClass(0,0,0)))
			return null;
		else
			return result;
    }
    else
        return null;
}

function DW_DatetimeParse(inString)
{
    var result = new DW_DatetimeClass();
    
    if (DW_parseDatetimeString (inString, result, DW_PARSEDT_DATETIME))
	{
		if(result.equals(new DW_DatetimeClass(0,0,0,0,0,0,0)))
			return null;
		else
			return result;
	}
    else
        return null;
}

function DW_TimeParse(inString)
{
    var result = new DW_TimeClass();
    
    if (DW_parseDatetimeString (inString, result, DW_PARSEDT_TIME))
        return result;
    else
        return null;
}

function DW_IsDatetime(inString, bNilIsNull)
{
    if (arguments.length < 2)
        bNilIsNull = false;
    
	if (inString == "")
        return bNilIsNull;
    else
        return DW_parseDatetimeString (inString, null, DW_PARSEDT_DATETIME);
}

function DW_IsDate(inString, bNilIsNull)
{
    if (arguments.length < 2)
        bNilIsNull = false;
    
	if (inString == "")
        return bNilIsNull;
    else
        return DW_parseDatetimeString (inString, null, DW_PARSEDT_DATE);
}

function DW_IsTime(inString, bNilIsNull)
{
    if (arguments.length < 2)
        bNilIsNull = false;
    
	if (inString == "")
        return bNilIsNull;
    else
        return DW_parseDatetimeString (inString, null, DW_PARSEDT_TIME);
}

function DW_Now()
{
    var now = new Date();
    return new DW_TimeClass(now.getHours(), now.getMinutes(), now.getSeconds(), now.getMilliseconds());
}

function DW_Today()
{
    var now = new Date();
    var year = now.getYear();
	year -= 1900;
    return new DW_DateClass(year, now.getMonth(), now.getDate());
}

// Dropdown calendar
// Global variables
var DW_Cal;

// Configurable parameters
var DWCAL_WeekChar = 2; // number of character for week day. if 2 then Mo,Tu,We. if 3 then Mon,Tue,Wed
var DWCAL_CellWidth = 20; // Width of day cell
var DWCAL_ShowLongMonth = true; // Show long month name in Calendar header. example: "January"
var DWCAL_ShowMonthYear = true; // Show Month and Year in Calendar header
var DWCAL_MonthYearColor = "#cc0033"; // Font Color of Month and Year in Calendar header
var DWCAL_WeekHeadColor = "#0099CC"; // Background Color in Week header
var DWCAL_SundayColor = "#6699FF"; // Background color of Sunday
var DWCAL_SaturdayColor = "#CCCCFF"; // Background color of Saturday
var DWCAL_WeekDayColor = "white"; // Background color of weekdays
var DWCAL_FontColor = "blue"; // color of font in Calendar day cell
var DWCAL_TodayColor = "#FFFF33"; // Background color of today
var DWCAL_SelDateColor = "#FFFF99"; // Backgrond color of selected date in textbox
var DWCAL_YrSelColor = "#cc0033"; // color of font of Year selector
var DWCAL_ThemeBg = ""; // Background image of Calendar window
// end Configurable parameters
// end Global variables

function DW_NewCalendar(dwObject, value, formatString)
{
    var cFName = dwObject.name + "_calFrame";
    var cF = document.getElementById(cFName);
    var control = dwObject.currentControl;
    var givenDate = null;

    if (control.bSetByCal + "" != "undefined" && control.bSetByCal == true)
        {
        control.bSetByCal = false;
        return;
        }

    DW_Cal = new DW_Calendar(new Date(), formatString);

    DW_Cal.dwObject = dwObject;
    DW_Cal.calFrameName = cFName;
    DW_Cal.calFrame = cF;

    if (value != null)
        {
        if (typeof(value) == "string")
            givenDate = DW_DateParse(value);
        else
            givenDate = value;
        }

    if (formatString != null)
        {
        var dateFormat = new DW_DateFormatClass(formatString);
        var format;

		if (!dateFormat.bValid)
			{
			if (value == null ||
				givenDate.toString == DW_DateToString)
				dateFormat = new DW_DateFormatClass( "[SHORTDATE]" );
			else if (givenDate.toString == DW_DatetimeToString)
				dateFormat = new DW_DateFormatClass( "[SHORTDATE] [TIME]" );
			else
				return;
			}

		if (value == null && dateFormat.nullFormat != null)
			format = dateFormat.nullFormat;
		else
			format = dateFormat.mainFormat;

		DW_Cal.bShowTime = format.bTime;
		DW_Cal.b24hr = format.b24hr;
		}

	if (givenDate != null)
	{
		DW_Cal.month = givenDate.month;
		DW_Cal.day = givenDate.day;
		DW_Cal.year = givenDate.year + 1900;

		if (DW_Cal.bShowTime)
		{
			DW_Cal.hour = givenDate.hour;
			DW_Cal.min = givenDate.min;
			DW_Cal.sec = givenDate.sec;
		}	
	}

	// in pb .net, might have multiple div parents
	// must overflow these, and must overlap divs below us
	for(var obj = cF.offsetParent;
		obj && obj.tagName == "DIV";
		obj = obj.offsetParent)
	{
		if (obj.style.overflowY == "hidden")
		{
			obj.style.overflowY = "visible";
			obj.style.zIndex = 32767;
		}
	}

	// display frame
	cF.style.display = "block";
	DW_RenderCalendar();
	dwObject.positionComboBox(control, cF);
}

function DW_RenderCalendar()
{
	var winCal;
	var docCal;
	var vCalHeader;
	var vCalData;
	var vCalTime;
	var i;
	var j;
	var SelectStr;
	var vDayCount=0;
	var vWeekCount=1;
	var vFirstDay;
	var now = new Date();

	if(window.frames && window.frames[DW_Cal.calFrameName]) //IE 5 (Win/Mac), Konqueror, Safari
		winCal = window.frames[DW_Cal.calFrameName];
	else if(DW_Cal.calFrame.contentWindow) //IE 5.5+, Mozilla 0.9+, Opera
	{
		winCal = DW_Cal.calFrame.contentWindow;
		DW_Cal.calFrame.style.backgroundColor = "white";
	}
	else //Moz below 0.9 (Netscape 6.0)
		winCal = DW_Cal.calFrame;

	if(winCal.document) //Moz 0.9+, Konq, Safari, IE, Opera
		docCal = winCal.document;
	else //Moz below 0.9 (Netscape 6.0)
		docCal = winCal.contentDocument;

	docCal.open("text/html","replace");
	docCal.writeln("<html><head>"); // <title>"+..+"</title>");
	docCal.writeln("<"+"script language=\"JavaScript\">");
	docCal.writeln("function DWCAL_SetItemDateTime(dateVal)");
	docCal.writeln("{");
	docCal.writeln("var parentDW = parent."+DW_Cal.dwObject.name+";");
	docCal.writeln("var parentControl = parentDW.currentControl;");
	if (DW_Cal.bShowTime)
		docCal.writeln("var vDatetime = new parent.DW_DatetimeClass( "+(DW_Cal.year - 1900)+", "+DW_Cal.month+", dateVal, parent.DW_Cal.hour, parent.DW_Cal.min, parent.DW_Cal.sec, 0 );");
	else
		docCal.writeln("var vDatetime = new parent.DW_DateClass( "+(DW_Cal.year - 1900)+", "+DW_Cal.month+", dateVal );");
	docCal.write("parentControl.value=");
	if (DW_Cal.format != null)
		docCal.writeln("parent.DW_FormatDate( \""+DW_Cal.format+"\", vDatetime, parentControl );");
	else
		docCal.writeln("vDatetime.toString();");
	docCal.writeln("parentControl.bChanged=true;");
	docCal.writeln("parentControl.bSetByCal=true;");
	docCal.writeln("parentDW.AcceptText();");
	docCal.writeln("window.frameElement.style.display=\"none\";");
	docCal.writeln("parentControl.focus();");
	docCal.writeln("}");
	docCal.writeln("</"+"script>");
	docCal.writeln("</head><body background='"+DWCAL_ThemeBg+"' link="+DWCAL_FontColor+" vlink="+DWCAL_FontColor+"><form name='DW_Calendar'>");

	vCalHeader = "<table border=0 cellpadding=1 cellspacing=1 width='100%' align=\"center\" valign=\"top\" style=\"border:2px solid black;font-family:Verdana;font-size:8pt\">\n";
	// Month Selector
	vCalHeader += "<tr>\n<td colspan='7'><table border=0 width='100%' cellpadding=0 cellspacing=0 style=\"font-family:Verdana;font-size:10pt\"><tr><td align='left'>\n";
	vCalHeader += "<select name=\"MonthSelector\" onchange=\"javascript:parent.DW_Cal.DW_SwitchMonth(this.selectedIndex);parent.DW_RenderCalendar();\">\n";
	for (i = 0; i < 12; i++)
	{
		if (i == DW_Cal.month)
			SelectStr = "selected";
		else
			SelectStr = "";	
		if(typeof(DW_displayLongMonthNames)=="object")
			vCalHeader += "<option "+SelectStr+" value = \"" + DW_longMonthNames[i] + "\">" +DW_displayLongMonthNames[i]+"\n";
		else
			vCalHeader += "<option "+SelectStr+" value >"+DW_longMonthNames[i]+"\n";
	}
	vCalHeader += "</select></td>";
	// Year selector
	vCalHeader += "\n<td align='right'><a href=\"javascript:parent.DW_Cal.DW_DecYear();parent.DW_RenderCalendar()\"><b><font color=\""+
				  DWCAL_YrSelColor+"\"><</font></b></a><font face=\"Verdana\" color=\""+DWCAL_YrSelColor+"\"><b> "+DW_Cal.year+
				  " </b></font><a href=\"javascript:parent.DW_Cal.DW_IncYear();parent.DW_RenderCalendar()\"><b><font color=\""+
				  DWCAL_YrSelColor+"\">></font></b></a></td></tr></table></td>\n";
	vCalHeader += "</tr>";
	// Calendar header shows Month and Year
	if (DWCAL_ShowMonthYear)
		vCalHeader += "<tr><td colspan='7' align='center' style=\"font-size:10pt\"><font color='"+DWCAL_MonthYearColor+"'><b>"+
		DW_Cal.DW_GetDisplayMonthName(DWCAL_ShowLongMonth)+" "+DW_Cal.year+"</b></font></td></tr>\n";
	// Week day header
	vCalHeader += "<tr bgcolor="+DWCAL_WeekHeadColor+">";

	var longDayNames = DW_longDayNames;
	var shortDayNames = DW_shortDayNames;
	if(typeof(DW_displayLongDayNames)=="object")
		longDayNames = DW_displayLongDayNames; 
	if(typeof(DW_displayShortDayNames)=="object")
		shortDayNames = DW_displayShortDayNames; 
	for (i = 0; i < 7; i++)
	{
		if(shortDayNames[i].length > 2)
			vCalHeader += "<td align='center'>"+longDayNames[i].substr(0,DWCAL_WeekChar)+"</td>";
		else
			vCalHeader += "<td align='center'>"+shortDayNames[i] + "</td>";
	}
	vCalHeader += "</tr>";
	docCal.write(vCalHeader);

	// Calendar detail
	CalDate = new Date(DW_Cal.year, DW_Cal.month);
	CalDate.setDate(1);
	vFirstDay = CalDate.getDay();
	vCalData = "<tr>";
	for (i = 0; i < vFirstDay; i++)
	{
		vCalData = vCalData + DW_GenCalendarCell();
		vDayCount = vDayCount + 1;
	}
	for (j = 1; j <= DW_Cal.DW_GetMonDays(); j++)
	{
		var strCell;
		vDayCount = vDayCount + 1;
		if ((j == now.getDate()) && (DW_Cal.month == now.getMonth()) && (DW_Cal.year == now.getFullYear()))
			strCell = DW_GenCalendarCell(j, true, DWCAL_TodayColor); // Highlight today's date
		else
		{
			if (j == DW_Cal.day)
			{
				strCell = DW_GenCalendarCell(j, true, DWCAL_SelDateColor);
			}
			else
			{	 
				if (vDayCount % 7 == 0)
					strCell = DW_GenCalendarCell(j, false, DWCAL_SaturdayColor);
				else if ((vDayCount + 6) % 7 == 0)
					strCell = DW_GenCalendarCell(j, false, DWCAL_SundayColor);
				else
					strCell = DW_GenCalendarCell(j, null, DWCAL_WeekDayColor);
			}
		}
		vCalData = vCalData + strCell;

		if((vDayCount % 7 == 0) && (j < DW_Cal.DW_GetMonDays()))
		{
			vCalData = vCalData + "</tr>\n<tr>";
			vWeekCount++;
		}
	}
	docCal.writeln(vCalData);	
	// Time picker
	if (DW_Cal.bShowTime)
	{
		var showHour;
		showHour = DW_Cal.DW_getShowHour();
		vCalTime = "<tr>\n<td colspan='7' align='center'>";
		vCalTime += "<input type='text' name='hour' maxlength=2 size=1 style=\"WIDTH: 22px\" value="+showHour+" onchange=\"javascript:parent.DW_Cal.DW_SetHour(this.value)\">";
		vCalTime += " : ";
		vCalTime += "<input type='text' name='minute' maxlength=2 size=1 style=\"WIDTH: 22px\" value="+DW_Cal.min+" onchange=\"javascript:parent.DW_Cal.DW_SetMinute(this.value)\">";
		vCalTime += " : ";
		vCalTime += "<input type='text' name='second' maxlength=2 size=1 style=\"WIDTH: 22px\" value="+DW_Cal.sec+" onchange=\"javascript:parent.DW_Cal.DW_SetSecond(this.value)\">";
		if (!DW_Cal.b24hr)
		{
			var SelectAm = (parseInt(DW_Cal.hour,10) < 12) ? "selected" : "";
			var SelectPm = (parseInt(DW_Cal.hour,10) >= 12) ? "selected" : "";

			vCalTime += "<select name=\"ampm\" onchange=\"javascript:parent.DW_Cal.DW_SetAmPm(this.options[this.selectedIndex].value);\">";
			vCalTime += "<option "+SelectAm+" value=\"AM\">AM</option>";
			vCalTime += "<option "+SelectPm+" value=\"PM\">PM<option>";
			vCalTime += "</select>";
		}
		vCalTime += "\n</td>\n</tr>";
		docCal.write(vCalTime);
	}
	// end time picker
	docCal.writeln("\n</table>");
	docCal.writeln("</form></body></html>");
	docCal.close();

	// adjust frame height
	var fHeight = 163;	// 6 wks
	if (vWeekCount == 5)
		fHeight = 147;
	else if (vWeekCount == 4)
		fHeight = 131;
	if (DW_Cal.bShowTime)
		fHeight += 27;
	DW_Cal.calFrame.style.height = fHeight;
}

function DW_GenCalendarCell(pValue, pHighLight, pColor) // Generate table cell with value
{
	var PValue;
	var PCellStr;
	var vColor;
	var vHLstr1; // HighLight string
	var vHLstr2;

	if (pValue == null)
		PValue = "";
	else
		PValue = pValue;

	if (pColor != null)
		vColor = "bgcolor=\""+pColor+"\"";
	else
		vColor = "";
	if ((pHighLight != null) && pHighLight)
	{
		vHLstr1 = "<font color='red'><b>";
		vHLstr2="</b></font>";
	}
	else
	{
		vHLstr1="";
		vHLstr2="";
	}	

	PCellStr = "<td "+vColor+" width="+DWCAL_CellWidth+" align='center'>"+vHLstr1+
				"<a href=\"javascript:DWCAL_SetItemDateTime("+PValue+");\">"+PValue+"</a>"+vHLstr2+"</td>";

	return PCellStr;
}

function DW_Calendar(pDate, format)
{
	// Properties
	this.month = pDate.getMonth(); // selected month number
	this.day = pDate.getDate(); // selected date
	this.year = pDate.getFullYear(); // selected year in 4 digits
	this.hour = pDate.getHours();

	if (pDate.getMinutes() < 10)
		this.min = "0" + pDate.getMinutes();
	else
		this.min = pDate.getMinutes();

	if (pDate.getSeconds() < 10)
		this.sec = "0" + pDate.getSeconds();
	else		
		this.sec = pDate.getSeconds();

	this.bShowTime = false;
	this.b24hr = false;
	if (pDate.getHours() < 12)
		this.ampm = "AM";
	else
		this.ampm = "PM";
	this.format = format;
}

function DW_GetMonthIndex(shortMonthName)
{
	for (i = 0; i < 12; i++)
	{
		if (DW_shortMonthNames[i].toUpperCase() == shortMonthName.toUpperCase())
			return i;
	}
}
DW_Calendar.prototype.DW_GetMonthIndex = DW_GetMonthIndex;

function DW_IncYear()
{
	this.year++;
}
DW_Calendar.prototype.DW_IncYear = DW_IncYear;

function DW_DecYear()
{
	this.year--;
}
DW_Calendar.prototype.DW_DecYear = DW_DecYear;
	
function DW_SwitchMonth(intMonth)
{
	this.month = intMonth;
}
DW_Calendar.prototype.DW_SwitchMonth = DW_SwitchMonth;

function DW_SetHour(intHour)
{
	var MaxHour;
	var MinHour;
	if (this.b24hr) {
		MaxHour=23;
		MinHour=0; }
	else {
		MaxHour=12;
		MinHour=1; }
	var HourExp=new RegExp("^\\d\\d$");
	if (HourExp.test(intHour) && (parseInt(intHour,10)<=MaxHour) && (parseInt(intHour,10)>=MinHour))
	{
		if (!this.b24hr && (this.ampm=="PM"))
		{
			if (parseInt(intHour,10)==12)
				this.hour=12;
			else
				this.hour=parseInt(intHour,10)+12;
		}
		else if (!this.b24hr && (this.ampm=="AM"))
		{
			if (intHour==12)
				intHour-=12;
			this.hour=parseInt(intHour,10);
		}
		else if (this.b24hr)
			this.hour=parseInt(intHour,10);	
	}
}
DW_Calendar.prototype.DW_SetHour = DW_SetHour;

function DW_SetMinute(intMin)
{
	var MinExp=new RegExp("^\\d\\d$");
	if (MinExp.test(intMin) && (intMin<60))
		this.min=intMin;
}
DW_Calendar.prototype.DW_SetMinute = DW_SetMinute;

function DW_SetSecond(intSec)
{
	var SecExp=new RegExp("^\\d\\d$");
	if (SecExp.test(intSec) && (intSec<60))
		this.sec=intSec;
}
DW_Calendar.prototype.DW_SetSecond = DW_SetSecond;

function DW_SetAmPm(pvalue)
{
	this.ampm = pvalue;
	if (pvalue == "PM")
	{
		this.hour = (parseInt(this.hour,10)) + 12;
		if (this.hour == 24)
			this.hour = 12;
	}
	else if (pvalue == "AM")
		this.hour -= 12;	
}
DW_Calendar.prototype.DW_SetAmPm = DW_SetAmPm;

function DW_getShowHour()
{
	var finalHour;
    if (!this.b24hr)
    {
    	if (parseInt(this.hour,10) == 0)
		{
			this.ampm = "AM";
			finalHour = 12;
		}
		else if (parseInt(this.hour,10) == 12)
		{
			this.ampm = "PM";
			finalHour = 12;
		}
		else if (this.hour > 12)
		{
			this.ampm = "PM";
			if ((this.hour - 12) < 10)
				finalHour = "0" + ((parseInt(this.hour,10)) - 12);
			else
				finalHour = parseInt(this.hour,10) - 12;
		}
		else
		{
			this.ampm = "AM";
			if (this.hour < 10)
				finalHour = "0" + parseInt(this.hour,10);
			else
				finalHour = this.hour;
		}
	}
	else
	{
		if (this.hour < 10)
			finalHour = "0" + parseInt(this.hour,10);
		else
			finalHour = this.hour;
	}
	return finalHour;
}				
DW_Calendar.prototype.DW_getShowHour = DW_getShowHour;

function DW_GetMonthName(isLong)
{
	if (isLong)
		return DW_longMonthNames[this.month];
	else
		return DW_shortMonthNames[this.month];
}

function DW_GetDisplayMonthName(isLong)
{
	if (isLong)
	{
		if(typeof(DW_displayLongMonthNames)=="object")
			return DW_displayLongMonthNames[this.month];
		else
			return DW_longMonthNames[this.month];
	}
	else
	{
		if(typeof(DW_displayShortMonthNames)=="object")
			return DW_displayShortMonthNames[this.month];
		else
			return DW_shortMonthNames[this.month];
	}
}

DW_Calendar.prototype.DW_GetMonthName = DW_GetMonthName;
DW_Calendar.prototype.DW_GetDisplayMonthName = DW_GetDisplayMonthName;

function DW_GetMonDays() // Get number of days in a month
{
	var DaysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
	if (this.DW_IsLeapYear())
	{
		DaysInMonth[1] = 29;
	}
	return DaysInMonth[this.month];	
}
DW_Calendar.prototype.DW_GetMonDays = DW_GetMonDays;

function DW_IsLeapYear()
{
	if ((this.year % 4) == 0)
	{
		if ((this.year % 100 == 0) && (this.year % 400) != 0)
		{
			return false;
		}
		else
		{
			return true;
		}
	}
	else
	{
		return false;
	}
}
DW_Calendar.prototype.DW_IsLeapYear = DW_IsLeapYear;


//
// Date formatting code
//

// these constants are for use in date formats
var DWFMT_daynz = 0;
var DWFMT_dayz = 1;
var DWFMT_dayshortname = 2;
var DWFMT_daylongname = 3;
var DWFMT_monthnz = 4;
var DWFMT_monthz = 5;
var DWFMT_monthshortname = 6;
var DWFMT_monthlongname = 7;
var DWFMT_2digityear = 8;
var DWFMT_4digityear = 9;
var DWFMT_hournz = 10;
var DWFMT_hourz = 11;
var DWFMT_minnz = 12;
var DWFMT_minz = 13;
var DWFMT_secnz = 14;
var DWFMT_secz = 15;
var DWFMT_msec = 16;
var DWFMT_apCaps = 17;
var DWFMT_apNCaps = 18;
var DWFMT_ampmCaps = 19;
var DWFMT_ampmNCaps = 20;
var DWFMT_changeToCurrent = 21;

function DW_DateEncodingClass(inString)
{
    var index;
    var currChar;
    var encodedFormat = new Array();
    var accum = "";
    var numInSection;
    var offset = 0;
    var bValid = true;
    var bGotHour = false;
    
    this.bTime = false;
    this.b24hr = true;
    this.color = "";

    var strLen = inString.length;
    for (index=0; index < strLen && bValid; )
        {
        currChar = inString.charAt(index);
        // handle keywords
        if (currChar == "[")
            {
            if (accum != "")
                encodedFormat[offset++] = accum;
            accum = "";
            index++;
            for (; inString.charAt(index) != "]"; index++)
                accum += inString.charAt(index);
            index++; // skip ]
            var inlineEncoding = null;
            var keyword = accum.toUpperCase();
            if (keyword == "CURRENT")
                encodedFormat[offset++] = DWFMT_changeToCurrent;
            else if (keyword == "GENERAL" || keyword == "SHORTDATE" || keyword == "DATE")
                inlineEncoding = new DW_DateEncodingClass(DW_shortDateFormat);
            else if (keyword == "LONGDATE")
                inlineEncoding = new DW_DateEncodingClass(DW_longDateFormat);
            else if (keyword == "TIME")
                inlineEncoding = new DW_DateEncodingClass(DW_timeFormat);
            else
                {
				if (!parseInt(accum)) 
					this.color = accum.toLowerCase();
				else
					this.color = eval(accum);
                this.keyword = accum;
                }
            // if we build another format, inline it into current one
            if (inlineEncoding != null && inlineEncoding.bValid)
                {
                var innerFormat = inlineEncoding.encodedFormat;
                for (var j=0; j<innerFormat.length; j++)
                    encodedFormat[offset++] = innerFormat[j];
				if (keyword == "TIME")
				    {
				    this.bTime = true;
					this.b24hr = inlineEncoding.b24hr;
					}
                }
            accum = "";
            }
        else if (currChar == "d" || currChar == "D")
            {
            if (accum != "")
                encodedFormat[offset++] = accum;
            accum = "";
            index++;
            // accumulate all the d's
            for (numInSection = 1; inString.charAt(index).toUpperCase() == "D"; index++, numInSection++)
                ;
            if (numInSection == 1)
                encodedFormat[offset++] = DWFMT_daynz;
            else if (numInSection == 2)
                encodedFormat[offset++] = DWFMT_dayz;
            else if (numInSection == 3)
                encodedFormat[offset++] = DWFMT_dayshortname;
            else if (numInSection == 4)
                encodedFormat[offset++] = DWFMT_daylongname;
            else
                bValid = false;
            }
        else if (currChar == "m" || currChar == "M")
            {
            if (accum != "")
                encodedFormat[offset++] = accum;
            accum = "";
            index++;
            // accumulate all the m's
            for (numInSection = 1; inString.charAt(index).toUpperCase() == "M"; index++, numInSection++)
                ;
            if (numInSection == 1)
                if ( bGotHour )
                    {
                    encodedFormat[offset++] = DWFMT_minnz;
                    bGotHour = false;
                    }
                else
                    encodedFormat[offset++] = DWFMT_monthnz;
            else if (numInSection == 2)
                if ( bGotHour )
                    {
                    encodedFormat[offset++] = DWFMT_minz;
                    bGotHour = false;
                    }
                else
                    encodedFormat[offset++] = DWFMT_monthz;
            else if (numInSection == 3)
                encodedFormat[offset++] = DWFMT_monthshortname;
            else if (numInSection == 4)
                encodedFormat[offset++] = DWFMT_monthlongname;
            else
                bValid = false;
            }
        else if(currChar == "y" || currChar == "Y")
            {
            if (accum != "")
                encodedFormat[offset++] = accum;
            accum = "";
            index++;
            // accumulate all the y's
            for (numInSection = 1; inString.charAt(index).toUpperCase() == "Y"; index++, numInSection++)
                ;
            if (numInSection == 2)
                encodedFormat[offset++] = DWFMT_2digityear;
            else if (numInSection == 4)
                encodedFormat[offset++] = DWFMT_4digityear;
            else
                bValid = false;
            }
        else if(currChar == "h" || currChar == "H")
            {
            if (accum != "")
                encodedFormat[offset++] = accum;
            accum = "";
            index++;
            this.bTime = true;
            bGotHour = true;
            // accumulate all the h's
            for (numInSection = 1; inString.charAt(index).toUpperCase() == "H"; index++, numInSection++)
                ;
            if (numInSection == 1)
                encodedFormat[offset++] = DWFMT_hournz;
            else if (numInSection == 2)
                encodedFormat[offset++] = DWFMT_hourz;
            else
                bValid = false;
            }
        else if(currChar == "m" || currChar == "M")
            {
            if (accum != "")
                encodedFormat[offset++] = accum;
            accum = "";
            index++;
            // accumulate all the m's
            for (numInSection = 1; inString.charAt(index).toUpperCase() == "M"; index++, numInSection++)
                ;
            if (numInSection == 1)
                encodedFormat[offset++] = DWFMT_minnz;
            else if (numInSection == 2)
                encodedFormat[offset++] = DWFMT_minz;
            else
                bValid = false;
            }
        else if(currChar == "s" || currChar == "S")
            {
            if (accum != "")
                encodedFormat[offset++] = accum;
            accum = "";
            index++;
            // accumulate all the s's
            for (numInSection = 1; inString.charAt(index).toUpperCase() == "S"; index++, numInSection++)
                ;
            if (numInSection == 1)
                encodedFormat[offset++] = DWFMT_secnz;
            else if (numInSection == 2)
                encodedFormat[offset++] = DWFMT_secz;
            else
                bValid = false;
            }
        else if(currChar == "f" || currChar == "F")
            {
            if (accum != "")
                encodedFormat[offset++] = accum;
            accum = "";
            index++;
            // accumulate all the f's
            for (numInSection = 1; inString.charAt(index).toUpperCase() == "F"; index++, numInSection++)
                ;
            if (numInSection <= 6)
                {
                encodedFormat[offset++] = DWFMT_msec;
                encodedFormat[offset++] = numInSection;
                }
            else
                bValid = false;
            }
        else if(currChar == "a" ||
                    currChar == "A" ||
                    currChar == "p" ||
                    currChar == "P")
            {
            if (accum != "")
                encodedFormat[offset++] = accum;
            accum = "";
            index++;
            this.b24hr = false;
            nextChar = inString.charAt(index);
            if (nextChar.toUpperCase() == "M")
                {
                index = index + 4;
                if (currChar == "A" || currChar == "P")
                    encodedFormat[offset++] = DWFMT_ampmCaps;
                else
                    encodedFormat[offset++] = DWFMT_ampmNCaps;
                }
            else
                {
                index = index + 2;
                if (currChar == "A" || currChar == "P")
                    encodedFormat[offset++] = DWFMT_apCaps;
                else
                    encodedFormat[offset++] = DWFMT_apNCaps;
                }
            }
        else if(currChar == "\\")
            {
            index++;
            accum += inString.charAt(index++);
            }
        else if(currChar == "'")
            {
            index++;
            while (index < strLen)
                {
                currChar = inString.charAt(index);
                if (currChar == "'")
                    break;
                accum += currChar;
                index++;
                }
            // check if we fell off end before finding closing quotes
            if (index == strLen)
                bValid = false;

            index++; // skip trailing '
            }
        else
            {
            accum += currChar;
            index++;
            }
        }

    if (accum != "")
        encodedFormat[offset++] = accum;

	if (encodedFormat.length == 0 ) 
		bValid = false;

    this.bValid = bValid;
    this.encodedFormat = encodedFormat;
}

function DW_DateFormatClass(formatString)
{
    var semiOffset = formatString.indexOf(";");
    
    if (semiOffset != -1)
        {
        this.mainFormat = new DW_DateEncodingClass(formatString.substring(0, semiOffset));
        this.nullFormat = new DW_DateEncodingClass(formatString.substring(semiOffset+1, formatString.length));

        this.bValid = this.mainFormat.bValid && this.nullFormat.bValid;
        }
    else
        {
        this.mainFormat = new DW_DateEncodingClass(formatString);
        this.nullFormat = null;
        this.bValid = this.mainFormat.bValid;
        }
}

function DW_FormatDate(formatString, value, control)
{
    var dateFormat = new DW_DateFormatClass(formatString);
    var result = "";
    var givenDate = null;
    var format;

    if (value != null)
        {
        if (typeof(value) == "string")
            givenDate = DW_DateParse(value);
        else
            givenDate = value;
        }

	if (!dateFormat.bValid)
		{
		if ( value == null )
			result = "";
		else if ( givenDate.toString == DW_DatetimeToString )
			dateFormat = new DW_DateFormatClass( "[SHORTDATE] [TIME]" );
		else if ( givenDate.toString == DW_DateToString )
			dateFormat = new DW_DateFormatClass( "[SHORTDATE]" );
		else if ( givenDate.toString == DW_TimeToString )
			dateFormat = new DW_DateFormatClass( "[TIME]" );
		}

    if (dateFormat.bValid)
        {
        if (value == null && dateFormat.nullFormat != null)
            format = dateFormat.nullFormat;
        else
            format = dateFormat.mainFormat;
            
        var index;
        var encodedFormat = format.encodedFormat;
        var action;
        var ampm = (value == null || givenDate.hour < 12) ? 1 : 0;
        var hour, msec;
        
        for (index=0; index < encodedFormat.length ; index++)
            {
            action = encodedFormat[index];
            if (typeof action == "string")
                result += action;
            else if (action == DWFMT_changeToCurrent)
			{
                var dateCurrent = new DW_DatetimeClass2(DW_Today(), DW_Now());
				result = dateCurrent.toString();
			}
            else if (action == DWFMT_dayz || action == DWFMT_daynz)
                {
                if (action == DWFMT_dayz)
                    {
                    if (value == null)
                        result += "";
                    else if (givenDate.day < 10)
                        result += "0";
                    }
                if (value == null)
                    result += "00";
                else
                    result += givenDate.day;
                }
            else if (action == DWFMT_dayshortname)
                {
                if (value == null)
                    result += "   ";
                else
                    result += DW_shortDayNames[DW_dayOfWeek (givenDate.year + 1900, givenDate.month + 1, givenDate.day)];
                }
            else if (action == DWFMT_daylongname)
                {
                if (value == null)
                    result += "";
                else
                    result += DW_longDayNames[DW_dayOfWeek (givenDate.year + 1900, givenDate.month + 1, givenDate.day)];
                }
            else if (action == DWFMT_monthz || action == DWFMT_monthnz)
                {
                if (action == DWFMT_monthz)
                    {
                    if (value == null)
                        result += "";
                    else if ((givenDate.month + 1) < 10)
                        result += "0";
                    }
                if (value == null)
                    result += "00";
                else
                    result += (givenDate.month + 1);
                }
            else if (action == DWFMT_monthshortname)
                {
                if (value == null)
                    result += "   ";
                else
                    result += DW_shortMonthNames[givenDate.month];
                }
            else if (action == DWFMT_monthlongname)
                {
                if (value == null)
                    result += "";
                else
                    result += DW_longMonthNames[givenDate.month];
                }
            else if (action == DWFMT_2digityear)
                {
                if (value == null)
                    result += "00";
                else
                    {
                    var tempStr = (givenDate.year + 1900).toString();
                    var startPos = tempStr.length - 2;
                    result += tempStr.substring(startPos, startPos + 2);
                    }
                }
            else if (action == DWFMT_4digityear)
                {
                if (value == null)
                    result += "0000";
                else
                    result += (givenDate.year + 1900).toString();
                }
            else if (action == DWFMT_hourz || action == DWFMT_hournz)
                {
                if ( value == null )
                    hour = 0;
                else
                    hour = givenDate.hour;
				
                if (! format.b24hr )
                {
                    if( hour > 12)
                        hour -= 12;
                    else if ( hour == 0 ) // 00:00:00(24hour) => 12:00:00 AM
                        hour = 12;
                }
                    
                if (action == DWFMT_hourz)
                    {
                    if (value == null)
                        result += "";
                    else if (hour < 10)
                        result += "0";
                    }
                if (value == null)
                    result += "00";
                else
                    result += hour;
                }
            else if (action == DWFMT_minz || action == DWFMT_minnz)
                {
                if (action == DWFMT_minz)
                    {
                    if (value == null)
                        result += "";
                    else if (givenDate.min < 10)
                         {
                        //CR495198,min is string type and is already "0n" format
                         if (typeof givenDate.min != "string")
                             result += "0";
                         else if (givenDate.min.length == 1)
                             result += "0";
                         }
                    }
                if (value == null)
                    result += "00";
                else
                    result += givenDate.min;
                }
            else if (action == DWFMT_secz || action == DWFMT_secnz)
                {
                if (action == DWFMT_secz)
                    {
                    if (value == null)
                        result += "";
                    else if (givenDate.sec < 10)
                         {
                         //CR495198,sec is string type and is already "0n" format
                         if (typeof givenDate.sec != "string")
                             result += "0";
                         else if (givenDate.sec.length == 1)
                             result += "0";
                         }
                    }
                if (value == null)
                    result += "00";
                else
                    result += givenDate.sec;
                }
            else if (action == DWFMT_msec)
                {
                index++;
                var numMsecDigits = encodedFormat[index];
                if (value == null)
                    for (var j=0; j<numMsecDigits; j++)
                    {
						if (typeof(goEditMaskManager) != "object")
							result = "";
						else
							result += "0";
					}
                else
                    {
                    var tempStr = "000000" + givenDate.msec;
                    var valueStart = tempStr.length - 6;
                    
                    result += tempStr.substring(valueStart, valueStart + numMsecDigits);
                    }
                }
            else if (action == DWFMT_apCaps)
                {
                if (value == null && typeof(goEditMaskManager) != "object")
                    result = "";
                else
                    result += ampm ? "A" : "P";
                }
            else if (action == DWFMT_apNCaps)
                {
                if (value == null && typeof(goEditMaskManager) != "object")
                    result = "";
                else
                    result += ampm ? "a" : "p";
                }
            else if (action == DWFMT_ampmCaps)
                {
                if (value == null && typeof(goEditMaskManager) != "object")
                    result = "";
                else
                    result += ampm ? "AM" : "PM";
                }
            else if (action == DWFMT_ampmNCaps)
                {
                if (value == null && typeof(goEditMaskManager) != "object")
                    result = "";
                else
                    result += ampm ? "am" : "pm";
                }
            }
        }

	if (this.bStylePositioning && format && format.bValid)  
        if ( format.color == "" || typeof format.color == "string")
            control.style.color = format.color;
        else
            control.style.color = convertToRGB( format.color );

    return result;
}

function DW_DaysAfter(date1,date2)
{
    return DW_daysDiff (date1.year + 1900, date1.month + 1, date1.day,
                date2.year + 1900, date2.month + 1, date2.day);
}

function DW_SecondsAfter(time1,time2)
{
	var    secs;

	// Calculate difference in times.
	secs = (time1.hour * 3600 + time1.min * 60 + time1.sec) - (time2.hour * 3600 + time2.min * 60 + time2.sec);

	return (secs);
}

function DW_DatetimeToDate(inDatetime)
{
    return new DW_DateClass(inDatetime.year, inDatetime.month, inDatetime.day);
}

function DW_DatetimeToTime(inDatetime)
{
    return new DW_TimeClass(inDatetime.hour, inDatetime.min, inDatetime.sec, inDatetime.msec);
}

function DW_RelativeDate(inDate, numDays)
{
	var year;
	var month;
	var day;
	var yearDays;
	var aleap;

    var newDate = new DW_DateClass (inDate.year, inDate.month, inDate.day);
    
	if (numDays != 0)         // No days; then same date
	    {
    	year = inDate.year + 1900;

    	day = numDays + DW_dayOfYear(year, inDate.month+1, inDate.day) - 1;
    	while (day >= (yearDays = DW_daysInYear(year)))
    		{
    		year++;
    		day -= yearDays;
    		}
    	while (day < 0)
    		day += DW_daysInYear(--year);

    	newDate.year = year - 1900;

    	aleap = DW_isLeap(year) ? 1 : 0;
    	for (month=0; month< 12 && day >= DW_cumDayTable[aleap][month]; month++)
    	    ;

    	newDate.month = month - 1;
    	newDate.day = DW_dayTable[aleap][month] - (DW_cumDayTable[aleap][month] - day) + 1;
    	}

    return newDate;
}

function DW_RelativeTime(inTime, numSeconds)
{
    var result;
    var totalSeconds = inTime.sec + inTime.min * 60 + inTime.hour * 3600 + numSeconds;

	if (totalSeconds < 0)// Under flow
		result = null;
	else if (totalSeconds >= 24 * 3600) // over flow
		result = null;
	else
		{
		var hours = Math.floor(totalSeconds / 3600);
		var min = Math.floor((totalSeconds - hours * 3600) / 60);
		var sec = totalSeconds - min * 60 - hours * 3600;
		
		result = new DW_TimeClass (hours, min, sec);
		}

    return result;
}

function DW_DatetimeCompare(date1, date2)
{
    var rc;
    
	if (date1.year != date2.year)
		rc = date1.year - date2.year;
	else if (date1.month != date2.month)
		rc = date1.month - date2.month;
	else if (date1.day != date2.day)
		rc = date1.day - date2.day;
	else if (date1.hour != date2.hour)
		rc = date1.hour - date2.hour;
	else if (date1.min != date2.min)
		rc = date1.min - date2.min;
	else if (date1.sec != date2.sec)
		rc = date1.sec - date2.sec;
	else if (date1.msec < date2.msec)
		rc = -1;
	else if (date1.msec > date2.msec)
		rc = 1;
	else
		rc = 0;
	return rc;
}

function DW_DateCompare(date1, date2)
{
    var rc;
    
	if (date1.year != date2.year)
		rc = date1.year - date2.year;
	else if (date1.month != date2.month)
		rc = date1.month - date2.month;
	else if (date1.day != date2.day)
		rc = date1.day - date2.day;
	else
		rc = 0;
	return rc;
}

function DW_TimeCompare(time1, time2)
{
    var rc;
    
    if (time1.hour != time2.hour)
		rc = time1.hour - time2.hour;
	else if (time1.min != time2.min)
		rc = time1.min - time2.min;
	else if (time1.sec != time2.sec)
		rc = time1.sec - time2.sec;
	else if (time1.msec < time2.msec)
		rc = -1;
	else if (time1.msec > time2.msec)
		rc = 1;
	else
		rc = 0;
	return rc;
}

function DW_DayNumber(theDate)
{
	return DW_dayOfWeek (theDate.year + 1900, theDate.month + 1, theDate.day);
}

function DW_DayName(theDate)
{
    var dayNumber = DW_dayOfWeek (theDate.year + 1900, theDate.month + 1, theDate.day);
    
	return DW_longDayNames[dayNumber];
}

