var DocLoad = {
    observers: $A(),
    observe: function(fun) {
        Event.observe(window, 'load', fun, false);
        DocLoad.observers.push(fun);
    },

    onLoad: function() {
        DocLoad.observers.each(function (fun){
            fun();
        });
    }
};

/*eCourt.smartInclude('popupWindow.css', 'lighting.css','lib/window.js');
eCourt.Popup = {
    TYPE_AJAX: 1,
    TYPE_IFRAME: 2,
    TYPE_HTML: 3,
    TYPE_DIV: 4,

    open: function(title, content, options) {
        var winContentId;
        var winOptions = Object.extend({
            title: title,
            className: 'bluelighting',
            destroyOnClose: true,
//            width: 400,
//            height: 300,
            modal: true,
            draggable: false,
            type: eCourt.Popup.TYPE_AJAX,
            zIndex: 500,
            minimizable: false,
            maximizable: false,
            onload: Prototype.emptyFunction,
            onBeforeShow: Prototype.emptyFunction,
            maxHeight: 4500
        }, options || {});

        var cWin = new Window(winOptions);
        if(winOptions.onClose) {
            Windows.addObserver({
                onDestroy: function(eventName, win) {
                    if (win == cWin) {
                        eval(winOptions.onClose);
                        Windows.removeObserver(this);
                    }
                }
            });
        }

        if(winOptions.type == eCourt.Popup.TYPE_AJAX) {
            cWin.setAjaxContent(content, {parameters: winOptions.parameters, postAjaxParameters: winOptions.postAjaxParameters}, true);

        } else if(winOptions.type == eCourt.Popup.TYPE_DIV) {
            if(winOptions.width) {
//                Element.setWidth(content, winOptions.width);
            }
            if(winOptions.height) {
//                Element.setHeight(content, winOptions.height);
            }

            cWin.setContent(content, true, true);

            Windows.addObserver({
                onDestroy: function(eventName, win) {
                    if (win == cWin) {
                        Element.hide(content);
                        Windows.removeObserver(this);
                    }
                }
            });

        } else if(winOptions.type == eCourt.Popup.TYPE_HTML) {
            cWin.setHTMLContent(content);
        } else if(winOptions.type == eCourt.Popup.TYPE_IFRAME) {
            cWin.setURL(content);
            if (Prototype.Browser.IE) {
                $(cWin.getId() + "_content").src = $(cWin.getId() + "_content").src;
            }
            winContentId = cWin.getId() + "_content";
            Event.observe($(winContentId), "load", winOptions.onload);
        }

        cWin.showCenter(winOptions.modal);
        return winContentId;
    },

    close: function() {
        Windows.closeAll();
    },

    resize:function(){
        Windows.windows.each(function(i){
            i.updateHeight();
        });
    }
}*/

var AutoSuggestControl = Class.create();
AutoSuggestControl.TYPE_JS = 1;
AutoSuggestControl.TYPE_AJAX = 2;

AutoSuggestControl.prototype = {
    initialize: function(textbox, items, options) {
        this.textbox = textbox;
        this.items = items;

         this.options = Object.extend({
             type: AutoSuggestControl.TYPE_JS,

             getItems: function(autoSuggest) {
                 return autoSuggest.items;
             },

             isMatch: function(value, match){
                 return match.toLowerCase().indexOf(value.toLowerCase()) == 0;
             },

             findMatches: function(autoSuggest) {

                var suggestions = new Array();
                var value = $F(autoSuggest.textbox);

                if(value.length > 0){
                    var items = autoSuggest.options.getItems(autoSuggest);

                    for(var i=0; i < items.length; i++) {
                        if(autoSuggest.options.isMatch(value, items[i])) {
                            suggestions.push(items[i]);
                        }
                    }
                }
                autoSuggest.suggest(suggestions);
            }

        }, options || {});

        this.textbox.onkeyup = this.onKeyUp.bindAsEventListener(this);
    },

    onKeyUp: function(event) {
         var keyCode = event.keyCode;
        //make sure not to interfere with non-character keys
        if(!(keyCode < 32 || (keyCode >= 33 && keyCode <= 46) || (keyCode >= 112 && keyCode <= 123))) {
            this.options.findMatches(this);
        }
    },

    suggest: function(suggestions) {
        if(suggestions.length > 0) {
            this.typeAhead(suggestions[0]);
        }
    },

    isRangeSupported: function() {
        return this.textbox.createTextRange || this.textbox.setSelectionRange;
    },

    typeAhead: function(suggestion) {
        if(this.isRangeSupported()){
            var length = this.textbox.value.length;
            this.textbox.value = suggestion;
            this.selectRange(length, suggestion.length);
        }
    },

    selectRange: function(start, length) {
        if (this.textbox.createTextRange) { //Internet Explorer
            var range = this.textbox.createTextRange();
            range.moveStart("character", start);
            range.moveEnd("character", length - this.textbox.value.length);
            range.select();
        } else if (this.textbox.setSelectionRange) { //Mozilla
            this.textbox.setSelectionRange(start, length);
        }
        this.textbox.focus();
    }
}

var TextBoxMessage = Class.create();
TextBoxMessage.onLoad = function() {
    $$('.textBoxMessage').each(function(label) {
        new TextBoxMessage($(label.readAttribute('for')), $(label).innerHTML);
        label.hide();
    });
};
TextBoxMessage.prototype = {
    initialize:function(textBox, defaultText, options) {
        this.textBox = $(textBox);
        this.defaultText = defaultText;

        this.options = Object.extend({
            removeBeforeSubmit: true,
            updateStyle: true
        }, options || {});

        Element.observe(this.textBox, 'focus', this.hideLabel.bindAsEventListener(this));
        Element.observe(this.textBox, 'blur', this.showLabel.bindAsEventListener(this));
        //Element.observe(this.textBox, 'onchange', this.hideLabel.bindAsEventListener(this));
        if(this.options.removeBeforeSubmit && this.textBox.form) {
            Element.observe(this.textBox.form, 'submit', this.hideLabel.bindAsEventListener(this));
        }
        this.showLabel();
    },

    showLabel: function() {
        if(this.textBox.value == '' || this.textBox.value == this.defaultText) {
            if(this.options.updateStyle) {
                this.textBox.addClassName('defaultTextBox');
            }
            this.textBox.value = this.defaultText;
        }
    },

    hideLabel: function() {
        if(this.options.updateStyle) {
            this.textBox.removeClassName('defaultTextBox');
        }

        if(this.textBox.value == this.defaultText) {
            this.textBox.value = "";
        }
    }
};
DocLoad.observe(TextBoxMessage.onLoad);

var TextElement = Class.create({
    generate: function(name, label, value, display) {
        var contents = new StringBuffer();
        contents.append(this.generateLeftSide(name, label, value, display));
        contents.append(this.generateRightSide(name, label, value, display));

        if(display.clear != false) {
            contents.append('<br style="clear:both;" />');
        }
        return contents.toString();
    },

    generateLeftSide: function(name, label, value, display) {
        var contents = new StringBuffer();
        if(display.showLabel != false) {
            contents.append('<div class="formLabel">');
            contents.append(label);
            contents.append('</div>');
        }
        return contents.toString();
    },

    generateRightSide: function(name, label, value, display) {
        var contents = new StringBuffer();
        contents.append('<div style="float:left;">');
        contents.append(this.generateFormElement(name, value, display));
        contents.append('</div>');
        return contents.toString();
    },

    generateFormElement: function(name, value, display) {
        var val = '<input type="text" name="' + name + '" value="'+value+'" size="40"';
        if(display.style) {
            val += ' style="' + display.style + '"';
        }
        if(display.className) {
            val += ' class="' + display.className +'"';
        }
        val += '  />';
        return val;
    }
});

var HiddenElement = Class.create(TextElement, {
    generateLeftSide: function(name, label, value, display) {
        return '';
    },

    generateRightSide: function(name, label, value, display) {
        return '<input type="hidden" name="' + name + '" id="' + name + '" value="' + value + '" />';
    }
});

var TextAreaElement = Class.create(TextElement, {
    generateFormElement: function(name, value, display) {
        return '<textarea name="' + name + '" cols="50" rows="5">' + value + '</textarea>';
    }
});

var CheckBoxElement = Class.create(TextElement, {
    generateFormElement: function(name, value, display) {
        return '<input type="checkbox" name="' + name + '" ' + (value==true?'checked="checked"':"") + '/>';
    }
});

var DatePickerElement = Class.create(TextElement, {
    generateFormElement: function($super, name, value, display) {
        display.className = 'addCalendar';
        return $super(name, value, display) +
               '<script type="text/javascript">HTMLUtils.addCalendar();</script>';
    }
});

var DropDownElement = Class.create(TextElement, {
    generateFormElement: function(name, value, display) {
        var contents = new StringBuffer();
        contents.append('<select name="').append(name).append('"');
        if(display.onChange) {
            contents.append(' onchange="');
            contents.append(display.onChange);
            contents.append('(this);" ');
        }
        contents.append('>');

        if(display.addBlank == true) {
            contents.append('<option value="">');
            if(display.blankText) {
                contents.append(display.blankText);
            }
            contents.append('</option>');
        }
        $H(display.options).each(function(optionPair){
            contents.append('<option value="'+optionPair.key+'"');
            if(value==optionPair.key) {
                contents.append(' selected="selected" ');
            }
            contents.append('>');
            contents.append(optionPair.value);
            contents.append("</option>");
        });
        contents.append('</select>');

        return contents.toString();
    }
});

var DropDownAjaxElement = Class.create(DropDownElement, {
    generate: function($super, name, label, value, display) {
        return $super(name, label, value, display) + '<div id="'+name+'dropAjaxContainer" class="dropAjaxContainer"></div>';
    },

    generateFormElement: function($super, name, value, display) {
        display.onChange = 'var f=DropDownAjaxElement.onChange.curry(\''+display.ajaxUrl+'\'); f';
        var contents = new StringBuffer();
        contents.append($super(name, value, display));
        if(value) {
            var formValues = $H();
            var i=0;
            if(display.formData.get(display.ajaxValuesKey)) {
                display.formData.get(display.ajaxValuesKey).each(function (formValue){
                    formValue.each(function (formValueItem) {
                        formValues.set(display.ajaxValuesKey + '[' + i + '].' + formValueItem.key, formValueItem.value);
                    });
                    i++;
                });
            }

            contents.append('<script type="text/javascript">');
            contents.append('DropDownAjaxElement.onLoad(\''+display.ajaxUrl+'\', \''+value+'\',\''+name+'dropAjaxContainer\', '+formValues.toJSON()+');');
            contents.append('</script>');
        }
        return contents.toString();
    }
});
DropDownAjaxElement.onLoad = function(url, value, element, data) {
    DropDownAjaxElement.currentElement = $(element);
    new Ajax.Request(url + value, {
        onSuccess: function(response) {
            var formItems = $H();
            eval(response.responseText);
            FormGenerator.update(DropDownAjaxElement.currentElement, formItems, data);
        }
    });
}
DropDownAjaxElement.onChange = function(url, element) {
    DropDownAjaxElement.currentElement = $(element).up().next('div .dropAjaxContainer');
    if(element.value) {
        new Ajax.Request(url + element.value, {
            onSuccess: function(response) {
                var formItems = $H();
                eval(response.responseText);
                FormGenerator.update(DropDownAjaxElement.currentElement, formItems);
            }
        });
    } else {
        Element.update(DropDownAjaxElement.currentElement, '');
    }
}

var ListElement = Class.create(TextElement, {
    generate: function(name, label, value, display) {
        var list = display.list;

        var contents = new StringBuffer();
        contents.append('<div class="formSectionLabel">');
        contents.append(label);
        contents.append('</div>');
        contents.append('<div id="').append(name).append('ContentList">');

        var i = 0;

        if(value != undefined && value.length != 0) {
            value.each(function(formValueItem) {
                if(i != 0 && !display.hideBreak == true) {
                    contents.append('<hr class="multItemHr" />');
                }
                contents.append(FormGenerator.generate(list, formValueItem, name + '['+i+'].'));
                i++;
            });
            i--;
        } else {
            contents.append(FormGenerator.generate(list, null, name + '[0].'));
        }


        contents.append('</div>');
        contents.append('<br />');

        ListElement.lists.set(name, {list: list, index: i});

        contents.append('<a class="formSectionAdd" href="javascript:;" onclick="ListElement.addElement(\''+name+'\');">')
                .append('Add ')
                .append(label.substring(0, label.length-1))
                .append('</a>');

        return contents.toString();
    }
});

ListElement.lists = $H();
ListElement.addElement = function(name) {
    var listValue = ListElement.lists.get(name);
    listValue.index++;
    FormGenerator.append(name + 'ContentList', listValue.list, null, name + '['+ listValue.index +'].');

};

var TextLabelElement =  Class.create(TextElement, {
    generateRightSide: function(name, label, value, display) {
        return '';
    }
});

var DivElement =  Class.create(TextElement, {
    generate: function(name, label, value, display) {
        return '<div id="'+name+'">'+ (value?value:'')+'</div>';
    }
});

var HtmlFormElement =  Class.create(TextElement, {
    generate: function(name, label, value, display) {
        return name;
    }
});

var FileElement = Class.create(TextElement, {
    generateRightSide: function(key, label, formValue, display) {
        return '<input type="file" name="' + key + '" id="' + key + '" />';
    }
});

var FormGenerator = {
    TYPE_HIDDEN: new HiddenElement(),
    TYPE_TEXT: new TextElement(),
    TYPE_TEXTAREA: new TextAreaElement(),
    TYPE_CHECKBOX: new CheckBoxElement(),
    TYPE_RADIO: new TextElement(),
    TYPE_DROPDOWN: new DropDownElement(),
    TYPE_DROPDOWN_AJAX: new DropDownAjaxElement(),
    TYPE_AUTOCOMPLETE: new TextElement(),
    TYPE_LIST: new ListElement(),
    TYPE_TEXTLABEL: new TextLabelElement(),
    TYPE_DIV: new DivElement(),
    TYPE_HTML: new HtmlFormElement(),
    TYPE_DATE_PICKER: new DatePickerElement(),
    TYPE_FILE: new FileElement(),

    generate: function(display, data, namePrepend) {
        display = $H(display);
        data = $H(data);

        var contents = new StringBuffer();
        display.each(function(pair) {
            var fieldName = pair.key;
            var fieldDefinition = pair.value;

            fieldDefinition.formDisplay = display;
            fieldDefinition.formData = data;

            var formValue = data.get(pair.key);
            if(formValue == undefined) {
                formValue = fieldDefinition.defaultValue;
                if(formValue == undefined) {
                    formValue = '';
                }
            }

            var label = fieldDefinition.displayString;
            if(label == undefined) {
                label = fieldName.labelize();
            }

            if(namePrepend != undefined) {
                fieldName = namePrepend + fieldName;
            }

            if(!fieldDefinition.type && fieldDefinition.typeClass) {
                fieldDefinition.type = new fieldDefinition.typeClass();
            }

            contents.append(fieldDefinition.type.generate(fieldName, label, formValue, fieldDefinition));
        });
        return contents.toString();
    },

    generateLabel: function(name, display) {
        if(display.displayString) {
            return display.displayString;
        } else {
            return name.labelize();
        }
    },

    append: function(element, display, data, namePrepend) {
        var value = FormGenerator.generate(display, data, namePrepend);
        Element.insert(element, '<hr class="multItemHr" /> ' + value, namePrepend);
    },

    update: function(element, display, data, namePrepend) {
        var value = FormGenerator.generate(display, data, namePrepend);
        Element.update(element, value, namePrepend);
    }
};



var AdminSystem = Class.create({
    MAIN_CONTAINER_ID: 'mainContainer',
    LIST_CONTAINER_ID: 'listContainer',
    FORM_CONTAINER_ID: 'editContainer',
    FORM_CONTAINER_CONTENT_ID: 'editContainerContents',
    FORM_CONTAINER_TITLE_ID: 'editContainerTitle',

    currentUrl: '',
    currentContainer: null,

    onEditForm: function(url, title, form, data) {
        return this.onEdit(url, title, FormGenerator.generate(form, data));
    },

    onEdit: function(url, title, contents) {
        this.currentUrl = url;
        this.sameEditWindow = this.currentTitle == title;
        this.currentTitle = title;
        $(this.FORM_CONTAINER_TITLE_ID).update(title);
        $(this.FORM_CONTAINER_CONTENT_ID).update(contents);
        this.showEdit();
    },

    onDelete: function(url, item) {
        if(confirm('Are you sure you want to delete ' +  + item)) {
            new Ajax.Request(url, {
                onSuccess: function() {
                    location.replace(window.location.href);
                }
            });
        }
        return false;
    },

    onSubmit: function(form) {
        if(form.enctype == 'multipart/form-data') {
            form.action = this.currentUrl;
            form.submit();
        } else {
            new Ajax.Request(this.currentUrl, {
                parameters: form.serialize(true),
                onSuccess: function() {
                    location.replace(window.location.href);
                }
            });
        }
        return false;
    },

    showEdit: function() {
        var editWindow = $(this.FORM_CONTAINER_ID);

        if(editWindow.visible() && this.sameEditWindow) {
            new Effect.BlindUp(editWindow, {duration: .5});
        } else {
            editWindow.hide();
            if(this.currentContainer != null && editWindow.up() != this.currentContainer) {
                $(this.currentContainer).appendChild(editWindow);
            }
            new Effect.BlindDown(editWindow, {duration: .5, queue:'end'});
        }
    },

    showList: function() {
        new Effect.BlindUp(this.FORM_CONTAINER_ID, {duration: .5});
    }
});

var HTMLUtils = {};
HTMLUtils.DragDrop = {
    registerDrop: function(elementId) {
        Droppables.add(elementId, {
            onDrop: function(element, droppable){
                if($(element.id + '_content')) {
                    droppable.value += $(element.id + '_content').innerHTML;
                } else {
                    droppable.value += element.innerHTML;
                }
            }
        });
    }
}

/*HTMLUtils.addCalendar = function() {
    $$('.addCalendar').each(function(element) {
        var id = element.identify();
        element.insert({
            after: '<img src="'+ eCourt.Path.IMAGES +'img.gif" id="' + id + '_cbn" alt="Date Select" style="cursor: pointer;" title="Date Select" onmouseover="this.style.background=\'blue\';" onmouseout="this.style.background=\'\'"/>'
        });

       Calendar.setup({
           inputField: element,
           ifFormat: "%m/%d/%Y",
           step: 1,
           button: id + '_cbn',
           align: "Bl",
           singleClick: true
       });

        element.removeClassName('addCalendar');
    });
};
DocLoad.observe(HTMLUtils.addCalendar);*/

HTMLUtils.addAutoGrowText = function() {
    $$('.addAutoGrowText').each(function(element) {
        var adjustHeight = function(element) {
            var rows = 1;
            while(rows == 1 || element.scrollHeight > element.clientHeight + 5) {
                element.setStyle({
                    height: (rows*17) +'px'
                });
                rows++;
            }
        };

        element.setStyle({
            overflowY: 'hidden'
        });

        adjustHeight(element);
        element.observe('keyup', function(event) {
            adjustHeight(event.element());

        });
        element.removeClassName('.addAutoGrowText');
    });
};
DocLoad.observe(HTMLUtils.addAutoGrowText);


HTMLUtils.addAutoComplete = function() {
    $$('.addAutoComplete').each(function(element) {
        var id = element.identify();
        element.hide();

        element.removeClassName('.addAutoComplete');
    });
}

if(Prototype.Browser.IE) {
    Event.observe(window, 'load', function() {
        var consoleDivLink = new Element('a', {
            href: 'javascript:;',
            style: 'font-size: 5px;'
        }).update('+');
        document.body.appendChild(consoleDivLink);
        consoleDivLink.observe('click', function() {$('ieConsoleDiv').toggle()});

        var consoleDiv = new Element('div', {
            id: 'ieConsoleDiv',
            style: 'display:none;'
        }).update('<div id="ieConsoleDivLog" style="height:100px;overflow:auto;border:1px solid #555;">Console ' + window.errLog + '</div><input type="text" id="ieConsoleDivTxt" style="width:100%;"/>');
        document.body.appendChild(consoleDiv);
        $('ieConsoleDivTxt').observe('keyup', function(event) {
            if(event.keyCode == Event.KEY_RETURN) {
                $('ieConsoleDivLog').insert('<div style="color:blue;border-bottom:1px solid #ccc;">&gt;&gt;' + $F('ieConsoleDivTxt') + '</div>');
                var output = '';
                try { output = eval($F('ieConsoleDivTxt')); } catch(e) { output = e.message; }
                $('ieConsoleDivLog').insert('<div style="border-bottom:1px solid #ccc;">' + output + '</div>');
            }
        });

        window.console = new Object();
        window.console.log = function(text) {
            $('ieConsoleDivLog').insert('<div style="color:green;border-bottom:1px solid #ccc;">' + text + '</div>');
        }
        window.onerror=function(msg, url, line) {
            $('ieConsoleDivLog').insert('<div style="color:red;border-bottom:1px solid #ccc;">Error: ' + msg + ' Line: ' + line + '</div>');
            return true;
        }
    });
}

var XmlUtils = {
    wrapInXml: function(tag, attributes, contents) {
        if(contents == undefined) {
            contents = attributes;
            attributes = undefined;
        }

        var output = new StringBuffer();
        output.append('<')
              .append(tag);
        if(attributes) {
            output.append(' ')
                  .append(attributes)
                  .append(' ');
        }
        output.append('>')
              .append(contents)
              .append('</')
              .append(tag)
              .append('>');
        return output.toString();
    },

    escapeXml: function(contents) {
        return String(contents).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;');
    }
};
