/*
 * $Archive: /RAPIDS/RAPIDS-v2.3.0.0/clientlibrary/formutil2.js $
 * $Date: 10/29/03 2:29p $
 * $Revision: 3 $
 * $Author: Gbrooks $
 */

function IsFormChanged(form) {
    var str = '';
    for (var i = 0; i < form.elements.length; ++i) {
        elt = form.elements[i];
        switch (elt.type) {
        case 'checkbox':
        case 'radio':
            if (elt.checked != elt.defaultChecked)
                str += ',' + elt.name;
            break;
        //case 'hidden':  // Removed - Doesn't work in Netscape
        case 'password':
        case 'text':
        case 'textarea':
            if (elt.value != elt.defaultValue)
                str += ',' + elt.name;
            break;
        case 'select-one':
        case 'select-multiple':
            for (var j = 0; j < elt.options.length; ++j)
                if (elt.options[j].selected != elt.options[j].defaultSelected) {
                    str += ',' + elt.name;
                    break;
                }
            break;
        default:
            ; // ignore button, submit, etc.
        }
    }
    
    if (str == '')
        return false;
        
    return str.substr(1, str.length); // strip off leading comma
}

//
// Class - FormValidator
//
function FormValidator(saFileUp) {

    _FormValidatorInit();

    // ===== Private data =====

    this._platform = (typeof(Request) != "undefined") ? this.SERVER_ONLY : this.CLIENT_ONLY;

    // each element in this array is a two-element array:
    //   [0] - string to evaluate
    //   [1] - prompt string if [0] evaluates to false
    this.v = new Array();

    if (saFileUp) {
        this.formVars = new FormVars_SAFileUp(saFileUp);
    } else {
        this.formVars = new FormVars_ASP();
    }
}

// This function copes with the difference between loading a js file via SSI and <script runat="server">
function _FormValidatorInit() {
    // Init only once per page execution
    if (typeof FormValidator._initComplete != "undefined") {
        return;
    }
    FormValidator._initComplete = 1;

    // ===== Class Constants =====
    FormValidator.prototype.CLIENT_ONLY = 1;
    FormValidator.prototype.SERVER_ONLY = 2;


    // ===== Public methods =====
    FormValidator.prototype.IsOnServer = function() {
        return this._platform == this.SERVER_ONLY;
    }

    FormValidator.prototype.IsOnClient = function() {
        return this._platform == this.CLIENT_ONLY;
    }

    FormValidator.prototype.AddCondition = function(condStr, errMsg, restrictions) {
        this.v[this.v.length] = new Array(condStr, errMsg, restrictions);
    }

    FormValidator.prototype.AddRegExp = function(fieldName, re, errMsg, restrictions) {
        if (!errMsg) {
            errMsg = "Please specify a";
            if (fieldName.match(/^[AEIOU]/i))
                errMsg += "n";
            errMsg += " " + fieldName.replace(/(\S)([A-Z])/g, "$1 $2");
        }

        if (!re)
            re = /\S/;
   
        this.AddCondition("${" + fieldName + "}.match(" + re.toString() + ")", errMsg, restrictions);
    }


    FormValidator.prototype.AddSimple = function(/* arg1 [, arg2 ...] */) {
        for (var i = 0; i < arguments.length; ++i)
            this.AddRegExp(arguments[i]);
    }

    FormValidator.prototype.GetValidationErrors = function(f) {
        var valRegExp = /\$\{([^}]+)\}/;  // matches ${SomeVar}
        var lenRegExp = /\@\{([^}]+)\}/;  // matches @{SomeVar}
        var str = "";
        for (var i = 0; i < this.v.length; ++i) {
            if (this._IsValidationRelevant(this.v[i])) {
                var evalStr = this.v[i][0];
                while (evalStr.match(valRegExp))
                    evalStr = evalStr.replace(valRegExp, this._Lookup(RegExp.$1, f));
                while (evalStr.match(lenRegExp))
                    evalStr = evalStr.replace(lenRegExp, this._LookupLen(RegExp.$1, f));
                try { 
                    if (!eval(evalStr)) {
                        str += this.v[i][1] + (this.IsOnServer() ? "<br>" : "\n");
                    } 
                } catch(err) {
                    str += 'FormValidtor.GetValidationErrors: unable to evaluate "' + evalStr + '" restrictions:' + this.v[i][2] + ' _platform: ' + this._platform;
                }
            }
        }

        // prompt if on client
        if (this.IsOnClient() && (str != ""))
            alert(str);

        return str;
    }

    FormValidator.prototype.Write = function(includeScriptTags) {
        str = "";
        str += "    var fv = new FormValidator();\n";
        for (var i = 0; i < this.v.length; ++i) {
            if (!this.v[i][2] || this.v[i][2] == this.CLIENT_ONLY) {
                var condStr = this.v[i][0];
                condStr = condStr.replace(/\\/g, "\\\\"); // help out regexps; must do this first and *then* backslash the quotes
                condStr = condStr.replace(/"/g, '\\"');   // ' help Emacs syntax highlighting
                str += "    fv.AddCondition(\"" + condStr + "\", \"" + this.v[i][1] + "\");\n";   //' help Emacs
            }
        }
        if (includeScriptTags)   // TBD: should include src="includeclient/formutil2.inc too?
            str = '<script language="JavaScript1.2">\n' + str + '</script>\n';
        return str;
    }

    // ===== Private methods =====

    FormValidator.prototype._IsValidationRelevant = function(validation) {
        if (validation[2]) {
            if (this.IsOnServer() && (validation[2] == this.CLIENT_ONLY))
                return false;
            if (this.IsOnClient() && (validation[2] == this.SERVER_ONLY))
                return false;
        }
        return true;
    }

    FormValidator.prototype._Lookup = function(name, f) {
        var retStr = "";
        if (this.IsOnServer()) {  // server side
            retStr = this.formVars.Get(name);
        } else { // client side
            var e = f.elements[name];
            if (typeof(e) == "undefined") {
                alert("GetValidationErrors(): ERROR: Field '" + name + "' is not a form element.");
                retStr = "???";
            } else if (e.length) { // then it's radio buttons or select
                for (var i = 0; i < e.length; ++i) {
                    if (e[i].checked || e[i].selected) {
                        retStr = e[i].value;
                        break;
                    }
                }
            } else {
                switch (e.type) {
                    case "hidden":   // fall ...
                    case "password": // ...
                    case "textarea": // ... through ...
                    case "text":     retStr = (e.value ? e.value : "").replace(/[\r\n]/g, ""); break;
                    case "checkbox": retStr = e.checked ? e.value : ""; break;
                    default:       
                        alert("Unhandled type: " + e.type + "/" + typeof(e));
                        retStr = "???" + e.type;
                }
            }
        }
        return '"' + retStr.replace(/\\/g, "\\\\").replace(/"/g, '\\"') + '"';   // " make Emacs happy
    }

    FormValidator.prototype._LookupLen = function(name, f) {
        if (this.IsOnServer()) { // server side
            return this.formVars.GetItemCount(name);
        } else { // client side
            var e = f.elements[name];
            if (e.type == "select-multiple") {
                var len = 0;
                for (var i = 0; i < e.length; ++i) {
                    if (e[i].selected)
                        ++len;
                }
                return len;
            } else
                return (this._Lookup(name, f) == '""') ? 0 : 1;
        }
    }
}

// These methods provide hooks to override Server field access - primarilly for when
// using SAFileUp
//

// Class - FormVars_ASP
// Intent - Provide FormVar adapter to ASP Request object for HTTP Form variables
//
function FormVars_ASP() {
    _FormVars_ASP_Init();
}

function _FormVars_ASP_Init() {

    if (typeof FormVars_ASP._initComplete != "undefined") {
        return;
    }
    FormVars_ASP._initComplete = 1;

    FormVars_ASP.prototype.Get = function (name, item) {
        if (!item) {
            item = 1;
        }
        return (this.IsDefined(name) ? Request(name)(item) : "");
    }

    FormVars_ASP.prototype.IsDefined = function (name, item) {
        if (!item) {
            item = 1;
        }
        try {
            return (typeof(Request(name)(item)) != "undefined");
        } catch(err) {
            return false;
        }
    }

    FormVars_ASP.prototype.GetItemCount = function (name) {
        if (!this.IsDefined(name))
            return 0;
        else
            return Request(name).Count;
    }
}

//
// Class - FormVars_SAFileUp
// Intent - Provide FormVar adapter to SAFileUp for HTTP Form variables
//
function FormVars_SAFileUp(saFileUp) {
    _FormVars_SAFileUp_Init();

    if (!saFileUp) {
        this.saFileUp = Server.CreateObject("SoftArtisans.FileUp");
    } else {
        this.saFileUp = saFileUp;
    }
}

function _FormVars_SAFileUp_Init() {

    if (typeof FormVars_SAFileUp._initComplete != "undefined") {
        return;
    }
    FormVars_SAFileUp._initComplete = 1;

    FormVars_SAFileUp.prototype.IsDefined = function(name) {
        return typeof(this.saFileUp.Form(name)) != "undefined";
    }

    FormVars_SAFileUp.prototype.Get = function(name) {
        return this.IsDefined(name) ? this.saFileUp.Form(name) : "";
    }

    FormVars_SAFileUp.prototype.GetItemCount = function(name) {
        if (!this.IsDefined(name)) {
            return 0;
        }
        return this.saFileUp.FormEx(name).Count;
    }
}

