Rtk.Tree = Class.create({
    initialize:
        function(data_object,allow_multiple,selection_limit) {
            this.children = [];
            this.flat_array = [];
            this.selected_items = [];
            this.allow_multiple = allow_multiple;
            this.selection_limit = selection_limit;

	    if (this.selection_limit && this.selection_limit < 0)
		this.selection_limit = 0;

	    this.root = this;
            this.depth = -1;
            this.data = data_object;

            for(var i = 0, len = data_object.length; i < len; ++i) {
                new Rtk.TreeItem(this,i);
            }
        },
    select:
        function(item_index) {
            if(!this.allow_multiple) {
                this.selected_items[0] = this.flat_array[item_index];
            } else {

		if (this.selected_items.indexOf(this.flat_array[item_index]) != -1) {
		    this.selected_items = this.selected_items.without(this.flat_array[item_index]);
		    return true;
		}

		if (this.selection_limit == 0 || this.selected_items.length >= this.selection_limit)
		    return false;

		if (this.selected_items.indexOf(this.flat_array[item_index]) == -1)
		{
		    this.selected_items.push(this.flat_array[item_index]);
		    return true;
		}
            }
	    return true;
        },
    clear:
        function() {
            $A(this.selected_items).each(function(item) { item.root.select(undefined,item.index); });
        }
    });

Rtk.TreeItem = Class.create({
    initialize:
        function(parent, order) {
            this.depth = parent.depth +1;
            this.data = parent.data[order + (this.depth ? 4 : 0)];
            if (!this.data) return;

            this.root = parent.root;
            this.parent = parent;
            this.order = order;

            this.index = this.root.flat_array.length;
            this.root.flat_array[this.index] = this;
            this.parent.children[order] = this;
            this.children = [];
            for (var i = 0, len = this.data.length -2; i < len; i++)
                new Rtk.TreeItem(this, i);

            this.is_open = (this.data[2] == 1);
        }
    });

