// IE seems not to support indexOf(). Add it if it doesn't exist.
if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function (val) {
        for (var i=0; i<this.length; i++) {
            if (this[i] == val) {
                return i;
            }
        }
        
        return -1;
    }
}


var IMG_DIR = 'mdTree/images/';

function Branch(id, label, url, prefix, isLast, isLeaf, isRoot)
{
    this.id = id;
    
    this.label = label;
    this.url = url;
    this.prefix = prefix || [];
    
    if (isLast == undefined)
        isLast = true;
        
    this.isLast = isLast;    
    this.isLeaf = isLeaf;
    this.isRoot = isRoot;
}

Branch.openNodes = [];

Branch.lastId = 0;

Branch.removeOpenNodeId = function (id) {
    var i = Branch.openNodes.indexOf(id);
    if (i >= 0) {
        Branch.openNodes.splice(i, 1);
        Branch.saveCookie();
    }
}

Branch.addOpenNodeId = function (id) {
    var i = Branch.openNodes.indexOf(id);
    if (i == -1) {
        Branch.openNodes.push(id);
        Branch.saveCookie();
    }
}

Branch.loadCookie = function () {
    Branch.openNodes = [];

    // Read cookie and store set of id:s for open nodes
    var cookies = document.cookie.split(/;\s*/);
    for (var i=0; i<cookies.length; i++) {
        var parts = cookies[i].split('=');
        if (parts[0] == 'mdTree') 
        {
            Branch.openNodes = parts[1].split('|');
            break;
        }
    }
}

//Branch.loadCookie();

Branch.saveCookie = function () {
    document.cookie = 'mdTree=' + Branch.openNodes.join('|');
}
    

Branch.prototype.toNode = function () {
        
    var d = document.createElement('div');
    d.id = 'b' + this.id;

    for (var i=0; i<this.prefix.length; i++) {
        d.appendChild(this.prefix[i].cloneNode(false));
    }

    if (!this.isRoot) {
        var i1 = document.createElement('img');
        i1.src = IMG_DIR + (this.isLast ? 'joinbottom.gif' : 'join.gif');
        d.appendChild(i1);
    }

    if (!this.isLeaf) {
        var i2 = document.createElement('img');
        i2.id = 'i' + this.id;
        i2.src = IMG_DIR + 'plus.gif';

        var b = this;
        i2.onclick = function () { b.toggle() };
        d.appendChild(i2);
    }

    if (this.url) {
        var a = document.createElement('a');
        a.href = this.url;

        //var t = document.createTextNode(this.label);
        //a.appendChild(t);
		var b = this;
		a.onclick = function () { 
			Branch.openNodes=[];
			for (var p=b; p; p=p.parent)
				Branch.addOpenNodeId(p.id);
		};
        
        a.innerHTML = this.label;
        
        d.appendChild(a);
    }
    else {
        var t = document.createTextNode(this.label);
        d.appendChild(t);
    }

    // Create div for subs
    var s = document.createElement('div');
    s.id = 's' + this.id;
    d.appendChild(s);

    return d;
}

Branch.prototype.addChild = function (node) {
    if (this.subs == undefined) 
        this.subs = [];
        
	node.parent = this;
    this.subs.push(node);

    var n = node.toNode();
    //alert('s' + this.id);
    var s = document.getElementById('s' + this.id);
    s.appendChild(n);
}

Branch.prototype.loadSubs = function () {

    // Clone current prefix (array of DOM nodes)
    var p = [];
    for (var i=0; i<this.prefix.length; i++) {
        p.push(this.prefix[i].cloneNode(false));
    }

    if (!this.isRoot) {
        // Extend prefix
        var img = document.createElement('img');
        img.src = IMG_DIR + (this.isLast ? 'empty.gif' : 'line.gif');
        p.push(img);
    }

    var req;
    if (window.XMLHttpRequest) { // Mozilla, Safari, ...
        req = new XMLHttpRequest();
    } else if (window.ActiveXObject) { // IE
        try {
            req = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
            try {
                req = new ActiveXObject("Microsoft.XMLHTTP");
            } catch (e) {}
        }
    }
    //var req = new XMLHttpRequest();
    if (this.cPath == undefined)
		this.cPath = this.id.substring(1);
		
    var url = 'mdTree/subs.php?id='+this.id+'&'+sid+'&cp='+cp+'&cPath='+this.cPath;
    //alert('Contacting ' + url);
    req.open('GET', url, true);
    var b = this;

    // Handle response
    req.onreadystatechange = function () {
        if (req.readyState == 4 && req.responseText != '') {
            var ns = req.responseText.split('||');
            var s;
            for (var i=0; i<ns.length; i++) {
                var id_name = ns[i].split('|');
                //alert('Got ' + id_name[3]);
                var isLast = (i == ns.length-1);
                s = new Branch(id_name[0].toLowerCase()+id_name[1], id_name[2], id_name[3], p, isLast, id_name[0] == 'P');
				s.cPath = id_name[4];
                b.addChild(s);
                if (!s.isLeaf) {
                    s.restoreState();
                }
            }
        }
    }
    req.send(null);
}

Branch.prototype.toggle = function () {

    // Load subs if necessary
    if (this.subs == undefined) {
        this.loadSubs();
    }
    
    var s = document.getElementById('s'+this.id);
    var i = document.getElementById('i'+this.id);
    if (s.style.display == 'block') {
        s.style.display = 'none';
        i.src = IMG_DIR + 'plus.gif';
        
        // Remove id of this node from open nodes
        Branch.removeOpenNodeId(this.id);
    }
    else {
        s.style.display = 'block';
        i.src = IMG_DIR + 'minus.gif';

        Branch.addOpenNodeId(this.id);
    }
}

Branch.prototype.open = function () {

    // Load subs if necessary
    if (this.subs == undefined) {
        this.loadSubs();
    }
    
    var s = document.getElementById('s'+this.id);
    var i = document.getElementById('i'+this.id);
    if (s.style.display != 'block') {
        s.style.display = 'block';
        i.src = IMG_DIR + 'minus.gif';

        Branch.addOpenNodeId(this.id);
    }
}

Branch.prototype.restoreState = function () {
    if (Branch.openNodes && Branch.openNodes.indexOf(this.id) >= 0) {
        this.open();
    }
}

Branch.prototype.openPath = function (path) {
	if (path.length == 0)
		return;
		
	if (this.id == path[0]) {
		this.open();

		if (this.subs != undefined)
			for (var i=0; i<this.subs.length; i++) {
				this.subs[i].openPath(path.slice(1));
			}
	}
}
