var trees = [];

var Forms = Rtk.Shared.Layout5.Forms;
var ObscureElements = Rtk.Shared.ObscureRenderedElements;

Rtk.TREE_ITEM_ASYNCHRONOUS_OPEN_THRESHOLD = 40;

Rtk.TreeItem = Class.create(Rtk.TreeItem, {
    listitem:
        function() {
            return $(this.root.cgi_name + '_item_' + this.index);
        },
    listitemlink:
        function() {
            return $(this.root.cgi_name + '_item_' + this.index + '_link');
        },
    renderChildren:
        function(sb) {

            if (!sb)
                sb = new Rtk.Util.StringBuilder();

            var child_list = new Element('ul');
            for (var i = 0, len = this.children.length; i < len; i++)
                this.children[i].render(sb);
            child_list.innerHTML = sb.toString();
            if(this.listitem()) {
                if (this.listitem().hasClassName('lastOpenTreeItem'))
                    child_list.style.border = 'none';
                this.listitem().appendChild(child_list);
            }
            for (var i = 0, len = this.children.length; i < len; i++)
                this.children[i].registerClickEvents();

            return child_list.innerHTML;

        },
    selectChildren:
        function(ev) {

            if(ev)
                Event.stop(ev);

            for (var i = 0, len = this.children.length; i < len; i++)
            {
                if(this.children[i].children.length == 0
                   && this.root.selected_items.indexOf(this.children[i]) == -1)
                    this.root.select(null,this.children[i].index);
            }

            this.open();
        },
    renderSpinner:
        function() {
            var spinner_div = new Element('div');
            spinner_div.id = this.root.cgi_name + '_item_' + this.index + '_spinner';
            spinner_div.className = "treeItemSpinner";
            spinner_div.innerHTML = "Loading...";
            this.listitem().appendChild(spinner_div);
        },
    removeSpinner:
        function() {
            var spinner_div = $(this.root.cgi_name + '_item_' + this.index + '_spinner');
            if(spinner_div)
                Element.remove(spinner_div);
        },
    render:
        function(builder) {
            var list_item_id = this.root.cgi_name + '_item_' + this.index;
            var list_item_class;
            var list_item_link_class = "";

            var is_last = (this.order == this.parent.children.length-1);

            if (this.children.length == 0) {
                if (is_last)
                    list_item_class = 'lastTreeLeaf';
                else
                    list_item_class = 'treeLeaf';
            } else {
                if(this.is_open) {
                    if(is_last)
                        list_item_class = 'lastOpenTreeItem';
                    else
                        list_item_class = 'openTreeItem';
                } else {
                    if(is_last)
                        list_item_class = 'lastClosedTreeItem';
                    else
                        list_item_class = 'closedTreeItem';
                }
            }

            if (this.parent == this.root && this.parent.children.length == 1) {
                list_item_class = "headerItem";
            }


            if (this.is_initially_selected) {
                list_item_link_class = "initialTreeItem";
            }

            if (this.root.only_leaves_selectable && this.children.length > 0) {
                list_item_link_class += " nonSelectableTreeItem";
            }

            builder.append('<li id="' + list_item_id + '" class="' + list_item_class + '">');
            builder.append('<span id="' + list_item_id + '_link" class="' + list_item_link_class + '">' + this.data[0] + '</span>');
            builder.append('</li>');
        },
    open:
        function() {
            if(Prototype.Browser.IE
               && !this.children_have_been_rendered
               && this.children.length > Rtk.TREE_ITEM_ASYNCHRONOUS_OPEN_THRESHOLD) {
                this.renderSpinner();
                setTimeout(this._open.bind(this),500);
            } else {
                this._open();
            }
        },
    _open:
        function() {
            if (!this.listitem() || this.children.length == 0) {
                this.removeSpinner();
                return;
            }

            var is_last = (this.order == this.parent.children.length-1);

            if(is_last) {
                this.listitem().removeClassName('lastClosedTreeItem');
                this.listitem().addClassName('lastOpenTreeItem');
            } else {
                this.listitem().removeClassName('closedTreeItem');
                this.listitem().addClassName('openTreeItem');
            }

            if(!this.children_have_been_rendered) {
                this.renderChildren();
                for(var i = 0, len = this.children.length; i < len; i++) {
                    this.children[i].registerClickEvents();
                    if(this.children[i].is_open)
                        this.children[i]._open();
                    else
                        this.children[i].is_open = false;
                }
                this.removeSpinner();
                this.children_have_been_rendered = true;
            }

	    ObscureElements.HideObscuredBy(option_container);

            if(this.root.allow_multiple) {
                var filter = this.root.filter();
                var option_container = this.root.optionContainer();
                var list_container = this.root.selectionListContainer();
                e3_snap(filter.id, list_container.id, option_container.getWidth(), filter.getHeight());
		ObscureElements.HideObscuredBy(list_container);
            }

            this.is_open = true;
        },
    close:
        function() {

            if (!this.listitem() || this.children.length == 0)
                return;

            var is_last = (this.order == this.parent.children.length-1);

            if(is_last) {
                this.listitem().removeClassName('lastOpenTreeItem');
                this.listitem().addClassName('lastClosedTreeItem');
            } else {
                this.listitem().removeClassName('openTreeItem');
                this.listitem().addClassName('closedTreeItem');
            }

  	    ObscureElements.HideObscuredBy(option_container);

            if(this.root.allow_multiple) {
                var filter = this.root.filter();
                var option_container = this.root.optionContainer();
                var list_container = this.root.selectionListContainer();
                e3_snap(filter.id, list_container.id, option_container.getWidth(), filter.getHeight());
		ObscureElements.HideObscuredBy(list_container);
            }

            this.is_open = false;
        },
    toggle:
        function(ev) {
            if(ev)
                Event.stop(ev);

            if(!this.is_open) {
                    this.open();
            } else {
                this.close();
            }
        },
    registerClickEvents:
        function() {
            var listitem = document.getElementById(this.root.cgi_name + '_item_' + this.index);
            var link = document.getElementById(this.root.cgi_name + '_item_' + this.index + '_link');
            listitem.onclick = this.toggle.bindAsEventListener(this);
            if(link.className.lastIndexOf("nonSelectableTreeItem") != -1)
            {
                link.onclick = this.toggle.bindAsEventListener(this);
                link.ondblclick = this.selectChildren.bindAsEventListener(this);
            }
            else
            {
                link.onclick = this.root.select.bindAsEventListener(this.root,this.index);
            }
        }
    });

Rtk.TreeFilter = Class.create(Rtk.Tree, {
    initialize:
        function($super, cgi_name, data_object, allow_multiple, only_leaves_selectable, selection_limit) {
            this.cgi_name = cgi_name;
            $super(data_object, allow_multiple, selection_limit);
            this.only_leaves_selectable = only_leaves_selectable;
            Event.observe(window, 'load', this.render.bindAsEventListener(this));
            Event.observe(window, 'load', this.registerKeyEvents.bindAsEventListener(this));
            this.keyed_item = null;
            this.initial_display = this.filter().innerHTML;
            var initial_values = this.initial_display.strip().split(",");
            for(var i = 0, len = this.flat_array.length; i < len; i++) {
                if($A(initial_values).indexOf(this.flat_array[i].data[0].strip()) != -1) {
                    this.flat_array[i].is_initially_selected = true;
                }
            }
            trees[trees.length] = this;

	    if (this.selection_limit == 0)
		this.filter().addClassName('disabled-tree-option');
        },
    form:
        function() {
            return $(this.cgi_name + '_tree_filter_key_proxy').form;
        },
    filter:
        function() {
            return $(this.cgi_name + '_tree_filter');
        },
    optionContainer:
        function() {
            return $(this.cgi_name + '_tree_option_div');
        },
    selectionListContainer:
        function() {
              return this.allow_multiple ? $(this.cgi_name + '_tree_option_selection_list_div') : undefined;
        },
    inputContainer:
        function() {
            if(this.allow_multiple)
                return $(this.cgi_name + '_tree_option_hidden_param_div');
            else
                return $(this.cgi_name);
        },
    keyProxy:
        function() {
            return $(this.cgi_name + '_tree_filter_key_proxy');
        },
    valueOfItem:
        function(item) {
            var value = item.data[1].replace(/\\\'/g,"x").split("'")[5];
            return value;
        },
    select:
        function($super, ev, item_index) {

            if ($super(item_index))
	    {
		if(!this.allow_multiple) {
                    if(this.selected_items[0])
			this.selected_items[0].listitemlink().removeClassName('selectedTreeItem');
		} else {
                    for(var i = 0, len = this.selected_items.length; i < len; i++) {
			this.selected_items[i].listitemlink().removeClassName('selectedItreeItem');
                    }
		}
	    } else {
		return;
	    }

            if(ev)
                Event.stop(ev);

            if(!this.allow_multiple)
                this.hide();

            var container = this.inputContainer();

            if (!this.allow_multiple) {

                var value = this.valueOfItem(this.selected_items[0]);
                var input_value = value;
                var input_name = this.cgi_name;
                var delimited_value = value.split("~");

                if(delimited_value.length > 1) {
                    input_name = delimited_value[0];
                    input_value = delimited_value[1];
                }

                var new_input = document.createElement("input");

                new_input.setAttribute("type", "hidden");
                new_input.setAttribute("id",this.cgi_name);
                new_input.setAttribute("name",input_name);
                new_input.setAttribute("value",input_value);

                var old_input;
                var form = this.form();
                for(var i = 0,len = form.elements.length; i < len; i++) {
                    if(form.elements[i].id == this.cgi_name) {
                        old_input = form.elements[i];
                        break;
                    }
                }
                old_input.parentNode.removeChild(old_input);

                form.appendChild(new_input);

                this.selected_items[0].listitemlink().addClassName('selectedItreeItem');

            } else {

                var markup_for_inputs = "";

                container.innerHTML = "";

                for(var i = 0; i < this.selected_items.length; i++) {

                    this.selected_items[i].listitemlink().addClassName('selectedItreeItem');

                    var value = this.valueOfItem(this.selected_items[i]);
                    var input_value = value;
                    var input_name = this.cgi_name;
                    var delimited_value = value.split("~");

                    if(delimited_value.length > 1) {
                        input_name = delimited_value[0];
                        input_value = delimited_value[1];
                    }

                    markup_for_inputs += '<input type="hidden" name="'
                                      +  input_name
                                      +  '" value="'
                                      +  input_value
                                      +  '" />';

                }

                container.innerHTML = markup_for_inputs;

            }

            if(this.onChange)
                this.onChange();

            this.refreshText();

            if (this.allow_multiple)
                this.refreshList();

            this.flat_array[item_index].listitemlink().toggleClassName('selectedTreeItem');

            if (this.selected_items.length > 0)
                Forms.ActivateButtonsForForm(this.form());
            else
                Forms.DeactivateButtonsForForm(this.form());
        },
    clear:
        function($super) {
            $super();
            this.refreshText();
            if(this.allow_multiple)
                this.refreshList();

	    Forms.DeactivateButtonsForFormOfItem($(this.cgi_name));
        },
    keyItem:
        function(item) {
            if(this.keyed_item)
                Element.removeClassName(this.keyed_item.listitemlink(), 'keyed-tree-item');
            this.keyed_item = item;
            if(this.keyed_item)
                Element.addClassName(this.keyed_item.listitemlink(), 'keyed-tree-item');
        },
    render:
        function() {
            var container = this.optionContainer();
            container.parentNode.removeChild(container);
            document.body.insertBefore(container, document.body.firstChild);
            if (this.allow_multiple) {
                var list_container = this.selectionListContainer();
                list_container.parentNode.removeChild(list_container);
                document.body.insertBefore(list_container, document.body.firstChild);
            }
            var sb = new Rtk.Util.StringBuilder('<ul class="treeFilter">');
            for(var i = 0, len = this.children.length; i < len; i++) {
                this.children[i].render(sb);
            }
            sb.append('</ul>');
            container.innerHTML = sb.toString();
            for(var i = 0, len = this.children.length; i < len; i++) {
                if(this.children[i].is_open)
                    this.children[i].open();
                else
                    this.children[i].is_open = false;
            }
            this.registerClickEvents();
        },
    registerClickEvents:
        function() {
	    Event.observe(document, 'mousedown', this.mouseDownHandler.bindAsEventListener(this));
            for(var i=0, len = this.children.length; i < len; ++i) {
                this.children[i].registerClickEvents();
            }
        },
    registerKeyEvents:
        function() {
            var key_proxy = this.keyProxy();
            Event.observe(key_proxy, 'focus', this.focusHandler.bindAsEventListener(this));
            Event.observe(key_proxy, 'blur', this.blurHandler.bindAsEventListener(this));
            Event.observe(key_proxy, 'keydown', this.keydownHandler.bindAsEventListener(this));
            Event.observe(key_proxy, 'keypress', this.keypressHandler.bindAsEventListener(this));
        },
    mouseDownHandler:
        function(ev) {
	    var target = !ev ? document.event.srcElement : ev.target;

	    var list_container_was_clicked = false;
	    var filter_was_clicked = false;
	    var selection_list_container_was_clicked = false;

	    if (target == this.optionContainer() || $(target).descendantOf(this.optionContainer()))
	        list_container_was_clicked = true;

	    if (target == this.filter() || $(target).descendantOf(this.filter()))
	        filter_was_clicked = true;

	    if (this.allow_multiple)
	    {
	        if (target == this.selectionListContainer() || $(target).descendantOf(this.selectionListContainer()))
	            selection_list_container_was_clicked = true;
	    }

	    if (!list_container_was_clicked
		&& !filter_was_clicked
		&& !selection_list_container_was_clicked
	        && this.optionContainer().style.display == "block")
	        this.hide();

  	    if (filter_was_clicked)
	        Event.stop(ev);

	},
    focusHandler:
        function(ev) {
            this.show();
            Element.addClassName(this.filter(), 'keyed-tree');
        },
    blurHandler:
        function(ev) {
            this.keyItem(null);
          Element.removeClassName(this.filter(), 'keyed-tree');
        },
    keypressHandler:
        function(ev) {
            if(window.event)
                ev = event;
            var code = ev.keyCode || ev.which;

            Event.stop(ev);

            return !(code == Event.KEY_RETURN);
        },
    keydownHandler:
        function(ev) {
            if(window.event)
                ev = event;
            var code = ev.keyCode || ev.which;

            Event.stop(ev);
            switch(code) {
            case Event.KEY_TAB:
                this.hide();
                return false;
            case Event.KEY_RETURN:
                this.select(ev, this.keyed_item.index);
                return false;
            case Event.KEY_UP:
            case Event.KEY_DOWN:
            case Event.KEY_LEFT:
            case Event.KEY_RIGHT:
                if(this.optionContainer().style.display == 'none') {
                    this.show();
                } else if(!this.keyed_item) {
                    this.keyItem(this.selected_items[this.selected_items.length] || this.children[0]);
                } else {
                    switch(code) {
                    case Event.KEY_UP:
                        if(this.keyed_item.order != 0) {
                            var item = this.keyed_item.parent.children[this.keyed_item.order - 1];
                            while(item.is_open && item.children.length > 0)
                                item = item.children[item.children.length - 1];
                            this.keyItem(item);
                        } else if(this.keyed_item.parent && this.keyed_item.parent != item) {
                            this.keyItem(this.keyed_item.parent);
                        }
                        break;
                    case Event.KEY_DOWN:
                        if(this.keyed_item.is_open && this.keyed_item.children.length > 0) {
                            this.keyItem(this.keyed_item.children[0]);
                        } else {
                            var item = this.keyed_item;
                            while(item.parent && item.parent != item && item.order == item.parent.children.length-1)
                                item = item.parent;
                            this.keyItem(item.parent.children[item.order + 1]);
                        }
                        break;
                    case Event.KEY_LEFT:
                        if(this.keyed_item.is_open)
                            this.keyed_item.toggle(ev);
                        break;
                    case Event.KEY_RIGHT:
                        if(!this.keyed_item.is_open)
                            this.keyed_item.toggle(ev);
                        break;
                    }
                }
                return false;
            default:
                return false;
            }
        },
    show:
        function() {
            var filter = this.filter();
            var option_container = this.optionContainer();
            Element.addClassName(filter, 'treeoption-container-opened');
            e3_snap(filter.id, option_container.id, 0, filter.getHeight());
            option_container.style.display = 'block';
	    ObscureElements.HideObscuredBy(option_container);
            if(this.allow_multiple) {
                var list_container = this.selectionListContainer();
                e3_snap(filter.id, list_container.id, option_container.getWidth(), filter.getHeight());
                list_container.style.display = 'block';
		ObscureElements.HideObscuredBy(list_container);
            }
        },
    hide:
        function() {
	    ObscureElements.ShowObscuredBy(this.optionContainer());
	    ObscureElements.ShowObscuredBy(this.selectionListContainer());
            this.filter().removeClassName('treeoption-container-opened');
            this.optionContainer().style.display = 'none';
            if(this.allow_multiple)
                this.selectionListContainer().style.display = 'none';
        },
    toggle:
        function() {
            if (this.optionContainer().style.display == 'none'
                && !this.filter().hasClassName('disabled-tree-option'))
                this.show();
            else
                this.hide();
        },
    refreshList:
        function() {
            var list = $(this.cgi_name + '_tree_option_selection_list');
            var list_markup = "";
            for (var i = 0; i < this.selected_items.length; i++) {
                var list_item_id = this.cgi_name + '_selected_' + this.selected_items[i].index;
                list_markup += '<li id="'
                            +  list_item_id
                            +  '">'
                            +  this.selected_items[i].data[0]
                            +  '</li>';
            }
            list.innerHTML = list_markup;
	    ObscureElements.HideObscuredBy(this.selectionListContainer());
            for (var i = 0; i < this.selected_items.length; i++) {
                var list_item_id = this.cgi_name + '_selected_' + this.selected_items[i].index;
                Event.observe($(list_item_id),'click', this.select.bindAsEventListener(this, this.selected_items[i].index));
            }

        },
    refreshText:
        function() {
            var display_text = this.initial_display;
            for(var i = 0; i < this.selected_items.length; i++) {
                if(display_text.substring(display_text.length-3) != "...") {
                    if (i==0) {
                      display_text = this.selected_items[i].data[0];
                    } else {
                        if((display_text.length + this.selected_items[i].data[0].length) >= 37)
                            display_text += "...";
                        else
                          display_text += ',' + this.selected_items[i].data[0];
                    }
                }
            }
            this.filter().update(display_text);
        }
    });

