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
        }
    }
    
    if (str == '')
        return false;
        
    return str.substr(1, str.length); // strip off leading comma
}

function FormValidator()
{
    function _Add(name, regexp, errmsg)
    {
        this.fields[this.fields.length] = new Array(name, regexp, errmsg);
    }

    function _AddRadioBtn(name, errmsg)
    {
        this.radios[this.radios.length] = new Array(name, errmsg);
    }

    function _AddCondition(condition, errmsg)
    {
        this.conditions[this.conditions.length] = new Array(condition, errmsg);
    }

    function _Do(form)
    {
        var isClient = false;
        if (typeof window != "undefined")
            isClient = true;

        var str = '';
        for (var i = 0; i < this.fields.length; ++i)
        {
            if (isClient)
            {
                var elt = form.elements[this.fields[i][0]];
                var val = elt.value;
            } else {
                var elt = Request(this.fields[i][0]);
                var val = elt.item;
            }
            if (typeof(elt) != "undefined")
            {
                if (!this.fields[i][1].test(val))
                    str += FormatValidatorStr(this.fields[i][2], isClient);
//                    str += this.fields[i][2] + '\n';
            }
        }
  
        if (isClient)
        {
            // Check radio buttons (for at least one checked)              
            for (var i = 0; i < this.radios.length; i++)
            {
                var checked = false;
                var radio = "form." + this.radios[i][0];
                for (var j = 0; j < eval(radio + ".length"); j++)
                {
                    if (eval(radio + "[j].checked"))
                    {
                        checked = true;
                        break;
                    }
                }
                if (!checked)
                    str += this.radios[i][1] + '\n';
            }
        }
    
        // Do conditional validation
        for (var i = 0; i < this.conditions.length; i++)
        {
            if (!eval(this.conditions[i][0]))
                str += FormatValidatorStr(this.conditions[i][1], isClient);
//                str += this.conditions[i][1] + '\n';
        }
        
        if (str != '')
        {
            if (isClient)
            {
                alert(str);
                return false;
            } else {
                return str;
            }
        }

        if (!isClient)
            return "";
        else
            return true;
    }

    // Methods
    this.Add          = _Add;
    this.AddRadioBtn  = _AddRadioBtn;
    this.AddCondition = _AddCondition;
    this.Do           = _Do;

    // Attributes
    this.fields     = new Array();
    this.radios     = new Array();
    this.conditions = new Array();
}

function FormatValidatorStr(str, isClient) {
    if (isClient)
    {
        str = str + "\n";
    }
    else
    {
        str = str + "<br>";
    }
    
    return str
}
