if (Object.isUndefined(Formalized)) {
    var Formalized = {};
};
Formalized = Class.create({
    initialize:function(options) {
        this.options = options || {};
        this.isIE6 = Prototype.Browser.IE && typeof document.body.style.maxHeight == "undefined";
        this.getUIitems();
        this.setupSelects(this.fakeSelects, this.selects);
        this.setupCheckboxes();
        this.setupCommandButtons();
        this.setupFileInputs();
        this.captureEnterKey();
    },

    extendArray: function(arrayToExtend){
        var tmpArray = [];
        for(var i=0; i<arrayToExtend.length; i++){
            tmpArray[i] = Element.extend(arrayToExtend[i]).addClassName("isFormalized");
        }
        return tmpArray;
    },

    getUIitems:function() {
        this.selects = this.extendArray(Sizzle("select:not(.listbox, .isFormalized)"));
        this.fakeSelects = this.extendArray(Sizzle(".select:not(.isFormalized)"));
        this.selectManyCheckboxes = this.extendArray(Sizzle(".selectManyCheckboxes input[type=checkbox]:not(.isFormalized)"));
        this.selectManyMappedRealCheckboxes = this.extendArray(Sizzle(".selectManyMappedRealCheckboxes input[type=checkbox]:not(.isFormalized)"));
        this.selectManyMappedFakeCheckboxes = this.extendArray(Sizzle(".selectManyMappedFakeCheckboxes input[type=checkbox]:not(.isFormalized)"));
        this.booleanCheckboxes = this.extendArray(Sizzle("input[type='checkbox']:not(.isFormalized)"));
        this.commandButtons = this.extendArray(Sizzle(".command-button:not(.isFormalized)"));
        this.fileInputs = this.extendArray(Sizzle("input[type='file']:not(.custom, .isFormalized)"));
        this.forms = this.extendArray(Sizzle("form"));

    },
    /**
     * Capture the enter key for forms
     */
    captureEnterKey:function() {
        this.forms.each(function(form){
            this.getProgressLinks(form);
            form.observe("click", function() {
                form.observe("keyup", function(e) {
                    if ((e.keyCode == 13) && (e.element().tagName.toLowerCase() != "textarea") && (e.element().tagName.toLowerCase() != "select")) {
                        var test = form.select(".action-button a")[0].readAttribute("onclick");
                        if(test){
                            var newTest = "function woohoo(){var event = {target: test}; BI.Custom.A4JEnter = true;" + test + "}; woohoo();";
                            eval(newTest);
                        } else {
                            test = form.select(".action-button a")[0].readAttribute("href");
                            eval(test);
                        }
                    }
                }.bind(this));
            }.bind(this));
        }.bind(this));
    },

    getProgressLinks: function(form) {
        form.select("a.useProgress").each(function(button) {
            button.observe("click", function() {
                this.triggerProgress(button);
            }.bind(this));
        }.bind(this));
    },

    /**
     * Create Checkbox behaviors
     */

    setupCheckboxes: function() {
        this.handleBooleanCheckboxes();
        this.handleSelectManyCheckboxes();
        this.handleSelectManyMappedCheckboxes();

    },

    handleBooleanCheckboxes: function() {
        this.booleanCheckboxes.each(function(checkbox) {
            //checks if checkbox is in admin tool
            if (checkbox.getStyle('display') != 'block') {
                this.hidecheckboxInIE6(checkbox);
                this.restoreCheckbox(checkbox);
                checkbox.up().previous().observe(atx.clickEvent, this.replicateSelection);
            }
        }.bind(this));
    },

    handleSelectManyCheckboxes: function() {
        this.selectManyCheckboxes.each(function(checkbox) {
            this.insertFakeCheckbox(checkbox);
            this.hidecheckboxInIE6(checkbox);
            this.restoreCheckbox(checkbox);
            checkbox.up().previous().observe(atx.clickEvent, this.replicateSelection);
        }.bind(this));
    },

    handleSelectManyMappedCheckboxes: function() {
        this.selectManyMappedFakeCheckboxes.each(function(checkbox, i) {
            checkbox.up().previous().observe(atx.clickEvent, this.replicateMappedSelection.bindAsEventListener(this, i));
            checkbox.remove();
        }.bind(this));
    },

    insertFakeCheckbox: function(checkbox) {
        var label = checkbox.next(0);
        if (label != null) {
            var labelValue = label.firstChild.nodeValue;
            label.remove();
            checkbox.insert({before:"<a class='fakeCheckbox'>" + labelValue + "</a>"});
            checkbox.wrap("span", {"className":"atxCheckboxContainer"});
        }
    },

    restoreCheckbox: function(checkbox) {
        if (checkbox.checked) {
            checkbox.up().previous().addClassName('selected');
        }
    },

    replicateSelection: function(e) {
        var fakeCheckbox = e.element();
        var realCheckbox = fakeCheckbox.next().getElementsByTagName('input')[0];
        realCheckbox.click();
        fakeCheckbox.toggleClassName('selected');
    },

    replicateMappedSelection: function(e, i) {
        var fakeCheckbox = e.element();
        var realCheckbox = this.selectManyMappedRealCheckboxes[i];
        realCheckbox.click();
        fakeCheckbox.toggleClassName('selected');
    },

    hidecheckboxInIE6: function(checkbox) {
        checkbox.addClassName('realCheckbox');
    },

    removeCheck:function(realCheckbox) {
        realCheckbox.checked = false;
        realCheckbox.up().previous().toggleClassName('selected');
    },



    /**
     * Create Selects behaviors
     * @param fakeSelects
     * @param selects
     */
    setupSelects:function(fakeSelects, selects) {
        if (Object.isUndefined(fakeSelects)) return;
        fakeSelects.each(function(selectContainer, i) {
            var realSelect = selects[i];
            this.selectForIE(selectContainer, realSelect);
            this.enableSelect(realSelect);
            selectContainer.addClassName('skinned-select');
            this.insertLabel(realSelect);
            this.disableSelect(selectContainer, realSelect);
            this.getSelectedValue(realSelect);
            this.observeFocus(realSelect);
            this.observeChange(realSelect);
            selectContainer.up().previous().hide();
            realSelect.up().up().show();
        }.bind(this));
    },
    enableSelect:function(target) {
        if (Object.isUndefined(target)) return;
        $(target).observe('change', function() {
            if ($(target).parentNode.hasClassName('disabled')) $(target).parentNode.removeClassName('disabled');
        });
    },
    disableSelect:function(selectContainer, target) {
        if (Object.isUndefined(target)) return;
        if ($(target).getAttribute("disabled")){
            $(selectContainer).addClassName("disabled");
        } else {
            $(selectContainer).removeClassName("disabled");
        }
    },
    getSelectedValue:function(realSelect) {
        //var test=document.location.href.toQueryParams();
        if (Object.isUndefined(realSelect)) return;
        if ($(realSelect).options.selectedIndex == 0) {
            $(realSelect).previous().update($(realSelect).options[$(realSelect).selectedIndex].firstChild.nodeValue);
        } else {
            $(realSelect).previous().update($(realSelect).options[$(realSelect).selectedIndex].firstChild.nodeValue);
        };
    },

    observeFocus: function(realSelect) {
        $A([realSelect]).each(function(realSelect) {
            realSelect.observe("focus", this.handleSelectFocus.bindAsEventListener(this));
            realSelect.observe("blur", this.handleSelectBlur.bindAsEventListener(this));
        }.bind(this));
    },

    handleSelectFocus: function(e) {
        var realSelect = e.element();
        realSelect.previous().setStyle({
            color: '#06c'
        });

        realSelect.observe('keypress', function(e) {
            var selectValue;

            if(e.keyCode == '38') {
                var currentValueIndex = realSelect.selectedIndex;
                selectValue = realSelect.options[realSelect.selectedIndex].firstChild.nodeValue;
                realSelect.previous().update(selectValue);
            }
            if(e.keyCode == '40') {
                var currentValueIndex = realSelect.selectedIndex;
                selectValue = realSelect.options[realSelect.selectedIndex].firstChild.nodeValue;
                realSelect.previous().update(selectValue);
            }
        });
    },

    handleSelectBlur: function(e) {
        var realSelect = e.element();
        realSelect.previous().setStyle({
            color: '#333'
        });
        realSelect.stopObserving('keypress');
    },

    observeChange:function(realSelect) {
        $A([realSelect]).each(function(item) {
            item.observe("change", (function() {
                item.previous().update(item.options[item.selectedIndex].firstChild.nodeValue);
            }.bind(this)));
        }.bind(this));
    },
    insertLabel:function(realSelect) {
        if (realSelect.options[0] != undefined) {
            $(realSelect).insert({before:'<div class="select-text">' + realSelect.options[0].firstChild.nodeValue + '</div>'});
        } else {
            realSelect.insert({before:'<div class="select-text">' + "No Options Available" + '</div>'});
        }
    },
    selectForIE: function(selectContainer, realSelect) {
        if (this.isIE6) {
            var dummyOptions = [];
            var existingOptions = realSelect.childElements().each(function(i, index) {
                dummyOptions += "<a href='javascript://' rel='" + index + "'>" + i.firstChild.nodeValue + "</a>";
            });
            var dummyOptionsWrapper = new Element("div", { "class" : "dummyOptionsWrapper" }).insert(dummyOptions).hide();
            selectContainer.insert({ top : dummyOptionsWrapper });
            realSelect.hide();
            this.watchIEclicks(dummyOptionsWrapper, selectContainer, realSelect);
         }
    },

    watchIEclicks: function(dummy, container, real) {
        container.observe("click", function(e) {
            if (!container.hasClassName("disabled")) {
                document.body.click();
                dummy.toggle();
                container.setStyle({ zIndex : "2" });
                e.stop();
            }
        });

        dummy.descendants().each(function(i) {
            var c = i.up("div.select");
            var s = c.down("select");
            i.observe("click", function(e) {
                e.stop();
                s.options[i.readAttribute("rel")].selected = true;
                c.down(".select-text").update(i.firstChild.nodeValue);
                if (s.hasAttribute("onchange")) { s.onchange(); }
                dummy.toggle();
                container.setStyle({ zIndex : "1" });
            });
        });

        document.observe("click", function() {
            container.setStyle({ zIndex : "1" });
            dummy.hide();
        });

//        container.observe("click", function(e) {
//            if (e.element() !== null) {
//                if((e.element().descendantOf(container) || e.element() == container) && !e.element().up("div.select").hasClassName("disabled")) {
//                    e.stop();
//                    dummy.toggle();
//                    if (e.element().descendantOf(dummy) || e.element() == dummy) {
//                        e.stop();
//                        real.options[e.element().readAttribute("rel")].selected = true;
//                        container.down(".select-text").update(e.element().firstChild.nodeValue);
//                        alert(real.innerHTML + " | " + real.nodeValue)
//                        alert(e.element().innerHTML + " | " + e.element().nodeValue)
//                        if (real !== null && real.onchange()) { real.onchange(); }
//                    } else {
//                        e.stop();
//                        container.setStyle({ zIndex : "999999" });
//                    }
//                } else {
//                    container.setStyle({ zIndex : "999998" });
//                    dummy.hide();
//                }
//            }
//        });
    },

    /**
     * Command Buttons
     */
    setupCommandButtons: function() {
        this.checkForCommandButton();
    },
    checkForCommandButton: function() {
        if (this.commandButtons) this.replaceCommandButton();
    },
    replaceCommandButton: function() {
        this.commandButtons.each(function(button, i) {
            var text = button.value;
            var buttonContainer = button.up();
            var fakeButton = new Element('a', {id: 'submit' + i}).update(text);
            buttonContainer.insert({bottom:fakeButton});
            if (button.disabled) {
                buttonContainer.addClassName('disabled-action-button');
            } else {
                fakeButton.observe('click', this.performFormAction.bindAsEventListener(this, button));
            }
        }.bind(this));
    },

    triggerProgress: function() {
        var doc = $("page-container");
        var docHeight = (doc.getHeight() + 6).toString();
        var allModalWrapper = new Element("div", { "id" : "modal-interupt-wrapper" });
        var interuptText = new Element("p", { "class" : "interupt-text" }).update("Loading...");
        var modalInterupt = new Element("div", { "class" : "modal-interupt" }).setStyle({ background : "#fff url(/img/theme1/shared/icons/ajax-loader.gif) center center no-repeat" }).update("&#160;");
        var overlay = new Element("div", { "class" : "modal-overlay" }).setStyle({ opacity : ".5", height : docHeight + "px" });
        doc.insert({ before : allModalWrapper });
        allModalWrapper.insert({ top : overlay });
        overlay.insert({ top : modalInterupt });
        modalInterupt.insert({ top : interuptText });
    },

    clearModalInterupt: function() {
        $("modal-interupt-wrapper").remove();
    },

    performFormAction: function(x, button) {
        button.click();
        if (button.hasClassName("useProgress")) { this.triggerProgress(); }
    },

    /**
     * File Inputs
     */
    setupFileInputs: function() {
        this.fileInputs.each(function(fileInput) {
            new StyledFileInput(fileInput);
        }.bind(this));
    },

    /**
     * Textareas
     */

    updateTextarea: function(elementReference, message) {
        var textarea = $(elementReference).previous().select('textarea').reduce();
        textarea.observe('focus', function() {
            if (textarea.value == message) {
                textarea.value='';
            }
        });
        textarea.value = message;
    },

    updateInputText: function(elementReference, message) {
        var input = $(elementReference).previous().select('input[type=text]').reduce();
        input.observe('focus', function() {
            if (input.value == message) {
                input.value='';
            }
        });
        input.value = message;
    },

    maxLength: function(elementReference, maxCharacters, errorMessage) {
        var textarea = $(elementReference).previous().select('textarea').reduce();
        var label = $(elementReference).previous().select('label').reduce();
        var isMaxedOut = false;
        var maxChars = maxCharacters;

        textarea.observe('keyup', function() {
            if(textarea.value.length > maxChars) {
                label.setStyle({color:'#ff0000'});
                if (!isMaxedOut) {
                    var errorMessageTemplate = new Template('<span class="errormsg">#{errorMsg}</span>');
                    var newErrorMessage = errorMessageTemplate.evaluate({errorMsg:errorMessage});
                    $(elementReference).insert({after:newErrorMessage});
                    isMaxedOut = true;
                }
                textarea.value = textarea.value.substring(0, maxChars);
            } else if (isMaxedOut && textarea.value.length < maxChars) {
                label.setStyle({color:'#333333'});
                $(elementReference).next().remove();
                isMaxedOut = false;
            }
        });
    }
});


var StyledFileInput = Class.create({
    initialize: function(fileInput) {
        this.fileInput = fileInput;
        console.log('The file input is, ', this.fileInput );
        this.fakeFileInputTemplate = new Template('<div class="fakeFileInput clearfix"><div class="action-button-wrapper secondary action-button-right clearfix"><div class="action-button"><span class="action-indicator">&#160;</span><a>#{action}</a></div></div><div class="input-container"><div class="input-wrapper"><input type="text" maxlength="80"/></div></div></div>');
        this.setupFileInput();
        this.resizeFakeInput();
    },

    setupFileInput: function() {
        this.createFakeFileInput(this.fileInput);
        this.fakeFileInput.value = this.fileInput.value;
        this.fileInput.observe('change', this.createFileSelection.bindAsEventListener(this));
        this.fakeBrowseButton.observe('click', this.recreateFileSelection.bindAsEventListener(this));
    },

    createFakeFileInput:function() {
        this.fileInput.wrap('div', {'className': 'file-input clearfix'});
        this.fileInput.parentNode.setStyle({width:this.fileInput.getWidth() + 'px'});
        this.fileInput.addClassName('realFileInput');
        var fakeFileInput = this.fakeFileInputTemplate.evaluate({content:'Browse for an image', action:'Browse'});
        this.fileInput.insert({after:fakeFileInput});

        // Cache new elements
        this.fakeBrowseButton = this.fileInput.next().down().select('a').reduce();
        this.fakeFileInputContainer = this.fileInput.next().down().next();
        this.fakeFileInput = this.fileInput.next().select('input[type=text]').reduce();
        this.resetFileInput = this.fileInput.cloneNode(true);
        this.resetFileInputId = this.resetFileInput.id;
        this.resetFileInput.id = 'ridonkTempId';
    },

    resizeFakeInput: function() {
        var fakeInputWidth = this.fileInput.getWidth() - this.fileInput.next().down().getWidth() - 15;
        this.fakeFileInputContainer.setStyle({
            width:fakeInputWidth + 'px'
        });
    },

    createFileSelection: function() {
        if (this.fileInput.value != '') {
            this.fakeBrowseButton.update('Remove');
            this.fakeFileInput.value = this.fileInput.value;
            this.fileInput.setStyle({
                visibility:'hidden'
            });
        }
    },

    recreateFileSelection: function() {
        if (this.fileInput.value != '') {
            this.fakeBrowseButton.update('Browse');
            this.fakeFileInput.value = '';
            this.fileInput.stopObserving('change');
            this.fakeBrowseButton.stopObserving('click');
            this.fileInput.remove();
            this.fileInput = this.resetFileInput.cloneNode(true);
            this.fileInput.id = this.resetFileInputId;
            this.fakeFileInput.up().up().up().insert({before:this.fileInput});

            this.resetDependencies();
        };
    },

    resetDependencies: function() {
        this.fakeBrowseButton = this.fileInput.next().down().select('a').reduce();
        this.fakeFileInput = this.fileInput.next().select('input[type=text]').reduce();
        this.fileInput.observe('change', this.createFileSelection.bindAsEventListener(this));
        this.fakeBrowseButton.observe('click', this.recreateFileSelection.bindAsEventListener(this));
    }

});



var styleForms;
document.observe("dom:loaded", function() {
    styleForms = new Formalized();
});
