Event.onDOMReady(function(){
    window._mailForms = [];
    $$('form.mailform').each(function(form){
        window._mailForms.push(new MailForm(form));
    });
});

var bool = function(v){ return !!v; }
var emptyFn = Prototype.emptyFunction;
if(!window.console) window.console = { error: emptyFn, log: emptyFn, debug: emptyFn, warn: emptyFn, trace: emptyFn };

var Messages = {
    lang: 'de',
    langAvailable: ['de','en'],
    de: {
        "communication.error": new Template("Es ist ein Verbindungsfehler beim Versenden der Nachricht aufgetreten! Möglicherweise ist der Server nicht erreichbar!"),
        "form.data.invalid": new Template("Das Formular ist nicht korrekt ausgefüllt:"),
        "field.error.mandatory": new Template("Das Feld #{fieldName} ist ein Pflichtfeld!"),
        "field.error.email": new Template("Der Wert des Feldes #{fieldName} ist keine gültige Emailadresse!")
    },
    en: {
        "communication.error": new Template("A communication error occured while sending you message! The server may be unreachable at the moment!"),
        "form.data.invalid": new Template("The form contains errors:"),
        "field.error.mandatory": new Template("The field #{fieldName} is mandatory!"),
        "field.error.email": new Template("The field #{fieldName} does not contain a valid email address!")
    },
    setLang: function(lang) {
        this.lang = lang;    
    },
    get: function(key, args) {
        var tpl = this[this.lang][key];
        if(!tpl){
            console.error("Message key not found: " + key);
            return key;
        }
        return tpl.evaluate(args);
    }
}

var MailForm = Class.create({
    initialize: function(form) {
        this.form = $(form);
        this.form.observe('submit', this.onSubmit.bind(this));
        this.form.enable();
        this.form.getElements().each(function(el) {
            el.observe('blur', this.validateSingleElement.bind(this, el, false));
            el.observe('change', this.validateSingleElement.bind(this, el, true));
            el.observe('keyup', this.validateSingleElement.bind(this, el, true));
            el.observe('keypress', this.validateSingleElement.bind(this, el, true));
        }.bind(this));
        var lang = this.form.getAttribute("lang");
        if(lang) Messages.setLang(lang);
    },
    onSubmit: function(ev) {
        if(!this.validate()) {
            Event.stop(ev);
            return false;
        } else {
            Event.stop(ev);
            this.send();
            return false;
        }
    },
    showSpinner: function() {
        if(!this._overlay) {
            this._overlay = $('form_overlay');
            this._overlay.setStyle({
                position: 'absolute',
                opacity: 0.8,
                background: '#ffffff'
            });
            this._overlay.clonePosition(this.form);
            this._overlay.show();
            var msg = this._overlay.down('.wait-msg');
            var off = parseInt(this.form.getDimensions().height/2 - 5);
            msg.setStyle({
                marginTop: off + "px",
                textAlign: "center"
            });
        }
        this._overlay.show();
    },
    hideSpinner: function() {
        if(this._overlay) this._overlay.hide();
    },
    send: function() {
        if(!this._request) {
            this.showSpinner();
            this._request = new Ajax.Request('send.jsp', {
                parameters: this.form.serialize(true),
//                method: 'post',
                onSuccess: this.onSuccess.bind(this),
                onFailure: this.onError.bind(this)
            });
            this.form.disable();
        }
    },
    onSuccess: function(response) {
        var rj = response.responseJSON;
        if(rj && rj.redirect) {
            window.location.href = rj.redirect;
        } else if(rj && rj.msg) {
            alert(rj.msg);
            this.form.enable();
            this.hideSpinner();
        } else {
            this.onError(response)
        }
        this._request = null;
    },
    onError: function(response) {
        alert(Messages.get("communication.error"));
        this.form.enable();
        this.hideSpinner();
        this._request = null;
    },
    validate: function() {
        try {
            var serializedForm = this.form.serialize(true);
            var errors = this.form.getElements().collect(this.validateElement.bind(this, serializedForm)).findAll(bool);
            if(errors.length == 0) return true;
            alert("Das Formular ist nicht korrekt ausgefüllt:\n" + errors.join('\n'));
            return false;
        } catch(e) {
            console.error(e);
        }
    },
    validateSingleElement: function(element, silent) {
        this.validateElement(this.form.serialize(true), element, silent);
        return true;
    },
    validateElement: function(serializedForm, el, silent) {
        try {
            var div = el.up('.form-field');
            if(!div) return;
            div.removeClassName('invalid');
            if(div.hasClassName('mandatory')) {
                if(!this.checkMandatory(el, serializedForm)) {
                    if(!silent) div.addClassName('invalid');
                    return Messages.get("field.error.mandatory", { fieldName: this.getFieldLabel(div) }); 
                    //"Das Feld " + this.getFieldLabel(div) + " ist ein Pflichtfeld!";
                }
            }
            if(div.hasClassName('email')) {
                if(!this.checkEmail(el, serializedForm)) {
                    if(!silent) div.addClassName('invalid');
                    return Messages.get("field.error.email", { fieldName: this.getFieldLabel(div) }); 
                    //"Das Wert des Feldes " + this.getFieldLabel(div) + " ist keine gültige Emailadresse!";
                }
            }
        } catch(e) {
            console.error(e);
        }
    },
    getFieldLabel: function(f) {
        return f.down('.form-field-label').innerHTML.stripTags().strip().gsub(/\s*\*?\s*:?\s*$/,"");
    },
    checkMandatory: function(f, serializedForm) {
        var v = serializedForm[f.name]; //f.getValue();
        return !!v && v.toString().strip().length > 0;
    },
    checkEmail: function(f, serializedForm) {
        var val = serializedForm[f.name];
        return !val || /^([\w]+)(.[\w]+)*@([\w-]+\.){1,5}([A-Za-z]){2,4}$/.test(val);
    }
});