var FV_NUMBER     = 1;
var FV_CURRENCY   = 2;
var FV_PERCENT    = 3;
var FV_DECIMAL    = 4;
var FV_DATETIME   = 5;
var FV_SQLDECIMAL = 6;

var fWhite = false;
var strErr = "";
var objInvalid = null;
var g_fFormProcessing = false;
var UNKNOWN_VALUE = "???";

function GetEventObj(evt)
{
    evt = (evt) ? evt : (window.event) ? window.event : null;
    
    return evt;
}

function SetValidColor(fW)
{   
    fWhite = fW;
}

function AddErrorEx(strText, fIndent)
{
    strErr += "\n";
    
    if (fIndent)
        strErr += "- ";
        
    strErr += strText + "\n";
}

function AddError(strText)
{
    AddErrorEx(strText, true);
}

function ClearError()
{
    strErr = "";
    objInvalid = null;
}

function HasError()
{
    return ((objInvalid != null) || (strErr != ""));
}

function RemoveZeroItem(objList)
{
    if ((objList.options[0].value == "") || (parseInt(objList.options[0].value) == "0"))
        objList.options.remove(0);
}

function Form_SetProcessing(fProcessing)
{
    g_fFormProcessing = fProcessing;
}

function Form_IsProcessing()
{
    return g_fFormProcessing;
}

function SubmitFormEx(fClearChanged)
{
    if (fClearChanged)
        fChanged = false;
    return true;                
}

function SubmitForm()
{
    return SubmitFormEx(true);
}

function IsObjectVisible(obj)
{
    return (obj != null) && (obj.style.display == "");
}

function IsObjectEnabled(obj)
{
    return (obj != null) && !obj.disabled;
}

function SetFocus(obj)
{
    if (IsObjectVisible(obj) && IsObjectEnabled(obj))
        obj.focus();
}

function ShowObjectEx(obj, fShow, fFocus)
{
    if (obj != null)
    {
        obj.style.display = fShow ? "" : "none";
        if (fShow && fFocus)
        {
            obj.style.zIndex = 1;
            SetFocus(obj);
        }
    }        
}

function ShowObject(obj, fShow)
{
    ShowObjectEx(obj, fShow, false);
}

function EnableObject(obj, fEnable)
{
    if (obj != null)
        obj.disabled = !fEnable;
}

function SetReadonly(obj, fReadOnly)
{
    if (obj != null)
    {
        obj.readOnly  = fReadOnly;
        
        if (fReadOnly)
            obj.style.backgroundColor = "#E7E7E7";
        else
            obj.style.backgroundColor = "";
    }
}

function ToggleVisiblity(obj)
{
    ShowObject(obj, !IsObjectVisible(obj));
}

function DisplayErrorEx(fHeader)
{
    var sErrorMsg = strErr;
    
    if (fHeader)
    {
        if (strErr != "")
            strErr = "\r\n" + strErr;

        sErrorMsg = "Please correct invalid and missing required data." + strErr;
    }
    
    alert(sErrorMsg);
    
    try
    {
        if (objInvalid)
            SetFocus(objInvalid);
    }
    catch(e)
    {
        // controls in preview pane are not accessible
    }
    
    Form_SetProcessing(false);
            
    return false;        
}

function DisplayError()
{
    return DisplayErrorEx(true);
}

function EnableEditBtn()
{
    var objBtn = document.getElementById("cmdClose");
    
    if (objBtn)
        Command_Enable("cmdClose", true);
}

function Plural(iValue)
{
    return (iValue == 1) ? "" : "s";
}

function PluralEx(iValue, sText)
{
    return iValue + " " + sText + Plural(iValue);
}

function GetAppendedClass(obj)
{
    var i = obj.className.indexOf(" clsInValid");
    
    if (i < 0)
    {
        i = obj.className.indexOf(" clsMissing");
        if (i < 0)
        {
            i = obj.className.indexOf(" clsValidW");
            if (i < 0)
                i = obj.className.indexOf(" clsMod");
        }                                            
    }
    
    return i;
}

function SetModifiedRowToggleEx(strName, fToggle, fSetChanged, fNoClass)
{
    if (fSetChanged)
        fChanged = true;

    //if (IsBrowserIE())
    //{
        var obj = document.getElementById("tr_" + strName);

        if (!obj)
            obj = document.getElementById("td_" + strName);

        if (obj && !fNoClass)
        {
            var sClass = obj.className;
            var iMod   = obj.className.indexOf(" clsMod");
            var i      = GetAppendedClass(obj);
            
            if ((iMod < 0) && (i >= 0))
                sClass = sClass.substr(0, i);
            else if ((iMod >= 0) && fToggle)
                sClass = sClass.substr(0, iMod);
            
            if (iMod < 0)
            {
                obj.className = sClass + " clsMod";
            }
            else if (fToggle)
            {
                obj.className = sClass;
            }
        }
        
        if (fSetChanged)
            EnableEditBtn();
    //}        
    
    return true;
}

function SetModifiedRowToggle(strName, fToggle)
{
    SetModifiedRowToggleEx(strName, fToggle, true, false);
}

function SetModifiedRow(strName)
{
    SetModifiedRowToggle(strName, false);
}

function OnDataChangedToggle(obj, fToggle)
{
    return SetModifiedRowToggle(obj ? obj.id : "", fToggle);
}

function OnDataChanged(obj)
{
    var fRet = OnDataChangedToggle(obj, false);
    
    if (obj != null)
        SetAttribute(obj, "Changed", "1");
    
    return fRet;
}

function OnDataChangedTA(obj)
{
    return SetModifiedRowToggleEx(obj.id, false, true, true);
}

function DoCancel()
{
    fChanged = false;
    window.close();
}

function DoCancelAndRefresh()
{
    fChanged = false;
    window.close();
    opener.parent.location.reload(true);
}

function DoCancelPage(sBackToPage)
{
    fChanged = false;
    RedirectEx(document, sBackToPage, true);
}

function String_Replace(src, find, rep)
{
    var re = new RegExp(find, "gi");

    src = src.replace(re, rep);
    return src;
}

function String_Trim(src, find)
{
    var re1 = new RegExp("^" + find + "*", "");
    var re2 = new RegExp(find + "*$", "");

    src = src.replace(re1, "");
    src = src.replace(re2, "");
    
    return src;
}

function String_ReplaceCH(src, sChar, sReplace)
{
    return String_Replace(src, sChar, sReplace);
}

function String_RemoveCH(src, sChar)
{
    return String_ReplaceCH(src, sChar, "");
}

function String_RemoveSP(src)
{
    return String_RemoveCH(src, " ");
}

// Trim leading and trailing spaces from a string
// returning true if its trims to NON-empty, FALSE if its trims to empty
function trimEx(srcStr, fObject)
{
    // This replaces TABS also, which is not what we want, so, we do it the brute force way
    //var str2 = src0.replace(/(^\s*)|(\s*$)/g, "");
    
    var src = String(fObject ? srcStr.value : srcStr);
    if (src.length > 0)
    {
        while (src.charAt(0) == ' ')
            src = src.substr(1);
            
        while (src.charAt(src.length-1) == ' ')
            src = src.substr(0, src.length-1);
    }
    
    if (fObject)
    {
      srcStr.value = src;
      return src.length;
    }
    else
    { 
      return src;
    }
}

function trim(src)
{
  return trimEx(src, true)
}

function String_TEXTtoHTML(src, fObject)
{
    var str = new String(fObject ? src.value : src);
    str = trimEx(str, false);
    
    str = String_Replace(str, "&",    "&amp;");
    str = String_Replace(str, "<",    "&lt;");
    str = String_Replace(str, ">",    "&gt;");
    str = String_Replace(str, "\"",   "&quot;");
    str = String_Replace(str, "\r\n", "<br/>");
    str = String_Replace(str, "\n",   "<br/>");
    str = String_Replace(str, "  ",   " &nbsp;");
    return str;
}

function Number_AddComma(sValue)
{
    var sPos = "";
    var i;
    var iCnt = 0;
    var iS   = sValue.indexOf('.');

    if (iS < 0)
        iS = sValue.length;

    iS--;

    for (i = iS; i >= 0; i--)
    {
        if ("0123456789".indexOf(sValue.charAt(i)) >= 0)
            iCnt++;
        else 
            iCnt = 0;

        if (iCnt == 4)
        {
            sPos += "," + (i + 1);
            iCnt = 1;
        }
    }

    if (sPos != "")
    {
        var rsPos = String_Trim(sPos, ',').split(",");
        
        for (i = 0; i < rsPos.length; i++)
        {
            var iPos = parseInt(rsPos[i]);

            sValue = sValue.substr(0, iPos) + "," + sValue.substr(iPos);
        }
    }

    return sValue;
}

var zeroNumber   = "0";
var zeroDecimal  = "0.00";
var zeroCurrency = "$0.00";
var zeroPercent  = "0.00%";

function SetDefaultValue(src, fv)
{
    // Switch statement does not work on NS 3.04
    if (fv == FV_NUMBER)
    {
        src.value = zeroNumber;
    }
    else if (fv == FV_DECIMAL)
    {
        src.value = zeroDecimal;
    }
    else if (fv == FV_CURRENCY)
    {
        src.value = zeroCurrency;
    }
    else if (fv == FV_PERCENT)
    {
        src.value = zeroPercent;
    }
    return true;
}

function ValidateNumbers(src, fv, fError, fObject, fNoSign, min, max)
{
    // Trim spaces.  If result is empty string, set to zero
    var value;
    
    if (!fObject)
    {
        value = src;
    }
    else 
    {
        if (!trim(src))
            SetDefaultValue(src, fv);
        value = src.value;
    }

    value = String_RemoveSP(value);
        
    var i;
    var n              = 0;
    var iBeforeDecimal = 0;
    var iAfterDecimal  = 0;
    var fDollarSign    = false;
    var fDecmialPoint  = false;
    var fSign          = false;
    var fZero          = false;
    var fComma         = false;
    
    for (i = 0; i < value.length; i++)
    {
        if (value.charAt(i) == ',')
        {
            // Comma's only allowed in SQLDECIMAL, and only one 
            if (fv == FV_SQLDECIMAL)
            {
                if (fComma || (i == 0))
                {
                    if (fError)
                        window.alert("Comma error");      
                    return false;
                }
                fComma = true;
                continue;
            }
            else
            {
                // remove commas for all other types
                value = value.substring(0, i) + value.substring(i+1, value.length);
            }
        }
    
        if (value.charAt(i) == '%')
        {
            if (i == 0 || fv != FV_PERCENT)
            {
                if (fError)
                  window.alert("Percent sign error");
                return false;            
            }
                            
            return (n!= 0 && i == value.length-1);
        }

        if ((value.charAt(i) == '+') || (value.charAt(i) == '-'))
        {
            if (fNoSign || fSign || i != 0)
            {
                if (fError)
                  window.alert("Sign error");
                return false;
            }
            
            // strip off "+" sign
            if (value.charAt(i) == '+')
            {
                value = value.substring(1, value.length);
                i--;
            }  
            fSign = true;
            continue;                            
        }

        if (value.charAt(i) == '$')
        {
            if (fDollarSign || fv != FV_CURRENCY)
            {
                if (fError)
                  window.alert("Dollar sign error 1");
                return false;
            }
                
            if (i != 0 && !fSign)
            {
                if (fError)
                  window.alert("Dollar sign error 2");
                return false;                
            }
                
            fDollarSign = true;
            continue;
        }
        
        if (value.charAt(i) == '.')
        {
            if (fDecmialPoint)
            {
                if (fError)
                  window.alert("Decimal point error");
                return false;
            }

            if (fv == FV_NUMBER || fv == FV_SQLDECIMAL)
            {
                if (fError)
                    window.alert("Decimal point error in " + ((fv == FV_NUMBER) ? "FV_NUMBER" : "FV_SQLDECIMAL"));
                return false;
            }
            fDecmialPoint = true;
            continue;
        }
        
        if (value.charAt(i) < '0' || value.charAt(i) > '9')
            break;
        
        if (!fZero && value.charAt(i) != '0')
            fZero = true;

        if (fv == FV_SQLDECIMAL)            
        {
            fComma ? iAfterDecimal++ : iBeforeDecimal++;
        }            
        
        n++;
    }
    
    if (i != value.length)
    {
        if (fError)
            window.alert("Invalid Format (1)");
        return false;
    }
    
    if (n == 0)
    {
        if (fError)
            window.alert("Invalid Format (2)");
        return false;
    }
                
    if ((fv == FV_SQLDECIMAL) && !(iAfterDecimal && iBeforeDecimal))
    {
        if (fError)
            window.alert("Invalid Format (3)");
        return false;
    }
    
    if (fv == FV_PERCENT)
    {
        value += "%";
    }
    else if (fv == FV_CURRENCY)        
    {
        if (fDecmialPoint)
        {
            // If only 1 digit after decimal, append a zero
            var sDecimal = value.substr(value.indexOf('.') + 1);
            
            if (sDecimal.length == 1)
                value += "0";
        }
        else
        {
            value += ".00";
        }
            
        if (!fDollarSign)
        {
            if (!fSign)
                value = "$" + value;
            else
                value = value.charAt(0) + "$" + value.substring(1, value.length);
        }
    }

    if (fObject)
    {
        if (!fZero)
            SetDefaultValue(src, fv);
        else
            src.value = value;
    }
    else
    {
        src = value;
    }
    
    if ((min != "") || (max != ""))
    {
        if (fv == FV_CURRENCY)
        {
            if (value.charAt(0) == '$')
                value = value.substr(1);
            else if (value.charAt(1) == '$')
                value = value.substr(0, 1) + value.substr(2);
        }
    }
    
    if (min != "")
    {
        if (parseFloat(value) < parseFloat(min))
        {
            if (fError)
                window.alert("Minimum value error");
                
            return false;
        }
    }
    
    if (max != "")
    {
       if (parseFloat(value) > parseFloat(max))
       {
          if (fError)
              window.alert("Maximum value error");
              
          return false;
       }
    }

    return true;
}

function ValidateNumber(src)
{
    return ValidateNumbers(src, FV_NUMBER, false, true, false, "", "");
}

function ValidateNumberValue(src)
{
    return ValidateNumbers(src, FV_NUMBER, false, false, false, "", "");
}

function ValidateNumberMM(src, iMin, iMax)
{
    return ValidateNumbers(src, FV_NUMBER, false, true, false, new String(iMin), new String(iMax));
}
    
function ValidateDecimal(src)
{
    return ValidateNumbers(src, FV_DECIMAL, false, true, false, "", "");
}

function ValidateSQLDecimal(src)
{
    return ValidateNumbers(src, FV_SQLDECIMAL, false, true, false, "", "");
}
    
function ValidatePercentMM(src, dMin, dMax)
{
    return ValidateNumbers(src, FV_PERCENT, false, true, false, new String(dMin), new String(dMax));
}

function ValidatePercent(src)
{
    return ValidateNumbers(src, FV_PERCENT, false, true, false, "", "");
}

function ValidateCurrencyEx(src, min, max)
{
    return ValidateNumbers(src, FV_CURRENCY, false, true, false, new String(min), new String(max));
}

function ValidateCurrency(src, max)
{
    return ValidateCurrencyEx(src, "", max)
}

function ValidateAlphaNumericValue(sValue, sExtraChars)
{
    var i = 0;
    
    for (i = 0; i < sValue.length; i++)
    {
        if (!(((sValue.charAt(i) >= '0') && (sValue.charAt(i) <= '9')) ||
              ((sValue.charAt(i) >= 'A') && (sValue.charAt(i) <= 'Z')) ||
              ((sValue.charAt(i) >= 'a') && (sValue.charAt(i) <= 'z')) ||
              ((sExtraChars != "") && (sExtraChars.indexOf(sValue.charAt(i)) >= 0))))
        {             
            return false;             
        }
    }
    
    return true;
}

function ValidateAlphaNumeric(src, sExtraChars)
{
    if (!trim(src))
    {
        return false;
    }   
    
    return ValidateAlphaNumericValue(src.value, sExtraChars);
}

function ValidateDateEx(sDate, fError)
{
    var fSuccess = false;
    var fEmpty   = true;
    
    sDate = trimEx(sDate, false);
    
    if (sDate != "")
    {
        fEmpty   = false;
      var d1 = sDate.indexOf("/");
    
      if (d1 >= 1)
      {
        var d2 = sDate.indexOf("/", d1 + 1);

        if (!(d2 < (d1+2) || d1 > (sDate.length-3)))
        {
          var month = sDate.substring(0, d1);
          var day   = sDate.substring(d1+1, d2);
          var year  = sDate.substring(d2+1, sDate.length); 

          if (!(month.length > 2 || day.length > 2 || (year.length != 2 && year.length != 4)))
          {
            if (month.length == 1)
                month = "0" + month;
            if (ValidateNumbers(month, FV_NUMBER, false, false, true, "01", "12"))
            {
              if (day.length == 1)
                  day = "0" + day;
              if (ValidateNumbers(day, FV_NUMBER, false, false, true, "01", "31"))
              {
                fSuccess = ValidateNumbers(year, FV_NUMBER, false, false, true, "00", "9999");
                if (fSuccess)
                {
                  if (year.length == 2)
                    year = ((year.charAt(0) == "9") ? "19" : "20") + year;
                  sDate = month + "/" + day + "/" + year;
                }
              }
            }
          }
        }
      }            
    }
    
    if (!fSuccess)
    {
      if (fError)
        window.alert("Invalid date: " + sDate + "\r\n\r\nFormat must be: Month/Day/Year, where:\r\n\r\nMonth is:\tnumber from 1-12\r\nDay is:\tnumber from 1-31\r\nYear is:\t2 digit or 4 digit number from 00-9999");
    }
    
    return fSuccess ? sDate : (fEmpty ? "" : "!");
}

function ValidateDate(src, fError)
{
    var sDate = ValidateDateEx(src.value, fError);
    var fValid = sDate != "!";
    
    if (fValid)
        src.value = sDate;
        
    return fValid;        
}

function ValidateEmailEx(email, fError)
{
    // Minimum length of valid address, eg; x@x.xx
    // Must include "@" symbol
    // Must contain at least one "."
    // Must end in .xx or .xxx
    // Must not contain "@." or ".@"
    // Must not begin or end with "@" or "."   
    var fValid;
    var i;
    var iAT = 0;
    
    for (i = 0; i < email.length; i++)
    {
        if (email.charAt(i) == '@')
            iAT++;
    }
    
    if (iAT != 1)
    {
        fValid = false
    }
    else
    {        
        fValid = (email.length >= 6)       &&
                 (email.indexOf(" ") <  0) &&
                 (email.indexOf(";") <  0) &&
                 (email.indexOf(",") <  0) &&
                 (email.indexOf("\"") < 0) &&
                 (email.indexOf("'") <  0) &&
                 (email.indexOf("@") >= 0) &&
                 (email.indexOf(".") >= 0) &&
                 //(email.indexOf("@.") < 0) && 
                 //(email.indexOf(".@") < 0) &&
                 (email.charAt(0) != '@')  &&
                 (email.charAt(0) != '.')  && 
                 (email.charAt(email.length-1) != '@') &&
                 (email.charAt(email.length-1) != '.');// &&
                 //(email.charAt(email.length-3) == '.' || email.charAt(email.length-4) == '.');
    }

    if (!fValid && fError)
        window.alert("Invalid email address format.");
        
    return fValid;                
}

function ValidateEmail(email, fError)
{
    var strEmail = new String(email.value);
    
    strEmail = trim(strEmail, false);
    return ValidateEmailEx(strEmail, fError);
}

function SetClassNameEx(obj, name, fMissingOk, fMissing, fInValid)
{
    var fNoClass = false;//obj && (obj.tagName.toLowerCase() == "textarea");
    var objT     = document.getElementById("tr_" + name);

    if (!objT)
    {
        objT = document.getElementById("td_" + name);

        if (!objT && (obj.parentNode.tagName == "TD"))
            objT = obj.parentNode;
    }            

    if (objT && !fNoClass)
    {
        var sClass = objT.className;
        var i      = GetAppendedClass(objT);
        
        if (i >= 0)
            sClass = sClass.substr(0, i);
        
        sClass += (fInValid || (fMissing && !fMissingOk)) ? " clsInValid" : (fMissing ? " clsMissing" : (fWhite ? " clsValidW" : ""));
        objT.className = sClass;
    }            
    
    if (!objInvalid && (fInValid || (fMissing && !fMissingOk)))
        objInvalid = obj;

    return ((fInValid || (fMissing && !fMissingOk)) ? 1 : 0);
}

function SetClassName(obj, fMissingOk, fMissing, fInValid)
{
    return SetClassNameEx(obj, obj.id, fMissingOk, fMissing, fInValid);
}

function CheckStringValue(obj, fMissingOk)
{
    var fMissing = !trim(obj);
    
    return SetClassName(obj, fMissingOk, fMissing, (obj.disabled && obj.value.length == 0) || (fMissing && !fMissingOk));
}

function CheckStringValueMMSizeEx(obj, iMin, iMax, fError, sObjectName)
{
    
    trim(obj);
    
    if ((iMin == "") || (iMin == null))
        iMin = 0;

    if ((iMax == "") || (iMax == null))
        iMax = 0;
        
    var fValid = (obj.value.length >= iMin) && ((iMax == 0) || (obj.value.length <= iMax));
    
    SetClassName(obj, iMin == 0, obj.value.length == 0, !fValid);
    
    var iRet = fValid ? 0 : (obj.value.length + 1);
 
    if (iRet && fError)
    {
        if (sObjectName == "")
            sObjectName = obj.name;
            
        if (iRet == 1)
            AddError(sObjectName + " is missing");
        else
            AddError(sObjectName + " is too long at " + (iRet - 1) + " chars, max length is " + iMax);
    }
    return iRet;
}

function CheckStringValueMMSize(obj, iMin, iMax, fError)
{
    return CheckStringValueMMSizeEx(obj, iMin, iMax, fError, "");
}

function CheckStringValueMMEx(obj, iMin, fError, sObjectName)
{
    return CheckStringValueMMSizeEx(obj, iMin, GetAttribute(obj, "maxlength"), fError, sObjectName)
}

function CheckStringValueMM(obj, iMin, fError)
{
    return CheckStringValueMMSizeEx(obj, iMin, GetAttribute(obj, "maxlength"), fError, "");
}

function CheckAlphaNumericEx(obj, fMissingOk, sExtraChars)
{
    var fValid = ValidateAlphaNumeric(obj, sExtraChars);

    return SetClassName(obj, fMissingOk, !obj.value.length, !fValid);
}

function CheckAlphaNumeric(obj, fMissingOk)
{
    return CheckAlphaNumericEx(obj, fMissingOk, "");
}

function CheckFLName(obj, fMissingOk, sField)
{
    var fInvalid = CheckStringValueMMEx(obj, fMissingOk ? 0 : 1, true, sField);
    
    if (!fInvalid && obj.value.length)
    {
        fInvalid = CheckAlphaNumericEx(obj, fMissingOk, " &-,.'\"");
    
        if (fInvalid)
            AddError(sField + " contains invalid characters");
    }
    
    return SetClassName(obj, fMissingOk, !obj.value.length, fInvalid);
}
        
function CheckEmailValue(obj, fMissingOk)
{
    var fMissing = !trim(obj);
    var fValid   = (fMissing && fMissingOk) || ValidateEmailEx(obj.value, false);
    var fRet     = SetClassName(obj, fMissingOk, !obj.value.length, !fValid);
    
    return fRet;
}

function CheckCurrencyValue(obj, fMissingOk, fZeroOk)
{
    var dblMaxValue = GetAttribute(obj, "maxvalue");
    
    if (dblMaxValue == null)
        dblMaxValue = "";
        
    var fValid = ValidateCurrency(obj, dblMaxValue);

    if (fValid && !fZeroOk)
        fValid = obj.value != zeroCurrency;

    return SetClassName(obj, fMissingOk, !obj.value.length, !fValid);; 
}

function CheckCurrencyValueMM(obj, fMissingOk, dMin, dMax)
{
    var fValid = ValidateCurrencyEx(obj, dMin, dMax);

    return SetClassName(obj, fMissingOk, !obj.value.length, !fValid);
}

function CheckPercentValueMM(obj, fMissingOk, dMin, dMax)
{
    var fValid = ValidatePercentMM(obj, dMin, dMax);
    
    return SetClassName(obj, fMissingOk, !obj.value.length, !fValid);
}

function CheckPercentValue(obj, fMissingOk, fZeroOk)
{
    var fValid = ValidatePercent(obj, "");
    
    if (fValid && !fZeroOk)
        fValid = obj.value != zeroPercent;
            
    return SetClassName(obj, fMissingOk, !obj.value.length, !fValid);
}

function CheckNumberValue(obj, fMissingOk, fZeroOk)
{
    var iMaxValue = GetAttribute(obj, "maxvalue");
    var fValid    = ValidateNumberMM(obj, "", iMaxValue);
    
    if (fValid && !fZeroOk)
        fValid = obj.value != zeroNumber;
            
    return SetClassName(obj, fMissingOk, !obj.value.length, !fValid);
}

function CheckNumberValueS(sValue, fMissingOk, fZeroOk)
{
    var fValid = (fMissingOk && (sValue == "")) || ValidateNumberValue(sValue);
    
    if (fValid && !fZeroOk)
        fValid = sValue != zeroNumber;
            
    return !fValid;
}

function CheckNumberValueMM(obj, fMissingOk, iMin, iMax)
{
    var fValid = ValidateNumberMM(obj, iMin, iMax);
    
    return SetClassName(obj, fMissingOk, !obj.value.length, !fValid);
}

function CheckDecimalValue(obj, fMissingOk, fZeroOk)
{
    var fValid = ValidateDecimal(obj);
    
    if (fValid && !fZeroOk)
        fValid = obj.value != zeroDecimal;
            
    return SetClassName(obj, fMissingOk, !obj.value.length, !fValid);
}

function CheckSQLDecimalValue(obj, fMissingOk)
{
    var fValid = ValidateSQLDecimal(obj);
    
    if (fValid)
    {
        // Format is valid, so check the actual numbers given
        var s      = new String(obj.value);
        var i      = s.indexOf(",");
        var iLeft  = parseInt(s.substr(0, i));
        var iRight = parseInt(s.substr(i+1));
        
        fValid = (iLeft > 0) && (iRight > 0);
        
    }
    return SetClassName(obj, fMissingOk, !obj.value.length, !fValid);
}

function CheckZipValue(obj, fMissingOk)
{
    var fValid = ValidateNumber(obj);
    
    if (fValid)
    {
        if (parseInt(obj.value) == 0)
            obj.value = "";
        else            
            fValid = obj.value.length == 5;
    }            
        
    return SetClassName(obj, fMissingOk, !obj.value.length, !fValid);
}

function CheckListValueEx(obj, fMissingOk, fError, sName)
{
    var fMissing = (obj.options.selectedIndex == -1) || (obj.options[obj.options.selectedIndex].value == 0);
    var fInValid = SetClassName(obj, fMissingOk, fMissing, (fMissing && !fMissingOk));
    
    if (fInValid && fError)
    {
        if (sName == "")
            sName = obj.name;
            
        AddError("Select a " + sName);            
    }
    
    return fInValid;
}

function CheckListValue(obj, fMissingOk)
{
    return CheckListValueEx(obj, fMissingOk, false, "") ;
}

function CheckDateValue(obj, fMissingOk)
{
    var fValid = ValidateDate(obj, false);
    
    return SetClassName(obj, fMissingOk, !obj.value.length, !fValid);
}
/*
function CheckPhoneNumber(strForm, obj, fMissingOk)
{
    var obj1 = eval("document." + strForm + "." + obj.name + "1");
    var obj2 = eval("document." + strForm + "." + obj.name + "2");
    var obj3 = eval("document." + strForm + "." + obj.name + "3");

    var f1 = !ValidateNumber(obj1, true);
    var f2 = !ValidateNumber(obj2, true);
    var f3 = !ValidateNumber(obj3, true);
    
    if (obj1.value == zeroNumber)
        obj1.value = "";
        
    if (obj2.value == zeroNumber)
        obj2.value = "";
        
    if (obj3.value == zeroNumber)
        obj3.value = "";

    var pn       = new String(obj1.value + obj2.value + obj3.value);
    var fInValid = (f1 || f2 || f3) || (pn.length > 0 && pn.length < 10) || (pn.length == 0 && !fMissingOk);
    
    if (!fInValid)
        obj.value = pn.length ? ("(" + obj1.value + ") " + obj2.value + "-" + obj3.value) : "";
        
    return SetClassNameEx(obj1, obj.name, fMissingOk, !(obj2.value.length || obj2.value.length || obj2.value.length), fInValid);
}
*/

function CheckPhoneNumber(obj, iMin, fError, sName)
{
    obj.value = String_Replace(obj.value, "/", " ");
    
    CheckStringValueMMEx(obj, iMin, fError, sName);
}

function CheckPasswordValueExEx(obj, sName, fMissingOk, fHigh)
{
    var iMin     = fHigh ? 8 : 5;
    var fMissing = !trim(obj);
    var fValid   = (fMissing && fMissingOk) || (!fMissing && (obj.value.length >= iMin));
    
    if (fValid && !fMissing)
    {
        var fLetter = false;
        var fNumber = false;
        var i = 0;
        
        for (i = 0; i < obj.value.length; i++)
        {
            if (!fLetter)
            {
                fLetter = ((obj.value.charAt(i) >= 'A') && (obj.value.charAt(i) <= 'Z')) ||
                          ((obj.value.charAt(i) >= 'a') && (obj.value.charAt(i) <= 'z'));
            }
            
            if (!fNumber)
                fNumber = ((obj.value.charAt(i) >= '0') && (obj.value.charAt(i) <= '9'));
        }
        
        fValid = !fHigh || (fLetter && fNumber);
    }
    
    if (!fValid)
    {
        if (sName == "")
            sName = "password";
            
        AddError("Invalid " + sName + ":\r\n\tMust be at least " + iMin + " chars long" + (fHigh ? ", and contain at least 1 number and 1 letter" : ""));
    }
            
    return SetClassName(obj, fMissingOk, fMissing, !fValid);
}

function CheckPasswordValueEx(obj, fMissingOk, fHigh)
{
    return CheckPasswordValueExEx(obj, "", fMissingOk, fHigh);
}

function CheckPasswordValue(obj, fMissingOk)
{
    return CheckPasswordValueEx(obj, fMissingOk, true);
}

function CheckIPValue(obj, fMissingOk)
{
    trim(obj);
    strIP = obj.value;
    
    var fValid = (strIP.length == 0) && fMissingOk;
    
    if (!fValid && (strIP.length <= 15))
    {
        var iDigits = 0;
        var iPoint  = 0;
        var i;

        for (i = 0; i < strIP.length; i++)
        {
            if (strIP.charAt(i) == '.')
            {
                if (!iDigits)
                    break;
                iPoint++;
                iDigits = 0;
            }
            else if (strIP.charAt(i) >= '0' && strIP.charAt(i) <= '9')
            {
                iDigits++;
                if (iDigits > 3)
                    break;
            }
            else
            {
                break;
            }
        }
        
        fValid = (iPoint == 3) && (iDigits >= 1 && iDigits <= 3);
    }                
    
    return SetClassName(obj, false, false, !fValid);        
}

function CheckCreditCardNumber(obj, iType, fMissingOk, sName)
{
    var iMaxLength1 = 16;
    var iMaxLength2 = 0;
    
    switch (iType)
    {
        case CreditCardType_Visa:
            iMaxLength2 = 13;
            break;
            
        case CreditCardType_Discover:
        case CreditCardType_MasterCard:
            break;
            
        case CreditCardType_AmericanExpress:
            iMaxLength1 = 15;
            break;
    }

    var sValue     = obj.value;
    var sOrgValue  = GetAttribute(obj, "orgnumber");
    var fValid     = (sValue == sOrgValue) && !((sValue == "") && !fMissingOk);
    var fMissing   = false;
    var fBadNumber = false;
    var fBadLength = false;
    var fBadChars  = false;
    
    if (!fValid)
    {
        sValue = trimEx(sValue, false);
        sValue = String_RemoveSP(sValue);
        sValue = String_RemoveCH(sValue, "-");
        
        fMissing   = sValue == "";
        fBadLength = !fMissing && (sValue.length != iMaxLength1) && (sValue.length != iMaxLength2);        
        fValid     = (!fMissing || fMissingOk) && !fBadLength;
        
        if (!fMissing)
        {
            // Got right number of chars, now make sure they are all numbers
            for (i = 0; i < sValue.length; i++)
            {
                if ((sValue.charAt(i) < '0') || (sValue.charAt(i) > '9'))
                {
                    fValid    = false;
                    fBadChars = true;
                    break;
                }
            }
            
            if (fValid)
            {
                if (sValue == sCC_TEST_ACCOUNT)
                {
                    fValid     = fAllowTestCCNumber && (iType == CreditCardType_Visa);
                    fBadNumber = !fValid;
                }
                else
                {
                    // Validate actual number
                    // Double every other digit and sum it as a single digit (i.e.  18 should be summed as 1+8 not 18)
                    var iSum = 0;
                    var i;
                    var j;
                    
                    for (i = sValue.length - 1, j = 1; i >= 0; i--, j++)
                    {
                        var iChar = parseInt(sValue.charAt(i));
                        
                        if ((j % 2) > 0)
                        {
                            iSum += iChar;
                        }
                        else
                        {
                            var sNumber = new String(iChar * 2);
                            var n;
                            
                            for (n = 0; n < sNumber.length; n++)
                                iSum += parseInt(sNumber.charAt(n));
                        }
                    }
                    
                    // Mod with sum should give us 0 if card is valid
                    fValid     = (iSum % 10) == 0;
                    fBadNumber = !fValid;
                }
            }                
        }
    }
       
    if (!fValid)
    {
        obj.value = sValue;
        
        if (fMissing)
        {
            AddError(sName + " is missing");
        }
        else
        {
            var sMessage = "";
            
            if (fBadNumber)
            {
                sMessage = "is invalid";
            }
            else if (fBadLength)
            {
                sMessage = "length is invalid, valid length is " + iMaxLength1;
                
                if (iMaxLength2 > 0)
                    sMessage += " or " + iMaxLength2;
            }
            
            else if (fBadChars)
            {
                sMessage = "contains invalid characters";                    
            }
            
            if (sMessage != "")
                AddError(sName + " " + sMessage);
        }
        SetClassName(obj, false, false, true);
    }
    else
    {
        SetClassName(obj, fMissingOk, fMissing, false);
    }        
   
   return !fValid
}

function LookupClearSelection()
{
    var iCtrl   = 0;
    var objCtrl = null;
    
    while (objCtrl = document.all[iCtrl++])
    {
        if (objCtrl.tagName.toUpperCase() == "INPUT")
        {
            if (objCtrl.type.toUpperCase() == "RADIO")
                objCtrl.checked = false;
        }
    }
}

function SaveCaretPos(obj)
{
    if (obj.caretPos >= 0)
        return;
        
    var objActive = document.activeElement;
    if (objActive != obj)
        obj.focus();
    
    var iCaretPos = -1;
    
    if (document.selection)
    {
        var range = document.selection.createRange();
        while (range.parentElement() == obj)
        {
            iCaretPos++;
            m = range.move("character", 1);
        }            
        m = range.move("character", -1);
    }        
    
    obj.caretPos = iCaretPos;
    
    if (objActive != obj)
        objActive.focus();
}

/*
function insertAtCaretX (input, text) 
{
    if (document.selection) 
    {
        var range = document.selection.createRange();
        if (range.parentElement() == input)
            range.text = text;
    }
}
*/
function CopyToClipboard(sText)
{
    clipboardData.clearData("Text");
    clipboardData.setData("Text", sText);
}

function insertAtCaret (input, text) 
{
    // Save clibboard to restore after insertion of Line Break
    var sText = clipboardData.getData("Text");
    
    if (sText != null)
        clipboardData.clearData("Text");
        
    clipboardData.setData("Text", text);
    document.execCommand("Paste");
    // Restore clipboard
    
    if (sText != null)
        clipboardData.setData("Text", sText);
        
    event.returnValue = false;
}

function InsertLineBreak(fHTML)
{
    var sText = fHTML ? "<br/>\r\n" : "\r\n";
    
    insertAtCaret(null, sText)
}

function RemoveParam(sSrcURL, sParam)
{
    var sSrc  = new String(sSrcURL);
    var fHTML = sSrc.toLowerCase().indexOf("&amp;") >= 0;
    
    if (fHTML)
        sSrc = String_Replace(sSrc, "&amp;", "&");
    
    var sURL = new String(sSrc);
    var iID  = sURL.indexOf("&" + sParam + "=");

    if (iID >= 0)
    {
        var iE = sURL.indexOf("&", iID + 1);
        if (iE == -1)
            iE = sURL.length;
        sURL = sURL.substr(0, iID) + sURL.substr(iE);
    }
    
    sURL = String_Replace(sURL, "#", "");

    if (fHTML)
        sURL = String_Replace(sURL, "&", "&amp;");
    
    return sURL;

}

function EncodeText(obj)
{
    obj.value = escape(obj.value);
}

function Select_Clear()
{
    if (IsBrowserIE())
        Select_ClearSel();
}

function RandomNumber(iLo, iHi)
{
    return parseInt((iHi - iLo + 1) * Math.random() + iLo);
}    

function Row_GetClass(iRowIndex)
{
    return (iRowIndex % 2) ? "clsEven" : "clsOdd";
}

function Row_InsertCell(objRow, sAlign, sPaddingTop)
{
    var objCell = objRow.insertCell();
    
    objCell.align  = sAlign;
    objCell.style.paddingTop = sPaddingTop;
    objCell.noWrap = true;
    
    return objCell;
}

function Table_InsertRowEx(objTbl, iIndex)
{
    var objRow = (iIndex < 0) ? objTbl.insertRow() : objTbl.insertRow(iIndex);
    
    objRow.className = Row_GetClass(objRow.rowIndex);
    return objRow;
}

function Table_InsertRow(objTbl)
{
    return Table_InsertRowEx(objTbl, -1);
}

function FormatAddress(sFName, sLName, sCompany, sAddress1, sAddress2, sCity, sState, sZip, sCountry)
{
    var sAddress = "";
    
    if (sFName != "")
        sAddress += sFName + " ";
        
    if (sLName != "")
    {
        if (sFName != "")
            sAddress += " ";
        sAddress += sLName;
    }

    if (sAddress != "")
        sAddress += "\r";

    if (sCompany != "")
        sAddress += sCompany + "\r";                    
    
    if (sAddress1 != "")
        sAddress += sAddress1 + "\r";
        
    if (sAddress2 != "")
        sAddress += sAddress2 + "\r";

    var fCityStateZip = false;

    if (sCity != "")
    {
        fCityStateZip = true;
        sAddress += sCity;
    }
            
    if (sState != "")
    {
        if (fCityStateZip)
            sAddress += ", ";
        sAddress += sState;
        fCityStateZip = true;
    }
    
    if (sZip != "")
    {
        if (fCityStateZip)
            sAddress += " ";
        sAddress += sZip;
        fCityStateZip = true;
    }
        
    if (sCountry != "")
    {
        if (fCityStateZip)
            sAddress += "\r";
        sAddress += sCountry;
    }

    return sAddress;
}

function RoundCurrency(dblValue)
{
        dblValue = parseFloat(dblValue);
    var sValue   = new String(dblValue);
    var iPoint   = sValue.indexOf(".");
    
    var sDollars = (iPoint <  0) ? sValue : ((iPoint == 0) ? "0" : sValue.substr(0, iPoint));
    var sCents   = (iPoint <  0) ? "0" : sValue.substr(iPoint + 1);

    if (sCents.length >= 3)
    {        
        sCents = sCents.substr(0, 2) + "." + sCents.substr(2);
        
        var dblCents = parseFloat(sCents);
        dblCents = Math.round(dblCents);
    
        if (dblCents == 100)
        {
            sDollars = parseFloat(sDollars) + 1;
            dblCents = 0;
        }
        
        sCents = new String(dblCents);        
        if (dblCents < 10)
            sCents = "0" + sCents;
    }
    
    if (sCents.length == 0)
        sCents = "00";
    else if (sCents.length == 1)
        sCents = sCents + "0";
        
    var sResult = sDollars + "." + sCents;
    
    return sResult;
}

function FormatFloat(dblValue, fCurrency)
{
    var sResult;
    
    if (isNaN(dblValue))
    {
        sResult = UNKNOWN_VALUE;
    }
    else
    {
        sResult = RoundCurrency(dblValue);
        sResult = Number_AddComma(sResult);
        
        if (fCurrency)
            sResult = "$" + sResult;
    }
                          
    return sResult;        
}

function FormatCurrency(dblValue)
{
    return FormatFloat(dblValue, true);
}

function FormatDouble(dblValue)
{
    return FormatFloat(dblValue, false);
}

function PreStringForNumber(sValue)
{
    sValue = trimEx(sValue, false);
    sValue = String_RemoveSP(sValue);
    sValue = String_ReplaceCH(sValue, ",", "");
    
    return sValue;
}

function CurValue(sValue)
{
    sValue = PreStringForNumber(sValue);
    
    if ((sValue == "") || (sValue == "$"))
    {
        sValue = "0";
    }
    else if (sValue.charAt(0) == "$")
    {
        sValue = sValue.substr(1);
    }
    
    sValue = RoundCurrency(sValue);
    
    return parseFloat(sValue);            
}

function DecValue(sValue)
{
    sValue = PreStringForNumber(sValue);
    
    if (sValue == "")
        sValue = "0";
        
    return parseFloat(sValue);        
}

function IntValue(sValue)
{
    sValue = PreStringForNumber(sValue);
    
    if (sValue == "")
        sValue = "0";
        
    return parseInt(sValue);        
}

function SetDateValue(obj, dt)
{
    obj.value = (dt.getMonth() + 1) + "/" + dt.getDate() + "/" + dt.getYear();
}

function TodaysDate()
{
    var dtToday = new Date();
        dtToday = new Date((dtToday.getMonth() + 1) + "/" + dtToday.getDate() + "/" + dtToday.getYear());
        
    return dtToday;        
}

function CompareDates(dtDate1, dtDate2)
{
    var fD1ltD2 = dtDate1 < dtDate2;
    var fD1gtD2 = dtDate1 > dtDate2;
    
    return fD1ltD2 ? -1 : (fD1gtD2 ? 1 : 0);
}

function CopyContents(objDoc, objContent)
{
    var r = objDoc.body.createTextRange();

    r.moveToElementText(objContent);
    r.select();
    objDoc.execCommand("Copy");
    
    return false;
}

function EatEvent()
{
    if (event != null)
    {
        event.cancelBubble = true;
        event.returnValue = false;     
    }
    return true;
}

function GetAttribute(obj, sAttribute)
{
    return obj.getAttribute(sAttribute);
}

function SetAttribute(obj, sAttribute, sValue)
{
    obj.setAttribute(sAttribute, sValue);
}

function AddListItem(obj, sText, iValue, iIndex)
{
    var opt = document.createElement("OPTION");
    
    opt.text  = sText;
    opt.value = iValue;
    
    if (IsBrowserIE())                    
    {
        if (iIndex == -1)
            iIndex = obj.options.length;
            
        obj.options.add(opt, iIndex);
    }
    else
    {
        var objNext = (iIndex == -1) ? null : obj.options[iIndex];
        
        obj.add(opt, objNext);                
    }
}

function ClearList(obj)
{
    while (obj.options.length)
    {
        if (IsBrowserIE())
            obj.options.remove(0);
        else
            obj.remove(0);
    }
}

function List_UpdateDayList(objM, objD, fSelFirst)
{
    var iDays = parseInt(GetAttribute(objM.options[objM.selectedIndex], "Days"));
 
    objD.selectedIndex = 0;
    objD.disabled = isNaN(iDays) || (iDays == 0);
 
    if (!objD.disabled)
    {
        var iDay;

        ClearList(objD);

        AddListItem(objD, "", 0, -1);        
        
        for (iDay = 1; iDay <= iDays; iDay++)
        {
            var sText  = iDay;
            
            if (iDay < 10)
                sText = "0" + sText;
                
            AddListItem(objD, sText, iDay, -1);                        
        }
        
        objD.selectedIndex = fSelFirst ? 1 : iDays;
    }        
}

function List_UpdateMonthDays(objM, objD, objY, iFeb)
{
    var fLeapYear = parseInt(GetAttribute(objY.options[objY.selectedIndex], "LeapYear"));
    
    SetAttribute(objM.options[iFeb], "Days", fLeapYear ? 29 : 28);
    
    if (objM.value == 2)
    {
        var i29 = (objD.options[0].value == 0) ? 29 : 28;
        
        if (fLeapYear)
        {
            if (objD.options.length == i29)
                AddListItem(objD, 29, 29, -1);
        }
        else
        {
            if (objD.value == 29)
                objD.value = 28;

            if (objD.options.length == i29 + 1)
                objD.options.remove(i29);
        }                
    }            
}

function GetDisplayValue(sName)
{
    var sValue = "";
    
    if (sName != "")  
    {
        // Double underscores are replaced with apostrphe's
        // Single underscores replaced with single space (After double underscores replaced)
        //sName = String_Replace(sName, "__", "&#39;");
        //sName = String_Replace(sName, "_", " ");

        // Single space inserted before each captial letter
        // Skip first char, and any double caps
        var i;
        var chLast = "";
        
        for (i = 0; i < sName.length; i++)
        {
            var ch = sName.charAt(i);
            
            if ((sValue != "") && ((ch >= 'A') && (ch <= 'Z')) && (((chLast < 'A') || (chLast > 'Z')) && ((chLast != ' ') && (chLast != '_') && (chLast != '-'))))
            {
                sValue += " ";
            }
                
            sValue += ch;    
            chLast = ch;
        }
    }
    
    return sValue;
}

function IsItemInListEx(sList, sItem, sDelimiter)
{
    var fInList = false;
    
    if (sList != "")
    {
        sItem   = sDelimiter + sItem + sDelimiter;
        sList   = sDelimiter + sList + sDelimiter;
        
        sItem   = sItem.toLowerCase()
        sList   = sList.toLowerCase();
        
        fInList = sList.indexOf(sItem) >= 0;
    }
    
    return fInList;
}

function IsItemInList(sList, sItem)
{
    return IsItemInListEx(sList, sItem, ",");
}

function AddItemToListEx(sList, sItem, fAdd, sDelimiter)
{
    if (fAdd)
    {
        if (sList != "")
            sList += sDelimiter;
            
        sList += sItem;
    }
    else
    {
        sList = sDelimiter + sList + sDelimiter;
        sList = String_Replace(sList, sDelimiter + sItem + sDelimiter, sDelimiter);
    }

    sList = String_Trim(sList, sDelimiter);
    
    return sList;
}

function AddItemToList(sList, sItem, fAdd)
{
    return AddItemToListEx(sList, sItem, fAdd, ",");
}

function GetObjectPosition(obj, fStopAtContentDiv)
{
    var iLeft = parseInt(GetAttribute(obj, "offsetLeft"));
    var iTop  = parseInt(GetAttribute(obj, "offsetTop"));

    try
    {        
        while (obj.offsetParent)
        {
            if (fStopAtContentDiv && (obj.offsetParent.id == "MainConsoleContentDiv"))
                break;
                
            obj = obj.offsetParent;
            iLeft += parseInt(GetAttribute(obj, "offsetLeft"));
            iTop  += parseInt(GetAttribute(obj, "offsetTop"));
        }   
    }
    catch(e)
    {
        alert(obj.id + ":" + e.message);
    }
        
    var rPosition = new Array();
    
    rPosition[0] = iLeft;
    rPosition[1] = iTop;

    return rPosition;
}