/*******************************************************************
    Validation Functions for String, Integer....
    The function names should be in form of isXXXX()
*******************************************************************/
var UC_DIGITS = "0123456789";
var UC_LOWERCASELETTERS = "abcdefghijklmnopqrstuvwxyz";
var UC_UPPERCASELETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var UC_WHITESPACE = " \t\n\r";
var UC_DECIMALPOINTDELIMITER = ".";
var UC_DEFAULTEMPTYOK = false;
var UC_DAYOFMONTH = [0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

// Returns true if s is null or empty
function isEmpty(s)
{
    return ((s == null) || (s.length == 0))
}

// Return true if all characters of string s are in charset
function isInValidCharSet(s,charset)
{
	for (var i=0;i<s.length;i++)
		if (charset.indexOf(s.charAt(i))<0)
			return false;

	return true;
}

// Return true if all characters in s are digits.
function isAllDigits(s)
{
    return isInValidCharSet(s,UC_DIGITS);
}

// Return true if s is a whitespace
function isWhitespace (s)
{   
    return isInValidCharSet(s,UC_WHITESPACE);
}

// Return true if all characters in s are in lowercase
function isAllLowerCase(s)
{
    return isInValidCharSet(s,UC_LOWERCASELETTERS);
}

// Return true if all characters in s are in uppercase
function isAllUpperCase(s)
{
    return isInValidCharSet(s,UC_UPPERCASELETTERS);
}

// Returns true if the combination of year, month and day is a valid date.
function isDate(year, month, day)
{
    if (!isAllDigits(year) || !isAllDigits(month) || !isAllDigits(day))
        return false;
    if (year.length != 2 || year.length != 4)
        return false;

	var y = parseInt(year,10);
	var m = parseInt(month,10);
	var d = parseInt(day,10);

    // check year
    if (y < 1)
        return false;

    // check month
    if (m < 1 || m > 12)
        return false;
        
    // check day
	if (d > UC_DAYOFMONTH[m] )
		return false;

	if (!( y%400 == 0 || ( y%4 == 0 && y%100 != 0)) && (m == 2) && (d == 29))
	    return false;

	return true;
}

// Return true if the date is valid and in form of dd/mm/yyyy
function isDate(date)
{
    if (isEmpty(date))
        return false;
           
	var elems = date.split("/");
	if (elems.length != 3)
	    return false;

    return isDate(elems[2], elems[1], elems[0]);
}

// Return true if email is a valid email address
function isEmail (email)
{
    if (isEmpty(email))
        return false;
        
    var result = false;
    var theStr = new String(email);
    var index = theStr.indexOf("@");
    if (index > 0)
    {
        var pindex = theStr.indexOf(".",index);
        if ((pindex > index+1) && (theStr.length > pindex+1))
	        result = true;
    }
    return result;
}

// Return true if amount is a valid amount, i.e. XXX.XX
function isAmount (amount)
{
    if (isEmpty(amount))
        return false;
        
    var result = false;
    var theStr = new String(amount);
    var index = theStr.indexOf(".");
    if (index > 0)
    {
        var intpart = theStr.substring(0,index);
        var frapart = theStr.substring(index+1,theStr.length);
        
        if (isEmpty(intpart) || isEmpty(frapart) || !isAllDigits(intpart) || !isAllDigits(frapart) || frapart.length>2)
            return false;
        else
            return true;
    }
    else
    {
        return isAllDigits(amount);
    }
}

/*******************************************************************
    Validation Functions for Form Fields
    The function names should be in form of checkXXXX()
*******************************************************************/
// Returns true if one of the radio buttons is checked.
function checkRadio(checkObj)
{
    var optionLen = checkObj.length
    
    if (optionLen == null)
    {
        if (checkObj.checked)
            return true;
        else
            return false;
    }
    else        
    {
        for (i=0;i<optionLen;i++)
        {
            if(checkObj[i].checked)
            {
                return true;
            }
        }     
    }
        
    return false;
}

function checkDate(yearObj, monthObj, dayObj)
{
    if (yearObj==null || monthObj==null || dayObj==null)
        return false;
        
	var year = parseInt(yearObj.value);
    var month = parseInt(monthObj.value);
	var day = parseInt(dayObj.value);
    
    return isDate(year, month, day);
}

// Return true if first date is before the second date, else false
function checkDateBefore(fromYearObj, fromMonthObj, fromDayObj, toYearObj, toMonthObj, toDayObj)
{
    if (checkDate(fromYearObj, fromMonthObj, fromDayObj) && (checkDate(toYearObj, toMonthObj, toDayObj)))
    {
	    date1 = new Date( fromYearObj.value, fromMonthObj.value, fromDayObj.value );
	    date2 = new Date( toYearObj.value, toMonthObj.value, toDayObj.value );
	    if ( date1.getTime() > date2.getTime() )
	    {
		    return false;
	    }
	    return true;
	}
	return false;
}


/*******************************************************************
    Set Object Functions
*******************************************************************/
function setTextValue(textObj, value)
{
    if (textObj != null)
    {
        if (value == null)
            return;
        textObj.value = value;
    }
}

function setHiddenValue(hiddenObj, value)
{
    if (hiddenObj != null)
    {
        if (value == null)
            return;
        hiddenObj.value = value;
    }
}

/* 
    To set the selected value for a selection list. 
    Usage:  setSelectValue(selectObj, "Option1", "Option2", ...)
    Example: 
    <form name="theForm">
        <select name="selectObj">
            <option value="Option0">Option0</option>
            <option value="Option1">Option1</option>
            <option value="Option2">Option2</option>
            ...
        </select>
    </form>
    Call setSelectValue(form.selectObj, "Option1"> will set the second option to be selected.
*/
function setSelectValue(selectObj)
{
    var argLen;
    var argIndex;
    var optionLen;
    var optionIndex;
    
    if (selectObj != null)
    {
        argLen    = setSelectValue.arguments.length;
        optionLen = selectObj.options.length;
        
        if ((argLen == 1) || (setSelectValue.arguments[1] == null))
            return;
            
        for (optionIndex=0; optionIndex<optionLen; optionIndex++)
        {
            selectObj.options[optionIndex].selected = false;
            for (argIndex=1; argIndex<argLen; argIndex++)
            {
                if (selectObj.options[optionIndex].value == setSelectValue.arguments[argIndex])
                {
                    selectObj.options[optionIndex].selected = true;
                    break;
                }
            }
        }
    }
}

/* 
    To set the selected value for a selection list. 
    Usage:  setSelectValue(selectObj, "Option1", "Option2", ...)
    Example: 
    <form name="theForm">
        <input type="radio" name="checkObj" value="Option0">
        <input type="radio" name="checkObj" value="Option1">
        <input type="radio" name="checkObj" value="Option2">
        ...
    </form>
    Call setCheckValue(form.checkObj, "Option1", "Option2"> will set the second and third options to be checked.
*/
function setCheckValue(checkObj)
{
    var argLen;
    var argIndex;
    var optionLen;
    var optionIndex;
    
    if (checkObj != null)
    {
        argLen    = setCheckValue.arguments.length;
        optionLen = checkObj.length;

        if ((argLen == 1) || (setCheckValue.arguments[1] == null))
            return;
            
        if (optionLen == null) // one checkbox only
        {
            checkObj.checked = false;
            
            for (argIndex=1; argIndex<argLen; argIndex++)
            {
                if (checkObj.value == setCheckValue.arguments[argIndex])
                {
                    checkObj.checked = true;
                    break;
                }
            }
        }
        else // many checkboxes with same name
        {
            for (optionIndex=0; optionIndex<optionLen; optionIndex++)
            {
                checkObj[optionIndex].checked = false;
                
                for (argIndex=1; argIndex<argLen; argIndex++)
                {
                    if (checkObj[optionIndex].value == setCheckValue.arguments[argIndex])
                    {
                        checkObj[optionIndex].checked = true;
                        break;
                    }
                }
            }
        }
    }
}

function setDate(yearObj, monthObj, dayObj, theDate)
{
    setSelectValue(yearObj, theDate.getYear());
    setSelectValue(monthObj, theDate.getMonth()+1);
    setSelectValue(dayObj, theDate.getDate());
}
    
function setToday(fromYearObj, fromMonthObj, fromDayObj, toYearObj, toMonthObj, toDayObj)
{
	now = new Date();
	setDate(fromYearObj, fromMonthObj, fromDayObj, now);
	setDate(toYearObj, toMonthObj, toDayObj, now);
}

function setLastday(fromYearObj, fromMonthObj, fromDayObj, toYearObj, toMonthObj, toDayObj)
{
    now   = new Date();
    fromDay = addDay(now, -1);
    
    setDate(fromYearObj, fromMonthObj, fromDayObj, fromDay);
    setDate(toYearObj, toMonthObj, toDayObj, fromDay);
}

function setLast7Days(fromYearObj, fromMonthObj, fromDayObj, toYearObj, toMonthObj, toDayObj)
{
    now   = new Date();
    fromDay = addDay(now, -7);
    toDay = addDay(now, -1);
    
    setDate(fromYearObj, fromMonthObj, fromDayObj, fromDay);
    setDate(toYearObj, toMonthObj, toDayObj, toDay);
}

function setLast30Days(fromYearObj, fromMonthObj, fromDayObj, toYearObj, toMonthObj, toDayObj)
{
    now   = new Date();
    fromDay = addDay(now, -30);
    toDay = addDay(now, -1);
    
    setDate(fromYearObj, fromMonthObj, fromDayObj, fromDay);
    setDate(toYearObj, toMonthObj, toDayObj, toDay);
}


/*******************************************************************
    Computational Functions
*******************************************************************/
// Return a new day which equals baseDay + incDay
function addDay(baseDay, incDay)
{
    milliseconds = baseDay.getTime() + incDay * 1000 * 60 * 60 * 24;
    otherDay = new Date(milliseconds);
    return otherDay;
}