var ds_Plugin_Form = ds_Base.extend({

    formElm: null,
    data: null,
    isValid: false,
    currentStep: 0,
    previousButton: null,
    titleElm: null,

    options: {
        onValid:null,
        setUrlFormatter: false,
        setDropdowns: true,
        wizardInstanceKey: '',
        scroll: true,
        titleElm: null
    },

    initialize: function(options) {

        // Implement given options
        this.setOptions(options);
        this.formElm = options.form;

        this.errorContainers = [];
        if ($type(options.onValid) === 'function') {
            this.onValid = options.onValid.bind(this);
        }

        if (this.options.setUrlFormatter) {
            this.setUrlFormatter();
        }

        if (this.options.titleElm) {
            this.titleElm = this.options.titleElm;
        } else {
            this.titleElm = false;
        }

        if ($defined(this.formElm.getElement('.submit input'))) {
            this.replaceSubmitButton();
        }

        this.setRequiredLabels();

        if (this.formElm.getElements('fieldset').length > 1) {
        //this.setWizardFromFieldsets();
        }

        if (this.options.setDropdowns){
            this.initDropdowns();
        }

        this.initFileSelects();

        this.initColorpickers();

        this.initDatepickers();

        this.initHasManies();

        this.initRegionWizards();

        this.initInputFilters();

    },

    replaceSubmitButton: function () {
        var aSubmit = new Element('a').addClass('optionSave').setProperty('href', 'javascript:void(0);').setText('Opslaan');
        this.formElm.getElement('.submit input').replaceWith(aSubmit);
    },

    setRequiredLabels: function (form) {
        $each(this.formElm.getElements('label.required'), function (el) {
            if (el.getText().substring(el.getText().length-1) != '*') {
                el.setText(el.getText() + ' *');
            }
        });
    },

    initDatepickers: function () {

        $each(this.formElm.getElements('input.datefield'), function (el) {
            var elmId = $(el).getAttribute('id');
            var initObj = {};
            initObj['' + elmId] = 'd-m-Y';
            var cal = new Calendar(initObj, { classes: ['dashboard'], direction: 0 });
            //console.log(initObj);
        });
    },

    initHasManies: function () {
        $each(this.formElm.getElements('.hasmanyfield'), function (el) {
            var hasMany = this.getHasMany({
                element: el.getElement('table'),
                key:el.getElement('table').getProperty('id')
            });
        }, this);
    },

    initDropdowns: function () {
        this.formElm.getElements('select').each(function (elm) {

            var currentDropdown = $(elm);
            var elmId = $(elm).getProperty('id');
            currentDropdown.getElements('option').each(function(option) {
                option.addClass('icon-' + option.value);
            });

            currentDropdown = this.getDropdown({
                key             : elmId,
                selectId	: elmId,
                width		: 271,
                hiddenInput : true
            });

        }, this);
    },

    initFileSelects: function () {
        this.formElm.getElements('input').each(function (elm) {
            if (elm.getParent().hasClass('filebox')) {
                var currentFileSelectContainer = $(elm).getParent();
                var elmId = $(elm).getProperty('id');
                var ddHeight = $(elmId).getProperty('outy').toInt() + 54;
                $(elm).getParent().setStyle('height', ddHeight);
                var filterValue = $(elm).getProperty('filter');
                var addButton = currentFileSelectContainer.getElement('.addFile').getProperty('title');

                var entityLabelValue = addButton.substring(0, addButton.length -9 );

                this.getFileSelector({
                    elm: currentFileSelectContainer,
                    key: elmId,
                    sampleOutputSizeX: $(elmId).getProperty('outx'),
                    sampleOutputSizeY: $(elmId).getProperty('outy'),
                    filter: filterValue,
                    entityLabel: entityLabelValue
                });
            }
        }, this);
    },

    initColorpickers: function() {
        this.formElm.getElements('input').each(function (elm) {
            if (elm.getParent().hasClass('colorpicker')) {
                this.getColorSelector($(elm).getProperty('id'), this.options.wizardInstanceKey);
            }
        }, this);
    },

    initRegionWizards: function() {
        this.formElm.getElements('input').each(function (elm) {
            if (elm.getParent().hasClass('regionWizard')) {
                this.getRegionSelector({
                    'elm' : $(elm).getProperty('id')
                    });
            }
        }, this);
    },

    initInputFilters: function() {

        this.formElm.getElements('input.numeric').each(function(elmInput) {
            this.forceNumericValueToElement($(elmInput).getAttribute('name'));
        }, this);
    },

    addErrorMsg: function(elm, msg) {

        $(elm).getParent().addClass('error');
        var currentHeight = this.numerateString($(elm).getParent().getStyle('height')).toInt() + 35;
        if (currentHeight == 70) {
            $(elm).getParent().setStyle('height', currentHeight + 'px');
        }
        var elmName = $(elm).getProperty('name');

        if ($defined($(elm).getParent().getElement('p.errormsg'))) {
            $(elm).getParent().getElement('p.errormsg').remove();
        }

        if ($defined(this.errorContainers.elmName)) {
            this.errorContainers.elmName.empty();
            this.errorContainers.elmName = new Element('p').addClass('errormsg').setText(msg).inject($(elm).getParent());
        } else {
            this.errorContainers.elmName = new Element('p').addClass('errormsg').setText(msg).inject($(elm).getParent());
        }


    },

    removeErrorMsg: function(elm) {
        $(elm).getParent().removeClass('error');
        if ($defined($(elm).getParent().getElement('p.errormsg'))) {
            $(elm).getParent().getElement('p.errormsg').remove();
            var currentHeight = this.numerateString($(elm).getParent().getStyle('height')).toInt() - 35;
            $(elm).getParent().setStyle('height', currentHeight + 'px');
        }
    },

    addInfoMsg: function(elm, msg) {
        if ($defined($(elm + "_infoMsg"))) {
            $(elm + "_infoMsg").setText(msg);
        }
        var infoMsg = new Element('p').setProperty('id', elm + "_infoMsg").addClass('infomsg').setText(msg).injectInside($(elm).getParent());
        $(infoMsg).getParent().setStyle('height','45px');
    },

    processForm: function() {
        // Define the processed form
        var ed = null, sText = '';
        this.processedForm = $(this.formElm);

        // Bind the function which has to be fired after completion
        var validateForm = this.validateForm.bind(this);

        ed = null;
        sText = '';
        this.processedForm.getElements('.advancedTiny textarea').each(function ( el ){
            var sId = el.getProperty('id');
            ed = tinyMCE.get(sId);
            if ($defined(ed)) {
                sText = ed.getContent();
                sText = sText.replace(/<([a-z][a-z0-9]*)[^>]*><\/\1>/ig,"<$1>");
                tinyMCE.execCommand('mceRemoveControl', false, sId);
                $(sId).value = sText;
            }
        });

        ed = null;
        sText = '';
        this.processedForm.getElements('.simpleTiny textarea').each(function ( el ){
            var sId = el.getProperty('id');
            ed = tinyMCE.get(sId);
            if ($defined(ed)) {
                sText = ed.getContent();
                sText = sText.replace(/<([a-z][a-z0-9]*)[^>]*><\/\1>/ig,"<$1>");
                tinyMCE.execCommand('mceRemoveControl', false, sId);
                $(sId).value = sText;
            }
        });

        this.processedForm.getElements('input').each(function ( el ){
            if (el.disabled) {
                el.disabled = false;
            }
        });

        this.processedForm.getElements('select').each(function ( el ){
            if (el.disabled) {
                el.disabled = false;
            }
        });

        this.processedForm.getElements('textarea').each(function ( el ){
            if (el.disabled) {
                el.disabled = false;
            }
        });
        // Send AJAX request
        this.processedForm.send({
            onComplete: validateForm
        });
    },

    validateForm: function(sResponse) {
        // Evaluate server response
        var oResponse = Json.evaluate(sResponse);

        this.formSent = false;
        this.isValid = oResponse.valid;
        // Function to execute if server response is valid
        if(oResponse.valid) {

            // Remove error classes
            this.processedForm.getElements('input').each(function(el) {
                el.removeClass('iError');
            });

            // Remove previous error messages
            this.processedForm.getElements('.errormsg').each(function(el) {
                el.remove();
            });
            this.data = oResponse.data;
            if ($type(this.options.onValid) == 'function') {
                this.options.onValid(oResponse.data);
                return false;
            }
            if ($type(this.options.onValid) == 'string') {
                switch(this.options.onValid) {
                    default:
                        document.location.href = oResponse.redirect;
                        break;
                }
            }


        // Redirect to the defined tab
        //document.location.href = oResponse.redirect;



        } else {
            // Remove error classes
            this.processedForm.getElements('input').each(function(el) {
                el.removeClass('iError');
            });

            // Remove previous error messages
            this.processedForm.getElements('.errormsg').each(function(el) {
                el.remove();
            });

            // For each error do
            $each(oResponse.errors, function(errorMessage, fieldName) {
                var formElement = null;
                formElement = this.processedForm.getElement('input[name^=' + fieldName + ']');
                if (formElement === null) {
                    formElement = this.processedForm.getElement('select[name^=' + fieldName + ']');
                }
                if (formElement === null) {
                    formElement = this.processedForm.getElement('textarea[name^=' + fieldName + ']');
                }

                // Find the dataHolder (<dd>) of the form element\
                var dataHolder = $(formElement).getParent();

                while($(dataHolder).getTag() != 'dd') {

                    dataHolder = $(dataHolder).getParent();

                }

                if(formElement.getProperty('type') == 'text' || formElement.getProperty('type') == 'select' || formElement.getProperty('type') == 'hidden' || formElement.getProperty('type') == 'password') {
                    $(dataHolder).addClass('iError');
                    $(dataHolder).getPrevious().addClass('iError');
                    $(formElement).value = '';

                } else if (formElement.getTag() == 'textarea'){
                    if ($(formElement).getParent().hasClass('simpleTiny')) {
                        $(dataHolder).addClass('iErrorSimpleTiny');
                        $(dataHolder).getPrevious().addClass('iErrorSimpleTiny');
                    } else if ($(formElement).getParent().hasClass('advancedTiny')) {
                        $(dataHolder).addClass('iErrorAdvancedTiny');
                        $(dataHolder).getPrevious().addClass('iErrorAdvancedTiny');
                    } else {
                        $(dataHolder).addClass('iErrorTextarea');
                        $(dataHolder).getPrevious().addClass('iErrorTextarea');
                    }

                } else {
                    $(formElement).checked = false;
                }

                if ($type(errorMessage) == 'object') {
                    $each(errorMessage, function(msg, key){
                        // Place the error message in the dataHolder
                        var oError = new Element('p').addClass('errormsg').setHTML(msg).inject(dataHolder);
                    });
                } else {

                    // Place the error message in the dataHolder
                    var oError = new Element('p').addClass('errormsg').setHTML(errorMessage).inject(dataHolder);
                }

            }, this);
            if (this.options.scroll) {
                this.scrollToTop($(this.formElm));
            }
            // hide the loading animation
            this.hideOverlay();

            if(oResponse.db_error) {

                this.showError('Systeemfout!', oResponse.db_error);
                this.processedForm.getParent().empty();
            }

            this.initTinyMceSimple();
            this.initTinyMceAdvanced();

            var fieldsets = this.processedForm.getElements('fieldset');
            var errorsInFieldset;
            var bActive = false;
            if (fieldsets.length > 1) {
                if (this.options.wizardInstanceKey !== '') {
                    var wizard = this.getWizard(this.options.wizardInstanceKey);
                    var i = 0;
                    $each(fieldsets, function (elm) {
                        if(!bActive) {
                            errorsInFieldset = elm.getElements('p.errormsg');
                            if (errorsInFieldset.length > 0) {
                                wizard.setActiveFieldset(i);
                                bActive = true;
                            }
                            i++;
                        }
                    });
                } else {
                    var i = 0;
                    $each(fieldsets, function (elm) {
                        if(!bActive) {
                            errorsInFieldset = elm.getElements('p.errormsg');
                            if (errorsInFieldset.length > 0) {
                                this.setActiveFieldset(i);
                                bActive = true;
                            }
                            i++;
                        }
                    }, this);
                }
            }
        }
    },

    initTinyMceSimple: function () {
        $(this.formElm).getElements('.simpleTiny textarea').each(function(elm) {
            tinyMCE.init({
                mode : "exact",
                elements : elm.getProperty('id'),
                theme : "advanced",
                language : "nl",
                height: "200px",
                width: "367px",
                plugins: "inlinepopups,style,advhr,insertdatetime,print,paste,directionality,visualchars",
                theme_advanced_buttons1: "tekstopmaak,bold,italic,underline,strikethrough,separator,undo,redo,removeformat",
                theme_advanced_buttons2: "link,unlink,bullist,numlist,charmap",
                theme_advanced_buttons3: "",
                theme_advanced_toolbar_location : "top",
                theme_advanced_toolbar_align : "left",
                cleanup_on_startup : true,
                extended_valid_elements: "p[id|class|style],a[class|name|href|target|title],img[class|src|mce_src|border=0|alt|title|width|height|align|onmouseover|onmouseout|name|obj|param],hr[class|width|size|noshade],font[face|size|color|style],span[class|align|style],div[align],hr,br,strike,sub,sup",
                document_base_url : "/",
                convert_urls : false,
                force_br_newlines : true,
                flashaudio : true,
                flashvideo : true,
                forced_root_block : "p"
            });
        });
    },

    initTinyMceAdvanced: function () {
        $(this.formElm).getElements('.advancedTiny textarea').each(function(elm) {
            tinyMCE.init({
                mode : "exact",
                elements : elm.getProperty('id'),
                theme : "advanced",
                language : "nl",
                height: "305px",
                width: "367px",
                plugins: "inlinepopups,media,style,table,advhr,advimage,insertdatetime,contextmenu,paste,directionality,visualchars",
                theme_advanced_buttons1: "tekstopmaak,bold,italic,underline,strikethrough,forecolor,separator,justifyleft,justifycenter,justifyright,justifyfull,separator,bullist,numlist,separator,outdent,indent,separator,sub,sup",
                theme_advanced_buttons2: "interactiviteit,link,unlink,anchor,separator,invoegen,image,media,charmap,hr,insertdate,inserttime,separator,overigen,undo,redo,removeformat,pasteword",
                theme_advanced_buttons3: "tablecontrols,fontselect",
                theme_advanced_toolbar_location : "top",
                theme_advanced_toolbar_align : "left",
                cleanup_on_startup : true,
                extended_valid_elements: "p[id|class|style],a[class|name|href|target|title],img[class|src|mce_src|border=0|alt|title|width|height|align|onmouseover|onmouseout|name|obj|param],hr[class|width|size|noshade],font[face|size|color|style],span[class|align|style],div[align],hr,br,strike,sub,sup",
                document_base_url : "/",
                convert_urls : false,
                force_br_newlines : true,
                flashaudio : true,
                flashvideo : true,
                forced_root_block : "p"
            });
        });
    },

    getFormData: function() {
        return this.data;
    },

    setElmValue: function(elmName, elmValue) {
        $(this.formElm).getElement('input[name^=' + elmName + ']').setProperty('value', elmValue);
    },

    getElmValue: function(elmName) {
        if ($defined($(this.formElm).getElement('#' + elmName))) {
            return $(this.formElm).getElement('#' + elmName).getProperty('value');
        } else {
            return false;
        }
    },

    setElmEvent: function(elmName, eventType, fn) {
        $(this.formElm).getElement('#' + elmName).addEvent(eventType, fn);
    },

    setUrlFormatter: function() {
        $(this.formElm).getElement('#' + this.options.formatterSourceElm).addEvent('blur', this.formatUrl.bindWithEvent(this));
    },

    setColorPickerToElement: function(elmId) {
    //		var newRainbow = ;

    },

    forceNumericValueToElement: function(elmName) {
        $(this.formElm).getElement('#' + elmName).addEvent('keyup', this.filterNumericValue.pass([elmName], this));
    },

    filterNumericValue: function(elmName, evt) {
        var oldValue = $(elmName).getProperty('value');
        var newValue = $(elmName).getProperty('value').replace(/[^0-9]/ig, '');
        $(elmName).setProperty('value', newValue);
        if (oldValue !== newValue) {
            this.addErrorMsg(elmName, 'U kunt hier alleen cijfers opgeven');
        } else {
            this.removeErrorMsg(elmName);
        }
    },

    setWizardFromFieldsets: function() {

        this.removeLoadingAnimation();

        var fieldsets = [],  i = 0, ii = 0;
        var allFieldsets = this.formElm.getElements('fieldset');
        for (var i = 0; i < allFieldsets.length; i++){
            if (!allFieldsets[i].hasClass('skip')){
                fieldsets[ii] = allFieldsets[i];
                ii++;
            }
        }

        this.amountSteps = fieldsets.length;

        currentStep = this.getCurrentStep();
        if (this.amountSteps > 1) {
            var i = 0;
            $each(fieldsets, function(el) {
                var sStyle = (currentStep === i) ? 'block' : 'none';
                if (currentStep === i) {
                    if (this.titleElm){
                        this.setTitlesFromFieldset(el.getFirst().getText());
                    }
                }
                el.setStyle('display', sStyle);
                i++;
            }, this);
            this.addFormstepButtons();
        }
        if (this.amountSteps == 1) {
            this.addFormstepButtons();
            $each(fieldsets, function(el) {
                el.setStyle('display', 'block');
            });
        }
    },

    addFormstepButtons: function() {
        this.removeButtons();
        this.addButtonCancel();
        this.addButtonPrevious();
        this.addButtonNext();
    },

    removeButtons: function() {
        $E('.myrelations-buttonbar').empty();
    },

    getCurrentStep: function() {
        return this.currentStep;
    },

    setCurrentStep: function(currentStep) {
        this.currentStep = currentStep;
    },

    addButtonPrevious: function() {
        if(this.getCurrentStep() !== 0) {
            this.previousButton = this.getButton({
                icon:'previous',
                text:'Vorige',
                event:this.previousStep.bind(this),
                container: $E('.myrelations-buttonbar')
                });
        }
    },

    getButtonPrevious: function() {
        return this.previousButton;
    },

    addButtonNext: function() {

        if(this.getCurrentStep() !== this.amountSteps-1) {
            this.addButton({
                icon:'next',
                text:'Volgende',
                event:this.nextStep.bind(this)
                });
        } else {
            this.addButton({
                icon:'submit',
                text:'Opslaan',
                event:this.submitForm.bind(this)
                });
        }
    },

    addButtonCancel: function() {
        this.addButton({
            icon:'cancel',
            text:'Annuleren',
            event: this.cancelForm.bind(this)
            });
    },

    cancelForm: function() {
        if ($defined(this.options.cancelUrl)) {
            document.location.href = this.options.cancelUrl;
        } else {
            history.go(-1);
        }
    },

    addButton: function(button) {
        if ($type(button) == 'object') {
            button.container = $E('.myrelations-buttonbar');
            var buttonLink = this.getButton(button);
        } else {
            alert('Er is een fout opgetreden bij het opmaken van een button.');
        }
    },

    submitForm: function() {
        this.removeButtons();
        this.processForm();
    },

    previousStep: function() {
        this.currentStep--;
        this.setWizardFromFieldsets();
    },

    nextStep: function() {
        this.currentStep++;
        this.setWizardFromFieldsets();
        if (this.options.scroll) {
            this.scrollToTop($('header'));
        }
    },

    setActiveFieldset: function(step) {
        this.currentStep = step;
        this.setWizardFromFieldsets();
    },

    setTitlesFromFieldset: function (sText){
        if (this.titleElm) {
            this.titleElm.setText(sText);
        }
    }
});
