
EitherMonad = {
    base: {
        bind: function(f) {
            if (this.s) return f(this.v);
            else return this;
        },
        plus: function(m) {
            if (this.s) return this;
            else return m;
        }
    },
    unit: function(x) {
        var ret = Object.clone(this.base);
        ret.s = true;
        ret.v = x;
        return ret;
    },
    fail: function(x) {
        var ret = Object.clone(this.base);
        ret.s = false;
        ret.v = x;
        return ret;
    },
    bind: function(a,b) {
        return a.bind(b);
    },
    plus: function(a,b) {
        return a.plus(b);
    }
};

CmpsblForm = Class.create({
    initialize: function(form, validator) {
        this.form = $(form);
        this.data = {};
        if (validator) this.validator = validator;
        this.form.observe("submit", this.submitCallback.bind(this));
    },
    scanInputs: function() {
        this.data = {};
        this.form.getElements().each(this.extendByElement.bind(this));
    },
    extendByElement: function(el) {
        var p = {root: this.data};
        var k = "root";
        el.name.sub("]","",1000).split("[").each(function(t) {
            if (p[k] == undefined) p[k] = {};
            p = p[k];
            k = t;
        });
        p[k] = $(el).getValue();
    },
    submitCallback: function(evt) {
        this.scanInputs();
        var vr = this.validator(this.data);
        if (!vr.s) Event.stop(evt);
    },
    validator: function(data) {
        return EitherMonad.unit();
    }
});


