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 str = '';
        for (var i = 0; i < this.fields.length; ++i)
        {
            var elt = form.elements[this.fields[i][0]];
            if (typeof(elt) != "undefined")
            {
                if (!this.fields[i][1].test(elt.value))
                    str += this.fields[i][2] + '\n';
            }
        }
  
        // 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 += this.conditions[i][1] + '\n';
        }
        
        if (str != '')
        {
            alert(str);
            return false;
        }

        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();
}

