/* xmlloader.js */ 
﻿/*--
Copyright © 1998, 2012, Oracle and/or its affiliates.  All rights reserved.
--*/

//////////////////////////////////////////////////////////////////////////////
// Simple function for load XML file by HTTPRequest
// Parameters:
//	url				url of xml file
//	workerFunction	name of callback function will be called with request in the following form:
//					workerFunction(req,extraInfo);
//	extraInfo		extra information for user will be give back with callback function

var _workerFunction = "";
var _errorFunction = "";
var _extraInfo = "";
var _req;
var _url;

function AbsUrl(url) {
    for (var i = 0; i < url.length; i++) {
        c = url.substr(i, 1);
        if (c == ':')
            return url;
    }
    base = window.location.href;

    var k1 = base.indexOf('?');
    var k2 = base.indexOf('#');
    if (k1 >= 0 || k2 >= 0) {
        if (k1 >= 0 && k2 >= 0) {
            base = base.substr(0, (k1 < k2 ? k1 : k2));
        }
        else if (k1 >= 0) {
            base = base.substr(0, k1);
        }
        else {
            base = base.substr(0, k2);
        }
    }

    if (url.substr(0, 3) == "../") {
        var k = base.lastIndexOf('/');
        base = base.substr(0, k);
        while (url.substr(0, 3) == "../") {
            k = base.lastIndexOf('/');
            base = base.substr(0, k);
            url = url.substr(3);
        }
        base = base + "/" + url;
    }
    else {
        if (url.substr(0, 1) == "/")
            url = url.substr(1);
        k = base.lastIndexOf('/');
        base = base.substr(0, k);
        base = base + "/" + url;
    }
    return (base);
}

function LoadXMLDoc(url, workerFunction, errorFunction, extraInfo) {
    _workerFunction = workerFunction;
    _errorFunction = errorFunction;
    _extraInfo = extraInfo;
    _url = AbsUrl(url);
    try {
        _req = new ActiveXObject("Microsoft.XMLHTTP");
    }
    catch (e) {
        _req = new XMLHttpRequest();
    }
    _req.onreadystatechange = state_Change;
    _req.open("GET", _url, true);
    _req.send(null);
}

function state_Change() {
    if (_req.readyState == 4) {
        if (_req.status == 200) {
            eval(_workerFunction + "(_req,_extraInfo)");
        }
        else if (_req.status == 0) {
            if (_req.responseXML.documentElement == null) {
                var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
                xmlDoc.async = false;
                xmlDoc.loadXML(_req.responseText);
                _req = new Object();
                _req.responseXML = xmlDoc;
            }
            eval(_workerFunction + "(_req,_extraInfo)");

        }
        else {
            if (_url.substr(0, 3) == "../") {
                LoadXMLDoc(_url.substr(3), _workerFunction, _errorFunction, _extraInfo);
            }
            else if (_errorFunction.length > 0) {
                alert(_url + " not found. Logged...");
                eval(_errorFunction + "(_extraInfo)");
            }
            else
                alert("Problem retrieving data: " + _req.statusText);
        }
    }
}

//////////////////////////////////////////////////////////////////////////////
// Function to load XML files contain simple arrays
// Parameters:
//	url				url of xml file
//	returnFunction	function will be call back with a simple array loaded from xml file
//	nodeName		name of node for load

var _returnFunction = "";
var _nodes;
var _nodesArray = new Array();

function LoadXMLDocArray(url, returnFunction, errorFunction, nodeName, xmlmode) {
    _returnFunction = returnFunction;
    _nodeName = nodeName;
    if (!xmlmode)
        LoadXMLDoc(url, "XMLDocArrayWorker", errorFunction, nodeName);
    else
        LoadXMLDoc(url, "XMLDocArrayWorker2", errorFunction, nodeName);
}

function XMLDocArrayWorker(req, extraInfo) {
    _nodesArray = new Array();
    _nodes = req.responseXML.getElementsByTagName(extraInfo);
    for (var i = 0; i < _nodes.length; i++) {
        n = _nodes[i];
        s = (n.textContent ? n.textContent : n.text);
        if (!s)
            s = "";
        k = s.length;
        if (k >= 2) {
            if ((s.substr(0, 1) == '\"') && (s.substr(k - 1, 1) == '\"')) {
                ss = s.substr(1, k - 2);
                s = ss;
            }
        }
        _nodesArray[_nodesArray.length] = s;
    }
    sfn = _returnFunction + "(_nodesArray)";
    setTimeout(sfn, 1);
}

function XMLDocArrayWorker2(req, extraInfo) {
    _nodesArray = new Array();
    _nodes = req.responseXML.getElementsByTagName(extraInfo);
    for (var i = 0; i < _nodes.length; i++) {
        n = _nodes[i];
        xmlname = n.attributes[0].nodeValue;
        xmltext = "";
        for (var j = 0; j < n.childNodes.length; j++) {
            if (n.childNodes[j].xml) {
                xmltext += n.childNodes[j].xml;
            } else {
                var oSerializer = new XMLSerializer;
                xmltext += oSerializer.serializeToString(n.childNodes[j]);
            }
        }
        _nodesArray[_nodesArray.length] = xmlname + "=" + xmltext;
    }
    sfn = _returnFunction + "(_nodesArray)";
    setTimeout(sfn, 1);
}

/* query.js */ 
﻿/*--
Copyright © 1998, 2012, Oracle and/or its affiliates.  All rights reserved.
--*/

// OnDemand query parser

datasourceroot = "querydb/";
ConvertDbSelector = { t: "text", u: "ctxod", e: "ctxex", r: "role", g: "genctx" };

var q_search_and = " and ";
var q_search_or = " or ";

function ToHalfWidth(str)
{
  var halfKatakanaSet = "ｦｧｨｩｪｫｬｭｮｯｰｱｲｳｴｵｶｷｸｹｺｻｼｽｾｿﾀﾁﾂﾃﾄﾅﾆﾇﾈﾉﾊﾋﾌﾍﾎﾏﾐﾑﾒﾓﾔﾕﾖﾗﾘﾙﾚﾛﾜﾝ";
  var fullKatakanaSet = "ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン";
  
  var result="";
  
  for (var i=0; i<str.length; i++)
  {
	var k = fullKatakanaSet.indexOf(str.charAt(i));
	if (k!=-1)
		result += halfKatakanaSet.charAt(k);
	else if (str.charCodeAt(i)>=0xff01 && str.charCodeAt(i)<=0xff5f)
		result += String.fromCharCode(str.charCodeAt(i)-0xfee0);
	else
		result += str.charAt(i);
  }
  
  return result;
}

var QueryParser = { 
	PS: null, // stack
	PT: [ 0,
//     e   (   )   &|  !  EOT q
	[  2,  3,  0,  0,  0,  0, 4 ],
	[ -1, -1, -1, -1,  5, -1, 0 ],
	[  2,  3,  0,  0,  0,  0, 6 ],
	[  0,  0,  0,  7,  0, 10, 0 ],
	[ -2, -2, -2, -2, -2, -2, 0 ],
	[  0,  0,  8,  7,  0,  0, 0 ],
	[  2,  3,  0,  0,  0,  0, 9 ],
	[ -4, -4, -4, -4, -4, -4, 0 ],
	[ -3, -3, -3, -3, -3, -3, 0 ]],

Parse: function(query_type, query_expression)
{
	if (window.R_search_AND)
		q_search_and = " " + R_search_AND.toLowerCase() + " ";
	if (window.R_search_OR)
		q_search_or = " " + R_search_OR.toLowerCase() + " ";

	var lexer;
	var keyws;
	if ("URI" == query_type) {
		lexer = /\(|\)|\+|-|[u,e,k,r,g]|!|\d|'[^']+'/g;
		keyws = ["(",")","+","-","u","e","t","r","g","!","0","1","2","3","4","5","6","7","8","9"];
	} else {
		lexer = new RegExp('\\(|\\)|'+q_search_and+'|'+q_search_or+'|"[^"]+"|[^ \\(\\)]+(?=\\(|\\)|\\s|$)','gi'); //doesn't support db|!|\d
		keyws = ["(",")",q_search_and,q_search_or];
	}
	var codem = [1,2,3,3,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4];
	var semvm = [0,0,"&","|",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];


	if (query_type!='URI')
	{
		query_expression = ToHalfWidth(query_expression);
		query_expression = query_expression.toLowerCase();
	}
	
	this.ev = null;
	this.pr = null;
	this.PS = new Array()
	this.PS.push({st: 1, se: 0});
	
	var result;
	var i;
	var opm = 0; // operator missing
	var cdb = "t"; // current database
	while ((result = lexer.exec(query_expression)) != null) {
		var sem = result[0]; // semantic value
		var sym = 0; // symbol value
		for (i in keyws) {
			if (sem == keyws[i]) {
				sym = codem[i];
				if (semvm[i])
					sem = semvm[i];
				break;
			}
		}

		// lexical preprocessor
		// 1) implicit db settings
		// 2) implicit operator '&'
		if (sym == 5) { // db change is stored but not passed
			cdb = sem;
			continue;
		}
		if (sym == 3) // operator
			opm = 0;
		if ((sym == 0 || sym == 1) && opm) { 
			if (this.SM(3, "&")) // insert missing '&'
				return;
			opm = 0;
		}
		if (sym == 0) { // condition
			if (sem.charAt(0) == '"' || sem.charAt(0) == "'")
				sem = sem.slice(1, sem.length - 1);
			if ("URI" != query_type) 
			{
				sem = Escape.MyEscape(sem.toLowerCase());
			}
			sem = cdb + sem;
			opm = 1;
		}
		if (this.SM(sym, sem))
			return;
	}
	if (!this.SM(5, "$")) {
		this.ev = this.PS[1].se.ev;
		this.pr = this.PS[1].se.pr;
	}
//	alert(this.ev + "\n" + this.pr);
},

SM: function(sym, sem)
{
//	alert(sym + ", " + sem);
	while (1) {
		var sp = this.PS[this.PS.length - 1];
		var ptv = this.PT[sp.st][sym];
		if (ptv == 10) {
//			alert("accept");
			return false;
		}
		if (ptv == 0) {
//			alert("error");
			return true; // error
		}
		if (ptv > 0) { // shift
			this.PS.push({st: ptv, se: sem});
			return false;
		}
		if (ptv < 0) {
			var nsem;
			var p = this.PS.length;
			var p1 = this.PS[p - 1];
			var p2 = this.PS[p - 2];
			var p3 = this.PS[p - 3];
			switch (-ptv) {
				case 1: 
					nsem = { 
					ev: "{a:'s', d:'" + p1.se.charAt(0) + "', p:'" + p1.se.slice(1) + "'}", 
					pr: p1.se.slice(1) }; 
					break;
				case 2:	
					if (p1.se == "!") {
						nsem = { ev: "{a:'s', d:'" + p2.se.charAt(0) + "', p:'" + p2.se.slice(1) + "', m:'" + p1.se + "'}" };
					} else {
						var ss = p2.se.slice(1, parseInt(p1.se) + 1) + "$002A";
						nsem = {
						ev: "{a:'s', d:'" + p2.se.charAt(0) + "', p:'" + p2.se.slice(1) +
						"'}, {a:'s', d:'" + p2.se.charAt(0) + "', p:'" + ss + 
						"'}, {a:'o', p:'|'}" };
					}
					nsem.pr = p2.se.slice(1);
					break;
				case 3: nsem = {
					ev: p3.se.ev + ", " + p1.se.ev + ", {a:'o', p:'" + p2.se + "'}",
					pr: p3.se.pr + (p2.se == "|" ? " or " : " ") + p1.se.pr };
					break;
				case 4: nsem = {
					ev: p2.se.ev,
					pr: "(" + p2.se.pr + ")" };	
					ptv = -3;
					break;
			}
			if (ptv == -1 || ptv == -2) {
				nsem.pr = decodeURIComponent(nsem.pr);
				if (nsem.pr.search(/\s/) != -1)
					nsem.pr = '"' + nsem.pr + '"';
			}
			this.PS.length += ptv;
			this.PS.push({st: this.PT[this.PS[this.PS.length - 1].st][6], se: nsem});
		}
	}
},

o: function(op, op1, op2)
{
	debug.insertAdjacentHTML("beforeEnd", "<div>" + op + ", " + op1 + ", " + op2 + "</div>");
	return op1 + op + op2;
},

e: function(db, se, st)
{
	if (!st)
		st = "";
	se = decodeURIComponent(se);
	debug.insertAdjacentHTML("beforeEnd", "<div>" + db + ", " + se + ", " + st + "</div>");
	
	return db + "=" + se + st;
}
};

var QueryProcessor = {
	rr: null,
Start: function(q, r)
{
	this.rr = r;
	eval("this.qa = [" + q + "]");
	this.qp = 0;
	this.Eval();
},

Eval: function()
{
	var n = this.qa[this.qp];
	if (n.a == "s") {
		var m = n.d == "t" ? false : true;
		if (n.m == "!")
			m = !m;
		SearchDBs[n.d].Search(decodeURIComponent(n.p), m);
	} else if (n.a == "o") {
		if (n.p == "&")
			this.qa[this.qp - 2].And(this.qa[this.qp - 1]);
		else
			this.qa[this.qp - 2].Or(this.qa[this.qp - 1]);
		this.qp -= 2;
		this.qa.splice(this.qp + 1, 2);
		this.Next();
	}
},

Next: function()
{
	if (this.qa.length == 1) {
		this.rr(this.qa[0].rs);
		return;
	}
	this.qp++;
	this.Eval();
},

ReportResult: function(r)
{
	this.qa[this.qp] = r;
	this.Next();
}
};

function ReadBase64_6(i)
{
	if (i == 43)
		return 62;
	if (i == 45)
		return 63;
	if (i < 58)
		return i - 48;
	if (i < 91)
		return i - 55;
	else
		return i - 61;
}

function ReadBase64_32(s)
{
	var i, j;
	j = 0;
	i = 0x20;
	while (i & 0x20) {
		i = ReadBase64_6(s.s.charCodeAt(s.p));
		j <<= 5;
		j |= (i & 0x1f);
		s.p++;
	}
	return j;
}

function ReadBase64_ITP(s, ctr)
{
	var r = new Array();
	var c, n, l = 0;
	while (s.p < s.s.length) {
		n = ReadBase64_32(s);
		c = 1 == n ? ReadBase64_32(s) : 1;
		while (c) {
			l += n;
			r.push(new ctr(l));
			c--;
		}
	}
	return r;
}

function SearchDB(dbid)
{
	this.db_id = dbid;
	this.ResetIndex();
	this.request_total = 0;
	this.request_count = 0;
}

SearchDB.prototype.ResetIndex = function()
{
	this.index = new Array();
	this.index.push({ key: null, node: "1" });
}

SearchDB.prototype.k = function(args)
{
	var prev = "";
	for (var i = 0; i < args.length; i++) {
		var s = { s: args[i], p: 0 };
		var l;
		var w = "";
		l = ReadBase64_32(s);
		var nk;
		nk = i == args.length - 1 ? this.index[this.index_insert_position]: new Object;
		nk.node = l > 0 ? s.s.slice(s.p, s.p + l): 0;
		s.p += l;
		l = ReadBase64_32(s);
		w += prev.slice(0, l);
		l = ReadBase64_32(s);
		w += s.s.slice(s.p, s.p + l);
		s.p += l;
		if (w.length > 0) {
			nk.key = w;
		}
		prev = w;
		while (s.p < s.s.length) {
			nk.values = new Array();
			l = ReadBase64_32(s);
			nk.values.push(s.s.slice(s.p, s.p + l));
			s.p += l;
		}
		if (i < args.length - 1) {
			this.index.splice(this.index_insert_position, 0, nk);
			this.index_insert_position++;
		}
	}
	this.d();
}

SearchDB.prototype.LoadScript = function(f)
{
	CDB=this;
	var dbPath = ConvertDbSelector[this.db_id];
//	setTimeout("jsdbfile.src='" + datasourceroot + dbPath + "/" + f + ".js'", 1);
	var s="SearchDBs."+this.db_id+".LoadScript_Callback";
	LoadXMLDocArray(datasourceroot+dbPath+"/"+f+".xml",s,"","N");
	this.request_total++;
	this.request_count++;
}

SearchDB.prototype.LoadScript_Callback = function(a)
{
	CDB=this;
	CDB.k(a);	
}

SearchDB.prototype.Search = function(s, m)
{
	this.RequestCount = 0;
	this.search = s;
	this.exact_match = m;
	this.results = new SearchResultSet();
	if (this.search.length == 0)
		return;
	this.index_match = 0;
	this.d = this.d1;
	this.d();
}

SearchDB.prototype.IndexSearch = function()
{
	var i;
	for (i = this.index_match; i < this.index.length; i++)
		if (null == this.index[i].key || this.search <= this.index[i].key)
			break;

	this.index_match = i;
}

SearchDB.prototype.d1 = function()
{
	this.IndexSearch();
	if (null != this.index[this.index_match].key && this.search == this.index[this.index_match].key) {
		if (!this.exact_match && this.index[this.index_match].values.length < 2) {
			this.d = this.d2;
			this.d();
		} else {
			var v = this.index[this.index_match].values;
			for (var j in v) {
				this.results.Or(new SearchResultSet(v[j]));
				if (this.exact_match)
					break;
			}			
			QueryProcessor.ReportResult(this.results);
		}
	} else {
		if (this.index[this.index_match].node != 0) {
			this.index_insert_position = this.index_match;
			this.LoadScript(this.index[this.index_match].node);
		} else {
			if (!this.exact_match) {
				this.d = this.d2;
				this.d();
			}
			else {
				QueryProcessor.ReportResult(this.results);
			}
		}
	}
}

SearchDB.prototype.d2 = function()
{
	if (null == this.index[this.index_match].key || (this.index[this.index_match].key.substring(0, this.search.length) != this.search && this.index[this.index_match].node == 0)) {
		QueryProcessor.ReportResult(this.results);
		return;
	}
	if (this.index[this.index_match].node == 0) {
		this.results.Or(new SearchResultSet(this.index[this.index_match].values[0]));
		this.index_match++;
		this.d2();
	} else {
		this.index_insert_position = this.index_match;
		this.LoadScript(this.index[this.index_match].node);
	} 
}

SearchDBs = { t: new SearchDB("t"), u: new SearchDB("u"), e: new SearchDB("e"), r: new SearchDB("r"), g: new SearchDB("g") };
CDB = null;

function SearchResult(index)
{
    this.index = index;
    this.weight = 1.0;
}

function SearchResultSet(s)
{
	if (s) {
		var ss = { s: s, p: 0 };
		this.rs = ReadBase64_ITP(ss, SearchResult);
	} else
		this.rs = new Array();
}

SearchResultSet.prototype.Or = function(srs)
{
    this.AOR(srs, true);
}

SearchResultSet.prototype.AOR = function(srs, or, weight)
{
	var i, j;
	for (i = 0, j = 0; i < srs.rs.length; i++) {
		while (j < this.rs.length && this.rs[j].index < srs.rs[i].index)
			j++;
		if (j == this.rs.length || this.rs[j].index != srs.rs[i].index)
			this.rs.splice(j, 0, srs.rs[i]);
		else {
		    var w1 = this.rs[j].weight;
		    var w2 = srs.rs[i].weight;
            this.rs[j].weight = or ? Math.max(w1, w2) : w1 + w2 * weight;
		}
	}
}

SearchResultSet.prototype.And = function(srs)
{
	var i, j;
	for (i = 0, j = 0; i < srs.rs.length && j < this.rs.length; i++) {
		while (j < this.rs.length && this.rs[j].index < srs.rs[i].index)
			this.rs.splice(j, 1);
		if (j < this.rs.length && srs.rs[i].index == this.rs[j].index) {
		    var w1 = this.rs[j].weight;
		    var w2 = srs.rs[i].weight;
	        this.rs[j].weight = Math.min(w1, w2);
			j++;
	    }
	}
	this.rs.splice(j, this.rs.length - j);
}

/* tree.js */ 
﻿/*--
Copyright © 1998, 2012, Oracle and/or its affiliates.  All rights reserved.
--*/

// common variables

var treeControlDB = false;
var bigsco = false;

function ModeDesc(k) {
    this.treeCreated = false;
    this.lastSelected = null;
    this.filteredGuids = new Array();
    this.filteredGuidList = new Array();
    this.filteredTopicCount = 0;
    this.guidsForFlat = new Array();
    this.lastSelectedFlat = null;
    this.flatMode = false;
    this.modeLetter = k;
    this.treeControl = null;
    this.flatControl = null;
}

var modeDescA = new ModeDesc("A");
var modeDescF = new ModeDesc("F");
var modeDescH = new ModeDesc("H");
var modeDescFH = new ModeDesc("X");

var treeViewMode = "ALL"; 			// view mode ("ALL" or "FILTERED" or "HEMI" or "FILTEREDHEMI")
var treeIsEmpty;
var _rootData = "";

function GetJunctionId(s) {
    k = s.indexOf('_');
    kk = s.indexOf('_', k + 1)
    ss = s.substr(0, kk);
    return ss;
}

////////////////////////////////////
// filtering support

var filteredGuidsR = new Array(); // associative array contains all guid to show
var filteredTopicCountR = 0; 	// number of filtered topics (ROLES)
var rolefilter_enabled = false;

var selection_need = 0;
var stl_mode = "ALL";
var stl_callback = "";
var stl_myTopicArray = new Array();
var stl_myscoresArray = new Array();
var stl_i = 0;
var stl_topicMapId = -1;
var stl_newtMap = false;
var stl_topicMapPageLen = -1;
var global_topicMap = new Array();
var seeAlsoSelection = 0;

var _lastChangeIsFilterOnly = false;

function SetTopicList(mode, topicarray, callbackfn) {
    stl_mode = mode;
    stl_callback = callbackfn;
    _lastChangeIsFilterOnly = false;
    if (mode == "FILTERED") {
        modeDescF.filteredGuids = new Array();
        modeDescF.filteredGuidList = new Array();
        modeDescF.filteredTopicCount = topicarray.length;
        modeDescF.guidsForFlat = new Array();
        modeDescF.flatMode = true;
    }
    else if (mode == "HEMI") {
        modeDescH.filteredGuids = new Array();
        modeDescH.filteredGuidList = new Array();
        modeDescH.filteredTopicCount = topicarray.length;
        modeDescH.guidsForFlat = new Array();
        modeDescH.flatMode = true;
    }
    else if (mode == "ROLES") {
        filteredGuidsR = new Array();
        filteredTopicCountR = topicarray.length;
        rolefilter_enabled = true;
        _lastChangeIsFilterOnly = true;
    }
    else	// "NOROLES"
    {
        rolefilter_enabled = false;
        _lastChangeIsFilterOnly = true;
        eval(stl_callback + "()");
        return;
    }
    stl_myTopicArray = new Array();
    stl_myTopicArray = topicarray;
    stl_myscoresArray = new Array();
    if (topicarray.length > 0) {
        try {
            var a = topicarray[0].index;
            if (a) {
                stl_myTopicArray = new Array();
                for (var i = 0; i < topicarray.length; i++) {
                    stl_myTopicArray[stl_myTopicArray.length] = topicarray[i].index;
                    stl_myscoresArray[topicarray[i].index] = topicarray[i].score;
                }
            }
        }
        catch (e) {
        }
    }
    stl_i = 0;
    if (stl_topicMapPageLen == -1)
        SetTopicList_LoadPageLen();
    else
        SetTopicList_Next();
}

function SetTopicList_LoadPageLen() {
    LoadXMLDocArray("../querydb/topicmap/0.xml", "SetTopicList_LoadPageLen_Return", "", "T");
}

function SetTopicList_LoadPageLen_Return(retArray) {
    stl_topicMapPageLen = parseInt(retArray[0]);
    SetTopicList_Next();
}

function SetTopicList_Next() {
    fTC = modeDescF.filteredTopicCount;
    if (stl_mode == "HEMI")
        fTC = modeDescH.filteredTopicCount;
    if (stl_mode == "ROLES")
        fTC = filteredTopicCountR;
    if (!(stl_i < fTC)) {
        eval(stl_callback + "()");
        return;
    }
    j = stl_myTopicArray[stl_i];
    a = Math.floor((j - 1) / stl_topicMapPageLen);
    if (!global_topicMap["" + a]) {
        stl_topicMapId = a;
        stl_newtMap = true;
        LoadXMLDocArray("../querydb/topicmap/" + a + ".xml", "SetTopicList_Next2", "", "T");
    }
    else {
        stl_topicMapId = a;
        stl_newtMap = false;
        setTimeout("SetTopicList_Next2()", 1);
    }
}

function DecodeTMapArray(tmapArray) {
    var newArray = new Array();
    var fullstr = "";
    for (var i = 0; i < tmapArray.length; i++) {
        if (i == 0) {
            newArray[newArray.length] = tmapArray[i];
        }
        else {
            var s = { s: tmapArray[i], p: 0 };
            l = ReadBase64_32(s);
            str = fullstr.substr(0, l) + s.s.substr(s.p, s.s.length);
            fullstr = str;
            newArray[newArray.length] = str;
        }
    }
    return newArray;
}

function ItemDesc(type, title, empty) {
    this.type = type;
    this.title = title;
    this.empty = empty;
    this.found = false;
    this.parentguid = null;
    this.openable = new Array();
    this.treeitemdiv = null;
}

function AddItemdesc(o, array, ss, type, title, empty, found, topicguid, parentguid) {
    l = false;
    try {
        l = array[ss].title.length > 0;
    }
    catch (e) { };
    if (!l) {
        array[ss] = new ItemDesc(type, title, empty);
        if (o)
            o.filteredGuidList[o.filteredGuidList.length] = ss;
        AddToIndexMap(ss);
    }
    array[ss].parentguid = parentguid;
    if (found == true)
        array[ss].found = true;
    if (topicguid.length > 0)
        array[ss].openable[array[ss].openable.length] = topicguid;
}

function AddTreeItemToItemDesc(guid, itemdiv) {
    md = getModeDesc();
    try {
        if (treeViewMode == "FILTEREDHEMI") {
            if (!md.filteredGuids)
                md.filteredGuids = new Array();
            if (!md.filteredGuids[guid]) {
                md.filteredGuids[guid] = new ItemDesc("", "", false);
                md.filteredGuidList[md.filteredGuidList.length] = guid;
            }
            AddToIndexMap(guid);
        }
        md.filteredGuids[guid].treeitemdiv = itemdiv;
    }
    catch (e) { };
    saveModeDesc(md);
}

function GetTreeItemOfItemDesc(guid) {
    md = getModeDesc();
    var _item = null;
    try {
        _item = md.filteredGuids[guid].treeitemdiv;
    }
    catch (e) { };
    return _item;
}

function FlatItemDesc(type, title, empty, guid, isroot, score) {
    this.type = type;
    this.title = title;
    this.empty = empty;
    this.guid = guid;
    this.isroot = isroot;
    if (!score)
        score = 0;
    this.score = score;
}

function AddFlatItemdesc(array, guid, type, title, empty, isroot, score) {
    for (var i = 0; i < array.length; i++) {
        if (array[i].guid == guid)
            return;
    }
    array[array.length] = new FlatItemDesc(type, title, empty, guid, isroot, score);
}

// IAS HOOK !!!
var foundApplicableList = new Array();
var foundApplicableTable = new Array();

function SetTopicList_Next2(tmapArray) {
    if (stl_newtMap) {
        global_topicMap["" + stl_topicMapId] = DecodeTMapArray(tmapArray);
    }
    j = stl_myTopicArray[stl_i];
    a = Math.floor((j - 1) / stl_topicMapPageLen);
    s = global_topicMap["" + stl_topicMapId][j - (a * stl_topicMapPageLen)];
    k = s.indexOf('#');
    s1 = s.substr(0, k);
    _tguid = s1;
    kk = s1.lastIndexOf('/')
    if (kk > 0)
        _tguid = s1.substr(kk + 1);

    var _isroot = (kk < 0);
    var _concept = (s.substr(k + 1, 1) == 'C');
    var _empty = (s.substr(k + 2, 1) == 'E');

    var rbs = { s: s.substr(k + 3), p: 0 };
    l = ReadBase64_32(rbs);
    s2 = rbs.s.substr(rbs.p + l);
    title = rbs.s.substr(rbs.p, l);
    type = s2;
    k = s2.indexOf('#');
    if (k >= 0) {
        type = s2.substr(0, k);
        s4 = s2.substr(k);
        s2 = s4;
    }
    else {
        s2 = "";
    }
    s = s1 + s2;
    k = s.indexOf('/');
    var _pguid = null;

    if (type == 'Topic' || _concept == true) {
        while (k >= 0) {
            ss = "" + s.substr(0, k);

            // IAS HOOK !!!
            if (parent.TocFirstCall) {
                var g = _tguid.substr(0, 36);
                if (foundApplicableTable[g] != true) {
                    foundApplicableTable[g] = true;
                    foundApplicableList.push(g);
                }
            }

            if (stl_mode == "FILTERED") {
                //  			filteredGuidsF[ss]=itemdesc;
                //  			filteredGuidsF[ss.substr(0,36)]=itemdesc;
                AddItemdesc(modeDescF, modeDescF.filteredGuids, ss, type, title, _empty, false, _tguid, _pguid);
                AddItemdesc(modeDescF, modeDescF.filteredGuids, ss.substr(0, 36), type, title, _empty, false, _tguid, _pguid);
            }
            else if (stl_mode == "HEMI") {
                //  			filteredGuidsH[ss]=itemdesc;
                AddItemdesc(modeDescH, modeDescH.filteredGuids, ss, type, title, _empty, false, _tguid, _pguid);
                AddItemdesc(modeDescH, modeDescH.filteredGuids, ss.substr(0, 36), type, title, _empty, false, _tguid, _pguid);
            }
            else	// "ROLES"
            {
                //  			filteredGuidsR[ss]=itemdesc;
                AddItemdesc(null, filteredGuidsR, ss, type, title, _empty, false, _tguid, null);
                AddItemdesc(null, filteredGuidsR, ss.substr(0, 36), type, title, _empty, false, _tguid, null);
            }
            _pguid = ss;
            ss = s.substr(k + 1);
            s = ss;
            k = s.indexOf('/');
        }
        if (s.length > 0) {
            ss = s;
            k = s.indexOf('#');
            if (k > 0)
                ss = s.substr(0, k);
            if (stl_mode == "FILTERED") {
                //  			filteredGuidsF[ss]=itemdesc;
                AddItemdesc(modeDescF, modeDescF.filteredGuids, ss, type, title, _empty, true, "", _pguid);
                AddFlatItemdesc(modeDescF.guidsForFlat, ss, type, title, _empty, _isroot);
            }
            else if (stl_mode == "HEMI") {
                //  			filteredGuidsH[ss]=itemdesc;
                AddItemdesc(modeDescH, modeDescH.filteredGuids, ss, type, title, _empty, true, "", _pguid);
                _score = stl_myscoresArray[stl_myTopicArray[stl_i]];
                AddFlatItemdesc(modeDescH.guidsForFlat, ss, type, title, _empty, _isroot, _score);
            }
            else {
                //  			filteredGuidsR[ss]=itemdesc;
                AddItemdesc(null, filteredGuidsR, ss, type, title, _empty, true, "", null);
                AddItemdesc(null, filteredGuidsR, ss.substr(0, 36), type, title, _empty, true, "", null);
            }
        }
    }
    stl_i++;
    SetTopicList_Next();
}

//////////////////////////////////////////////////////////////////////////////

function TreeViewModeLetter() {
    if (treeViewMode == "FILTEREDHEMI")
        return "X";
    return treeViewMode.substr(0, 1);
}

function IsFiltered(guid, tMode) // true if the guid must be show
{
    var k;
    l = 0;
    try {
        l = filteredGuidsR[guid].title.length;
    }
    catch (e) { };

    roles = 0; //not enabled
    if (rolefilter_enabled) {
        roles = (l > 0 ? 1 : 2); // 1 -> found, 2 -> not found
    }

    if (tMode == "ALL") {
        if (roles == 0) {
            treeIsEmpty = false;
            return true;
        }
        else if (roles == 1) {
            l = false;
            try {
                l = (filteredGuidsR[guid].openable.length > 0 || filteredGuidsR[guid].found);
            }
            catch (e) { };
            if (l == true)
                treeIsEmpty = false;
            return l;
        }
        else {
            return false;
        }


    }
    else if (tMode == "FILTERED") {
        l = 0;
        try {
            l = modeDescF.filteredGuids[guid].title.length;
        }
        catch (e) { };
        if (l == 0)
            return false;

        if (roles == 0) {
            treeIsEmpty = false;
            return true;
        }
        else if (roles == 1) {
            l = false;
            try {
                l = Cut(modeDescF.filteredGuids[guid].openable, filteredGuidsR[guid].openable) ||
							(modeDescF.filteredGuids[guid].found && filteredGuidsR[guid].found);
            }
            catch (e) { };
            if (l == true)
                treeIsEmpty = false;
            return l;
        }
        else {
            return false;
        }
    }
    else if (tMode == "HEMI") {
        l = 0;
        try {
            l = modeDescH.filteredGuids[guid].title.length;
        }
        catch (e) { };
        if (l == 0)
            return false;

        if (roles == 0) {
            treeIsEmpty = false;
            return true;
        }
        else if (roles == 1) {
            l = false;
            try {
                l = Cut(modeDescH.filteredGuids[guid].openable, filteredGuidsR[guid].openable) ||
							(modeDescH.filteredGuids[guid].found && filteredGuidsR[guid].found);
            }
            catch (e) { };
            if (l == true)
                treeIsEmpty = false;
            return l;
        }
        else {
            return false;
        }
    }
    else	// FILTEREDHEMI
    {
        if (roles == 0) {
            l = false;
            try {
                l = Cut(modeDescF.filteredGuids[guid].openable, modeDescH.filteredGuids[guid].openable) ||
							(modeDescF.filteredGuids[guid].found && modeDescH.filteredGuids[guid].found);
            }
            catch (e) { };
            if (l)
                treeIsEmpty = false;
            return l;
        }
        else if (roles == 1) {
            l = false;
            try {
                l = Cut3(modeDescF.filteredGuids[guid].openable, modeDescH.filteredGuids[guid].openable, filteredGuidsR[guid].openable) ||
							(modeDescF.filteredGuids[guid].found && modeDescH.filteredGuids[guid].found && filteredGuidsR[guid].found);
            }
            catch (e) { };
            if (l)
                treeIsEmpty = false;
            return l;

        }
        else {
            return false;
        }
    }
}

function Cut(array1, array2) {
    if (array2 == null) {
        return array1.length > 0;
    }
    for (var i = 0; i < array1.length; i++) {
        for (var j = 0; j < array2.length; j++) {
            if (array1[i] == array2[j])
                return true;
        }
    }
    return false;
}

function Cut3(array1, array2, array3) {
    if (array3 == null)
        return Cut(array1, array2);
    for (var i = 0; i < array1.length; i++) {
        for (var j = 0; j < array2.length; j++) {
            for (var k = 0; k < array3.length; k++) {
                if (array1[i] == array2[j] && array2[j] == array3[k])
                    return true;
            }
        }
    }
    return false;
}

function IsOpenable(guid) {
    var roleArray = null;
    if (rolefilter_enabled == true) {
        roleArray = filteredGuidsR[guid].openable;
    }

    if (treeViewMode == "ALL") {
        if (rolefilter_enabled) {
            l = false;
            try {
                l = roleArray.length > 0;
            } catch (e) { };
            return l;
        }
        return true;
    }
    else if (treeViewMode == "FILTERED") {
        l = true;
        try {
            l = Cut(modeDescF.filteredGuids[guid].openable, roleArray);
        }
        catch (e) { };
        return l;
    }
    else if (treeViewMode == "HEMI") {
        l = true;
        try {
            l = Cut(modeDescH.filteredGuids[guid].openable, roleArray);
        }
        catch (e) { };
        return l;
    }
    else		// FILTEREDHEMI
    {
        l = Cut3(modeDescF.filteredGuids[guid].openable, modeDescH.filteredGuids[guid].openable, roleArray);
        return l;
    }
}

function IsAutoExpand()	// true if the tree must be appear expanded
{
    if (treeViewMode == "ALL")
        return false;
    else if (treeViewMode == "FILTERED")
        return (modeDescF.filteredTopicCount < TreeConfig.AutoExpandLimit)
    else if (treeViewMode == "FILTEREDHEMI")
        return (modeDescF.filteredTopicCount < TreeConfig.AutoExpandLimit)
    else	//"HEMI"
        return (modeDescH.filteredTopicCount < TreeConfig.AutoExpandLimit)
}

////////////////////////////////////
// delayed tree load support

var treeLoadQueue = new Array();
var treeLoadQueueDivs = new Array();
var treeLoadQueuePtr = 0;

function Queue_Init()	// init queue internal variables
{
    treeLoadQueue = new Array();
    treeLoadQueueDivs = new Array();
    treeLoadQueuePtr = 0
}

function Queue_Add(s, div)	// add section html file to queue
{
    treeLoadQueue[treeLoadQueue.length] = s;
    treeLoadQueueDivs[treeLoadQueueDivs.length] = div;
}

function Queue_Next(t)	// load next section html file
{
    if (treeLoadQueuePtr < treeLoadQueue.length) {
        t.LoadScript(treeLoadQueue[treeLoadQueuePtr], treeLoadQueueDivs[treeLoadQueuePtr]);
        treeLoadQueuePtr++;
    }
    else if (_childItem_found) {
        _childItem_found = false;
        createTreeControl(null, false, null);
    }
    else {
        if (selection_need > 0) {
            var sel = false;
            if (_lastSelectedGlobal.length > 0) {
                if (rolefilter_enabled == true) {
                    l = 0;
                    try {
                        l = filteredGuidsR[_lastSelectedGlobal].title.length;
                    }
                    catch (e) { };
                    if (l > 0) {
                        sel = true;
                    }
                }
                else {
                    sel = true;
                }
            }

            if (sel == true) {
                selection_need = 0;
                if (ChangeTreeView_CallBack() == true)
                    return;
            }
            t.SelectFirstItem();
        }
        if (parent.TreeFinished) {
            parent.TreeFinished(treeViewMode, treeIsEmpty);
        }
        //		if (parent.selector.SearchEnable)
        //		{
        //			setTimeout("parent.selector.SearchEnable()",100);
        //		}
        //		else
        //		{
        //			setTimeout("parent.selector.SearchEnable()",500);
        //		}
    }
}

function SelectionCallBack(_item) {
    var t;
    md = getModeDesc();
    switch (treeViewMode) {
        case "ALL":
            if (_lastSelectedItem != null) {
                if (_lastSelectedItem.startAction == true) {
                    _lastSelectedItem.startAction = false;
                }
                else {
                    _lastSelectedItem.startAction = true;
                    ChangeTreeView_CallBack()
                    return;
                }
            }
            t = (_item == null ? md.lastSelected : _item);
            break;
        default:
            if (md.flatMode == true) {
                SetFlatSelection();
                return;
            }
            t = ((md.flatMode == true) ? md.lastSelectedFlat : (_item == null ? md.lastSelected : _item));
            break;
    }

    if (t == null) {
        if (parent.TreeItemSelected)
            parent.TreeItemSelected(null, null);
        return;
    };
    var tpc = t.getAttribute("tpc");
    if (tpc == null)
        tpc = t.parentNode.getAttribute("tpc");
    if (tpc == null)
        tpc = t.parentNode.parentNode.getAttribute("tpc");
    if (md.flatMode == false) {
        ChangeSelection(t);
        window.scrollTo(0, (t.parentNode.offsetTop / 2) + 10);
    }
    if (tpc != null)
        SetLastSelected(tpc, treeViewMode);
    if (parent.TreeItemSelected)
        parent.TreeItemSelected(tpc, treeViewMode);
}

function ClearDescriptor(md, fm) {
    md.treeCreated = true;
    md.lastSelected = null;
    md.lastSelectedFlat = null;
    //	if (_lastChangeIsFilterOnly==false)
    md.flatMode = fm;
    for (var i = 0; i < md.filteredGuidList.length; i++) {
        s = md.filteredGuidList[i];
        md.filteredGuids[s].treeitem = null;
        md.filteredGuids[s].treeitemdiv = null;
    }
}

function LastSelectedItem(guid, mode) {
    this.guid = guid;
    this.mode = mode;
    this.startAction = false;
    this.firsdBuild = false;
}

var _lastSelectedItem = null;
var _lastSelectedGlobal = "";
var _lastSelectedGlobalMode = "";

function SetLastSelected(guid, mode, force) {
    _lastSelectedGlobal = guid;
    _lastSelectedGlobalMode = mode;
    if (!force) {
        if (treeViewMode == "ALL")
            return;
    }
    _lastSelectedItem = new LastSelectedItem(guid, mode);
}

function GetTpcAttribute(obj) {
    var tpc = null;
    while (tpc == null) {
        try {
            tpc = obj.getAttribute("tpc");
        }
        catch (e) {
            return null;
        }
        if (tpc == null)
            obj = obj.parentNode;
    }
    return tpc;
}

var _childItem = null;
var _childItem_found = false;

function createTreeControl(rootData, flatmode, _item, selection, childitem) {
    if (rootData)
        _rootData = rootData;
    try {
        bigsco = parent.SCO_Supported();
    }
    catch (e) { }
    InitTocStates();
    if (selection)
        seeAlsoSelection = selection;
    if (childitem)
        _childItem = childitem;
    fm = (flatmode == true ? true : false);
    selection_need = 1;
    if (treeViewMode == "ALL") {
        if (modeDescA.treeCreated == true) {
            SelectionCallBack(_item);
            return;
        }
        ClearDescriptor(modeDescA, false);
        if (_lastSelectedItem != null) {
            _lastSelectedItem.startAction = true;
            _lastSelectedItem.firstBuild = true;
        }
        else {
            selection_need = 2;
        }
    }
    else if (treeViewMode == "FILTERED") {
        if (modeDescF.treeCreated == true) {
            //			if (fm==true && _lastChangeIsFilterOnly==false)
            //				modeDescF.flatMode=true;
            modeDescF.flatMode = fm;
            SelectionCallBack(_item);
            return;
        }
        ClearDescriptor(modeDescF, fm);
    }
    else if (treeViewMode == "FILTEREDHEMI") {
        if (modeDescFH.treeCreated == true) {
            //			if (fm==true && _lastChangeIsFilterOnly==false)
            //				modeDescFH.flatMode=true;
            modeDescFH.flatMode = fm;
            SelectionCallBack(_item);
            return;
        }
        ClearDescriptor(modeDescFH, fm);
    }
    else	//"HEMI"
    {
        if (modeDescH.treeCreated == true) {
            //			if (fm==true && _lastChangeIsFilterOnly==false)
            //				modeDescH.flatMode=true;
            modeDescH.flatMode = fm;
            SelectionCallBack(_item);
            return;
        }
        ClearDescriptor(modeDescH, fm);
    }
    treeIsEmpty = true;
    if (treeViewMode == "ALL")
        treeControl = new TreeControl(document.getElementById("treeControlHostForAll"), rootData);
    else if (treeViewMode == "FILTERED") {
        treeControl = new TreeControl(document.getElementById("treeControlHostForFiltered"), rootData);
        modeDescF.flatControl = new FlatControl("flatControlHostForFiltered");
        modeDescF.flatControl.Load();
        selection_need = (modeDescF.flatMode == true ? 0 : 1);
    }
    else if (treeViewMode == "FILTEREDHEMI") {
        treeControl = new TreeControl(document.getElementById("treeControlHostForFilteredHemi"), rootData);
        modeDescFH.flatControl = new FlatControl("flatControlHostForFilteredHemi");
        modeDescFH.flatControl.Load();
        selection_need = (modeDescFH.flatMode == true ? 0 : 1);
    }
    else	//"HEMI"
    {
        treeControl = new TreeControl(document.getElementById("treeControlHostForHemi"), rootData);
        modeDescH.flatControl = new FlatControl("flatControlHostForHemi");
        modeDescH.flatControl.Load();
        selection_need = (modeDescH.flatMode == true ? 0 : 1);
    }
    Queue_Init();

    treeControl.LoadScript(treeControl.rootData + ".html", treeControl.treeHost.id);
}

function TreeControl(host, rootData) {
    this.host = host;
    this.rootData = rootData;

    host.innerHTML = "";
    this.treeHost = document.createElement("div");
    this.treeHost.id = rootData + "_" + TreeViewModeLetter();
    this.treeHost.className = "treeControlNode";
    this.treeHost.onclick = this.OnClick;
    this.treeHost.onmouseup = this.OnMouseUp;
    this.treeHost.ondblclick = this.OnDoubleClick;
    this.host.appendChild(this.treeHost);

    if (treeViewMode == "ALL")
        this.loader = document.getElementById("treeControlDataForAll");
    else if (treeViewMode == "FILTERED")
        this.loader = document.getElementById("treeControlDataForFiltered");
    else if (treeViewMode == "FILTEREDHEMI")
        this.loader = document.getElementById("treeControlDataForFilteredHemi");
    else	//"HEMI"
        this.loader = document.getElementById("treeControlDataForHemi");
    this.loader.className = "treeControlData";

    /*var imagesToCache = new Array(
    "module_c.gif", "module_o.gif", "outl_f.gif", "outl_fc.gif", "outl_fo.gif", "outl_l.gif",
    "outl_lc.gif", "outl_lo.gif", "outl_m.gif", "outl_mc.gif", "outl_mo.gif", "outl_r.gif",
    "sco_empty.gif", "sco_completed.gif", "sco_incomplete.gif", "sco_failed.gif", "sco_notstarted.gif", "sco_passed.gif",
    "outl_rc.gif", "outl_ro.gif", "topic.gif", "question.gif", "assessment.gif", "vert_line.gif", "vert_line_wide.gif", "s.gif");

    this.imageCache = new Array();
    for (var i = 0; i < imagesToCache.length; i++) {
    this.imageCache[i] = new Image();
    this.imageCache[i].src = "../../img/" + imagesToCache[i];
    }*/
}

var _indexedSrc = "";

TreeControl.prototype.LoadScript = function (src, indexedSrc) {
    _indexedSrc = indexedSrc;
    setTimeout("treeControl.LoadScriptInternal('" + src + "')", 1);
}

TreeControl.prototype.LoadScriptInternal = function (src) {
    var l = this.loader;
    var d = (l.contentDocument ? l.contentDocument : (l.contentWindow ? l.contentWindow.document : null));
    if (!d)
        return;
    treeControlDB = true;
    d.location.replace(src);
}

TreeControl.prototype.Bind = function (data) {
    if (treeControlDB) {
        treeControlDB = false;
        this.TraverseChildren(data.c, document.getElementById(_indexedSrc));
        _childNode_Loaded();
    }
    if (directMode == true)
        ChangeTreeView_CallBack()
    else
        Queue_Next(this);
}

function UnescapeQuotes(s) {
    ss = s;
    k = ss.indexOf('&amp;');
    while (k >= 0) {
        sss = ss.substr(0, k) + "&" + ss.substr(k + 5);
        ss = sss;
        k = ss.indexOf('&amp;');
    }
    k = ss.indexOf('&gt;');
    while (k >= 0) {
        sss = ss.substr(0, k) + ">" + ss.substr(k + 4);
        ss = sss;
        k = ss.indexOf('&gt;');
    }
    k = ss.indexOf('&lt;');
    while (k >= 0) {
        sss = ss.substr(0, k) + "<" + ss.substr(k + 4);
        ss = sss;
        k = ss.indexOf('&lt;');
    }
    return ss;
}

function GetClassNameFromFile(filename) {

    var mytool_array = filename.split("/");
    cname = mytool_array[mytool_array.length - 1];
    return cname.replace(".gif", "");
}

TreeControl.prototype.TraverseNode = function (node, parentElement, image, last) {
    var e, f, g, hasChildren;
    var _empty = (node.e ? true : false);
    if (treeViewMode == "ALL") {
        var pGuid = parentElement.getAttribute("id");
        k = pGuid.lastIndexOf("_");
        pGuid = pGuid.substr(0, k);
        var iGuid = (node.d ? node.d : node.i);
        AddItemdesc(modeDescA, modeDescA.filteredGuids, iGuid, "", "-", _empty, false, "", pGuid);
        AddTreeItemToItemDesc(iGuid, true);
    }
    node.element = document.createElement("div");
    f = node.element;
    f.className = "treeControlNode";

    hasChildren = node.c || node.d;
    emptylesson = false;
    if (node.e)
        emptylesson = true;
    _openable = (node.d ? IsOpenable(node.d) : false)

    g = f.appendChild(document.createElement("div"));
    guid = (node.i ? node.i : node.d);
    g.setAttribute("tpc", guid);

    e = g.appendChild(document.createElement("img"));
    e.setAttribute("srcroot", "../../img/outl_" + image);
    if (emptylesson || (node.d && !_openable)) {
        esrc = e.getAttribute("srcroot") + ".gif";
        e.className = GetClassNameFromFile(esrc);
        e.openable = false;
        e.src = "../../img/empty.gif";
    }
    else {
        esrc = e.getAttribute("srcroot") + (hasChildren ? (IsAutoExpand() ? "o.gif" : "c.gif") : ".gif");
        e.className = GetClassNameFromFile(esrc);
        e.src = "../../img/empty.gif";
        e.openable = (hasChildren ? (IsAutoExpand() ? true : true) : false);
    }

    e = g.appendChild(document.createElement("img"));
    if (bigsco) {
        var stat = GetItemStatus(guid, true);
        e.className = _GetItemStatusFile(stat);
        e.src = "../../img/empty.gif";
        e.title = _GetItemStatusTitle(stat);
        e.alt = _GetItemStatusTitle(stat);
    }
    else {
        e.src = "../../img/sco_empty.gif";
    }

    e = g.appendChild(document.createElement("img"));

    if (emptylesson) {
        esrc = "../../img/emptysection.gif";
        e.className = GetClassNameFromFile(esrc);
        e.src = "../../img/empty.gif";

    }
    else {
        esrc = (hasChildren ? ((IsAutoExpand() && _openable) ? "../../img/module_o.gif" : "../../img/module_c.gif") :
							"../../img/topic.gif");
        e.src = "../../img/empty.gif";
        e.className = GetClassNameFromFile(esrc);

        if (node.q) {
            e.className = GetClassNameFromFile("../../img/question.gif");
        }
        if (node.a) {
            e.className = GetClassNameFromFile("../../img/assessment.gif");
        }

    }
    e = g.appendChild(document.createElement("span"));
    ee = e.appendChild(document.createElement("a"));
    ee.className = "";
    ee.style.cursor = "pointer";
    ee.onmouseover = this.OnOverItem;
    ee.onmouseout = this.OnOutItem;
    ee.appendChild(document.createTextNode(UnescapeQuotes(node.t)));
    AddTreeItemToItemDesc(guid, ee);

    parentElement.appendChild(f);

    if (hasChildren && _openable) {
        e = node.element.appendChild(document.createElement("table"));
        e.className = "treeControlChildren" + (!IsAutoExpand() ? "H" : "V");
        e.cellSpacing = 0;
        e = e.appendChild(document.createElement("tbody"));
        e = e.appendChild(document.createElement("tr"));
        f = e.appendChild(document.createElement("td"));
        f.className = "treeControlLine" + (last ? "H" : "V") + (bigsco ? "W" : "");
        f = f.appendChild(document.createElement("img"));
        f.src = "../../img/s.gif";

        f = e.appendChild(document.createElement("td"));
        if (node.c)
            this.TraverseChildren(node.c, f);
        if (node.d) {
            f.id = node.d + "_" + TreeViewModeLetter();
            return f.id;
        }
    }
    return null;
}

TreeControl.prototype.TraverseChildren = function (children, parentElement) {
    if (!children)
        return;

    var children2 = new Array();
    var childrendivs = new Array();

    for (var c = 0; c < children.length; c++) {
        var guid = (children[c].d ? children[c].d : children[c].i);
        if (IsFiltered(guid, treeViewMode))
            children2[children2.length] = children[c];
    }

    if (children2.length > 0) {
        if (parentElement.className == "treeControlNode") {
            if (children2.length == 1) {
                childrendivs[0] = this.TraverseNode(children2[0], parentElement, "r", true);
            }
            else {
                childrendivs[0] = this.TraverseNode(children2[0], parentElement, "f", false);
                var lasti = children2.length - 1;
                for (var i = 1; i < lasti; i++)
                    childrendivs[i] = this.TraverseNode(children2[i], parentElement, "m", false);
                childrendivs[lasti] = this.TraverseNode(children2[lasti], parentElement, "l", true);
            }
        }
        else {
            var lasti = children2.length - 1;
            for (var i = 0; i < lasti; i++)
                childrendivs[i] = this.TraverseNode(children2[i], parentElement, "m", false);
            childrendivs[lasti] = this.TraverseNode(children2[lasti], parentElement, "l", true);
        }
    }

    if (IsAutoExpand()) {
        for (var j = 0; j < children2.length; j++) {
            if (children2[j].d)
                Queue_Add(children2[j].d + ".html", childrendivs[j]);
        }
    }

    if (_childItem != null) {
        var maxindex = children2.length - 1;
        for (var j = 0; j < children2.length; j++) {
            var chindex = (children2[j].d ? children2[j].d.substr(37) : children2[j].i.substr(37));
            try {
                chindex = parseInt(chindex, 10);
            }
            catch (e) { };
            if (chindex > _childItem && j == 0) {
                _childItem = null;
                // FAILED
                break;
            }
            else if (chindex < _childItem && j == maxindex) {
                if (children2[j].d) {
                    Queue_Add(children2[j].d + ".html", childrendivs[j]);
                    break;
                }
                else {
                    _childItem = null;
                    // FAILED
                    break;
                }

            }
            else if (chindex == _childItem) {
                _childItem = null;
                _childItem_found = true;
                SetLastSelected(children2[j].d ? children2[j].d : children2[j].i, "ALL", true);
                // FOUND
                break;
            }
            else if (chindex > _childItem) {
                if (children2[j - 1].d) {
                    Queue_Add(children2[j - 1].d + ".html", childrendivs[j - 1]);
                    break;
                }
                else {
                    _childItem = null;
                    // FAILED
                    break;
                }
            }
        }
    }

}

TreeControl.prototype.OnOverItem = function (event) {
    if (!event)
        event = window.event;
    target = event.target;
    if (!target)
        target = event.srcElement;
    if (target.className == "tselected")
        return;
    target.className = "thover";
}

TreeControl.prototype.OnOutItem = function (event) {
    if (!event)
        event = window.event;
    target = event.target;
    if (!target)
        target = event.srcElement;
    if (target.className == "tselected")
        return;
    target.className = "";
}

TreeControl.prototype.OnMouseUp = function (event) {
    try {
        if (event.target.nodeName == "A") {
            event.target.focus();
        }
    }
    catch (e) { };
}

TreeControl.prototype.OnClick = function (event) {
    if (!event)
        event = window.event;
    target = event.target;
    if (!target)
        target = event.srcElement;
    treeControl.OnClickHandler(event, target);
}

TreeControl.prototype.OnDoubleClick = function (event) {
    if (!event)
        event = window.event;
    target = event.target;
    if (!target)
        target = event.srcElement;
    if (!target.tagName)
        target = target.parentNode;
    if (target.tagName == "A" || target.tagName == "IMG") {
        if (target.tagName == "IMG") {
            s = target.outerHTML;
            if ((s.substr(s.length - 11, 9) != "topic.gif") || (s.substr(s.length - 14, 12) != "question.gif") || (s.substr(s.length - 16, 14) != "assessment.gif")) {
                return;
            }
        }
        var t = target.parentNode.parentNode.firstChild;
        target = t;
        treeControl.OnClickHandler(event, target);
        if (parent.TreeItemDoubleSelected)
            parent.TreeItemDoubleSelected();
    }
    clearTextSelection();
}

function ChangeSelection(e, first) {
    ee = (e.tagName == "A" ? e : e.childNodes[0]);
    SetLastSelected(GetTpcAttribute(ee), treeViewMode);
    if (treeViewMode == "ALL") {
        if (modeDescA.lastSelected) {
            modeDescA.lastSelected.className = "";
        }
        modeDescA.lastSelected = ee;
        modeDescA.lastSelected.className = "tselected";
    }
    else if (treeViewMode == "FILTERED") {
        if (modeDescF.lastSelected) {
            modeDescF.lastSelected.className = "";
        }
        modeDescF.lastSelected = ee;
        modeDescF.lastSelected.className = "tselected";
    }
    else if (treeViewMode == "FILTEREDHEMI") {
        if (modeDescFH.lastSelected) {
            modeDescFH.lastSelected.className = "";
        }
        modeDescFH.lastSelected = ee;
        modeDescFH.lastSelected.className = "tselected";
    }
    else	//"HEMI"
    {
        if (modeDescH.lastSelected) {
            modeDescH.lastSelected.className = "";
        }
        modeDescH.lastSelected = ee;
        modeDescH.lastSelected.className = "tselected";
    }
    //	if (!first)
    //	{
    //		if (ee.parentNode.parentNode.focus)
    //			ee.parentNode.parentNode.focus();
    //	}

    //	if (parent["selector"].FocusToSearchField)
    //		parent["selector"].FocusToSearchField();
}

TreeControl.prototype.SelectFirstItem = function () {
    var hostname = "";
    if (treeViewMode == "ALL")
        hostname = "treeControlHostForAll";
    else if (treeViewMode == "FILTERED")
        hostname = "treeControlHostForFiltered";
    else if (treeViewMode == "FILTEREDHEMI")
        hostname = "treeControlHostForFilteredHemi";
    else	//"HEMI"
        hostname = "treeControlHostForHemi";
    var tpc = "";
    var span;
    var f = document.getElementById(hostname);

    f = f.firstChild;
    if (seeAlsoSelection >= f.childNodes.length) {
        f = f.firstChild;
    }
    else {
        f = f.childNodes[seeAlsoSelection];
    }

    while (tpc == "") {
        try {
            t = f.getAttribute("tpc");
        }
        catch (e) {
            return;
        }
        if (t) {
            tpc = t;
            span = f.lastChild;
        }
        f = f.firstChild;
    }
    ChangeSelection(span, true);
    mode = treeViewMode;
    if (selection_need == 1) {
        mode = "HIDE";
    }
    selection_need = 0;
    if (parent.TreeItemSelected)
        parent.TreeItemSelected(tpc, treeViewMode);
}

TreeControl.prototype.OnClickHandler = function (event, t) {
    var realselect = false;
    var callback = true;
    //	var t = event.target;
    if (!t.tagName)
        t = t.parentNode;
    if (t.tagName == "IMG") {
        var e = t.parentNode.parentNode.lastChild;
        if (e.tagName == "TABLE") // section icon
        {
            var f = t.parentNode.firstChild;

            if (t.openable || f.openable || e.openable) {
                if (e.className == "treeControlChildrenV") {
                    fsrc = f.getAttribute("srcroot") + "c.gif";
                    f.src = "../../img/empty.gif";
                    f.className = GetClassNameFromFile(fsrc);
                    f = f.nextSibling;
                    f = f.nextSibling;
                    f.src = "../../img/empty.gif";
                    f.className = GetClassNameFromFile("../../img/module_c.gif");
                    e.className = "treeControlChildrenH";
                    _go_closed = true;
                }
                else {
                    fsrc = f.getAttribute("srcroot") + "o.gif";
                    f.src = "../../img/empty.gif";
                    f.className = GetClassNameFromFile(fsrc);
                    f = f.nextSibling;
                    f = f.nextSibling;
                    f.src = "../../img/empty.gif";
                    f.className = GetClassNameFromFile("../../img/module_o.gif");
                    e.className = "treeControlChildrenV";
                    var g = e.firstChild.firstChild.lastChild;
                    if (!g.firstChild) {
                        goriginal = (g.id.length > 36 ? GetJunctionId(g.id) : g.id);
                        callback = false;
                        treeControl.LoadScript(goriginal + ".html", g.id);
                    }
                }
            }
        }
        else	// topic icon
        {
            var e = t.parentNode.lastChild;
            if (e.tagName == "IMG")
                return;
            ChangeSelection(e);
            realselect = true;
        }
    }
    if (t.tagName == "A") // text field in <A> tag
    {
        ChangeSelection(t);
        realselect = true;
    }

    var tpc = t.parentNode.getAttribute("tpc");
    if (tpc == null)
        tpc = t.parentNode.parentNode.getAttribute("tpc");
    if (realselect && parent.TreeItemSelected)
        parent.TreeItemSelected(tpc, treeViewMode);
    if (callback) {
        var n = null;
        try {
            n = f.parentNode.childNodes[f.parentNode.childNodes.length - 1].childNodes[0];
        }
        catch (e) { };
        _childNode_Loaded(n);
    }
}

function GetTableItemForThis(_item) {
    _tItem = _item.parentNode;
    if (_tItem == null)
        return null;
    while (_tItem.tagName != "TABLE") {
        _tItem = _tItem.parentNode;
        if (_tItem == null)
            return null;
    }
    return _tItem;
}

function ShowTreeItem(guid) {
    mdActual = getModeDesc();
    mdSource = getModeDesc(true);
    _item = GetTreeItemOfItemDesc(guid);
    if (_item == null) {
        while (_item == null) {
            var Item = null;
            Item = mdSource.filteredGuids[guid];
            if (Item == null)
                Item = modeDescF.filteredGuids[guid];
            if (Item == null)
                Item = modeDescH.filteredGuids[guid];
            if (Item == null)
                return false;
            guid = Item.parentguid;
            if (guid == null)
                return false;
            _item = GetTreeItemOfItemDesc(guid);
        }
        treeControl.LoadScript(guid + ".html", guid + "_" + mdActual.modeLetter);
    }
    return true;
}

function OpenItem(_tItem) {
    if (_tItem.className == "treeControlChildrenH") {
        f = _tItem.parentNode.firstChild.firstChild;
        f.src = "../../img/empty.gif";
        fscr = f.getAttribute("srcroot") + "o.gif";
        f.className = GetClassNameFromFile(fscr);
        f = f.nextSibling;
        f = f.nextSibling;
        f.src = "../../img/empty.gif";
        f.className = GetClassNameFromFile("../../img/module_o.gif");
        _tItem.className = "treeControlChildrenV";
    }
}

function ChangeTreeView() {
    retvalue = false;
    dA = document.getElementById("treeControlHostForAll");
    dS = document.getElementById("treeControlHostForFiltered");
    dSf = document.getElementById("flatControlHostForFiltered");
    dH = document.getElementById("treeControlHostForHemi");
    dHf = document.getElementById("flatControlHostForHemi");
    dFH = document.getElementById("treeControlHostForFilteredHemi");
    dFHf = document.getElementById("flatControlHostForFilteredHemi");

    if (treeViewMode == "FILTERED") {
        modeDescF.flatMode = !modeDescF.flatMode;
        retvalue = modeDescF.flatMode;
        dS.style.display = (modeDescF.flatMode ? "none" : "block");
        dSf.style.display = (modeDescF.flatMode ? "block" : "none");
    }
    else if (treeViewMode == "HEMI") {
        modeDescH.flatMode = !modeDescH.flatMode;
        retvalue = modeDescH.flatMode;
        dH.style.display = (modeDescH.flatMode ? "none" : "block");
        dHf.style.display = (modeDescH.flatMode ? "block" : "none");
    }
    else	// FILTEREDHEMI
    {
        modeDescFH.flatMode = !modeDescFH.flatMode;
        retvalue = modeDescFH.flatMode;
        dFH.style.display = (modeDescFH.flatMode ? "none" : "block");
        dFHf.style.display = (modeDescFH.flatMode ? "block" : "none");
    }
    ChangeTreeView_CallBack();
    return retvalue;
}

var directMode = false;

function _rec_SearchAInFlat(obj, tpc) {
    if (obj.nodeName == "IMG") {
        attr = obj.getAttribute("tpc");
        if (attr == tpc) {
            return obj;
        }
    }
    for (var i = 0; i < obj.childNodes.length; i++) {
        r = _rec_SearchAInFlat(obj.childNodes[i], tpc);
        if (r != null)
            return r;
    }
    return null;
}

function _rec_GetFirstObjInFlat(obj) {
    if (obj.nodeName == "IMG") {
        return obj;
    }
    for (var i = 0; i < obj.childNodes.length; i++) {
        r = _rec_GetFirstObjInFlat(obj.childNodes[i]);
        if (r != null)
            return r;
    }
    return null;
}

function SetFlatSelection() {
    mdActual = getModeDesc();
    obj = _rec_SearchAInFlat(mdActual.flatControl.host, _lastSelectedGlobal);
    if (obj == null)
        obj = _rec_GetFirstObjInFlat(mdActual.flatControl.host);
    if (obj != null) {
        mdActual.flatControl.OnClickHandler(null, obj);
        return;
    }
    if (parent.TreeItemSelected)
        parent.TreeItemSelected(null, null);
}

function ChangeTreeView_CallBack() {
    mdActual = getModeDesc();
    mdSource = getModeDesc(true);
    var _item = null;
    if (mdActual.flatMode == true) {
        SetFlatSelection();
        return true;
    }
    if (mdActual.flatMode == false || treeViewMode == "ALL") {
        var guid = null;
        //	    if (treeViewMode=="ALL")
        //	    {
        //	        guid=_lastSelectedItem.guid;
        //	    }
        //	    else
        //	    {
        //		    guid=mdSource.lastSelectedFlat.getAttribute("tpc");
        //		}
        guid = _lastSelectedGlobal;
        _item = GetTreeItemOfItemDesc(guid);
        if (_item == null) {
            if (!IsFiltered(guid, treeViewMode)) {
                return false;
            }
            directMode = true;
            k = ShowTreeItem(guid);
            return k;
        }
        if (_item != null) {
            _tItem = GetTableItemForThis(_item);
            while (_tItem != null) {
                OpenItem(_tItem);
                _tItem = GetTableItemForThis(_tItem);
            }
        }
    }
    directMode = false;
    createTreeControl(null, mdActual.flatMode, _item);
    return true;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// FLAT VIEW
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

function FlatControl(hostname) {
    this.host = document.getElementById(hostname);
    this.document = (this.host.document ? this.host.document : this.host.ownerDocument);
}

function showOnFlat(desc) {
    k = parseInt(desc.guid.split("_")[1]);
    if (desc.isroot == true && k == 1)
        return false;
    if (rolefilter_enabled == false)
        return true;
    ret = false;
    try {
        ret = filteredGuidsR[desc.guid].found;
    }
    catch (e) { };
    return ret;
}

function isInOutline(mydesc, guid) {
    if (mydesc.filteredGuids.length == 0)
        return true;
    var p = mydesc.filteredGuids[guid].parentguid;
    if (p == null)
        return false;
    var a = p.split("_");
    if (a[1] == "1")
        return true;
    else
        return isInOutline(mydesc, p);
}

function getModeDesc(source) {
    if (source == null)
        source = false;
    var mode = (source == true ? _lastSelectedGlobalMode : treeViewMode);
    if (mode == "ALL") {
        return modeDescA;
    }
    else if (mode == "FILTERED") {
        return modeDescF;
    }
    else if (mode == "HEMI") {
        return modeDescH;
    }
    else if (mode == "FILTEREDHEMI") {
        modeDescFH.guidsForFlat = new Array();
        for (var i = 0; i < modeDescF.guidsForFlat.length; i++) {
            guidF = modeDescF.guidsForFlat[i];
            for (var j = 0; j < modeDescH.guidsForFlat.length; j++) {
                guidH = modeDescH.guidsForFlat[j];
                if (guidF.guid == guidH.guid) {
                    modeDescFH.guidsForFlat[modeDescFH.guidsForFlat.length] = guidF;
                }
            }
        }
        return modeDescFH;
    }
    return null;
}

function saveModeDesc(md) {
    if (treeViewMode == "ALL") {
        modeDescA = md;
    }
    else if (treeViewMode == "FILTERED") {
        modeDescF = md;
    }
    else if (treeViewMode == "HEMI") {
        modeDescH = md;
    }
    else if (treeViewMode == "FILTEREDHEMI") {
        modeDescFH = md;
    }
}

FlatControl.prototype.Load = function () {
    myDesc = getModeDesc();
    this.host.innerHTML = "";

    div = this.host.appendChild(this.document.createElement("div"));
    div.className = "treeControlNode";
    div.onclick = this.OnClick;
    div.ondblclick = this.OnDoubleClick;
    div.onmouseup = this.OnMouseUp;
    table = div.appendChild(this.document.createElement("table"));
    table.cellSpacing = 0;
    first = true;
    var showCt = 0;
    for (var i = 0; i < myDesc.guidsForFlat.length; i++) {
        itemdesc = myDesc.guidsForFlat[i];
        if (showOnFlat(itemdesc) && isInOutline(myDesc, itemdesc.guid)) {
            showCt++;
            if (showCt > TreeConfig.SearchResultLimit)
                continue;
            myDesc.actualFlatCounter = showCt;
            tr = table.appendChild(this.document.createElement("tbody"));
            tr = tr.appendChild(this.document.createElement("tr"));
            td = tr.appendChild(this.document.createElement("td"));
            img = td.appendChild(this.document.createElement("img"));
            var esrc = (itemdesc.type == "Topic" ? "../../img/topic.gif" : (itemdesc.empty ? "../../img/emptysection.gif" : "../../img/module_c.gif"));
            img.className = GetClassNameFromFile(esrc);
            img.src = "../../img/empty.gif";
            img.setAttribute("tpc", itemdesc.guid);
            td = tr.appendChild(this.document.createElement("td"));
            td.className = "treeControlNode";
            a = td.appendChild(this.document.createElement("a"));
            if (first == true) {
                myDesc.lastSelectedFlat = a;
                saveModeDesc(myDesc);
            }
            a.className = (first == true ? "tselected" : "");
            if (first == true && _lastChangeIsFilterOnly == false) {
                SetLastSelected(itemdesc.guid, treeViewMode);
            }
            first = false;
            a.style.cursor = "pointer";
            a.setAttribute("tpc", itemdesc.guid);
            a.onmouseover = this.OnOverItem;
            a.onmouseout = this.OnOutItem;
            var _tname = itemdesc.title;
            if (treeViewMode == "HEMI" && parent.showscore > 0) {
                _tname = "" + Math.round(itemdesc.score * 100) + " " + itemdesc.title;
            }
            a.appendChild(this.document.createTextNode(_tname));
        }
    }
    if (myDesc.flatMode == true) {
        SetFlatSelection();
    }
    var tpc = null;
    try {
        tpc = myDesc.lastSelectedFlat.getAttribute("tpc");
    }
    catch (e) { };
    if (parent.TreeItemSelected)
        parent.TreeItemSelected(tpc, treeViewMode);

}

FlatControl.prototype.OnOverItem = function (event) {
    if (!event)
        event = window.event;
    target = event.target;
    if (!target)
        target = event.srcElement;
    if (target.className == "tselected")
        return;
    target.className = "thover";
}

FlatControl.prototype.OnOutItem = function (event) {
    if (!event)
        event = window.event;
    target = event.target;
    if (!target)
        target = event.srcElement;
    if (target.className == "tselected")
        return;
    target.className = "";
}

FlatControl.prototype.OnMouseUp = function (event) {
    try {
        if (event.target.nodeName == "A") {
            event.target.focus();
        }
    }
    catch (e) { };
}

FlatControl.prototype.OnClick = function (event) {
    if (!event)
        event = window.event;
    target = event.target;
    if (!target)
        target = event.srcElement;
    mdActual = getModeDesc();
    mdActual.flatControl.OnClickHandler(event, target);
}

FlatControl.prototype.OnDoubleClick = function (event) {
    if (!event)
        event = window.event;
    target = event.target;
    if (!target)
        target = event.srcElement;
    mdActual = getModeDesc();
    mdActual.flatControl.OnClickHandler(event, target);
    if (parent.TreeItemDoubleSelected)
        parent.TreeItemDoubleSelected();
}

FlatControl.prototype.OnClickHandler = function (event, target) {
    a = target;
    t = GetTpcAttribute(a);
    if (t != null)
        SetLastSelected(t, treeViewMode);
    if (target.tagName != "A" && target.tagName != "IMG")
        return;
    if (target.tagName != "A") {
        tr = target.parentNode.parentNode;
        for (var i = 0; i < tr.childNodes.length; i++) {
            k = tr.childNodes[i].childNodes[0];
            if (k.tagName == "A") {
                a = k;
                continue;
            }
        }
    }
    if (treeViewMode == "FILTERED") {
        modeDescF.lastSelectedFlat.className = "";
    }
    else if (treeViewMode == "HEMI") {
        modeDescH.lastSelectedFlat.className = "";
    }
    else	// FILTEREDHEMI
    {
        modeDescFH.lastSelectedFlat.className = "";
    }
    a.className = "tselected";
    if (treeViewMode == "FILTERED") {
        modeDescF.lastSelectedFlat = a;
    }
    else if (treeViewMode == "HEMI") {
        modeDescH.lastSelectedFlat = a;
    }
    else	// FILTEREDHEMI
    {
        modeDescFH.lastSelectedFlat = a;
    }
    var tpc = a.getAttribute("tpc");
    if (parent.TreeItemSelected)
        parent.TreeItemSelected(tpc, treeViewMode);
}

function GetActualFlatView() {
    md = getModeDesc();
    return md.flatMode;
}

function GetActualFlatItemCounter() {
    md = getModeDesc();
    return md.actualFlatCounter;
}

function IsActualViewEmpty() {
    md = getModeDesc();
    return (md.filteredGuidList == 0);
}

//////////////////////////////////////////////////////////////////////////////////////////

function getActualIndex_Flat() {
    md = getModeDesc();
    if (md.flatMode == true) {
        for (var i = 0; i < md.flatControl.host.firstChild.firstChild.childNodes.length; i++) {
            if (md.flatControl.host.firstChild.firstChild.childNodes[i].firstChild.childNodes[1].firstChild.className == "tselected") {
                return i;
            }
        }
    }
    return "";
}

function getActualIndex_Tree(ls, md) {
    for (var i = 0; i < ls.length; i++) {
        if (ls[i].firstChild.childNodes[3].firstChild.className == "tselected") {
            return i;
        }
    }
    if (md.lastSelected != null) {
        _tpc = md.lastSelected.parentNode.parentNode.getAttribute("tpc");
        for (var i = 0; i < ls.length; i++) {
            if (ls[i].firstChild.getAttribute("tpc") == _tpc)
                return i;
        }
    }
    return "";
}

function getTargetForIndex_Flat(md, i) {
    return md.flatControl.host.firstChild.firstChild.childNodes[i].firstChild.firstChild.firstChild;
}

function getTargetForIndex_Tree(i) {
    return ls[i].firstChild.childNodes[3].firstChild;
}

function getActualImageObj_Tree(md) {
    return md.lastSelected.parentNode.parentNode.firstChild;
}

function getSpecifiedImageObj_Tree(ls, k) {
    return ls[k].firstChild.firstChild;
}

function getOwnerOfSelection() {
    var myid = md.lastSelected.parentNode.parentNode.parentNode.childNodes[0].getAttribute("tpc");
    var owner = md.filteredGuids[myid].parentguid;
    return owner;
}

function getOpenedStatus(obj) {
    /*
    s = obj.getAttribute("src");
    k = s.indexOf(".gif");
    c = s.substr(k - 1, 1);
    */
    s = obj.className;
    c = s.substr(s.length - 1, 1);
    return (c == "o");
}

function getFilteredStatus(guid) {
    var r = IsFiltered(guid, "ALL");
    return !r;
}

function _getLinearStructure_Recursive(o, a) {
    a[a.length] = o;
    _imgObj = o.firstChild.firstChild;
    if (getOpenedStatus(_imgObj) == true) {
        for (var i = 0; i < o.childNodes[1].firstChild.firstChild.childNodes[1].childNodes.length; i++) {
            _getLinearStructure_Recursive(o.childNodes[1].firstChild.firstChild.childNodes[1].childNodes[i], a);
        }
    }
}

function getRoot(o) {
    if (o.tagName == "DIV" && o.id.substr(0, 15) == "treeControlHost")
        return o.firstChild;
    return getRoot(o.parentNode);
}

function getLinearStructure_Tree(md) {
    var oArray = new Array();
    root = getRoot(md.lastSelected);
    //    root = treeControl.host.firstChild;
    for (var i = 0; i < root.childNodes.length; i++) {
        _getLinearStructure_Recursive(root.childNodes[i], oArray);
    }
    return oArray;
}

function EventKeyDown(event) {
    if (event == null)
        event = window.event;
    var code = event.which ? event.which : event.keyCode;
    if (code == 13) {
        if (parent.TreeItemDoubleSelected)
            parent.TreeItemDoubleSelected();
        return;
    }
    md = getModeDesc();
    if (md.flatMode == true) {
        index = getActualIndex_Flat();
        if (code == 38) {  // up
            if (index > 0) {
                t = getTargetForIndex_Flat(md, index - 1);
                md.flatControl.OnClickHandler(null, t);
            }
        }
        else if (code == 40) {  // down
            if (index < md.actualFlatCounter - 1) {
                t = getTargetForIndex_Flat(md, index + 1);
                md.flatControl.OnClickHandler(null, t);
            }
        }
    }
    else {
        imgObj = getActualImageObj_Tree(md);
        _isOpenable = (imgObj.openable ? imgObj.openable : imgObj.getAttribute("openable"));
        _isOpened = getOpenedStatus(imgObj);
        ls = getLinearStructure_Tree(md);
        index = getActualIndex_Tree(ls, md);
        if (code == 37) {  // left
            if (_isOpenable == true) {
                if (_isOpened == true) {
                    treeControl.OnClickHandler(null, imgObj);
                    return false;
                }
            }
        }
        else if (code == 38) {  // up
            if (index > 0) {
                t = getTargetForIndex_Tree(index - 1);
                treeControl.OnClickHandler(null, t);
            }
        }
        else if (code == 39) {  // right
            if (_isOpenable == true) {
                if (_isOpened == false) {
                    treeControl.OnClickHandler(null, imgObj);
                    return false;
                }
            }
        }
        else if (code == 40) {  // down
            if (index < ls.length - 1) {
                t = getTargetForIndex_Tree(index + 1);
                treeControl.OnClickHandler(null, t);
            }
        }
    }
}

function tree_SetFocus() {
    document.frames[0].document.childNodes[1].childNodes[1].focus();
}

function tree_Init() {
    document.onkeydown = EventKeyDown;
    if (parent.Init_treeloaded)
        parent.Init_treeloaded();
}

function clearTextSelection() {
    if (document.selection)
        document.selection.empty();
    if (window.getSelection)
        window.getSelection().removeAllRanges();
}

function GoToNext() {
    md = getModeDesc();
    if (md.flatMode == true) {
        index = getActualIndex_Flat();
        if (index < md.actualFlatCounter - 1) {
            t = getTargetForIndex_Flat(md, index + 1);
            md.flatControl.OnClickHandler(null, t);
        }
    }
    else {
        imgObj = getActualImageObj_Tree(md);
        _isOpenable = (imgObj.openable ? imgObj.openable : imgObj.getAttribute("openable"));
        _isOpened = getOpenedStatus(imgObj);
        ls = getLinearStructure_Tree(md);
        index = getActualIndex_Tree(ls, md);
        if (index < ls.length - 1) {
            t = getTargetForIndex_Tree(index + 1);
            treeControl.OnClickHandler(null, t);
        }
    }
}

///////////////////////////////////////////////////////////////////////////////////////////////////////

var _go_next = false;
var _go_prev = false;
var _go_closed = false;

function Navigation_Up() {
    md = getModeDesc();
    if (md.flatMode == false) {
        ls = getLinearStructure_Tree(md);
        index = getActualIndex_Tree(ls, md);
        prevImgObj = getSpecifiedImageObj_Tree(ls, index - 1);
        _isOpenable = Bool(prevImgObj.openable != undefined ? prevImgObj.openable : prevImgObj.getAttribute("openable"));
        _isOpened = getOpenedStatus(prevImgObj);
        if (_isOpenable && !_isOpened) {
            _go_prev = true;
            treeControl.OnClickHandler(null, prevImgObj);
            return;
        }
    }

    var e = new Object();
    e.keyCode = 38;
    EventKeyDown(e);
}

function Navigation_Down() {
    md = getModeDesc();
    if (md.flatMode == false) {
        imgObj = getActualImageObj_Tree(md);
        _isOpenable = Bool(imgObj.openable != undefined ? imgObj.openable : imgObj.getAttribute("openable"));
        _isOpened = getOpenedStatus(imgObj);
        if (_isOpenable && !_isOpened) {
            _go_next = true;
            var e = new Object();
            e.keyCode = 39;
            EventKeyDown(e);
            return;
        }
    }
    var e = new Object();
    e.keyCode = 40;
    EventKeyDown(e);
}

function isFirstItem() {
    md = getModeDesc();
    if (md.flatMode == true) {
        index = getActualIndex_Flat();
    }
    else {
        if (md.lastSelected == null)
            return true;
        ls = getLinearStructure_Tree(md);
        index = getActualIndex_Tree(ls, md);
    }
    return (index == 0);
}

function isLastItem() {
    md = getModeDesc();
    if (md.flatMode == true) {
        return (index == md.filteredTopicCount - 1);
    }
    else {
        if (md.lastSelected == null)
            return false;
        ls = getLinearStructure_Tree(md);
        index = getActualIndex_Tree(ls, md);
        if (index == ls.length - 1) {
            imgObj = getActualImageObj_Tree(md);
            _isOpenable = imgObj.openable;
            return (_isOpenable == false);
        }
        return false;
    }
}

function _childNode_Loaded(node) {
    if (_go_next == true) {
        _go_next = false;
        Navigation_Down();
    }
    if (_go_prev == true) {
        md = getModeDesc();
        if (md.flatMode == false) {
            ls = getLinearStructure_Tree(md);
            index = getActualIndex_Tree(ls, md);
            prevImgObj = getSpecifiedImageObj_Tree(ls, index - 1);
            _isOpenable = Bool(prevImgObj.openable != undefined ? prevImgObj.openable : prevImgObj.getAttribute("openable"));
            _isOpened = getOpenedStatus(prevImgObj);
            if (_isOpenable && !_isOpened) {
                _go_prev = true;
                treeControl.OnClickHandler(null, prevImgObj);
                return;
            }
            else {
                _go_prev = false;
                Navigation_Up();
            }
        }
    }
    if (_go_closed == true) {
        _go_closed = false;
        md = getModeDesc();
        if (md.flatMode == false) {
            ls = getLinearStructure_Tree(md);
            index = getActualIndex_Tree(ls, md);
            if (index == "") {
                treeControl.OnClickHandler(null, node);
            }
        }
    }
}

function Bool(s) {
    if (typeof (s) == "boolean")
        return s;
    if (typeof (s) == "string") {
        if (s.toLowerCase() == "false")
            return false;
        if (s.toLowerCase() == "true")
            return true;
    }
    return null;
}

///////////////////////////////////////////////////////////////////////////////

var indexMap = new Array();
var treeIndex = new Array();

function AddToIndexMap(s) {
    if (bigsco == false)
        return;
    if (s.length <= 36)
        return;
    var guid = s.substr(0, 36);
    var index = s.substr(37);
    indexMap[index] = guid;
}

var _tocStates2 = null;
var _tocStates_initialized = false;

function InitTocStates() {
    if (_tocStates_initialized)
        return;
    _tocStates_initialized = true;
    if (bigsco == false)
        return;

    for (var i = 0; i < parentIndex.length; i++) {
        treeIndex[i] = new Array();
        treeIndex[i][0] = parentIndex[i];
    }
    for (var i = 0; i < parentIndex.length; i++) {
        var v = parentIndex[i];
        treeIndex[v][treeIndex[v].length] = i;
    }

    _tocStates2 = new Array();
    for (var i = 0; i < parent.lms_TOCState.NodeCounter; i++) {
        _tocStates2[i] = parent.lms_GetItemStatus(i);
    }
    InitOneItemState(childIndexLocal2Global(0));
    var a = parent.lms_GetItemStatus(0);
    var b = _tocStates2[0];
    if (a != b) {
        parent.lms_SetItemStatus(0, b);
    }
    updateTreeTrace()
}

// global index parameter
function InitOneItemState(k) {
    var ch = index_getChildList(k);
    for (var i = 0; i < ch.length; i++) {
        InitOneItemState(ch[i]);
    }
    var x = childIndexGlobal2Local(k);
    if (k != 0)
        _tocStates2[k] = BuildItemStatus(k, true);
}

function GetItemStatus(guid, init) {
    var g_index = guid.substr(37);
    var l_index = childIndexGlobal2Local(g_index);
    var s = BuildItemStatus(g_index, init);
    _tocStates2[l_index] = s;
    return s;
}

function _GetItemStatusFile(status) {
    var base = "";
    switch (status) {
        case "N": return base + "sco_notstarted";
        case "I": return base + "sco_incomplete";
        case "C": return base + "sco_completed";
        case "P": return base + "sco_passed";
        case "F": return base + "sco_failed";
    }
    return "";
}

function _GetItemStatusTitle(status) {
    switch (status) {
        case "N": return R_status_tree_notstarted;
        case "I": return R_status_tree_inprogress;
        case "C": return R_status_tree_complete;
        case "P": return R_status_tree_passed;
        case "F": return R_status_tree_failed;
    }
    return "";
}

// local index parameter
function UpdateItemStatus(index) {
    _tocStates2[index] = parent.lms_GetItemStatus(index);
    var i = childIndexLocal2Global(index);
    var guid = indexMap[i] + "_" + i;
    RefreshItemStatus(guid);
    BuildRootItemStatus();
    updateTreeTrace();
}

function RefreshItemStatus(guid) {
    if (bigsco == false)
        return;
    var md = getModeDesc(guid);

    var item = md.filteredGuids[guid];
    if (item == null)
        return;

    var stat = GetItemStatus(guid);
    item.treeitemdiv.parentNode.parentNode.childNodes[1].setAttribute("src", "../../img/empty.gif");
    _itemState = _GetItemStatusFile(stat);
    item.treeitemdiv.parentNode.parentNode.childNodes[1].setAttribute("class", _itemState); // for FF, Chrome, Safari
    item.treeitemdiv.parentNode.parentNode.childNodes[1].setAttribute("className", _itemState); // for IE
    item.treeitemdiv.parentNode.parentNode.childNodes[1].setAttribute("title", _GetItemStatusTitle(stat));
    item.treeitemdiv.parentNode.parentNode.childNodes[1].setAttribute("alt", _GetItemStatusTitle(stat));

    if (item.parentguid == null)
        return;
    RefreshParentItemStatus(item.parentguid);
}

function RefreshParentItemStatus(guid) {
    var g_index = guid.substr(37);
    var l_index = childIndexGlobal2Local(g_index);
    var st0 = _tocStates2[l_index];
    var st1 = BuildItemStatus(g_index);
    if (l_index == 0) {
        if (st1 == "N") {
            return;
        }
    }
    if (st1 != st0) {
        //        parent.lms_SetItemStatus(l_index, st1);
        _tocStates2[l_index] = st1;
        if (l_index == 0) {
            parent.lms_SetItemStatus(0, st1);
        }
        updateTreeTrace();
        var md = getModeDesc(guid);
        var item = md.filteredGuids[guid];
        if (item == null)
            return;
        item.treeitemdiv.parentNode.parentNode.childNodes[1].setAttribute("src", "../../img/empty.gif");
        _itemState = _GetItemStatusFile(st1);
        item.treeitemdiv.parentNode.parentNode.childNodes[1].setAttribute("class", _itemState); // for FF, Chrome, Safari
        item.treeitemdiv.parentNode.parentNode.childNodes[1].setAttribute("className", _itemState); // for IE
        item.treeitemdiv.parentNode.parentNode.childNodes[1].setAttribute("title", _GetItemStatusTitle(st1));
        item.treeitemdiv.parentNode.parentNode.childNodes[1].setAttribute("alt", _GetItemStatusTitle(st1));
        if (item.parentguid != null)
            RefreshParentItemStatus(item.parentguid);
    }
}

function getBaseIndex() {
    return parseInt(_rootData.substr(37));
}

function childIndexLocal2Global(x) {
    return (parseInt(x) + getBaseIndex());
}

function childIndexGlobal2Local(x) {
    return (x - getBaseIndex());
}

function index_getParent(x) {
    if (!index_checkIndex(x))
        return -1;
    return treeIndex[x][0];
}

function index_getChildList(x, f) {
    if (!index_checkIndex(x))
        return -1;
    var a0 = treeIndex[x];
    var a = new Array();
    for (var i = 1; i < a0.length; i++) {
        if (!f)
            a[i - 1] = a0[i];
        else if (f != a0[i])
            a[i - 1] = a0[i];
    }
    return a;
}

function index_hasChildren(x) {
    if (!index_checkIndex(x))
        return -1;
    var a0 = treeIndex[x];
    return (a0.length > 1);
}

function index_checkIndex(x) {
    if (x > treeIndex.length - 1)
        return false;
    return (treeIndex[x].length > 0);
}

// global index parameter
function BuildItemStatus(x, init) {
    var l_x = childIndexGlobal2Local(x);
    var s = BuildItemStatus2(x, l_x);
    return s;
}

function BuidStatus(s, haschild) {
    if (s.indexOf("I") >= 0)
        return "I";
    if (s.indexOf("N") >= 0) {
        if (s.indexOf("C") >= 0 || s.indexOf("F") >= 0 || s.indexOf("P") >= 0)
            return "I";
        else
            return "N";
    }
    if (s.indexOf("F") >= 0) {
        if (haschild == false)
            return "F";
        else
            return "C";
    }
    if (s.indexOf("P") >= 0) {
        if (haschild == false)
            return "P";
        else
            return "C";
    }
    return "C";
}

function BuildItemStatus2(x, l_x) {
    var ch = index_getChildList(x);
    var s = "";
    if (l_x != 0) {
        if (conceptIndex[x] > 0)
            s += parent.lms_GetItemStatus(l_x);
    }
    for (var i = 0; i < ch.length; i++) {
        s += _tocStates2[childIndexGlobal2Local(ch[i])];
    }
    var _stat = BuidStatus(s, ch.length > 0);
    return _stat;
}

function BuildRootItemStatus() {
    var x = childIndexLocal2Global(0);
    var ch = index_getChildList(x);
    var s = "";
    for (var i = 0; i < ch.length; i++) {
        s += _tocStates2[childIndexGlobal2Local(ch[i])];
    }
    var _stat = BuidStatus(s, ch.length > 0);
    _tocStates2[0] = _stat;
}

/************************************************************************************/

var treeTraceOn = false;
var treeTraceWnd = null;

function updateTreeTrace() {
    try {
        if (!treeTraceOn)
            return;
        if (treeTraceWnd == null)
            treeTraceWnd = window.open();
        treeTraceWnd.document.body.innerHTML = "";
        for (var i = 0; i < _tocStates2.length; i++) {
            treeTraceWnd.document.write(" " + i + ": " + _tocStates2[i] + " - " + parent.lms_GetItemStatus(i) + "<br/>");
        }
    }
    catch (e) { };
}