//-----------------------------------------------------------------------------------------
function get_text(form, name)
{
    if(name || name != "")
    {
        var current_form = document[form];
        if(current_form)
        {
            var text_item = current_form[name];
            if (navigator.appName == 'Netscape' && navigator.appVersion.indexOf('4.') != -1)
            {
                if (text_item)
                {
                    if (text_item.type == 'select-one')
                    {
                        // item IS a select box
                        return text_item.options[text_item.selectedIndex].value;
                    }
                    else
                    {

                        return text_item.value;
                    }
                }
                else
                    return null;
            }
            else
            {
                if (text_item)
                    return text_item.value;
                else
                    return null;
            }
        }
    }
    return null;
}

//-----------------------------------------------------------------------------------------
function set_text(form, name, value)
{
    if(name || name != "")
    {
        var current_form = document[form];
        if(current_form)
        {
            var text_item = current_form[name];
            if (navigator.appName == 'Netscape' && navigator.appVersion.indexOf('4.') != -1)
            {
                text_item.value = value;
            }
            else
            {
                if (text_item)
                    text_item.value = value;
            }
        }
    }
    return null;
}

//-----------------------------------------------------------------------------------------

//-----------------------------------------------------------------------------------------
function count_chars(text, char_set)
{
    var count = 0;
    for (var pos = 0; pos < text.length; pos++)
    {
        temp_char = text.charAt(pos);
        if (char_set.indexOf(temp_char, 0) != -1)
            count++;
    }
    return count;
}

//-----------------------------------------------------------------------------------------
function validate_chars(text, char_set)
{
    for (var pos = 0; pos < text.length; pos++)
    {
        temp_char = text.charAt(pos);
        if (char_set.indexOf(temp_char, 0) == -1)
            return false;
    }
    return true;
}

//-----------------------------------------------------------------------------------------
function validate_item(form_name, name)
{
    var result = false;
    var fields = field_metadata(form_name);
    for(var loop = 0; loop < fields.length; loop++)
    {
        var field = fields[loop];
        var pos = 0;
        var form = field[pos++];
        var item_name = field[pos++];
        if(item_name == name)
        {
            result = true;
            var mandatory = field[pos++];
            var type      = field[pos++];
            var min_size  = field[pos++];
            var max_size  = field[pos++];
            var text = validate_text(form, name, mandatory, type, min_size, max_size);
            if(text != "")
            {
                result = false;
            }
        }
    }
    return result;
}
//-----------------------------------------------------------------------------------------
function bits_to_date(day, month, year)
{
    return new Date(year, parseFloat(month)-1, parseFloat(day)+1, 0, 0, 0);
}
//-----------------------------------------------------------------------------------------
function date_to_bits(date)
{
//  alert("date_to_bits(" + date + " )");
    if(date == null)
        return null;

    var dateObj = new Date(date);
    if(dateObj == null)
        return null;

    var bits = new Array();
    bits[0] = "";
    bits[1] = dateObj.getDate();
    bits[2] = parseFloat(dateObj.getMonth() + 1);
    bits[3] = dateObj.getFullYear();
    bits[4] = null
    return bits;
}
//-----------------------------------------------------------------------------------------
function validate_date(result, bits)
{
//  alert("validate_date(" + result + ", " + bits + ")");
    var day = bits[0];
    var month = bits[1];
    var year = bits[2];
    var leapyear = false;

    if(year/4 == Math.floor(year/4))
        leapyear = true;
    if(year/100 == Math.floor(year/100))
        leapyear = false;
    if(year/400 == Math.floor(year/400))
        leapyear = true;

    //oracle cannot accept years outside these ranges
    if (year>9999 || year==0 || year<-4713)
        result[0] += " year is invalid";

    if(month < 1 || month > 12)
        result[0] += " month is invalid";

    var months = new Array(0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
    if(leapyear == true && month == 2)
    {
        if (day < 1 || day > 29)
            result[0] += " day is invalid";
    }
    else if(day < 1 || day > months[month])
        result[0] += " day is invalid";

    result[1] = day;
    result[2] = month;
    result[3] = year;
    result[4] = leapyear;

    return result;
}

//-----------------------------------------------------------------------------------------
function validate_short_date(value)
{
    var result = new Array("");

    var bits = value.split("/");
    if(bits && bits.length == 3)
        return validate_date(result, bits);
    result[0] = "is not a valid date. e.g. 10 May 2000";
    return result;
}
//-----------------------------------------------------------------------------------------
// return bits of dates as well
function validate_long_date(date)
{
// alert("validate_long_date(" + date + ")");
    var value = date.toLowerCase();
    var result = new Array("");

    var split_bits = value.split(" ");
    if(!split_bits || split_bits == null || split_bits.length<3)
    {
        split_bits = value.split("-"); //try for oracle style dates.
        if(!split_bits || split_bits == null || split_bits.length<3)
        {
            result[0] = " is not a valid date. e.g. 10 May 2000";
            return result;
        }
    }

    var new_size = 0;
    var bits = new Array();
    for(var loop = 0; loop < split_bits.length; loop++)
    {
        if(split_bits[loop] != "")
            bits[new_size++] = split_bits[loop];
    }

    if(bits && bits.length == 3)
    {
        var month = bits[1];
        var month_names = new Array("jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec");
        for(var month_num = 0; month_num < month_names.length; month_num++)
        {
            if(month == month_names[month_num])
            {
                bits[1] = month_num + 1;    // convert to 1 indexed
                return validate_date(result,bits);
            }
        }
    }
    result[0] = " is not a valid date. e.g. 10 May 2000";
    return result;
}

//-----------------------------------------------------------------------------------------
function validate_mask(alias, text, mask)
{
    // ? = any, # = digit, ! = letter
    var errText = alias + " is invalid, expected format is '" + mask + "'\n    (where # = digit, ! = letter, ? = any).";
    var textNumber = "0123456789";
    var textLetter = "abcdefghijklmnopqrstuvwxyz";

    var textSize = text.length;
    var maskSize = mask.length;
    if(textSize != maskSize)
        return errText;

    var lowerText = text.toLowerCase();
    for(var loop = 0; loop < textSize; loop++)
    {
        if(mask.charAt(loop) == '#')
        {
            if (textNumber.indexOf(text.charAt(loop), 0) == -1) // is the matching char a number?
                return errText;
        }
        else if(mask.charAt(loop) == '!')
        {
            if (textLetter.indexOf(lowerText.charAt(loop), 0) == -1)    // is the matching char a letter?
                return errText;
        }
        else if(mask.charAt(loop) == '?')
        {
            // no checking needed
        }
        else
        {
            if (text.charAt(loop) != mask.charAt(loop)) // does it match exactly?
                return errText;
        }
    }
    return "";
}
//-----------------------------------------------------------------------------------------
// returns errText
function validate_type(alias, text, type)
{
// alert("validate_type(" + alias + ", " + text + ", " + type + ")");
    var errText = "";
    if(type == "bool")
    {
        if(text != "true" && text != "TRUE" && text != "false" && text != "FALSE")
            errText += alias + " must be either 'true' or 'false'" + "\n";
    }
    else if(type == "int")
    {
        if(validate_chars(text, "0123456789-") == false)
            errText += alias + " must be a whole number.\n";
    }
    else if(type == "num")
    {
        if(validate_chars(text, "0123456789.-") == false)
            errText += alias + " must be a number.\n";
    }
    else if(type == "alpha")
    {
        if(validate_chars(text.toLowerCase(), "abcdefghijklmnopqrstuvwxyz") == false)
            errText += alias + " must be all letters.\n";
    }
    else if(type == "alphanum")
    {
        if(validate_chars(text.toLowerCase(), "abcdefghijklmnopqrstuvwxyz0123456789.-") == false)
            errText += alias + " must be all alphanumeric.\n";
    }
    else if((type == "any") || (type == "mask"))
    {
        // do no character checking
    }
    else if(type == "shortdate")
    {
        if(validate_chars(text, "0123456789/") == false)
            errText += alias + " has invalid date characters.\n";
        else
        {
            var tmpResult = validate_short_date(text);
            if(tmpResult[0] != "")
                errText += alias + tmpResult[0] + "\n";
        }
    }
    else if(type == "longdate")
    {
        // only letters for jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec
        if(validate_chars(text.toLowerCase(), "abcdefgjlmnoprstuvy0123456789 -") == false)
            errText += alias + " has invalid date characters.\n";
        else
        {
            var tmpResult = validate_long_date(text.toLowerCase());
            if(tmpResult[0] != "")
                errText += alias + tmpResult[0] + "\n";
        }
    }
    else    //chars
    {
        if(validate_chars(text, type) == false) // type contains valid chars
            errText += alias + " contains invalid characters.\n";
    }
    return errText;
}

//-----------------------------------------------------------------------------------------
function validate_range(alias, text, type, min_size, max_size)
{
//  alert("validate_range(" + alias + ", " + text + ", " + type + ", " + min_size + ", " + max_size + ")");
    var errText = "";
    if((min_size == null || min_size == "") && (max_size == null || max_size == ""))
        return errText;

    if(type == "int" || type == "num")  // numerical
    {
        // need to count . and - and numerical chars.
        if(count_chars(text, ".") > 1 || count_chars(text, "-") > 1 || count_chars(text, "1234567890") < 1)
            errText += alias + " is not a valid number.\n";
        else
        {
            if(min_size)
            {
                if(parseFloat(text) < parseFloat(min_size))
                    errText += alias + " must be " + min_size + " or more\n";
            }
            if(max_size)
            {
                if(parseFloat(text) > parseFloat(max_size))
                    errText += alias + " must be " + max_size + " or less\n";
            }
        }
    }
    else if(type == "alpha" || type == "alphanum" || type == "chars" || type == "any")              // text
    {
        if(min_size)
        {
            if(text.length < parseInt(min_size))
                errText += alias + " must be " + min_size + " or more characters long\n";
        }
        if(max_size)
        {
            if(text.length > parseInt(max_size))
                errText += alias + " must be " + max_size + " or less characters long\n";
        }
    }
    else if(type == "shortdate")
    {
        var date_field = validate_short_date(text.toLowerCase());
        var date_val = parseFloat(date_field[3] * 372) + parseFloat(date_field[2] * 31) + parseFloat(date_field[1]);

        if(min_size != "")
        {
            var min_date = null;
            if(min_size.toLowerCase() == "now")
                min_date = date_to_bits(Date());
            else
                min_date = validate_long_date(min_size.toLowerCase());

            var min_date  = validate_short_date(min_size.toLowerCase());
            if(min_date.length != 5 || min_date[0] != "")
                alert("Error in min date specification : " + min_size);

            var min_val = parseFloat(min_date[3] * 372) + parseFloat(min_date[2] * 31) + parseFloat(min_date[1]);
            if(parseFloat(date_val) < parseFloat(min_val))
                errText += alias + " must not be before " + min_size + "\n";
        }
        if(max_size != "")
        {
            var max_date = null;
            if(max_size.toLowerCase() == "now")
                max_date = date_to_bits(Date());
            else
                max_date = validate_long_date(max_size.toLowerCase());

            if(!max_date || max_date.length != 5 || max_date[0] != "")
                alert("Error in max date specification : " + min_size);

            var max_val = parseFloat(max_date[3] * 372) + parseFloat(max_date[2] * 31) + parseFloat(max_date[1]);
            if(parseFloat(date_val) > parseFloat(max_val))
                errText += alias + " must not be after " + max_size + "\n";
        }
    }
    else if(type == "longdate")
    {
        var date_field = validate_long_date(text.toLowerCase());
        var date_val = parseFloat(date_field[3] * 372) + parseFloat(date_field[2] * 31) + parseFloat(date_field[1]);
        if(min_size != "")
        {
            var min_date = null;
            if(min_size.toLowerCase() == "now")
                min_date = date_to_bits(Date());
            else
                min_date = validate_long_date(min_size.toLowerCase());

            if(min_date.length != 5 || min_date[0] != "")
                alert("Error in min date specification : " + min_size);
            var min_val = parseFloat(min_date[3] * 372) + parseFloat(min_date[2] * 31) + parseFloat(min_date[1]);
            if(parseFloat(date_val) < parseFloat(min_val))
                errText += alias + " must not be before " + min_size + "\n";
        }

        if(max_size != "")
        {
            var max_date = null;
            if(max_size.toLowerCase() == "now")
                max_date = date_to_bits(Date());
            else
                max_date = validate_long_date(max_size.toLowerCase());

            if(max_date.length != 5 || max_date[0] != "")
                alert("Error in max date specification : " + max_size);
            var max_val = parseFloat(max_date[3] * 372) + parseFloat(max_date[2] * 31) + parseFloat(max_date[1]);
            if(parseFloat(date_val) > parseFloat(max_val))
                errText += alias + " must not be after " + max_size + "\n";
        }
    }
    else if(type == "mask")
    {
        errText += validate_mask(alias, text, min_size);
    }
    return errText;
}

//-----------------------------------------------------------------------------------------
function validate_text(form_name, alias, name, mandatory, type, min_size, max_size)
{
    var errText = "";
    var text = get_text(form_name, name);
    if(text != null)
    {
        if(text.length < 1)
        {
            if(mandatory)
                errText += alias + " must be populated" + "\n";
        }
        else
        {
            errText += validate_type(alias, text, type);
            errText += validate_range(alias, text, type, min_size, max_size);
        }
    }
    else
    {
        // Null mandatory items are invalid - doh
        if(mandatory)
            errText += alias + " must be populated" + "\n";

    }
    return errText;
}

//-----------------------------------------------------------------------------------------
function validate_form(form_name)
{
// alert("in in validate_form");
// alert(form_name);
    var valid = true;
    var errMsg = "Form is Invalid\n";
    var meta_data = self.field_metadata;
    if(meta_data != null)
    {
        var fields = field_metadata(form_name);
        // NB. loops from 1, since element 0 is the name of the form (normally 'action_form')
        for(var loop = 1; loop < fields.length; loop++)
        {
            var field = fields[loop];
            var pos = 0;

            var form      = field[pos++];
            var alias     = field[pos++];
            var name      = field[pos++];
            var mandatory = field[pos++];
            var type      = field[pos++];
            var min_size  = field[pos++];
            var max_size  = field[pos++];
            var errText = validate_text(form, alias, name, mandatory, type, min_size, max_size);
            if(errText != "")
            {
                valid = false;
                errMsg += errText;
            }
        }
    }
    if(valid == false)
        alert(errMsg);
    else
    {
//      alert("valid");
//      valid = false;
    }
    return valid;
}

//-----------------------------------------------------------------------------------------
// Validates two dates, and if both are populated the second must be >= first, and 2nd cannot be in past if
// ensure_second_date_in_future is true.
// message_type can be one of the following values:
//      - "alert"   : Show an alert message with an OK button only.
//      - "confirm" : Show a confirm message box with OK and Cancel buttons.
//      - "none"    : Show no message, just return true or false.
function validate_two_dates(the_form,first_date_name, first_date_alias, second_date_name, second_date_alias, 
                            ensure_second_date_in_future, message_type)
{
    if (arguments.length == 5)
    {
        // ensure_second_date_in_future and message_type have not been supplied so default them so
        // function works as it always has.
        ensure_second_date_in_future = true;
        message_type = "alert";
    }
    
    var errText = "";
    var ret = true;
    var first_date = get_text(the_form.name, first_date_name);
    var second_date = get_text(the_form.name, second_date_name);

    if(first_date != "")
        first_date = validate_long_date(first_date);

    if(second_date != "")
        second_date = validate_long_date(second_date);

    if(first_date != null && first_date != "" && first_date[0] != "")
        errText += first_date_alias + first_date[0] + "\n";

    if(second_date != null && second_date != "")
    {
        if(second_date[0] != "")
              errText += second_date_alias + second_date[0] + "\n";
        else
        {
            var expiry = bits_to_date(second_date[1], second_date[2], second_date[3]);
            if(first_date != null && first_date[0] == "")   // i.e. populated and valid
            {
                var join = bits_to_date(first_date[1], first_date[2], first_date[3]);
                if(join > expiry)
                {
                    errText += second_date_alias + " cannot be before " + first_date_alias + ".\n";
                }
            }

            if (ensure_second_date_in_future == true)
            {
                var now = new Date(); // do we have a problem with timezones?
                if(expiry < now)
                {
                    errText += second_date_alias + " cannot be in the past.\n";
                }
            }
        }
    }

    if(errText == "")
    {
        ret = true;
    }
    else
    {
        ret = display_error_message(errText, message_type);
    }
   
    return ret;
}


//-----------------------------------------------------------------------------------------
// Validates that the supplied date is not in the past and displays alert message only
// if alert_now is true
function validate_date_in_future(the_form, date_name, date_alias, message_type)
{
    var ret = true;
    var in_date = get_text(the_form.name, date_name);

    if (in_date != "")
    {
        in_date = validate_long_date(in_date);
    }

    var dateToCheck = bits_to_date(in_date[1], in_date[2], in_date[3]);
    var now = new Date();

    if (dateToCheck < now)
    {
        ret = display_error_message(date_alias + " cannot be in the past.\n", message_type);
    }

    return ret;
}

//-----------------------------------------------------------------------------------------
// Display a message box based on the value of message_type. This can be one of the following values:
//      - "alert"   : Show an alert message with an OK button only. Return false.
//      - "confirm" : Show a confirm message box with OK and Cancel buttons. Return true on OK, false on Cancel.
//      - "none"    : Show no message, return false.
function display_error_message(message_text, message_type)
{
    var ret = false;
    
    if (message_type == "alert")
    {
        alert(message_text);
    }
    else if (message_type == "confirm")
    {
        // Add a message explaining the consequences of their actions
        message_text += "\nPress OK to continue or Cancel to edit the form.";
        ret = confirm(message_text);
    }

    return ret;
}