function AitThesaurus(tree_cls_name, req_cls_name, session_id, click_code, occ_filter)
{
	var ait_thes = this;
	
	this.tree_cls = eval(tree_cls_name);
	this.tree_cls.prototype.selectNode = function (node_no) 
	{
		var node = ait_thes.tree_cls.nodes_[node_no];
		eval(ait_thes.click_code);
	}
	this.tt = new this.tree_cls();
	this.req_cls = req_cls_name;
	this.req = new AitThesaurus.AjaxLink(this.req_cls);

	this.session_id = session_id;
	this.click_code = click_code;
	this.thes_lang_ = 'eng';
	this.css_pfx = '';
	this.serial_no = AitThesaurus.serial - 1;
	this.ID = "AitThesaurus" + AitThesaurus.serial++;
	this.occ_filter = occ_filter;

	this.tt.create();

	this.tt.loadChildren = function (node_no, renderer) 
	{
		var node = ait_thes.tree_cls.nodes_[node_no ];
		node.vis_.expand_hook = null;
		node.vis_.renderers[renderer.id].expanded = false;
		var nid = node.ID;

		var ret = ait_thes.req.GetChildren(ait_thes.session_id, nid, '',1 , 500, ait_thes.occ_filter);
		for(var ofs=0; ofs < ret.nodes.length; ofs++) 
		{
			//Skip corrupt data
			if(ret.nodes[ofs].ID != nid && typeof(ret.nodes[ofs].terms) != "undefined") 
			{
				if(ret.nodes[ofs].NT && ret.nodes[ofs].NT.length > 0) 
				{
					ret.nodes[ofs].EX_HK_ = true;
				}
				ait_thes.tree_cls.nodes_.push(ret.nodes[ofs]);
				ait_thes.tt.tvSetChild(node_no, ait_thes.tree_cls.nodes_.length - 1);
				ait_thes.thesChNLang(ait_thes.tree_cls.nodes_.length - 1);
			}
		}
		node.vis_.expand_hook = null;
		node.vis_.renderers[renderer.id].expanded = false;
		ait_thes.thesChangeLang(ait_thes.thes_lang_);

		return(true);
	}
	
	AitThesaurus.objects.push(this);
}

AitThesaurus.objects = [];

AitThesaurus.showing = null;

AitThesaurus.showThesaurusPicklist = function(selid)
{
	if(AitThesaurus.showing == selid)
		return;
	if(AitThesaurus.showing) 
		AitThesaurus.hideThesaurusPicklist(AitThesaurus.showing);
	AitThesaurus.showing = selid;
	document.getElementById(selid + 'searchfree').style.display='none';
	document.getElementById(selid + 'searchthes').style.display='inline';
	document.getElementById(selid + 'thespopup').style.display='block';
	var s_val = document.getElementById(selid + 'searchvalues');
	if(typeof(s_val.thesval) != "undefined")
		s_val.value = s_val.thesval;
	for(var idx = 1; ; ++idx)
	{
		var elem = document.getElementById(selid + "thespopupreg" + idx);
		if(!elem)
			break;
		if(elem.className == "active")
		{
			AitThesaurus.thesPicklistChoose(selid, idx);
			break;
		}
	}
}
AitThesaurus.hideThesaurusPicklist = function(selid)
{
	AitThesaurus.showing = null;
	document.getElementById(selid + 'thespopup').style.display='none';
}

AitThesaurus.disableThesaurusPicklist = function(selid)
{
	AitThesaurus.showing = null;
	document.getElementById(selid + 'searchfree').style.display='inline';
	var s_val = document.getElementById(selid + 'searchvalues');
	s_val.thesval = s_val.value;
	s_val.value = document.getElementById(selid + 'searchfreeval').value;
	document.getElementById(selid + 'searchthes').style.display='none';
	document.getElementById(selid + 'thespopup').style.display='none';
}
		
AitThesaurus.showingTree = null;
AitThesaurus.thesPicklistChoose = function (selid, num)
{
	if(AitThesaurus.showingTree) 
	{
		AitThesaurus.loadedThes[AitThesaurus.showingTree].container.style.display = "none";
	}
	
	var ts = AitThesaurus.thesSets[selid];
	ts.container.appendChild(AitThesaurus.loadedThes[ts.set[num]].container);
	AitThesaurus.loadedThes[ts.set[num]].container.style.display = "block";
	var o = AitThesaurus.loadedThes[ts.set[num]].object;

	if(typeof(o.never_shown) == "undefined")
	{
		o.showAll();
		o.never_shown = "defined";
	}
	AitThesaurus.showingTree = ts.set[num];
	
	for(var idx = 1; ; ++idx)
	{
		var elem = document.getElementById(selid + "thespopupreg" + idx);
		if(!elem)
			break;
		if(elem.className != "")
			elem.setAttribute("class", "");
		//elem = document.getElementById("thespopup" + selid + "_" + idx);
		//elem.style.display = "none";
	}
	//document.getElementById("thespopup" + selid + "_" + num).style.display = "block";
	document.getElementById(selid +"thespopupreg" + num).setAttribute("class", "active");
}

AitThesaurus.loadedThes = {};
AitThesaurus.thesSets = {};
AitThesaurus.jobs = [];
AitThesaurus.jobsRunning = false;

AitThesaurus.loadThesauri = function (selid, names)
{
	var tabs = document.getElementById(selid + "thespopupclose");
	var panes = document.getElementById(selid + "thespopuppanes");
	var wait_msg = tabs.parentNode.parentNode.parentNode.parentNode.appendChild(document.createElement("div"));
	wait_msg.setAttribute("class", "WaitMessage");
	wait_msg.className = "WaitMessage";
	wait_msg.appendChild(document.createTextNode("loading Thesauri ..."));
	for(var num = 1; num <= names.length; ++num)
	{
		if(tabs)
		{
			var li = document.createElement("li");
			li.setAttribute("id", selid + "thespopupreg" + num);
			li.setAttribute("class", (num == 1)? "active" : "");
			li.setAttribute("onclick", "AitThesaurus.thesPicklistChoose("+selid+", "+num+")");
// 			li.onclick = function() { AitThesaurus.thesPicklistChoose(selid, num); };
			var a = li.appendChild(document.createElement("a"));
			a.setAttribute("name", "");
			
			if (names[num-1] && names[num-1].label) {
				a.appendChild(document.createTextNode(names[num-1].label));
				tabs.parentNode.insertBefore(li, tabs);
			}
			
		}	
	}
	
	AitThesaurus.setThesfields = function(node, term) 
		{
			if(!AitThesaurus.showing)
				return;
			document.getElementById(AitThesaurus.showing + "searchvalues").value = node.ID;
			document.getElementById(AitThesaurus.showing + "searchthesval").value = term.TRM;
		}
	
	var thes_set = [null];
	var gI = new ThesAjax();
	//var gI = ThesAjax.globalInstance();

	for(var num = 1; num <= names.length; ++num)
	{
		if (names[num-1] && names[num-1].id) {
			if(typeof(AitThesaurus.loadedThes[names[num-1].id]) != "undefined")
			{
			}
			else
			{
				var div = null;
				if(panes)
				{
					div = document.createElement("div");
					div.setAttribute("id", "thespopup" + selid + "_" + num);
					div.setAttribute("style",(num == 1)? "display:block;" : "display:none;");
					panes.appendChild(div);
				}
				var url = MDM_JS_WEB_ROOT + "/forms/ThesaurusFrame.php?thes="
				+ encodeURIComponent(names[num-1].id) 
				+ "&set_function=AitThesaurus.setThesfields"
				//+ "&set_field=" + encodeURIComponent(selid + "searchvalues") 
				//+ "&set_label=" + encodeURIComponent(selid + "searchthesval") 
				+ "&container=" + encodeURIComponent("thespopup" + selid + "_" + num);
				
				gI.callSync(url);
				
				AitThesaurus.loadedThes[names[num-1].id] = { "name" : names[num-1].id, "container" : div, "object" : AitThesaurus.objects[AitThesaurus.serial - 2] };
			}
			thes_set.push(names[num-1].id);
		}
	}
	
	
	AitThesaurus.thesSets[selid] = { set : thes_set, container: panes };
	AitThesaurus.thesPicklistChoose(selid, 1);
	
// 	window.setTimeout(AitThesaurus.showAllNew, 50);
	
	wait_msg.parentNode.removeChild(wait_msg);
}

AitThesaurus.loadAndRenderThes = function(thes_id, container_id, min_occ, set_func)
{
	var gI = ThesAjax.globalInstance();
	var url = MDM_JS_WEB_ROOT + "/forms/ThesaurusFrame.php?thes="
				+ encodeURIComponent(thes_id) 
				+ (set_func? "&set_function=" + set_func : "")
				//+ "&set_field=" + encodeURIComponent(selid + "searchvalues") 
				//+ "&set_label=" + encodeURIComponent(selid + "searchthesval") 
				+ "&container=" + encodeURIComponent(container_id)
				+ "&min_occ=" + min_occ;
	gI.callSync(url);
	var cont = document.getElementById(container_id);
	var thes = AitThesaurus.objects[AitThesaurus.serial - 2];
	AitThesaurus.loadedThes[thes_id] = { 
		"name" : thes_id, 
		"container" : cont, 
		"object" : thes };
	thes.showAll();
}

AitThesaurus.show_all_new_ofs = 0;
AitThesaurus.showAllNew = function()
{
	AitThesaurus.objects[AitThesaurus.show_all_new_ofs++].showAll();
	if(AitThesaurus.show_all_new_ofs < AitThesaurus.objects.length)
		window.setTimeout(AitThesaurus.showAllNew, 2000);
	return;
	for(var ofs = AitThesaurus.show_all_new_ofs; ofs < AitThesaurus.objects.length; ++ofs)
	{
		AitThesaurus.objects[ofs].showAll();
		//break;//DEBUG
	}
	AitThesaurus.show_all_new_ofs = AitThesaurus.objects.length;
}


AitThesaurus.serial = 1;

AitThesaurus.prototype.render = function(position)
{
	this.tvr = new TVDefaultRenderer();
	this.tvr.setRoot(this.tt.root);
	if(typeof(position) == "undefined" || position == null)
	{
		document.write("<div id='"+this.ID+"'></div>");
		this.container = document.getElementById(this.ID);
	}
	else if(typeof(position) == "string")
		this.container = document.getElementById(position);
	else
		this.container = position;
	this.tree_container = this.container.appendChild(document.createElement('div'));
	this.container.insertBefore(this.searchBox(), this.tree_container);
	this.tvr.draw(this.tree_container);
	this.tt.root.show(this.tvr, true);
}

AitThesaurus.prototype.clearDisplay = function()
{
}

AitThesaurus.prototype.searchBox = function()
{
	var me = this;
	var div = document.createElement("div");
	div.className = this.css_pfx + "Query";
	var frm = document.createElement("form");
	this.search_box = frm;
	frm.setAttribute("name", this.tree_cls_name + "Form");
	frm = div.appendChild(frm);
	var tbl = frm.appendChild(document.createElement("table"));
	tbl = tbl.appendChild(document.createElement("tbody"));
	var tr = tbl.appendChild(document.createElement("tr"));
	var td;
	td = tr.appendChild(document.createElement("td"));
	td.className = this.css_pfx + "Label";
	td.appendChild(document.createTextNode('Term'));
	
	td = tr.appendChild(document.createElement("td"));
	td.className = this.css_pfx + "Field";
	var inp = td.appendChild(document.createElement("input"))
	inp.setAttribute("type", "text");
	inp.setAttribute("name", "query");
	inp.setAttribute("value", "");
	inp.setAttribute("onkeypress", "return noenter(event);");
	
	td = tr.appendChild(document.createElement("td"));
	td.className = this.css_pfx + "Button";
	td.onclick = function() { me.searchNodes(me.search_box.query.value); };
	td.appendChild(document.createTextNode('Filter'));
	
	tr = tbl.appendChild(document.createElement("tr"));
	td = tr.appendChild(document.createElement("td"));
	td = tr.appendChild(document.createElement("td"));
	var sel = td.appendChild(document.createElement("select"));
	sel.setAttribute("name", "lang");
	sel.setAttribute("size", "1");
	
	sel.onchange = function() { me.thesChangeLang(this.value); };
	var langs = this.req.io.callSync(this.req.service + "?GetLanguages", [this.session_id]);
	
	for(var ofs = 0; ofs < langs.languages.length; ++ofs)
	{
		var opt = sel.appendChild(document.createElement("option"));
		opt.setAttribute("value", langs.languages[ofs].lang_code);
		if(langs.languages[ofs].lang_code == this.thes_lang_)
			opt.setAttribute("selected", "selected");
		opt.appendChild(document.createTextNode(langs.languages[ofs].language));
	}
	td = tr.appendChild(document.createElement("td"));
	td.className = this.css_pfx + "Button";
	td.onclick = function() { me.showAll(); };
	td.appendChild(document.createTextNode('ShowAll'));
// 	var aa = tr.appendChild(document.createElement("td"));
// 	var aa = aa.appendChild(document.createElement("a"));
// 	aa.setAttribute("href", "javascript:AitThesaurus.objects[" +this.serial_no + "].showAll();");
// 	aa.appendChild(document.createTextNode("SHOWALLLLLL"));
	return(div);
}

AitThesaurus.prototype.thesChNLang = function(nd)
{
	if(nd.terms) 
	{
		var tn = nd.vis_;
		var done = false;
		for(var ofs2 = 0, end2 = nd.terms.length; ofs2 < end2; ++ofs2)
			if(nd.terms[ofs2].LANG == this.thes_lang_)
			{
				var trm = nd.terms[ofs2];
				tn.content.innerHTML = "<div>" + trm.TRM + "</div>";
				done = true;
				break;
			}
		if(!done)
		{
			//<em>["+nd.terms[0].LANG+"]</em>
			tn.content.innerHTML = "<div><span style='font-size:8px;'><img alt='[eng]' src='"+ MDM_JS_WEB_ROOT + "/templates/default/images/grossbritannien.gif' /> </span> " + nd.terms[0].TRM+ "</div>";
		}
		tn.content.style.cursor = 'pointer';
		
		var me = this;
		tn.content.onclick = function () 
			{
				var node = nd;
				var term = node.terms[0];
				for(var ofs = node.terms.length; ofs-- > 0; )
					if(node.terms[ofs].LANG == me.thes_lang_)
					{
						term = node.terms[ofs];
						break;
					}
				var ait_thes = me;
				eval(me.click_code);
			}
	}
}

AitThesaurus.prototype.thesChangeLang = function(lang)
{
	this.thes_lang_ = lang;
	for(var ofs = 0, end = this.tree_cls.nodes_.length; ofs < end; ++ofs) 
	{
		this.thesChNLang(this.tree_cls.nodes_[ofs]);

	}
}

AitThesaurus.prototype.searchNodes = function (query) 
{
		//		alert("searchNodes("+query+" in <?php echo $lang; ?>)");
	var ret;
	try
	{
		ret = this.req.GetTreeNodes(this.session_id, query, {field:"SCOPE", query:""}, this.thes_lang_, '', 0, 0, 700);
	} catch(e) {
		//document.getElementsByName('body')[0].appendChild(document.createComment(e.message));
		//alert(e.message);
	}
// alert(ThesAjax.serializeJs(ret));
	if(ret.nodes.length > 0)
	{
		this.renderNodes(ret.nodes);
	}
	var msg = this.tvr.container.insertBefore(document.createElement("div"), this.tvr.container.firstChild);
	msg.appendChild(document.createTextNode(
	"Found %c terms".replace(/%c/, "" + ret.nodes.length)));

}

AitThesaurus.prototype.showAll = function () 
{
//	alert(this.ID);
	if(this.showAll.lock)
		return;
	this.showAll.lock = true;
	var ret;
	try
	{	
		var req = new AitThesaurus.AjaxLink(this.req_cls);
		//ret = req.GetTreeNodes(this.session_id, "", {field:"SCOPE", query:""}, '', '', 1, 0, 700);
		ret = req.GetChildren(this.session_id, "", '', 0, 700, this.occ_filter)
		for(var i = 0; i < ret.nodes.length; ++i)
			if(ret.nodes[i].NT.length > 0)
				ret.nodes[i].EX_HK_ = true;
		
		this.renderNodes(ret.nodes);
	} catch(e) {
		this.container.removeChild(this.tree_container);
		this.tree_container = this.container.appendChild(document.createElement('div'));
		this.tree_container.setAttribute("class", "ErrorMessage");
		this.tree_container.appendChild(document.createTextNode("Could not load thesaurus from '" + this.req_cls + "'.\nInternal failure"));
		var err_detail = this.tree_container.appendChild(document.createElement('div'));
		err_detail.setAttribute("class", "ExceptionDump");
		err_detail.appendChild(document.createTextNode(e.message));
	}
// 		alert(ret.nodes.length);
	
	this.showAll.lock = false;
}

AitThesaurus.prototype.renderNodes = function(nodes)
{
	this.tree_cls.nodes_ = nodes;
	this.tt.create();
	
	this.tvr = new TVDefaultRenderer();
	this.tvr.setRoot(this.tt.root);
	
	this.container.removeChild(this.tree_container);
	this.tree_container = this.container.appendChild(document.createElement('div'));
	this.tvr.draw(this.tree_container);
	this.tt.root.show(this.tvr, true);
	this.thesChangeLang(this.thes_lang_);
}



AitThesaurus.AjaxLink = function(srv)
{
  this.io = new ThesAjax();
  this.service = MDM_JS_AJAX_GATEWAY + srv;
}


AitThesaurus.AjaxLink.prototype.GetTreeNodes = function(session_ticket, TRM, SCOPE, language, BT, GS_LEVEL, max_subtree_depth, max_node_count)
{
  var ret = this.io.callSync(this.service + "?GetTreeNodes", [session_ticket, TRM, SCOPE, language, BT, GS_LEVEL, max_subtree_depth, max_node_count]);
  return(ret);
}

AitThesaurus.AjaxLink.prototype.GetTreeNodesQualified = function(session_ticket, select_sub_tree, filter_tree, lang, max_subtree_depth, max_node_count)
{
  var ret = this.io.callSync(this.service + "?GetTreeNodesQualified", [session_ticket, select_sub_tree, filter_tree, lang, max_subtree_depth, max_node_count]);
  return(ret);
}

AitThesaurus.AjaxLink.prototype.GetSubTree = function(session_ticket, tree_root, filter, lang, max_subtree_depth, max_node_count)
{
  var ret = this.io.callSync(this.service + "?GetSubTree", [session_ticket, tree_root, filter, lang, max_subtree_depth, max_node_count]);
  return(ret);
}


AitThesaurus.AjaxLink.prototype.GetParents = function(session_ticket, ID, count, pref_only)
{
  var ret = this.io.callSync(this.service + "?GetParents", [session_ticket, ID, count, pref_only]);
  return(ret);
}

AitThesaurus.AjaxLink.prototype.GetChildren = function(session_ticket, ID, lang, max_subtree_depth, max_node_count, occ_filter)
{
  var ret = this.io.callSync(this.service + "?GetChildren", [session_ticket, ID, lang, max_subtree_depth, max_node_count, occ_filter]);
  return(ret);
}

AitThesaurus.AjaxLink.prototype.IndexLookup = function(session_ticket, field, language, term, max_term_count)
{
  var ret = this.io.callSync(this.service + "?IndexLookup", [session_ticket, field, language, term, max_term_count]);
  return(ret);
}

AitThesaurus.AjaxLink.prototype.Login = function(username, password, timeout)
{
  var ret = this.io.callSync(this.service + "?Login", [username, password, timeout]);
  return(ret);
}

AitThesaurus.AjaxLink.prototype.Logout = function(session_ticket)
{
  var ret = this.io.callSync(this.service + "?Logout", [session_ticket]);
  return(ret);
}
