var AmazingTree = {

    lastId: -1,
    idToNode: [],
    enableDragDrop: false,
    dragged: {node: null, parent: null, above: null, below: null},
    dropTargets: {parent: null, above: null, below: null},
    mouseOverExpand: {id: null, timer: null},
    successfulDragDrop: function() {},
    unsuccessfulDragDrop: function() {},
    sizes: {window: {x: 0, y: 0}, scroll: {x: 0, y: 0}},
    scroll: {speed: 25, boundary: {top: 20, bottom: 20, left: 20, right: 20}},
    scrollTimer: {up: null, down: null, left: null, right: null},
    pointsOfInterest: [],
    baseURL: "",

    getNewId: function() {

        this.lastId++;
        return this.lastId;

    },

    toggle: function(id) {

        if (AmazingTree.idToNode[id].open) {
            AmazingTree.idToNode[id].collapse();
        } else {
            AmazingTree.idToNode[id].expand();
        }

    },
	
    handleMouseDown: function(element, e) {

        e = e ? e : window.event;

        if (!AmazingTree.enableDragDrop) {
            return;
        }

        if (element.id.match("at_itemLink_")) {
            var draggedNode = AmazingTree.idToNode[ parseInt(element.id.substring(12)) ];
            if (!draggedNode.parentNode) {  // root node
                return
            }
            AmazingTree.dragged.node = draggedNode;
            AmazingTree.dragged.parent = draggedNode.parentNode;
            AmazingTree.dragged.above = draggedNode.nextNode;
            AmazingTree.dragged.below = draggedNode.previousNode;
        } else {
            return;
        }

        var icon = this.dragged.node.icon;
        if (!icon) {
            if (this.dragged.node.children.length > 0) {
                icon = AmazingTree.baseURL + "images/folder.gif";
            } else {
                icon = AmazingTree.baseURL + "images/page.gif";
            }
        }

        if (document.addEventListener) {
            document.addEventListener("mousemove", AmazingTree.trackMouseMove, false);
            document.addEventListener("mouseup", AmazingTree.handleMouseUp, false);
        } else {
            document.attachEvent("onmousemove", AmazingTree.trackMouseMove);
            document.attachEvent("onmouseup", AmazingTree.handleMouseUp);
        }

        var temp = icon.split(",");
        var offsetLeftPixels = temp[1] ? temp[1] : 0;
        var offsetTopPixels = temp[1] ? temp[2] : 0;
        
        var mouseFollower = document.getElementById("at_mouseFollower");
        mouseFollower.innerHTML = "<NOBR><img id='at_mouseFollower_addType' class='drop_cancel' src='" + AmazingTree.baseURL + "images/empty.gif'>&nbsp;<img class='itemImage' src='" + AmazingTree.baseURL + "images/empty.gif' width='16' height='16' style='background: transparent url(\"" + temp[0] + "\") no-repeat scroll " + offsetLeftPixels + "px " + offsetTopPixels + "px;'> " + this.dragged.node.text + "</NOBR>";

        AmazingTree.sizes.window = AmazingTree.getWindowSize();
        AmazingTree.sizes.scroll = AmazingTree.getScrollWidthHeight();

        if (e.preventDefault)
            e.preventDefault();
        else
            e.returnValue= false;
        return false;

    },

    trackMouseMove: function(e) {

        e = e ? e : window.event;

        var disableMouseOverExpand = true;
        var mousePos = AmazingTree.mouseCoords(e);

        var mouseFollower = document.getElementById("at_mouseFollower");
        mouseFollower.style.display = "block";

        if ((mousePos.x + 15 + mouseFollower.offsetWidth) > AmazingTree.sizes.scroll.x) {
            mouseFollower.style.left = (AmazingTree.sizes.scroll.x - mouseFollower.offsetWidth) + "px";
        } else {
            mouseFollower.style.left = mousePos.x + 15 + "px";
        }

        if ((mousePos.y + 15 + mouseFollower.offsetHeight) > AmazingTree.sizes.scroll.y) {
            mouseFollower.style.top = (AmazingTree.sizes.scroll.y - mouseFollower.offsetHeight) + "px";
        } else {
            mouseFollower.style.top = mousePos.y + 15 + "px";
        }

        var rootNode = AmazingTree.dragged.node;

        while (rootNode.parentNode) {
            rootNode = rootNode.parentNode;
        }

        var node = AmazingTree.getMouseOverNode(rootNode, mousePos);

        var oldDropTargets = {};
        oldDropTargets.parent = AmazingTree.dropTargets.parent;
        oldDropTargets.above = AmazingTree.dropTargets.above;
        oldDropTargets.below = AmazingTree.dropTargets.below;

        if (!node) {
            AmazingTree.dropTargets.parent = null;
            AmazingTree.dropTargets.above = null;
            AmazingTree.dropTargets.below = null;
            document.getElementById("at_mouseFollower_addType").className = "drop_cancel";
        } else {
            var element = document.getElementById("at_item_" + node.id);
            var elementPos = AmazingTree.elementCoords(element);

            if ( (mousePos.y < (elementPos.y + 0.25 * element.offsetHeight)) && (node.parentNode) ) {
                AmazingTree.dropTargets.parent = node.parentNode;
                AmazingTree.dropTargets.above = node;
                AmazingTree.dropTargets.below = node.previousNode;
                if (node.previousNode) {
                    document.getElementById("at_mouseFollower_addType").className = "drop_between";
                } else {
                    document.getElementById("at_mouseFollower_addType").className = "drop_above";
                }
            } else if (mousePos.y > (elementPos.y + 0.75 * element.offsetHeight)) {
                if (node.open) {
                    AmazingTree.dropTargets.parent = node;
                    AmazingTree.dropTargets.above = node.children[0];
                    AmazingTree.dropTargets.below = null;
                    document.getElementById("at_mouseFollower_addType").className = "drop_above";
                } else {
                    AmazingTree.dropTargets.parent = node.parentNode;
                    AmazingTree.dropTargets.above = node.nextNode;
                    AmazingTree.dropTargets.below = node;
                    if (node.nextNode) {
                        document.getElementById("at_mouseFollower_addType").className = "drop_between";
                    } else {
                        document.getElementById("at_mouseFollower_addType").className = "drop_below";
                    }
                }
            } else {
                AmazingTree.dropTargets.parent = node;
                AmazingTree.dropTargets.above = null;
                if (node.children.length > 0) {
                    AmazingTree.dropTargets.below = node.children[ node.children.length - 1 ];
                } else {
                    AmazingTree.dropTargets.below = null;
                }
                document.getElementById("at_mouseFollower_addType").className = "drop_add";

                disableMouseOverExpand = false;

                if ( (AmazingTree.mouseOverExpand.timer && (AmazingTree.mouseOverExpand.id != node.id) ) ||
                     !AmazingTree.mouseOverExpand.timer) {
                    window.clearTimeout(AmazingTree.mouseOverExpand.timer);
                    AmazingTree.mouseOverExpand.timer = window.setTimeout("AmazingTree.idToNode[" + AmazingTree.dropTargets.parent.id + "].expand(); AmazingTree.sizes.scroll = AmazingTree.getScrollWidthHeight();", 750);
                    AmazingTree.mouseOverExpand.id = AmazingTree.dropTargets.parent.id;
                }

            }
        }

        if ( (AmazingTree.dropTargets.parent && !AmazingTree.dropTargets.parent.permission.parent(AmazingTree.dragged.node, AmazingTree.dropTargets.parent)) ||
            (AmazingTree.dropTargets.above && !AmazingTree.dropTargets.above.permission.above(AmazingTree.dragged.node, AmazingTree.dropTargets.above)) ||
            (AmazingTree.dropTargets.below && !AmazingTree.dropTargets.below.permission.below(AmazingTree.dragged.node, AmazingTree.dropTargets.below)) ) {

            document.getElementById("at_mouseFollower_addType").className = "drop_cancel";
            AmazingTree.dropTargets.parent = null;
            AmazingTree.dropTargets.above = null;
            AmazingTree.dropTargets.below = null;

        }

        if (disableMouseOverExpand && AmazingTree.mouseOverExpand.timer) {
            window.clearTimeout(AmazingTree.mouseOverExpand.timer);
            AmazingTree.mouseOverExpand.timer = null;
            AmazingTree.mouseOverExpand.id = null;
        }

        if (AmazingTree.dragged.node == AmazingTree.dropTargets.parent ||
            AmazingTree.dragged.node == AmazingTree.dropTargets.above ||
            AmazingTree.dragged.node == AmazingTree.dropTargets.below ||
            AmazingTree.dragged.node.isParentOf(AmazingTree.dropTargets.parent)) {

            document.getElementById("at_mouseFollower_addType").className = "drop_cancel";
            AmazingTree.dropTargets.parent = null;
            AmazingTree.dropTargets.above = null;
            AmazingTree.dropTargets.below = null;
        }

        for (var i = 0; i < AmazingTree.pointsOfInterest.length; i++) {
            if (AmazingTree.pointIsWithinElement(AmazingTree.pointsOfInterest[i].element, mousePos.x, mousePos.y)) {
                if (AmazingTree.pointsOfInterest[i].mouseOverCallback) {
                    AmazingTree.pointsOfInterest[i].mouseOverCallback.call(AmazingTree.pointsOfInterest[i], AmazingTree.dragged.node, mousePos);
                }
                AmazingTree.pointsOfInterest[i].over = true;
            } else if (AmazingTree.pointsOfInterest[i].over) {
                if (AmazingTree.pointsOfInterest[i].mouseOutCallback) {
                    AmazingTree.pointsOfInterest[i].mouseOutCallback.call(AmazingTree.pointsOfInterest[i], AmazingTree.dragged.node, mousePos);
                }
                AmazingTree.pointsOfInterest[i].over = false;
            }
        }

        if (oldDropTargets.parent) {
            document.getElementById("at_itemLink_" + oldDropTargets.parent.id).style.border = "0px";
        }

        if (oldDropTargets.above) {
            document.getElementById("at_itemLink_" + oldDropTargets.above.id).style.borderTop = "0px";
        }

        if (oldDropTargets.below) {
            document.getElementById("at_itemLink_" + oldDropTargets.below.id).style.borderBottom = "0px";
        }

        if (AmazingTree.dropTargets.parent) {
            document.getElementById("at_itemLink_" + AmazingTree.dropTargets.parent.id).style.border = "1px dashed blue";
        }

        if (AmazingTree.dropTargets.above) {
            document.getElementById("at_itemLink_" + AmazingTree.dropTargets.above.id).style.borderTop = "1px dashed blue";
        }

        if (AmazingTree.dropTargets.below) {
            document.getElementById("at_itemLink_" + AmazingTree.dropTargets.below.id).style.borderBottom = "1px dashed blue";
        }

        if ((mousePos.y > (document.body.scrollTop + AmazingTree.sizes.window.y - AmazingTree.scroll.boundary.bottom)) && (mousePos.y < (document.body.scrollTop + AmazingTree.sizes.window.y))) {
            if (!AmazingTree.scrollTimer.down) {
                AmazingTree.scrollTimer.down = window.setInterval("AmazingTree.doScroll('down')", parseInt(1000 / AmazingTree.scroll.speed));
            }
        } else if(AmazingTree.scrollTimer.down) {
            window.clearInterval(AmazingTree.scrollTimer.down);
            AmazingTree.scrollTimer.down = null;
        }

        if ((mousePos.y < (document.body.scrollTop + 15)) && (mousePos.y > document.body.scrollTop)) {
            if (!AmazingTree.scrollTimer.up) {
                AmazingTree.scrollTimer.up = window.setInterval("AmazingTree.doScroll('up')", parseInt(1000 / AmazingTree.scroll.speed));
            }
        } else if(AmazingTree.scrollTimer.up) {
            window.clearInterval(AmazingTree.scrollTimer.up);
            AmazingTree.scrollTimer.up = null;
        }

        if ((mousePos.x > (document.body.scrollLeft + AmazingTree.sizes.window.x - 15)) && (mousePos.x < (document.body.scrollLeft + AmazingTree.sizes.window.x))) {
            if (!AmazingTree.scrollTimer.right) {
                AmazingTree.scrollTimer.right = window.setInterval("AmazingTree.doScroll('right')", parseInt(1000 / AmazingTree.scroll.speed));
            }
        } else if(AmazingTree.scrollTimer.right) {
            window.clearInterval(AmazingTree.scrollTimer.right);
            AmazingTree.scrollTimer.right = null;
        }

        if ((mousePos.x < (document.body.scrollLeft + 15)) && (mousePos.x > document.body.scrollLeft)) {
            if (!AmazingTree.scrollTimer.left) {
                AmazingTree.scrollTimer.left = window.setInterval("AmazingTree.doScroll('left')", parseInt(1000 / AmazingTree.scroll.speed));
            }
        } else if(AmazingTree.scrollTimer.left) {
            window.clearInterval(AmazingTree.scrollTimer.left);
            AmazingTree.scrollTimer.left = null;
        }

        if (e.preventDefault)
            e.preventDefault();
        else
            e.returnValue= false;
        return false;

    },

    doScroll: function(direction) {

        var mouseFollower = document.getElementById("at_mouseFollower");

        switch (direction){
            case "up":
                if ( (document.body.scrollTop - 1) >= 0) {
                    document.body.scrollTop = document.body.scrollTop - 1;
                    mouseFollower.style.top = (parseInt(mouseFollower.style.top) - 1) + "px";
                }
                break;

            case "down":
                if ( (document.body.scrollTop + AmazingTree.sizes.window.y + 1 - 18) <= AmazingTree.sizes.scroll.y) {
                    document.body.scrollTop = document.body.scrollTop + 1;
                    mouseFollower.style.top = (parseInt(mouseFollower.style.top) + 1) + "px";
                }
                break;

            case "left":
                if ( (document.body.scrollLeft - 1) >= 0) {
                    document.body.scrollLeft = document.body.scrollLeft - 1;
                    mouseFollower.style.left = (parseInt(mouseFollower.style.left) - 1) + "px";
                }
                break;

            case "right":
                if ( (document.body.scrollLeft + AmazingTree.sizes.window.x + 1 - 18) <= AmazingTree.sizes.scroll.x) {
                    document.body.scrollLeft = document.body.scrollLeft + 1;
                    mouseFollower.style.left = (parseInt(mouseFollower.style.left) + 1) + "px";
                }
                break;
        }

    },

    handleMouseUp: function(e) {

        e = e ? e : window.event;

        var mousePos = AmazingTree.mouseCoords(e);

        var mouseFollower = document.getElementById("at_mouseFollower");
        mouseFollower.style.display = "none";

        if (document.removeEventListener) {
            document.removeEventListener("mousemove", AmazingTree.trackMouseMove, false);
            document.removeEventListener("mouseup", AmazingTree.handleMouseUp, false);
        } else {
            document.detachEvent("onmousemove", AmazingTree.trackMouseMove);
            document.detachEvent("onmouseup", AmazingTree.handleMouseUp);
        }

        if (AmazingTree.dropTargets.parent) {
            document.getElementById("at_itemLink_" + AmazingTree.dropTargets.parent.id).style.border = "0px";
        }

        if (AmazingTree.dropTargets.above) {
            document.getElementById("at_itemLink_" + AmazingTree.dropTargets.above.id).style.borderTop = "0px";
        }

        if (AmazingTree.dropTargets.below) {
            document.getElementById("at_itemLink_" + AmazingTree.dropTargets.below.id).style.borderBottom = "0px";
        }

        if (AmazingTree.dropTargets.parent ||
            AmazingTree.dropTargets.above ||
            AmazingTree.dropTargets.below) {

            if (!AmazingTree.dragged.node.clone) {
                AmazingTree.dragged.node.parentNode.removeChildNode(AmazingTree.dragged.node);
            }

            if (AmazingTree.dropTargets.parent &&
                AmazingTree.dropTargets.above &&
                AmazingTree.dropTargets.below) {

                var index = null
                for (var i = 0; i < AmazingTree.dropTargets.parent.children.length; i++) {
                    if (AmazingTree.dropTargets.parent.children[i] == AmazingTree.dropTargets.above) {
                        index = i;
                        break;
                    }
                }

                if (AmazingTree.dragged.node.clone) {
                    var temp = new AT_Node({text: AmazingTree.dragged.node.text, url: AmazingTree.dragged.node.url, target: AmazingTree.dragged.node.target, icon: AmazingTree.dragged.node.icon, iconOpen: AmazingTree.dragged.node.iconOpen, data: AmazingTree.dragged.node.data});
                    temp.permission = AmazingTree.dragged.node.permission;
                    AmazingTree.dropTargets.parent.addChildNode(temp, index);
                } else {
                    AmazingTree.dropTargets.parent.addChildNode(AmazingTree.dragged.node, index);
                }

            } else if (AmazingTree.dropTargets.parent &&
                AmazingTree.dropTargets.above) {
                if (AmazingTree.dragged.node.clone) {
                    var temp = new AT_Node({text: AmazingTree.dragged.node.text, url: AmazingTree.dragged.node.url, target: AmazingTree.dragged.node.target, icon: AmazingTree.dragged.node.icon, iconOpen: AmazingTree.dragged.node.iconOpen, data: AmazingTree.dragged.node.data});
                    temp.permission = AmazingTree.dragged.node.permission;
                    AmazingTree.dropTargets.parent.addChildNode(temp, 0);
                } else {
                    AmazingTree.dropTargets.parent.addChildNode(AmazingTree.dragged.node, 0);
                }
            } else if (AmazingTree.dropTargets.parent) {
                if (AmazingTree.dragged.node.clone) {
                    var temp = new AT_Node({text: AmazingTree.dragged.node.text, url: AmazingTree.dragged.node.url, target: AmazingTree.dragged.node.target, icon: AmazingTree.dragged.node.icon, iconOpen: AmazingTree.dragged.node.iconOpen, data: AmazingTree.dragged.node.data});
                    temp.permission = AmazingTree.dragged.node.permission;
                    AmazingTree.dropTargets.parent.addChildNode(temp);
                } else {
                    AmazingTree.dropTargets.parent.addChildNode(AmazingTree.dragged.node);
                }
                AmazingTree.dropTargets.parent.expand();
            }

            if (AmazingTree.successfulDragDrop) {
                AmazingTree.successfulDragDrop(AmazingTree.dragged, AmazingTree.dropTargets);
            }

        } else {
            for (var i = 0; i < AmazingTree.pointsOfInterest.length; i++) {
                if (AmazingTree.pointsOfInterest[i].over) {
                    if (AmazingTree.pointsOfInterest[i].mouseOutCallback) {
                        AmazingTree.pointsOfInterest[i].mouseOutCallback.call(AmazingTree.pointsOfInterest[i], AmazingTree.dragged.node, mousePos);
                    }
                    AmazingTree.pointsOfInterest[i].over = false;
                }

                if (AmazingTree.pointIsWithinElement(AmazingTree.pointsOfInterest[i].element, mousePos.x, mousePos.y)) {
                    if (AmazingTree.pointsOfInterest[i].mouseUpCallback) {
                        AmazingTree.pointsOfInterest[i].mouseUpCallback.call(AmazingTree.pointsOfInterest[i], AmazingTree.dragged.node, mousePos);
                    }
                }
            }

            if (AmazingTree.unsuccessfulDragDrop) {
                AmazingTree.unsuccessfulDragDrop(AmazingTree.dragged, AmazingTree.dropTargets);
            }
        }

        AmazingTree.dropTargets.parent = null;
        AmazingTree.dropTargets.above = null;
        AmazingTree.dropTargets.below = null;
        AmazingTree.dragged.node = null;

        if (e.preventDefault)
            e.preventDefault();
        else
            e.returnValue= false;
        return false;

    },

    elementCoords: function(element) {

        var x = 0;
        var y = 0;

        do {
            y += element.offsetTop  || 0;
            x += element.offsetLeft || 0;
            element = element.offsetParent;
        } while (element);

        return {x: x, y: y};

    },

    pointIsWithinElement: function(element, x, y) {
        elementPos = AmazingTree.elementCoords(element)
        elementBottomRightPos = { x: elementPos.x + element.offsetWidth, y: elementPos.y + element.offsetHeight + 1 };
        if ( (x > elementPos.x) &&
             (y > elementPos.y) &&
             (x < elementBottomRightPos.x) &&
             (y < elementBottomRightPos.y)
           ) {
            return true;
        }

        return false;
    },

    mouseCoords: function(e){
	if(e.pageX || e.pageY){
		return {x:e.pageX, y:e.pageY};
	}
	return {
		x:e.clientX + document.body.scrollLeft - document.body.clientLeft,
		y:e.clientY + document.body.scrollTop  - document.body.clientTop
	};
    },

    getMouseOverNode: function(node, mousePos) {

        if ( AmazingTree.pointIsWithinElement(document.getElementById("at_unit_" + node.id), mousePos.x, mousePos.y) ) {
            if ( AmazingTree.pointIsWithinElement(document.getElementById("at_children_" + node.id), mousePos.x, mousePos.y) ) {
                for (var i = 0; i < node.children.length; i++) {
                    var value = AmazingTree.getMouseOverNode(node.children[i], mousePos);
                    if (value) {
                        return value;
                    }
                }
            } else if (AmazingTree.pointIsWithinElement(document.getElementById("at_item_" + node.id), mousePos.x, mousePos.y)) {
                return node;
            }
        }

        return false;

    },

    getWindowSize: function() {
      var myWidth = 0, myHeight = 0;
      if( typeof( window.innerWidth ) == 'number' ) {
        //Non-IE
        myWidth = window.innerWidth;
        myHeight = window.innerHeight;
      } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
        //IE 6+ in 'standards compliant mode'
        myWidth = document.documentElement.clientWidth;
        myHeight = document.documentElement.clientHeight;
      } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
        //IE 4 compatible
        myWidth = document.body.clientWidth;
        myHeight = document.body.clientHeight;
      }

      return {x: myWidth, y: myHeight};
    },

    getScrollWidthHeight: function() {
        var width = 0, height = 0;
        width = document.body.scrollWidth;
        height = document.body.scrollHeight;
        return {x: width, y: height};
    }

}

function AT_Node(options) {

    this.id = null;
    this.unit = null;
    this.parentNode = null;
    this.nextNode = null;
    this.previousNode = null;
    this.children = [];
    this.indent = [];
    this.open = false;
    this.permission = {parent: function() { return true; }, above: function() { return true; }, below: function() { return true; }};

    this.text = options.text ? options.text : "";
    this.url = options.url ? options.url : "";
    this.target = options.target ? options.target : null;
    this.icon = options.icon ? options.icon : "";
    this.iconOpen = options.iconOpen ? options.iconOpen : "";
    this.clone = options.clone ? true : false;
    this.data = options.data ? options.data : {};

}

AT_Node.prototype.id;
AT_Node.prototype.unit;
AT_Node.prototype.parentNode;
AT_Node.prototype.nextNode;
AT_Node.prototype.previousNode;
AT_Node.prototype.children;
AT_Node.prototype.indent;
AT_Node.prototype.open;
AT_Node.prototype.permission;
AT_Node.prototype.callbacks;
AT_Node.prototype.text;
AT_Node.prototype.url;
AT_Node.prototype.target;
AT_Node.prototype.icon;
AT_Node.prototype.iconOpen;
AT_Node.prototype.clone;
AT_Node.prototype.data;

AT_Node.prototype.addChildNode = function(child, index) {

    child.parentNode = this;

    if (this.children.length == 0) {
        this.children[0] = child;
        child.nextNode = null;
        child.previousNode = null;
    } else if (typeof index == "undefined") {
        this.children[ this.children.length - 1 ].nextNode = child;
        child.previousNode = this.children[ this.children.length - 1 ];
        child.nextNode = null;
        this.children[ this.children.length ] = child;
    } else if (index <= this.children.length) {
        this.children.splice(index, 0, child);
        if (index != 0) {
            this.children[index - 1].nextNode = this.children[index];
            this.children[index].previousNode = this.children[index - 1];
        } else {
            this.children[index].previousNode = null;
        }
        if (index != (this.children.length - 1) ) {
            this.children[index].nextNode = this.children[index + 1];
            this.children[index + 1].previousNode = this.children[index];
        } else {
            this.children[index].nextNode = null;
        }
    }

    if (document.getElementById( "at_unit_" + this.id )) {
        this.recursiveCalculateIndent();

        var tempElement = document.createElement("DIV");
        tempElement.innerHTML = child.getHTML();

        if ( (typeof index == "undefined") || ( (typeof index != "undefined") && (index == (this.children.length - 1) )) ) {
            document.getElementById("at_children_" + this.id).appendChild(tempElement.childNodes[0]);
        } else {
            document.getElementById("at_children_" + this.id).insertBefore(tempElement.childNodes[0], this.children[ index + 1 ].unit);
        }

        child.updateUnit();
    }

}

AT_Node.prototype.removeChildNode = function(child) {

    var index = null;

    for (var i = 0; i < this.children.length; i++) {
        if (this.children[i] == child) {
            index = i;
            break;
        }
    }

    if (index == null) {
        return false;
    }

    if (this.children[index].nextNode) {
        this.children[index].nextNode.previousNode = this.children[index].previousNode;
    }

    if (this.children[index].previousNode) {
        this.children[index].previousNode.nextNode = this.children[index].nextNode;
    }

    this.children.splice(index, 1);

	if (this.open && (this.children.length == 0)) {
		this.collapse(); //xyz
	}
	
    document.getElementById("at_unit_" + child.id).parentNode.removeChild( document.getElementById("at_unit_" + child.id) );

    this.recursiveCalculateIndent();

    return true;

}

AT_Node.prototype.isParentOf = function(node) {

    if (!node) {
        return false;
    }

    while (node.parentNode) {
        node = node.parentNode;
        if (node == this) {
            return true;
        }
    }

    return false;

}

AT_Node.prototype.buildClassName = function(obj) {

    var returnString = "";

    if (obj.up) {
        returnString = "up";
    } else {
        returnString = "empty";
    }

    if (obj.down) {
        returnString = returnString + "_down";
    } else {
        returnString = returnString + "_empty";
    }

    if (obj.right) {
        returnString = returnString + "_right";
    } else {
        returnString = returnString + "_empty";
    }

    if (obj.image) {
        returnString = returnString + "_" + obj.image;
    } else {
        returnString = returnString + "_empty";
    }

    return returnString;

}

AT_Node.prototype.copyIndent = function() {

    returnArray = [];

    for (var i = 0; i < this.indent.length; i++) {
        returnArray[i] = {};
        returnArray[i].up = this.indent[i].up;
        returnArray[i].down = this.indent[i].down;
        returnArray[i].right = this.indent[i].right;
        returnArray[i].image = this.indent[i].image;
    }

    return returnArray;

}

AT_Node.prototype.recursiveCalculateIndent = function() {

    this.calculateIndent();

    for (var i = 0; i < this.children.length; i++) {
        this.children[i].recursiveCalculateIndent();
    }

}

AT_Node.prototype.calculateIndent = function() {

    this.indent = this.parentNode ? this.parentNode.copyIndent() : [];

    if (this.indent.length > 0) {
        if (this.indent[ this.indent.length - 1 ].down) {
            this.indent[ this.indent.length - 1 ].up = true;
            this.indent[ this.indent.length - 1 ].down = true;
            this.indent[ this.indent.length - 1 ].right = false;
            this.indent[ this.indent.length - 1 ].image = false;
        } else {
            this.indent[ this.indent.length - 1 ].up = false;
            this.indent[ this.indent.length - 1 ].down = false;
            this.indent[ this.indent.length - 1 ].right = false;
            this.indent[ this.indent.length - 1 ].image = false;
        }
    }

    if (this.parentNode) {
        var i = this.indent.length;
        this.indent[i] = {up: true, right: true};

        if (this.children.length > 0) {
            if (this.open) {
                this.indent[i].image = "minus";
            } else {
                this.indent[i].image = "plus";
            }
        } else {
            this.indent[i].image = "empty";
        }

        if (this.nextNode) {
            this.indent[i].down = true;
        } else {
            this.indent[i].down = false;
        }
    }

    if (document.getElementById("at_indent_" + this.id)) {
        var htmlString = "";

        for (var i = 0; i < (this.indent.length - 1); i++) {
            htmlString = htmlString + "      <img class='" + this.buildClassName(this.indent[i]) + "' src='" + AmazingTree.baseURL + "images/empty.gif'> ";
        }

        document.getElementById("at_indent_" + this.id).innerHTML = htmlString;

        if (this.indent.length > 0) {
            document.getElementById("at_treeImage_" + this.id).className = this.buildClassName(this.indent[ this.indent.length - 1 ]);
        }

        if (!this.icon) {
            if (this.children.length > 0) {
                if (this.open) {
					document.getElementById("at_itemImage_" + this.id).style.background = "transparent url(\"" + AmazingTree.baseURL + "images/folderopen.gif" + "\") no-repeat scroll 0px 0px";
                } else {
					document.getElementById("at_itemImage_" + this.id).style.background = "transparent url(\"" + AmazingTree.baseURL + "images/folder.gif" + "\") no-repeat scroll 0px 0px";
                }
            } else {
				document.getElementById("at_itemImage_" + this.id).style.background = "transparent url(\"" + AmazingTree.baseURL + "images/page.gif" + "\") no-repeat scroll 0px 0px";
            }
        }
    }

},

AT_Node.prototype.getHTML = function() {

    if (!this.id) {
        this.id = AmazingTree.getNewId();
        AmazingTree.idToNode[ this.id ] = this;
    }

    this.calculateIndent();

    if (!this.parentNode) {  // root node

        this.open = true;

        var mouseFollower = document.getElementById("at_mouseFollower");
        if (!mouseFollower){
            mouseFollower = document.createElement('div');
            mouseFollower.className = "mouseFollower";
            mouseFollower.style.zIndex = 10000;
            mouseFollower.id = "at_mouseFollower";
            document.body.appendChild(mouseFollower);
        }

    }

    var icon = this.icon;
    if (!icon) {
        if (this.children.length > 0) {
            if (this.open) {
                icon = AmazingTree.baseURL + "images/folderopen.gif";
            } else {
                icon = AmazingTree.baseURL + "images/folder.gif";
            }
        } else {
            icon = AmazingTree.baseURL + "images/page.gif";
        }
    }

    returnString = "";
    returnString = returnString + "<div id='at_unit_" + this.id + "' class='unit'>";
    returnString = returnString + "  <div id='at_item_" + this.id + "' class='item'>";
    returnString = returnString + "    <span id='at_indent_" + this.id + "'>";

    for (var i = 0; i < (this.indent.length - 1); i++) {
        returnString = returnString + "      <img class='" + this.buildClassName(this.indent[i]) + "' src='" + AmazingTree.baseURL + "images/empty.gif'>";
    }

    returnString = returnString + "    </span>";

    if (this.indent.length > 0) {
        returnString = returnString + "    <img id='at_treeImage_" + this.id + "' class='" + this.buildClassName(this.indent[ this.indent.length - 1 ]) + "' src='" + AmazingTree.baseURL + "images/empty.gif' onclick='AmazingTree.toggle(" + this.id + ")'>";
    }
    
    var temp = icon.split(",");
    var offsetLeftPixels = temp[1] ? temp[1] : 0;
    var offsetTopPixels = temp[1] ? temp[2] : 0;
    returnString = returnString + "    <img id='at_itemImage_" + this.id + "' class='itemImage' src='" + AmazingTree.baseURL + "images/empty.gif' width='16' height='16' style='background: transparent url(\"" + temp[0] + "\") no-repeat scroll " + offsetLeftPixels + "px " + offsetTopPixels + "px;'>";

    if (this.url) {
        returnString = returnString + "    <a id='at_itemLink_" + this.id + "' " + (this.target ? ("target='" + this.target + "' ") : "" ) + "href='" + this.url + "' onmousedown='return AmazingTree.handleMouseDown(this, event);'>";
    } else {
        returnString = returnString + "    <span id='at_itemLink_" + this.id + "' onmousedown='return AmazingTree.handleMouseDown(this, event);'>";
    }
    returnString = returnString + "      <span id='at_itemLinkText_" + this.id + "'>" + this.text + "</span>";

    if (this.url) {
        returnString = returnString + "    </a>";
    } else {
        returnString = returnString + "    </span>";
    }
    returnString = returnString + "    <span id='at_itemIndicator_" + this.id + "'></span>";
    returnString = returnString + "  </div>";
    returnString = returnString + "  <div id='at_children_" + this.id + "' class='children' style='display:" + (this.open ? "block" : "none") + ";'>";

    for (i = 0; i < this.children.length; i++) {
        returnString = returnString + this.children[i].getHTML();
    }

    returnString = returnString + "  </div>";
    returnString = returnString + "</div>";

    return returnString;

}

AT_Node.prototype.render = function(element) {

    element.innerHTML = this.getHTML();

    this.updateUnit();

}

AT_Node.prototype.updateUnit = function(element) {

    this.id ? this.unit = document.getElementById("at_unit_" + this.id) : null;

    for (var i = 0; i < this.children.length; i++) {
        this.children[i].updateUnit();
    }

}

AT_Node.prototype.expand = function() {

    if (this.children.length == 0) {
        return;
    }

    this.open = true;

    if (this.id && document.getElementById("at_children_" + this.id)) {
        this.indent[ this.indent.length - 1 ].image = "minus";
        document.getElementById("at_treeImage_" + this.id).className = this.buildClassName( this.indent[ this.indent.length - 1 ] );
        if (this.iconOpen) {
        	var temp = this.iconOpen.split(",");
            var offsetLeftPixels = temp[1] ? temp[1] : 0;
            var offsetTopPixels = temp[1] ? temp[2] : 0;
            document.getElementById("at_itemImage_" + this.id).style.background = "transparent url(\"" + temp[0] + "\") no-repeat scroll " + offsetLeftPixels + "px " + offsetTopPixels + "px";
        } else {
        	document.getElementById("at_itemImage_" + this.id).style.background = "transparent url(\"" + AmazingTree.baseURL + "images/folderopen.gif" + "\") no-repeat scroll 0px 0px";
        }
        document.getElementById("at_children_" + this.id).style.display = "block";
    }

    if (this.parentNode) {
        this.parentNode.expand();
    }

}

AT_Node.prototype.collapse = function() {

    this.open = false;

	if (this.icon) {
     	var temp = this.icon.split(",");
        var offsetLeftPixels = temp[1] ? temp[1] : 0;
        var offsetTopPixels = temp[1] ? temp[2] : 0;
        document.getElementById("at_itemImage_" + this.id).style.background = "transparent url(\"" + temp[0] + "\") no-repeat scroll " + offsetLeftPixels + "px " + offsetTopPixels + "px";
    } else {
       	document.getElementById("at_itemImage_" + this.id).style.background = "transparent url(\"" + AmazingTree.baseURL + "images/folder.gif" + "\") no-repeat scroll 0px 0px";
    }

    if (this.children.length == 0) {
        return;
    }
	
    if (document.getElementById("at_children_" + this.id)) {
        this.indent[ this.indent.length - 1 ].image = "plus";
        document.getElementById("at_treeImage_" + this.id).className = this.buildClassName( this.indent[ this.indent.length - 1 ] );
        document.getElementById("at_children_" + this.id).style.display = "none";
    }

}
