<!--\r

// public
// Change this if you want to send the http request to an other server object.
// make sure to put a '?' at the end so parameters concatenate well.
// NOTE this property is not overall supported and will be removed.
var DSHttpRequestUrlBase = "?";


var NotebookScrollerEventSource;
var NotebookScrollerEventTimeout;
var NavigatorOnResizeHACKTimeout;
var FactoryFrameOnResizeHACKTimeout;
var DSSuppressLayout;

// used to register DataSetCaches
var DSDataSetChaches = null;

// managed by AspxRequest, DSHttpRequestMap, HttpRequestItem and HandlerOnRecieve
    var CurrentXmlHttpRequestItem;
    var CurrentXmlHttpRequest;
    var httpRequestMap;
//

/* Managed by RequestContext. Only one RequestContext can be gathering viewstates to make a request.
 * No new RequestContext can be made before the last one has fired. Used by AddNewBusy to name the
 * busies. Use this var to write viewstates to that are needed by the c# side to anwer the request.
 */
var DSCurrentRequestContext;

// managed by HandlerOnRecieve() and GetNextResponseText
var DSCurrentResponseText;

// managed by EvaluateResponse. Used to pass thru data to the Set functions.
var DSCurrentData;

// Use to pass thru the layout size to a component via the DoLayout functions.
var DSLayoutWidth;
var DSLayoutHeight;

function GetHttpRequest()
{
	if (window.XMLHttpRequest){
		// If IE7, Mozilla, Safari, etc: Use native object
		return new XMLHttpRequest()
	}
	else if (window.ActiveXObject){
		// ...otherwise, use the ActiveX control for IE5.x and IE6
		var result = new ActiveXObject("Microsoft.XMLHTTP"); 
		if (result == null)
		{
			result = new ActiveXObject("Msxml2.XMLHTTP");
		}
		return result;
	}
}

// Do not call this function directly, use RequestContext.Fire() instead.
function AspxRequest(requestContext)
{
	var httpRequest = new HttpRequestItem(requestContext)
	if (httpRequestMap == null)
	{
		httpRequestMap = new DSHttpRequestMap();
	}
	
	var delay = httpRequestMap.AddHttpRequest(httpRequest);
	
	if (delay)
	{
		setTimeout(function()
		{
			if (CurrentXmlHttpRequestItem == null && httpRequestMap[httpRequest.name] == httpRequest)
			{
				var next = httpRequestMap.next;
				next.DoAspxRequest();
			}
		}
		, 300); 
	}
	else
	{
		if (CurrentXmlHttpRequestItem == null)
		{
			var next = httpRequestMap.next;
			next.DoAspxRequest();
		}
	}
}

function DSHttpRequestMap()
{
	this.AddHttpRequest = HttpRequestMapAddHttpRequest;
	this.CancelHttpRequest = HttpRequestMapCancelHttpRequest;
	this.RemoveHttpRequest = HttpRequestMapRemoveHttpRequest;
	//private
	this.last = this;
}

function HttpRequestMapAddHttpRequest(httpRequest)
{
	var delay = this.CancelHttpRequest(httpRequest.name);

	this[httpRequest.name] = httpRequest;
	this.last.next = httpRequest;
	this.last = httpRequest;

	return delay;
}

function HttpRequestMapCancelHttpRequest(requestName)
{
	var remover = this[requestName];
	if (remover != null)
	{
		var isCurrent = remover == CurrentXmlHttpRequestItem && CurrentXmlHttpRequest != null;
	    if (isCurrent)
	    {
	    	remover.context.busyList.clear();
			CurrentXmlHttpRequest.onreadystatechange = function() {};
	        CurrentXmlHttpRequest.abort();
		    CurrentXmlHttpRequest = null;
		    CurrentXmlHttpRequestItem = null;
		}
		this.RemoveHttpRequest(remover);
		this[requestName] = null;
		
		if (isCurrent)
		{
			var next = httpRequestMap.next;
			if (next != null)
			{
				next.DoAspxRequest();
			}
			return true;
		}
	}
	return false;
}

function HttpRequestMapRemoveHttpRequest(httpRequest)
{
	this[httpRequest.name] = null;

	var i = this.next;
	var prev = this;
	while (i != null)
	{
		if (i == httpRequest)
		{
			prev.next = i.next;
			if (i == this.last)
			{
				this.last = prev;
			}
		}
		else
		{
			prev = i;
		}
		i = i.next;
	}
}

/* Set caller to your own id this is used at the c# side to find the Voyager
 * Create a new RequestContext before calling eval("GetViewStates...") on other Components.
 * The name is used to administrate which Busy indicators belong to which request, and
 * to abort previous requests that relate to constraints that where send to the same target. 
 * When sending a constraint set the name to the target component you want to send a constraint to.
 */
function RequestContext(caller, name, xx)
{
    // readonly
		this.xx = xx;
        this.caller = StringMapEscape(caller);
        this.name = name;
        this.busyList = new BusyList(this);
    //
    if (DSCurrentRequestContext != null)
    {
        alert("DSCurrentRequestContext was not null. caller = " + caller + " request name = " + name);
    }
    DSCurrentRequestContext = this;
    
    this.Fire = RequestContextFire;
    this.AddUnsecureVS = RequestContextAddUnsecureVS;
    this.AddSecureVS = RequestContextAddSecureVS;
    // private
    this.viewStates = "";
}

function RequestContextFire()
{
    DSCurrentRequestContext = null;
    AspxRequest(this);
}

function RequestContextAddUnsecureVS(key, val)
{
    this.viewStates = this.viewStates + ";#" + StringMapEscape(key) + "=" + StringMapEscape("" + val);
}

function RequestContextAddSecureVS(svs)
{
    this.viewStates = this.viewStates + ";" + svs;
}

function HttpRequestItem(requestContext)
{
    //readonly
        this.context = requestContext;
        this.name = requestContext.name;
    //
	this.DoAspxRequest = HttpRequestItemDoAspxRequest;
}

function HttpRequestItemDoAspxRequest()	
{	
	CurrentXmlHttpRequestItem = this;
	CurrentXmlHttpRequest = GetHttpRequest();
	if (CurrentXmlHttpRequest != null)
	{
		this.context.busyList.startTimer();
		CurrentXmlHttpRequest.onreadystatechange = HandlerOnRecieve;
		this.context.AddUnsecureVS("DScaller", this.context.caller);
		var url = DSHttpRequestUrlBase + "xx=";
	    var data = document.getElementById("FactoryContainer");
		if (this.context.xx == null)
		{
		    this.context.AddUnsecureVS("DSticket", data.getAttribute("ticket"));
		    this.context.AddUnsecureVS("DSuserdata", data.getAttribute("userdata"));
		    
			var dscId = DSDataSetChaches;
			while (dscId != null)
			{
				var dsc = document.getElementById(dscId.Id)
				this.context.AddSecureVS(dsc.getAttribute("viewState"));
				dscId = dscId.next;
			}
			
		    CurrentXmlHttpRequest.open("POST", url + "DSComponent", true);
		    CurrentXmlHttpRequest.send(this.context.viewStates);          
		}	
		else
		{
			url = url + this.context.xx;
			var queryDatabase = data.getAttribute("queryDatabase");
			if (queryDatabase != null)
			{
				url = url + "&DSdatabase=" + escape(queryDatabase);
			}
			var queryModule = data.getAttribute("queryModule");
			if (queryModule != null)
			{
				url = url + "&DSmodule=" + escape(queryModule);
			}
		    CurrentXmlHttpRequest.open("POST", url, true);
		    CurrentXmlHttpRequest.send(this.context.viewStates);          
		}    
	}
	else
	{
		alert("Sumatra Aspxclient: Unable to open a XmlHttpRequest");
	}
}

function HandlerOnRecieve()
{  
	// This handler is called 4 times for each 
	// state change of xmlhttp
	// States are: 0 uninitialized
	//      1 loading
	//      2 loaded
	//      3 interactive
	//      4 complete
	var cur = CurrentXmlHttpRequest;
	if (cur.readyState==4){
		CurrentXmlHttpRequestItem.context.busyList.clear();
	    if (cur.status != 200)
	    {
	        WriteDebug("Status = " + cur.status + "Text ='" + cur.statusText + "'");
		    alert("Http connection error.");    
	    }
		DSCurrentResponseText = cur.responseText;
		httpRequestMap.RemoveHttpRequest(CurrentXmlHttpRequestItem);
		httpRequestMap[CurrentXmlHttpRequestItem.name] = null;
		CurrentXmlHttpRequest = null;

		if (NotAnException())
		{
			EvaluateResponse()
		}
		
		CurrentXmlHttpRequestItem = null;
		var next = httpRequestMap.next;
		if (next != null)
		{
			next.DoAspxRequest();
		}
	}
}

function NotAnException()
{
    var response = DSCurrentResponseText;
	var exstring = "\xFF\xFFExceptionMessage=";
	splitpos = response.lastIndexOf(exstring);
	if (splitpos < 0)
	{
	    var endstring = "\xFF\xFF\xFF End\xFF";
	    if (response.length >= endstring.length)
	    {
    	    if (response.substr(response.length - endstring.length) == endstring)
    	    {
    	        DSCurrentResponseText = response.substr(0, response.length - endstring.length); 
    	        return true;
    	    }
	    }
	    if (response.length > 200)
	    {
	        response = response.substr(response.length - 200)
	    }
        WriteDebug("Unterminated response!\r\n" + response);
	    
	    alert("Http connection error.");    
		return false;
	}
	response = response.substring(splitpos + exstring.length);
	alert(response);
	return false;
}

function EvaluateResponse()
{
	/*
	 * When a request is aborted both ie and fireFox call HandlerOnRecieve with readyState == 4
	 * the DSCurrentResponseText is then null or "" so even when the javascript wont set this to ""
	 * this state should be checked.
	 */
	while (DSCurrentResponseText != null && DSCurrentResponseText != "")
	{
		var response = GetNextResponseText();
		DSCurrentData = GetNextResponseText();
		eval(response);
	}
}

function GetNextResponseText()
{
    var restxt = DSCurrentResponseText;
    if (restxt == null || restxt.substr(0, 2) != "\xFF\xFF")
    {
        return null;
    }
	splitpos = DSCurrentResponseText.indexOf("\xFF\xFF", 2);
	var result;
	if (splitpos < 0)
	{
		DSCurrentResponseText = null;
		return restxt.substr(2);
	}
	else
	{
		DSCurrentResponseText = restxt.substring(splitpos);
		return restxt.substring(2, splitpos);
	}
}


function DSNavigatorHandlerSet(myId, property)
{
	if (property == "accessibleDatabases")
	{
		var dbSelect = document.getElementById("NavigatorDatabase");
		var databaseConcat = DSCurrentData;
		var databaseList = databaseConcat.split(";");
		while(dbSelect.options.length > 0)
		{
			dbSelect.removeChild(dbSelect.firstChild);
		}
		for (var i = 1; i < databaseList.length; i++)
		{
			var oOption = document.createElement('OPTION');
			var dbData = StringMapUnEscape(databaseList[i]).split(";");
			oOption.value= dbData[1];
			oOption.text = dbData[2];
			dbSelect.options.add(oOption);
		}
		dbSelect.selectedIndex = -1;
	}
	if (property == "currentDatabase")
	{
		var database = DSCurrentData;
		var dbSelect = document.getElementById("NavigatorDatabase");
		for (var i = 0; i < dbSelect.options.length; i++)
		{
			if (dbSelect.options[i].value == database)
			{
				dbSelect.selectedIndex = i;
				break;
			}
		}
	}
	if (property == "accessibleModules")
	{
		var modSelect = document.getElementById("NavigatorModule");
		var moduleConcat = DSCurrentData;
		var moduleList = moduleConcat.split(";");
		while(modSelect.options.length > 0)
		{
			modSelect.removeChild(modSelect.firstChild);
		}
		for (var i = 1; i < moduleList.length; i++)
		{
			var oOption = document.createElement('OPTION');
			var modData = StringMapUnEscape(moduleList[i]).split(";");
			oOption.text = modData[1];
			oOption.value= modData[2];
			oOption.title = modData[3];
			modSelect.options.add(oOption);
		}
		if (modSelect.options.length == 1)
		{
		    modSelect.selectedIndex = 0;
		    DSNavigatorChangeMod(null);
		}
		else
		{
		    modSelect.selectedIndex = -1;
		}
	}
}

function checkQuirksMode()
{
	if (document.compatMode != "CSS1Compat")
	{
		alert("The containing page is not rendered in standards-compliant mode but in quirks mode.\nThis may result in unexpected behavior of the page."); 
	}
}

function DSNavigatorOnLoad()
{
    window.onresize = FactoryFrameHandlerWindowOnResize;
    window.offscreenBuffering = "true";
    FactoryFrameHandlerBodyOnResize();
    
    var rc = new RequestContext("DSNavigator", "DSNavigator", "DSNavigator");
	rc.AddUnsecureVS("NavigatorReq", "databases");
	rc.Fire();
}

function DSNavigatorChangeDB()
{
	var dbSelect = document.getElementById("NavigatorDatabase");
	var database = dbSelect.options[dbSelect.selectedIndex].value;

    var rc = new RequestContext("DSNavigator", "DSNavigator", "DSNavigator");
	rc.AddUnsecureVS("NavigatorReq", "modules");
	rc.AddUnsecureVS("DSdatabase", database);
	rc.Fire();
}

function DSNavigatorChangeMod(e)
{
	if (e == null)
	{
		e = window.event;
	}
	var dbSelect = document.getElementById("NavigatorDatabase");
	if (dbSelect.selectedIndex == -1)
	{
		if (dbSelect.options.length == 1)
		{
			dbSelect.selectedIndex = 0;
		}
		else
		{
			return;
		}
	}
	var targets = document.getElementById("DSNavigatorTargetContainer");
	var database = dbSelect.options[dbSelect.selectedIndex].value;
	var modSelect = document.getElementById("NavigatorModule");
	var module = modSelect.options[modSelect.selectedIndex].value;
	
	//NOTE database and module are already uri escaped.
	var frameUrl = DSHttpRequestUrlBase + "&DSdatabase=" + database + "&DSmodule=" + module;
	var moduleId = escape(database) + "&" + escape(module);
	
	var target = null;
	var i = targets.firstChild;
	while (i != null)
	{
		i.style.display = "none";
		//i.style.width = "0px";
		//i.style.height = "0px";
		if (i.getAttribute("moduleId") == moduleId)
		{
			target = i;
		}
		i = i.nextSibling;
	}
	if (target == null)
	{
		target = document.createElement("IFrame");
//		target.style.width = "100%";
//		target.style.height = "100%";
		target.style.width = targets.style.width;
		target.style.height = targets.style.height;
		target.setAttribute("moduleId", moduleId);
		target.scrolling = "NO";
		target.frameBorder = "0";
		targets.appendChild(target);
		target.src = frameUrl;
	}
	else
	{
		target.style.display = "block";
		if (e.ctrlKey)
		{
			target.src = frameUrl;
		}
	}
}

var lastDSNavigatorWidth;

function DSNavigatorDoLayout()
{
	var targets = document.getElementById("DSNavigatorTargetContainer");
	var navigator = document.getElementById("DSNavigator");

	var w = PixelToStr(DSLayoutWidth);
	var h = PixelToStr(DSLayoutHeight - navigator.offsetHeight);

	var mod = targets.style.width == w && targets.style.height != h
	targets.style.width = w;
	targets.style.height = h;
	if (document.all != null && mod)
	{
		lastDSNavigatorWidth = w;
		if (ToPixel(w) > 0)
		{
			w = PixelToStr(DSLayoutWidth - 1);
		}
		NavigatorOnResizeHACKTimeout = setTimeout("DSNavigatorOnRezizeHack();", 150);
	}
	var i = targets.firstChild;
	while (i != null)
	{
		i.style.width = w;
		i.style.height = h;
		i = i.nextSibling;
	}
}

function DSNavigatorOnRezizeHack(width, newHeight)
{
	var targets = document.getElementById("DSNavigatorTargetContainer");
	var i = targets.firstChild;
	while (i != null)
	{
		i.style.width = lastDSNavigatorWidth;
		i = i.nextSibling;
	}
}

function BodyOnLoad()
{
    checkQuirksMode();
    var rc = new RequestContext("FactoryContainer", "FactoryContainer");
	var container = document.getElementById("FactoryContainer")
    AddNewBusy(container);
    
	rc.Fire();
}

function FactoryCallbackHandlerSet(myId, property)
{
//	var me = document.getElementById(myId);
	var container = document.getElementById("FactoryContainer")
	if (property == "factory")
	{
		DSDataSetChaches = null;
	    ParseHtmlTo(container, DSCurrentData);
	    window.onresize = FactoryFrameHandlerWindowOnResize;
	    window.offscreenBuffering = "true";
	    FactoryFrameHandlerBodyOnResize();
	}
}

function FactoryFrameHandlerWindowOnResize()
{
    if (DSSuppressLayout != "true")
    {
        DSSuppressLayout = "true";
        if (document.all)
        {
			if (FactoryFrameOnResizeHACKTimeout != null)
			{
				clearTimeout(FactoryFrameOnResizeHACKTimeout);
			}
		    FactoryFrameOnResizeHACKTimeout = setTimeout("FactoryFrameOnResizeTimeout();", 200);
        }
        else
        {
	        FactoryFrameHandlerBodyOnResize();
        }
        DSSuppressLayout = null;
    }
}

var OldWindowSizeX;
var OldWindowSizeY;

function FactoryFrameOnResizeTimeout()
{
	if (FactoryFrameOnResizeHACKTimeout != null)
	{
		clearTimeout(FactoryFrameOnResizeHACKTimeout);
	}
	DSSuppressLayout = "true";
	FactoryFrameHandlerBodyOnResize();
    DSSuppressLayout = null;
}

function FactoryFrameHandlerBodyOnResize()
{
    var w;
    var h;
	if (window.innerWidth == null)
	{
        w = document.documentElement.offsetWidth; // causes the window to fire a onresize event.
        h = document.documentElement.offsetHeight; // causes the window to fire a onresize event.
	}
	else
	{
		w = window.innerWidth;
		h = window.innerHeight;
	}
	
 	// HACK prevents the event from fireing twice in IE
	if (OldWindowSizeX == w && OldWindowSizeY == h)
	{
	    return;
	}
	OldWindowSizeX = w;
	OldWindowSizeY = h;
	if (h <= 0 || w <= 0)
	{
		return;
	}
	//WriteDebug("Rezized to: " + h + ", " + w);
	var debugStatusBar = document.getElementById("DebugStatusBar");
	if (debugStatusBar != null)
	{
		h = h - debugStatusBar.offsetHeight;
	}
	
	DSLayoutWidth = w;
	DSLayoutHeight = h;
	
	var container = document.getElementById("FactoryContainer");
	if (container.firstChild)
	{
		var t = container.firstChild.getAttribute("doLayout");
		if (t != null)
		{
			eval(t);
		}
	}
}

function WriteDebug(message)
{
	DSCurrentData = message;
	DebugStatusBarSet("DebugStatusBar", "traceMessage")
}

function DebugStatusBarSet(myId, property)
{
	var me = document.getElementById(myId);
	if (me == null)
	{
		return;
	}
	if (property == "traceMessage")
	{
		me.innerHTML = DSCurrentData;
		var lastline = parseInt(me.getAttribute("lastline"));
		lastline = isFinite(lastline) ? lastline + 1 : 0;
		me.setAttribute("line" + lastline, DSCurrentData);
		me.setAttribute("lastline", lastline);
		if (lastline >= 100)
		{
			me.setAttribute("line" + (lastline - 100), "-- Removed --");
			if (lastline >= 101)
			{
				me.removeAttribute("line" + (lastline - 101));
			}
		}
		var debugWindow = document.getElementById("DebugWindow");
		if (debugWindow != null)
		{
			DebugWindowAppend(debugWindow, DSCurrentData);
		}
	}
	
	if (property == "logTable")
	{
		var logField = document.getElementById("DebugWindowLogField");
		if (logField != null)
		{
			while (logField.lastChild != null)
			{
				logField.removeChild(logField.lastChild);
			}
			ParseHtmlTo(logField, DSCurrentData);
		}
	}
}

function DebugWindowAppend(me, line)
{
	var textField = me.lastChild.firstChild;
	textField.innerHTML = textField.innerHTML + (line + "<br>");
	textField.scrollTop = 65535;
}

function DebugStatusBarOndblclick()
{
	var debugStatusBar = document.getElementById("DebugStatusBar");
	if (document.getElementById("DebugWindow") == null)
	{
		var debugWindow = document.createElement("div");
		debugWindow.id = "DebugWindow";
		debugWindow.style.position = "absolute";
		debugWindow.style.zIndex = "100";
		debugWindow.style.left = "20px";
		debugWindow.style.top = "20px";
		debugWindow.style.width = "700px";
		debugWindow.style.height = "400px";
		debugWindow.style.overflow = "hidden";
		debugWindow.style.borderTop = "solid 2px #FFFFFF";
		debugWindow.style.borderLeft = "solid 2px #FFFFFF";
		debugWindow.style.borderRight = "solid 2px #808080";
		debugWindow.style.borderBottom = "solid 2px #808080";
		debugWindow.style.backgroundColor = "#C0C0C0";
		debugWindow.style.fontSize = "12px";
		
		var debugWindowTitle = document.createElement("div");
		debugWindowTitle.style.backgroundColor = "#4040FF";
		debugWindowTitle.style.padding = "1px";
		debugWindowTitle.style.color = "#FFFFFF";
		debugWindowTitle.innerHTML = "Query Tracer";
		debugWindowTitle.style.width = "700px";
		debugWindowTitle.style.height = "20px";
		debugWindowTitle.style.fontSize = "14px";
		
		var closeBtn = document.createElement("div");
		closeBtn.style.overflow = "hidden";
		closeBtn.style.width = "12px";
		closeBtn.style.height = "12px";
		closeBtn.style.borderTop = "solid 2px #FFB0B0";
		closeBtn.style.borderLeft = "solid 2px #FFB0B0";
		closeBtn.style.borderRight = "solid 2px #802020";
		closeBtn.style.borderBottom = "solid 2px #802020";
		closeBtn.style.marginTop = "-14px";
		closeBtn.style.marginLeft = "680px";
		closeBtn.style.paddingLeft = "2px";
		closeBtn.style.backgroundColor = "#C04040";
		closeBtn.style.color = "#FFFFFF";
		closeBtn.style.fontFamily = "Commic";
		closeBtn.style.fontSize = "10px";
		closeBtn.innerHTML = "X";
		closeBtn.onclick = function(event)
		{
			debugWindow.parentNode.removeChild(debugWindow);
		}
		
		var content = document.createElement("div");
		content.id = "DebugWindowContent";
		content.style.backgroundColor = "#FFFFFF";
		content.style.color = "#000000";
		content.style.borderTop = "solid 2px #808080";
		content.style.borderLeft = "solid 2px #808080";
		content.style.borderRight = "solid 2px #FFFFFF";
		content.style.borderBottom = "solid 2px #FFFFFF";
		
		var textField = document.createElement("div");
		textField.id = "DebugWindowTextField";
		textField.style.backgroundColor = "#FFFFFF";
		textField.style.color = "#000000";
		textField.style.width = "696px";
		textField.style.height = "356px";
		textField.style.overflow = "scroll";
		
		var logField = document.createElement("div");
		logField.id = "DebugWindowLogField";
		logField.style.backgroundColor = "#FFFFFF";
		logField.style.color = "#000000";
		logField.style.width = "696px";
		logField.style.height = "356px";
		logField.style.overflow = "scroll";
		logField.style.display = "none";
		
		var LogBtn = document.createElement("div");
		LogBtn.style.overflow = "hidden";
		LogBtn.style.width = "112px";
		LogBtn.style.height = "12px";
		LogBtn.style.borderTop = "solid 1px #FFFFFF";
		LogBtn.style.borderLeft = "solid 1px #FFFFFF";
		LogBtn.style.borderRight = "solid 1px #808080";
		LogBtn.style.borderBottom = "solid 1px #808080";
		LogBtn.style.marginTop = "-20px";
		LogBtn.style.marginLeft = "121px";
		LogBtn.style.padding = "3px";
		LogBtn.style.backgroundColor = "#C0C0C0";
		LogBtn.style.color = "#000000";
		LogBtn.style.fontFamily = "sans-serif";
		LogBtn.style.fontSize = "12px";
		LogBtn.style.textAlign = "center";
		LogBtn.innerHTML = "Log Messages";
		LogBtn.onclick = function(event)
		{
			LogBtn.innerHTML = "Refresh";
			textField.style.display = "none";
			logField.style.display = "block";
			
		    var rc = new RequestContext("DebugStatusBar", "logTable", "DSDebugger");
		    var data = document.getElementById("FactoryContainer");
			rc.AddUnsecureVS("DSticket", data.getAttribute("ticket"));
			rc.AddUnsecureVS("DSuserdata", data.getAttribute("userdata"));	

			rc.AddUnsecureVS("DebugReq", "logTable");
			
			AddNewBusy(logField);
			rc.Fire();
		}
		
		var QueryBtn = document.createElement("div");
		QueryBtn.style.overflow = "hidden";
		QueryBtn.style.width = "112px";
		QueryBtn.style.height = "12px";
		QueryBtn.style.borderTop = "solid 1px #FFFFFF";
		QueryBtn.style.borderLeft = "solid 1px #FFFFFF";
		QueryBtn.style.borderRight = "solid 1px #808080";
		QueryBtn.style.borderBottom = "solid 1px #808080";
		QueryBtn.style.marginTop = "0px";
		QueryBtn.style.marginLeft = "0px";
		QueryBtn.style.padding = "3px";
		QueryBtn.style.backgroundColor = "#C0C0C0";
		QueryBtn.style.color = "#000000";
		QueryBtn.style.fontFamily = "sans-serif";
		QueryBtn.style.fontSize = "12px";
		QueryBtn.style.textAlign = "center";
		QueryBtn.innerHTML = "Queries";
		QueryBtn.onclick = function(event)
		{
			LogBtn.innerHTML = "Log Messages";
			logField.style.display = "none";
			textField.style.display = "block";
		}
		
		debugWindowTitle.appendChild(closeBtn);
		debugWindow.appendChild(debugWindowTitle);
		debugWindow.appendChild(QueryBtn);
		debugWindow.appendChild(LogBtn);
		debugWindow.appendChild(content);
		content.appendChild(textField);
		content.appendChild(logField);
		
		
		debugStatusBar.parentNode.appendChild(debugWindow);
		
		var lastline = parseInt(debugStatusBar.getAttribute("lastline"));
		lastline = isFinite(lastline) ? lastline : 0;
		for (var i = lastline > 100 ? lastline - 100 : 0; i <= lastline; i++)
		{
			DebugWindowAppend(debugWindow, debugStatusBar.getAttribute("line" + i))
		}


	}
}

function ModuleDoLayout(myId)
{
	var me = document.getElementById(myId);
	var myW = DSLayoutWidth;
	var myH = DSLayoutHeight;
	me.style.overflow = "hidden";
	me.style.width = PixelToStr(myW);
	me.style.height = PixelToStr(myH);
		
	var t = me.firstChild.getAttribute("doLayout");
	if (t != null)
	{
		eval(t);
	}
}

function ModuleSet(myId, property)
{
	var me = document.getElementById(myId);
	alert("MODULE Set" + property + "=" + DSCurrentData);
}

function ModuleGetViewStates(myId)
{
	var me = document.getElementById(myId);
}


function NoneSet(myId, property)
{
	var me = document.getElementById(myId);
	alert("NONE(" + me.id +"): " + property + "=" + DSCurrentData);
}

function NoneGetViewStates(myId)
{
	var me = document.getElementById(myId);
}

function NoneDoLayout(myId)
{
}

function ReportGeneratorSet(myId, property)
{
	var me = document.getElementById(myId);
	var obj = me.lastChild;
	if (property == "url")
	{
		var url = DSHttpRequestUrlBase + "xx=custom&id=" + DSCurrentData;
		var base = document.location.href;
		var queryMark =base.indexOf('?');
		if (queryMark > 0)
		{
			base = base.substring(0, queryMark);
		}
		obj.src = base + url;
	}
	else if (property == "pageCount")
	{
		var count = DSCurrentData;
		var countBar = me.firstChild;
		if (count == "")
		{
			countBar.style.display = "none";
			countBar.innerHTML = "";
		}
		else
		{
			countBar.style.display = "block";
			countBar.style.backgroundColor = "transparent";
			countBar.innerHTML = count == "0" ? "Waiting for PDF" : "Generating page: " + count;
			setTimeout(function()
			{	
			    var rc = new RequestContext(myId, myId + "_url");
				rc.Fire();
			}, 1500);

		}
	}
	else if (property == "message")
	{
		alert(DSCurrentData);
	}
}

function ReportGeneratorSetViewState(myId)
{
	var me = document.getElementById(myId);
	me.setAttribute("viewState", DSCurrentData);
	
	var vs = me.getAttribute("viewState");
	if (vs != null && vs.length > 0)
	{
	    var rc = new RequestContext(myId, myId + "_url");
		rc.AddSecureVS(vs); 
		rc.Fire();
	}
	else
	{
		var obj = me.lastChild;
		obj.src = "";
	}
}


function ReportGeneratorGetViewStates(myId)
{
	var me = document.getElementById(myId);
}

function ReportGeneratorDoLayout(myId)
{
	var me = document.getElementById(myId);
	var myW = DSLayoutWidth;
	var myH = DSLayoutHeight;
	me.style.overflow = "hidden";
	me.style.width = PixelToStr(myW);
	me.style.height = PixelToStr(myH);
	var countBar = me.firstChild;
	countBar.style.display = "block";
//	obj.style.width = PixelToStr(myW);
//	obj.style.height = PixelToStr(myH);
}

function ImagePanelSet(myId, property)
{
	var me = document.getElementById(myId);
	var obj = me.firstChild;
	if (property == "clear")
	{
		ImagePanelSetUrl(me, "about:blank", "iframe");
	}
	if (property == "src")
	{
		var url = DSCurrentData;
		var newTag = getTagNameFromUrl(url);
		if (url.indexOf("http:") != 0 && url.indexOf("https:") != 0 && url.indexOf("ftp:") != 0)
		{
			var base = document.location.href;
			var queryMark =base.indexOf('?');
			if (queryMark > 0)
			{	
				base = base.substring(0, queryMark);
			}
			url = base + url;
		}
		ImagePanelSetUrl(me, url, newTag)
	}
	if (property == "file")
	{
		var url = DSHttpRequestUrlBase + "xx=custom&id=" + DSCurrentData;
		ImagePanelSetUrl(me, url, "iframe")
	}
	if (property == "image")
	{
		var url = DSHttpRequestUrlBase + "xx=custom&id=" + DSCurrentData;
		ImagePanelSetUrl(me, url, "img")
	}
}

function ImagePanelSetUrl(me, url, newTag)
{
	var obj = me.firstChild;
	if (obj.tagName.toLowerCase() != newTag.toLowerCase())
	{
		while(me.firstChild != null)
		{
			me.removeChild(me.firstChild);
		}
		obj = document.createElement(newTag);
		me.appendChild(obj)
	}
	me.removeAttribute("objWidth");
	me.removeAttribute("objHeight");
	if (obj.tagName.toLowerCase() == "img")
	{
		obj.src = url;
		obj.style.width="auto";
		obj.style.height="auto";
		obj.onload = function()
		{
			me.setAttribute("objWidth", me.firstChild.offsetWidth);
			me.setAttribute("objHeight", me.firstChild.offsetHeight);
			ImagePanelDoLayout(me.id);
			obj.onload = null;
		}
	}
	if (obj.tagName.toLowerCase() == "iframe")
	{
		obj.style.width=me.style.width;
		obj.style.height=me.style.height;
		obj.src = url;
		obj.frameborder = 0;
	}
}



function getTagNameFromUrl(url)
{
	var extension = url.substring(url.lastIndexOf("."));
	extension = extension.toLowerCase();
	switch (extension)
	{
		case ".jpg":
			return "img";
		case ".jpeg":
			return "img";
		case ".png":
			return "img";
		case ".gif":
			return "img";
		case ".bmp":
			return "img";
		case ".wmf":
			return "img";
		default :
			return "iframe";
	}
}

function ImagePanelGetViewStates(myId)
{
	var me = document.getElementById(myId);
}

function ImagePanelDoLayout(myId)
{
	var me = document.getElementById(myId);
	var myW = DSLayoutWidth;
	var myH = DSLayoutHeight;
	me.style.width = PixelToStr(myW);
	me.style.height = PixelToStr(myH);
	var obj = me.firstChild;
	if (obj.tagName.toLowerCase() == "img")
	{
	var objW = parseInt(me.getAttribute("objWidth"));
	var objH = parseInt(me.getAttribute("objHeight"));

	myH = myH - 2; // firefox adds 2 pixels somewhere sometimes and adds scrollbars.
	if (isFinite(objW) && isFinite(objH))
	{
		me.style.overflow = "auto";
		var needsShrinking =  (objW > myW || objH > myH);
		if (needsShrinking && me.getAttribute("Shrink") == "true")
		{
			var scale = Math.min(myW / objW , myH / objH);
			obj.style.width = PixelToStr(Math.floor(scale * objW));
			obj.style.height = PixelToStr(Math.floor(scale * objH));
		}
		else if (!needsShrinking && me.getAttribute("Stretch") == "true")
		{
			var scale = Math.min(myW / objW , myH / objH);
			obj.style.width = PixelToStr(Math.floor(scale * objW));
			obj.style.height = PixelToStr(Math.floor(scale * objH));
		}
		else
		{
			obj.style.width = "auto";
			obj.style.height = "auto";
		}
	}
	else
	{	
		obj.width = (myW);
		obj.height = (myH);
	}
	}
	else
	{
		me.style.overflow = "hidden";
		obj.style.width = PixelToStr(myW);
		obj.style.height = PixelToStr(myH);
	}
}


function MatrixGetViewStates(myId)
{	
	TableListGetViewStates(myId);
}
function MatrixSetViewState(myId)
{	
	TableListSetViewState(myId);
}
function MatrixSet(myId, property)
{	
	TableListSet(myId, property);
}
function MatrixDoLayout(myId)
{	
	TableListDoLayout(myId);
}


function TreeTableDoLayout(myId)
{
	var me = document.getElementById(myId);
	
	me.style.width = PixelToStr(DSLayoutWidth);
	me.style.height = PixelToStr(DSLayoutHeight);
	
	TreeTableLayoutInner(me, null);	
}

function TreeTableInitLayout(me)
{
	var content = document.getElementById(me.id + "_content");
	if (content == null)
	{
		return ;
	}
	var lastLevel = parseInt(content.getAttribute("lastLevel"));
	var expandLevel = parseInt(content.getAttribute("expandLevel"));
//	content.firstChild.firstChild.firstChild.style.alligment = "left";
   	var headerDiv = content.tHead.rows[0].cells[0].firstChild;//table.thead.tr.th.div
   	var treeTHs = headerDiv.childNodes; //div.childNodes
   	var colWidthss = [];
   	
   	// calculate the withes of each column in the collapsable part of the tree
   	for (var level = 0; level < treeTHs.length - 1; level++)
   	{
   		var headergroup = treeTHs[level]; // the first element is a filler.
   		var colWidths = [];
		var col = 0;
		for (var c = 0; c < headergroup.childNodes.length; c++)
   		{
   			if (headergroup.childNodes[c].getAttribute("filler") == null)
   			{
   				colWidths[col] = headergroup.childNodes[c].offsetWidth;
   				col++;
   			}
   		}
   		colWidthss[level] = colWidths;
   	}
   	
   	for (var rg = 0; rg < content.tBodies.length; rg++)
   	{
   		var rowgroup = content.tBodies[rg];
   		var colWidths = colWidthss[parseInt(rowgroup.getAttribute("level"))];
   		
   		for (var r = 0; r < rowgroup.childNodes.length; r++)
   		{
   			var rowchilds = rowgroup.childNodes[r].firstChild.childNodes;
   			var col = 0;
   			for (var c = 0; c < rowchilds.length; c++)
   			{
   				if (rowchilds[c].getAttribute("filler") == null)
   				{
   					colWidths[col] = Math.max(colWidths[col], rowchilds[c].offsetWidth);
   					col++;
   				}
   			}
   		}
   	}
   	
   	// apply the widths to the headers and the cells;
   	// And make unselected headergroups and collapsed rows invisible.
   	var maxWidth = 0;
   	for (var level = 0; level < treeTHs.length - 1; level++)
   	{
   		var headergroup = treeTHs[level]; 
   		var colWidths = colWidthss[level];
		var col = 0;
		var totalWidth = 0;
		for (var c = 0; c < headergroup.childNodes.length; c++)
   		{
   			if (headergroup.childNodes[c].getAttribute("filler") == null)
   			{
   				headergroup.childNodes[c].style.width = PixelToStr(colWidths[col]);
   				col++;
   			}
 			totalWidth += headergroup.childNodes[c].offsetWidth;
   		}
   		headergroup.style.width = PixelToStr(totalWidth);
   		maxWidth = Math.max(maxWidth, headergroup.offsetWidth);
   		// If we also turn of the level 0 headers the header th might collapse
		if (level != 0)
		{
			headergroup.style.display="none";
		}
   	}
  	headerDiv.style.width =  PixelToStr(maxWidth + 1);
  	if (document.all)
  	{
		for (var i = 0; i < treeTHs.length - 1; i++)
   		{
	   		treeTHs[i].style.width =  PixelToStr(maxWidth + 1); 
	   	}
   	}
   	
   	for (var rg = 0; rg < content.tBodies.length; rg++)
   	{
   		var rowgroup = content.tBodies[rg];
   		var level = rowgroup.getAttribute("level");
   		var colWidths = colWidthss[parseInt(level)];
   		
   		for (var r = 0; r < rowgroup.childNodes.length; r++)
   		{
   			var rowchilds = rowgroup.childNodes[r].firstChild.childNodes;
   			var col = 0;
   			for (var c = 0; c < rowchilds.length; c++)
   			{
   				if (rowchilds[c].getAttribute("filler") == null)
   				{
   					 rowchilds[c].style.width = PixelToStr(colWidths[col]);
   					 col++;
   				}
   			}
   		}
   		if (level > expandLevel)
   		{
   			rowgroup.style.display="none";
   		}
   		else if (level < expandLevel)
   		{
   			rowgroup.setAttribute("open", "true");
   		}
   	}
}

function TreeTableInit(myId)
{
	var me = document.getElementById(myId);
	var inner = document.getElementById(myId + "_inner");
	var scroller = document.getElementById(myId + "_scroller");
	var content = document.getElementById(me.id + "_content");

	var lastLevel = parseInt(content.getAttribute("lastLevel"));
	
	scroller.onscroll = TreeTableOnscroll;
	
	if (content != null && content.getAttribute("initialized") == null)
	{
		content.setAttribute("initialized", "true");
		
		inner.style.position = "relative";
		inner.style.overflowX = "auto";
		inner.style.overflowY= "hidden";
		content.style.position = "relative";
		scroller.style.float = "right";
		scroller.style.overflowY= "auto";

		TreeTableInitLayout(me);
		

		var row = content.tHead.rows[0];
		for (var i = 0; i < row.childNodes.length; i++)
		{
		    var thdiv = row.childNodes[i].firstChild;
		    thdiv.style.position = "relative";
		    thdiv.style.whiteSpace = "";
		}
		
		for (var col = 1; col < parseInt(content.getAttribute("headerCount")); col++)
		{
			var div = document.getElementById(myId + "_H" + col);
			var text = me.getAttribute("headText" + col);
			if (text != null)
			{
				div.innerHTML = text;
			}
			//div.onclick = TreeTableTHOnclick;
			//div.ondblclick = TreeTableTHOnclick;
   		}
   		
		if (row.childNodes.length > 0 && me.getAttribute("target") == null)
		{
			content.setAttribute("focusHead", 0);
		}

	   	for (var rg = 0; rg < content.tBodies.length; rg++)
   		{
   			var rowgroup = content.tBodies[rg];
	   		var level = parseInt(rowgroup.getAttribute("level"));
   			for (var r = 0; r < rowgroup.childNodes.length; r++)
   			{
				rowgroup.childNodes[r].onclick = TreeTableOnclick;
   				var rowchilds = rowgroup.childNodes[r].firstChild.childNodes;
   				for (var c = 0; c < rowchilds.length; c++)
   				{
	   				if (level < lastLevel && containsClass(rowchilds[c], "DSttToggle"))
   					{
   						 rowchilds[c].onclick = TreeTableToggleOnclick;
   						 rowchilds[c].ondblclick = TreeTableToggleOnclick;
   					}
   				}
   			}
	   	}
   	
        content.onkeydown = TreeTableKeydown;
        content.onfocus = TreeTableOnfocus;
        content.onblur = TreeTableOnblur;

//		content.tHead.onkeydown = TreeTableHeadKeydown;
//		content.tHead.onfocus = TreeTableHeadOnfocus;
//		content.tHead.onblur = TreeTableHeadOnblur;
        
		inner.onmousewheel = TreeTableOnwheel;
        if (inner.addEventListener)
        {
			inner.addEventListener('DOMMouseScroll', TreeTableOnwheel, true);
		}
		TreeTableLayoutInner(me, null);
	}
}

function TreeTableSet(myId, property)
{
	if (property == "innerHTML")
	{
		var inner = document.getElementById(myId + "_inner");
	    while (inner.firstChild != null)
	    {
	        inner.removeChild(inner.firstChild);
	    }
		inner.style.overflowY= "hidden";
	    inner.style.height = "1px"; // make the tree invisible until the layout has been performed
	    ParseHtmlTo(inner, DSCurrentData);
	}
	else if (property == "init")
	{
			TreeTableInit(myId);
    }
}

function TreeTableSetViewState(myId)
{
	var content = document.getElementById(myId+ "_content");
	content.setAttribute("viewState", DSCurrentData);
}

function TreeTableGetViewStates(myId)
{
	var inner = document.getElementById(myId + "_inner");
	while (inner.firstChild != null)
	{
	    inner.removeChild(inner.firstChild);
	}
	AddNewBusy(inner);
}

function TreeTableLayoutInner(me, secondTime)
{
	var inner = document.getElementById(me.id + "_inner");
	var scroller = document.getElementById(me.id + "_scroller");
	var content = document.getElementById(me.id + "_content");
	if (content == null)
	{
	    scroller.firstChild.style.height = "1px";
	}
	else
	{
	    scroller.firstChild.style.height = PixelToStr(content.offsetHeight);
	    
    	var heads = content.tHead.rows[0].childNodes;
    	if (document.all)
    	{
    		/* Somehow IE decides that a relative div is transparent to mouseclicks on places that do not
    		 * contain any text. setting the width triggers IE to send onclicks to the div again. */
    		for (var i = 0; i < heads.length; i++)
    		{
	    		var thdiv = heads[i].firstChild;
   				thdiv.style.width = "auto";
			}
		}
    }
	inner.style.height = PixelToStr(me.clientHeight);
	scroller.style.height = PixelToStr(me.clientHeight);
	scroller.style.marginBottom = "-" + scroller.style.height;
	scroller.style.width = PixelToStr(me.clientWidth);
	inner.style.width = PixelToStr(me.clientWidth - scroller.offsetWidth + scroller.clientWidth);

    // IE doesnt remove or add scrollbars during the javascript execution so all width and heigth calculations depending on this must be delayed.
	if (document.all && secondTime == null)
	{
	    setTimeout("TreeTableLayoutInner(document.getElementById('" + me.id + "'), 'true')", 100);
	}
	else
	{
    	scroller.style.height = PixelToStr(inner.clientHeight);
    	scroller.style.marginBottom = "-" + scroller.style.height;
    	inner.style.width = PixelToStr(me.clientWidth - scroller.offsetWidth + scroller.clientWidth);
        TreeTableDoScroll(me);
	}
}

function TreeTableDoScroll(me)
{
	var inner = document.getElementById(me.id + "_inner");
	var scroller = document.getElementById(me.id + "_scroller");
	var content = document.getElementById(me.id + "_content");
	if (content != null)
	{
	
	    content.style.top = -scroller.scrollTop + "px";
		var row = content.tHead.rows[0];
		for (var i = 0; i < row.childNodes.length; i++)
		{
    		var thdiv = row.childNodes[i].firstChild;
		    thdiv.style.top = scroller.scrollTop + "px";
		}
		// Do the same thing again to prevent firefox from flickering with the last column header
		if (document.all == null)
		{
			content.style.top = -scroller.scrollTop + "px";
	    }
	}
}

function TreeTableOnscroll(e)
{
	var source;
	if (e == null)
	{
		e = window.event;
		source = e.srcElement;
	}
	else
	{
		source = e.target;
	}
	var me = source;
	while (me.className != "DStlMain")
	{
	    me = me.parentNode;
	    if (me == null)
	    {
	        return;
	    }
	}
	TreeTableDoScroll(me);
}

function TreeTableKeydown(e)
{
	var source;
	if (e == null)
	{
		e = window.event;
		source = e.srcElement;
	}
	else
	{
		source = e.target;
	}
	
	var content = source;
	while (!containsClass(content, "DStlContent"))
	{
	    content = content.parentNode;
	    if (content == null)
	    {
	        return;
	    }
	}
	
	var rows = content.rows;
	var heads = content.lastChild.firstChild.childNodes;
	var focusRow = parseInt(content.getAttribute("focusRow"));
	var focusHead = parseInt(content.getAttribute("focusHead"));
	var lastLevel = parseInt(content.getAttribute("lastLevel"));
	var visibleRowCount = rows.length > 1 ? Math.floor((content.parentNode.clientHeight - rows[0].offsetHeight) / rows[1].offsetHeight) : 1;
	visibleRowCount = visibleRowCount > 2 ? visibleRowCount - 1 : 1;
	
	if (e.keyCode == 13) // Enter
	{
	    if (isFinite(focusHead) && containsClass(heads[focusHead], "DStlFocusHead"))
	    {
			//TreeTableHeadDoSort(content, heads[focusHead])
	    }
	}
	else if (e.keyCode == 32) // Space
	{
		if (isFinite(focusHead) && containsClass(heads[focusHead], "DStlFocusHead"))
	    {
			//TreeTableHeadDoSort(content, heads[focusHead])
	    }
	}
	else if (e.keyCode == 109) // Keypad minus
	{
		if (isFinite(focusRow) &&
			rows[focusRow].parentNode.getAttribute("open") == "true")
		{
			TreeTableToggleRow(rows[focusRow]);
		}
	}
	else if (e.keyCode == 107) // Keypad plus
	{
		var tbody = isFinite(focusRow) ? rows[focusRow].parentNode : null;
		if (tbody != null && 
			tbody.getAttribute("level") < lastLevel &&
			tbody.getAttribute("open") != "true")
		{
			TreeTableToggleRow(rows[focusRow]);
		}
	}
	else if (e.keyCode == 37) // Left
	{
		if (isFinite(focusRow) &&
			rows[focusRow].parentNode.getAttribute("open") == "true")
		{
			TreeTableToggleRow(rows[focusRow]);
		}
		else
		{
			TreeTableMoveFocusRowUp(content, 1);
		}	
	}
	else if (e.keyCode == 39) // Right
	{
		var tbody = isFinite(focusRow) ? rows[focusRow].parentNode : null;
		if (tbody != null && 
			tbody.getAttribute("level") < lastLevel &&
			tbody.getAttribute("open") != "true")
		{
			TreeTableToggleRow(rows[focusRow]);
		}
		else
		{
			TreeTableMoveFocusRowDown(content, 1);
		}	
	}
	else if (e.keyCode == 38) // Up
	{
		TreeTableMoveFocusRowUp(content, 1);
	}
	else if (e.keyCode == 40) // Down
	{
		TreeTableMoveFocusRowDown(content, 1);
	}
	else if (e.keyCode == 33) // PageUp
	{
		TreeTableMoveFocusRowUp(content, visibleRowCount);
	}
	else if (e.keyCode == 34) // PageDown
	{
		TreeTableMoveFocusRowDown(content, visibleRowCount);
	}
	else if (e.keyCode == 36) // Home
	{
		TreeTableMoveFocusRowUp(content, rows.length);
	}
	else if (e.keyCode == 35) // End
	{
		TreeTableMoveFocusRowDown(content, rows.length);
	}
	else
	{
		return;
	}
	if (e.preventDefault)
	{
		e.preventDefault();
	}
	return false;
}

function TreeTableMoveFocusRowUp(content, count)
{
	var rows = content.rows;
	var focusRow = parseInt(content.getAttribute("focusRow"));
	
    if (isFinite(focusRow))
    {
		var curRow = focusRow;
		var newRow = focusRow;
		while (curRow >= 2 && count > 0)
		{
			curRow--;
			if (rows[curRow].parentNode.style.display != "none")
			{
				newRow = curRow;
				count--;
			}
		}
		if (newRow != focusRow)
		{
			TreeTableMoveFocusRow(content, newRow);
		}
	}
	else
	{
		if (rows.length >= 2)
		{
			TreeTableMoveFocusRow(content, 1);
		}
	}
}

function TreeTableMoveFocusRowDown(content, count)
{
	var rows = content.rows;
	var focusRow = parseInt(content.getAttribute("focusRow"));
	
    if (isFinite(focusRow))
    {
		var curRow = focusRow;
		var newRow = focusRow;
		while (curRow < (rows.length - 1) && count > 0)
		{
			curRow++;
			if (rows[curRow].parentNode.style.display != "none")
			{
				newRow = curRow;
				count--;
			}
		}
		if (newRow != focusRow)
		{
			TreeTableMoveFocusRow(content, newRow);
		}
	}
	else
	{
		if (rows.length >= 2)
		{
			TreeTableMoveFocusRow(content, rows.length - 1);
		}
	}
}

// rowNr is the row nr in the TABLE.rows collection, ie inclusive the header row tree rows start at 1.
function TreeTableMoveFocusRow(content, rowNr)
{
	var rows = content.rows;
	var focusRow = parseInt(content.getAttribute("focusRow"));
	
    if (isFinite(focusRow))
    {
		removeClasses(rows[focusRow], "DSttSelected");
		removeClasses(rows[focusRow], "DSttFocusRow");
    }
        
    focusRow = rowNr
	addClasses(rows[focusRow], "DStltFocusRow");
    addClasses(rows[focusRow], "DSttSelected");
	content.setAttribute("focusRow", focusRow);
	
   	var headerDiv = content.tHead.rows[0].cells[0].firstChild;//table.thead.tr.th.div
   	var treeTHs = headerDiv.childNodes; //div.childNodes
	var focusRowLevel = parseInt(rows[focusRow].getAttribute("level"));
	if (!isFinite(focusRowLevel) || level >= (treeTHs.length - 1))
	{
		focusRowLevel = 0;
		}
   	for (var level = 0; level < treeTHs.length - 1; level++)
   	{
   		var headergroup = treeTHs[level]; 
   		// If we also turn of the level 0 headers the header th might collapse
		if (level != focusRowLevel)
		{
			headergroup.style.display="none";
		}
		else
		{
			headergroup.style.display="block";
		}
   	}

    TreeTableScrollRowIntoView(content, focusRow);
    
	TreeTableFireConstraint(rows[focusRow]);
}

function TreeTableScrollRowIntoView(content, rowNr)
{
	var me = content;
	while (me.className != "DStlMain")
	{
	    me = me.parentNode;
	}
	var inner = document.getElementById(me.id + "_inner");
	var scroller = document.getElementById(me.id + "_scroller");
	var row = content.rows[rowNr];
	var top = row.offsetTop;
	var topd = top - content.tHead.rows[0].offsetHeight - scroller.scrollTop;
	var botd = (top + row.offsetHeight) - (inner.clientHeight + scroller.scrollTop);
	var scrolldiff = botd > 0 ? botd : 0;
	if (scrolldiff > topd)
	{
		scrolldiff = topd;
	}
	scroller.scrollTop = scroller.scrollTop + scrolldiff;		
}

/* For the head it would be possible to use heads[focusHead].scrollIntoView(),
 * but this works buggy in IE */
function TreeTableScrollHeadIntoView(content, head)
{
	var heads = content.lastChild.firstChild.childNodes;
	var me = content;
	while (me.className != "DStlMain")
	{
	    me = me.parentNode;
	}
	var inner = document.getElementById(me.id + "_inner");
	
	var left = heads[head].offsetLeft;
	var leftd = left - inner.scrollLeft;
	var rightd = (left + heads[head].offsetWidth) - (inner.clientWidth + inner.scrollLeft);
	var scrolldiff = rightd > 0 ? rightd : 0;
	if (scrolldiff > leftd)
	{
		scrolldiff = leftd;
	}
	inner.scrollLeft = inner.scrollLeft + scrolldiff;		
}

function TreeTableOnfocus(e)
{
	var source;
	if (e == null)
	{
		e = window.event;
		source = e.srcElement;
	}
	else
	{
		source = e.target;
	}

	var content = source;
	while (!containsClass(content, "DStlContent"))
	{
	    content = content.parentNode;
	    if (content == null)
	    {
	        return;
	    }
	}
	
	addClasses(content, "DStlFocus");

	var rows = content.rows;
	var focusRow = parseInt(content.getAttribute("focusRow"));
	var lastRow = rows.length -1;
	
	if (lastRow <= 0)
	{
	    return;
	}
    if (!isFinite(focusRow))
    {
		TreeTableMoveFocusRow(content, 1);
    }
    else
    {
		addClasses(rows[focusRow], "DSttFocusRow");
	}	
}

function TreeTableOnblur(e)
{
	var source;
	if (e == null)
	{
		e = window.event;
		source = e.srcElement;
	}
	else
	{
		source = e.target;
	}

	var content = source;
	while (!containsClass(content, "DStlContent"))
	{
	    content = content.parentNode;
	    if (content == null)
	    {
	        return;
	    }
	}
	
	removeClasses(content, "DStlFocus");
	
	var rows = content.rows;
	var focusRow = parseInt(content.getAttribute("focusRow"));
	var focusHead = parseInt(content.getAttribute("focusHead"));
	
	if (isFinite(focusRow) && containsClass(rows[focusRow], "DSttFocusRow"))
	{
		removeClasses(rows[focusRow], "DSttFocusRow");
	}
}

function TreeTableHeadKeydown(e)
{
}

function TreeTableHeadOnfocus(e)
{
	var source;
	if (e == null)
	{
		e = window.event;
		source = e.srcElement;
	}
	else
	{
		source = e.target;
	}

	var thead = source;
	while (!containsClass(thead, "DSttHeader"))
	{
	    thead = thead.parentNode;
	    if (thead == null)
	    {
	        return;
	    }
	}

	var focusHead = parseInt(content.getAttribute("focusHead"));
	var lastRow = rows.length -1;
	
	if(isFinite(focusHead))
	{
	    addClasses(heads[focusHead], "DStlFocusHead");
	    return;
	} 

	e.cancelBubble = true;
	if (e.stopPropagation) e.stopPropagation();
}

function TreeTableHeadOnblur(e)
{
	var source;
	if (e == null)
	{
		e = window.event;
		source = e.srcElement;
	}
	else
	{
		source = e.target;
	}

	var thead = source;
	while (!containsClass(thead, "DSttHeader"))
	{
	    thead = thead.parentNode;
	    if (thead == null)
	    {
	        return;
	    }
	}
	
	var focusHead = parseInt(content.getAttribute("focusHead"));
	
	if(isFinite(focusHead))
	{
	    removeClasses(heads[focusHead], "DStlFocusHead");
	}
	
	e.cancelBubble = true;
	if (e.stopPropagation) e.stopPropagation();
}

function TreeTableOnwheel(e){
	var source;
	if (e == null)
	{
		e = window.event;
		source = e.srcElement;
	}
	else
	{
		source = e.target;
	}

	var me = source.parentNode; // in firefox source can also be a text node and has no className.
	while (!containsClass(me, "DStlMain"))
	{
	    me = me.parentNode;
	    if (me == null)
	    {
	        return;
	    }
	}
	
	var delta = 0;
	if (e.wheelDelta)
	{
		delta = e.wheelDelta/120; 
		if (window.opera) delta = -delta;
	} 
	else if (e.detail) 
	{
		delta = -e.detail/3;
	}
	if (delta)
	{
		var scroller = document.getElementById(me.id + "_scroller");
		scroller.scrollTop = scroller.scrollTop - 50 * delta;
	}
		
    if (e.preventDefault)
    {
		e.preventDefault();
	}
    e.returnValue = false;
    return false;
}

function TreeTableToggleOnclick(e)
{
	var source;
	if (e == null)
	{
		e = window.event;
		source = e.srcElement;
	}
	else
	{
		source = e.target;
	}
	var row = source;
	while (row.tagName != "TR")
	{
	    row = row.parentNode;
	    if (row == null)
	    {
	        return;
	    }
	}
	TreeTableToggleRow(row);
	
	if (e.preventDefault)
	{
		e.preventDefault();
		e.stopPropagation();
	}
	else
	{
		e.cancelBubble = true;
	}
	return false;
}

function TreeTableToggleRow(row)
{
	var tbody = row.parentNode;
	var status = tbody.getAttribute("open") == "true";
	
	if (status)
	{
		var toggleLevel = tbody.getAttribute("level");
		var curTBody = tbody.nextSibling;
		while (curTBody != null && parseInt(curTBody.getAttribute("level")) > toggleLevel)
		{
			curTBody.style.display="none";
			curTBody = curTBody.nextSibling;
		}
		tbody.setAttribute("open", null);
	}
	else
	{
		TreeTableSetOpen(tbody);
		tbody.setAttribute("open", "true");
	}
	
	var toggle = row.firstChild;
   	var rowchilds = row.firstChild.childNodes;
   	for (var c = 0; c < rowchilds.length; c++)
   	{
		if (containsClass(rowchilds[c], "DSttToggle"))
   		{
			var toggle = rowchilds[c];
			if (status)
			{
				replaceClass(toggle, "DSttToggleOpen", "DSttToggleClosed");
			}
			else
			{
				replaceClass(toggle, "DSttToggleClosed", "DSttToggleOpen");
			}
   		}
   	}
   	
	var me = row;
	while (!containsClass(me, "DStlMain"))
	{
	    me = me.parentNode;
	}
	TreeTableLayoutInner(me, null);
}

function TreeTableSetOpen(tbody)
{
	var level = parseInt(tbody.getAttribute("level"));

	var curTBody = tbody.nextSibling;
	var curLevel = curTBody == null ? 0 : parseInt(curTBody.getAttribute("level"));
	while (curLevel > level)
	{
		var advance  = true;
		if (curLevel == (level + 1))
		{
			curTBody.style.display=""; // "block" in IE  and "table-row-group" in CSS compliant browsers
			if (curTBody.getAttribute("open") == "true")
			{
				curTBody = TreeTableSetOpen(curTBody);
				advance  = false;
			}
		}
		if (advance)
		{
			curTBody = curTBody.nextSibling;
		}
		curLevel = curTBody == null ? 0 : parseInt(curTBody.getAttribute("level"));
		
	}
	return curTBody;
}

function TreeTableOnclick(e)
{	
	var source;
	if (e == null)
	{
		e = window.event;
		source = e.srcElement;
	}
	else
	{
		source = e.target;
	}
	
	while (source.tagName != "TD" && !containsClass(source.parentNode, "DSttTreeCell"))
	{
		source = source.parentNode;
	}
	if (source.childNodes.length > 1 || source.firstChild.tagName != null)
	{
		// the cell contains something else than text
		return;
	}
	var content = source;
	while (!containsClass(content, "DStlContent"))
	{
	    content = content.parentNode;
	    if (content == null)
	    {
	        return;
	    }
	}
	var row = source;
	while (row.tagName != "TR")
	{
		row = row.parentNode;
	}
	
	content.focus();
	var rows = content.rows;
	TreeTableMoveFocusRow(content, row.rowIndex);
	
	if (e.preventDefault)
	{
		e.preventDefault();
	}
	return false;
}

function TreeTableFireConstraint(source)
{
	var me = source;
	// Somehow IE invents a node in the tree that doesnt have a getAttribute function when a component is put under a notebook
	while (!me.getAttribute || me.getAttribute("target") == null)
	{
		me = me.parentNode;
		if (me == null)
		{
			return;
		}
	}
	var lineVs = source.getAttribute("viewState");
	var target = me.getAttribute("target");
	if (target == null || lineVs == null || lineVs.length == 0)
	{
		return;
	}
    var rc = new RequestContext(me.id, target);

	var i = document.getElementById(target);
	eval(i.getAttribute("GetViewStates"));
	
	var content = document.getElementById(me.id + "_content");
	var vs = content.getAttribute("viewState");
	if (vs != null)
	{
		rc.AddSecureVS(vs); 
	}
    
	rc.AddSecureVS(lineVs);

	rc.Fire();
}

function TreeTableTHOnclick(e)
{
	var source;
	if (e == null)
	{
		e = window.event;
		source = e.srcElement;
	}
	else
	{
		source = e.target;
	}
	while (source.tagName != "TH")
	{
	    source = source.parentNode;
	    if (source == null)
	    {
	        return;
	    }    
	}
	var content = source
	while (content.tagName != "TABLE")
	{
	    content = content.parentNode;
	}
	content.focus();
	TreeTableHeadDoSort(content, source)
}

function TreeTableHeadDoSort(content, head)
{	
	var sortDirection = head.getAttribute("sortDirection");
	
	var row = head.parentNode;
	for(var i = 0; i < row.childNodes.length; i++)
	{
	    var th = row.childNodes[i];
	    th.setAttribute("sortDirection", null);
	    if (th.firstChild.lastChild.className != null && th.firstChild.lastChild.className.indexOf("DStlSortArrow") >= 0)
	    {
	        th.firstChild.removeChild(th.firstChild.lastChild);
	    }
	}
	
	if (sortDirection == "down")
	{
	    sortDirection = "up";
   	    ParseHtmlTo(head.firstChild, "<SPAN class=\"DStlSortArrow DStlSortUp\" UNSELECTABLE = on>&nbsp;&nbsp;&nbsp;</SPAN>");
	}
	else
	{
	    sortDirection = "down";
	    ParseHtmlTo(head.firstChild,"<SPAN class=\"DStlSortArrow DStlSortDown\" UNSELECTABLE = on>&nbsp;&nbsp;&nbsp;</SPAN>");
	}
	
	var me = content;
	while (me.className != "DStlMain")
	{
	    me = me.parentNode;
	}
	var rows = content.lastChild.childNodes;
	var lastRow = rows.length -1;
	while (lastRow > 0 && rows[lastRow].getAttribute("viewState") == null)
	{
	    lastRow--;
	}
	var focusRow = parseInt(content.getAttribute("focusRow"));
	
	TreeTableLayoutInner(me, null);
	
    if(isFinite(focusRow))
	{
		rows[focusRow].setAttribute("focusRow", "true");
	}
	
	TreeTableSort(content, head.cellIndex, sortDirection);
	
    if(isFinite(focusRow))
	{
		focusRow = null;
		for (var i = 1; i <= lastRow; i++)
		{
		    if (rows[i].getAttribute("focusRow") != null)
		    {
				rows[i].removeAttribute("focusRow");
				focusRow = i;
				break;
		    }
		}
		content.setAttribute("focusRow", focusRow);
		if (focusRow != null)
		{
			TreeTableScrollRowIntoView(content, focusRow);
		}
	}
    content.setAttribute("lastSelected", null);
    
	head.setAttribute("sortDirection", sortDirection);
}

function TreeTableSort(content, col, direction)
{
    var temp = new Array();
    
	var row = content.lastChild.firstChild;
	var cell = row.childNodes[col];
	var firstSortType;
	var currentSortType = null;
	while (cell != null)
	{
		var st;
		if (cell.getAttribute("sortType") == "NUMBER")
		{
			st = new TreeTableSortTypeNumber();
		}
		else
		{
			if (cell.align == "right")
			{
	            st = new TreeTableSortTypeAlignRight();
			}
			else
			{
	            st = new TreeTableSortTypeAlignLeft();
			}
		}
		if (currentSortType == null)
		{
			firstSortType = st;
		}
		else
		{
			currentSortType.next = st;
		}
		currentSortType = st;
		cell = cell.nextSibling;
	}
	var sumrow = null;

	row = row.nextSibling;
	var index = 0;
	while (row != null)
	{
		if (row.className == "DStlSum")
		{
		    sumrow = row;
		}
		else
		{
		    var td = row.childNodes[col];
    	    temp[index] = new TreeTableSortItem(firstSortType, row, td);
	    	index++;
		}
		row = row.nextSibling;
	}
	
    temp.sort(TreeTableSortMain);
    
    var body = content.lastChild;
    if (direction == "up")
    {
        for (var i = temp.length - 1; i >= 0; i--)
        {
            body.appendChild(temp[i].row);
        }
    }
    else
    {
        for (var i = 0; i < temp.length; i++)
        {
            body.appendChild(temp[i].row);
        }
    }
    if (sumrow != null)
    {
            body.appendChild(sumrow);
    }
}

function TreeTableSortMain(a, b)
{
	var result = 0;
	var sortType = a.sortType;
	var sortvalA = a.sortval;
	var sortvalB = b.sortval;
	while (sortType != null)
	{
		result = sortType.Compare(sortvalA, sortvalB);
		if (result != 0)
		{
			return result;
		}
		sortType = sortType.next;
		sortvalA = sortvalA.GetNext(sortType);
		sortvalB = sortvalB.GetNext(sortType);
	}
	return 0;	
}

function TreeTableSortTypeNumber()
{
    this.Compare = function(a, b)
    {
		if (a.val < b.val)
		{
			return -1;
		}
		else
		{
			if (a.val > b.val)
			{
				return 1;
			}
			else
			{
				return 0;
			}
		}
    }
    
    this.GetValFromCell = function(cell)
    {
		var result = cell.getAttribute("sortValue");
		if (result == null)
		{
			result = cell.innerHTML;
			cell.setAttribute("sortValue", result);
		}
		result = parseFloat(result);
		if (!isFinite(result))
		{
			result = Number.NEGATIVE_INFINITY;
		}
		return result;
    }
}

function TreeTableSortTypeAlignLeft()
{
    this.Compare = function(a, b)
    {
		if (a.val < b.val)
		{
			return -1;
		}
		else
		{
			if (a.val > b.val)
			{
				return 1;
			}
			else
			{
				return 0;
			}
		}
    }
    
    this.GetValFromCell = function(cell)
    {
		var result = cell.getAttribute("sortValue");
		if (result == null)
		{
			result = cell.innerHTML;
			cell.setAttribute("sortValue", result);
		}
		return result;
    }
}

function TreeTableSortTypeAlignRight()
{
    this.Compare = function(a, b)
    {
		var diff = a.val.length - b.val.length;
		if (diff != 0)
		{
			return diff;
        }
		if (a.val < b.val)
		{
			return -1;
		}
		else
		{
			if (a.val > b.val)
			{
				return 1;
			}
			else
			{
				return 0;
			}
		}
    }
    
    this.GetValFromCell = function(cell)
    {
		var result = cell.getAttribute("sortValue");
		if (result == null)
		{
			result = cell.innerHTML;
			cell.setAttribute("sortValue", result);
		}
		return result;
    }
}

function TreeTableSortValue(cell, sortType)
{
    this.cell = cell;
    this.val = sortType.GetValFromCell(cell);
    this.next = null;
    this.GetNext = function(sortType)
    {
		if (this.next == null && cell.nextSibling != null)
		{
			this.next = new TreeTableSortValue(cell.nextSibling, sortType);
		}
		return this.next;
    }
}

function TreeTableSortItem(sortType, row, cell)
{
	this.sortType = sortType;
    this.row = row;
    this.sortval = new TreeTableSortValue(cell, sortType);
}

//===============================================================================================================

function TableListDoLayout(myId)
{
	var me = document.getElementById(myId);
	
	me.style.width = PixelToStr(DSLayoutWidth);
	me.style.height = PixelToStr(DSLayoutHeight);
	
	TableListLayoutInner(me, null);	
}

function TableListLayoutInner(me, secondTime)
{
	var inner = document.getElementById(me.id + "_inner");
	var scroller = document.getElementById(me.id + "_scroller");
	var content = document.getElementById(me.id + "_content");
	if (content == null)
	{
	    scroller.firstChild.style.height = "1px";
	}
	else
	{
	    scroller.firstChild.style.height = PixelToStr(content.offsetHeight);
	    
    	var heads = content.lastChild.firstChild.childNodes;
    	if (document.all)
    	{
    		/* Somehow IE decides that a relative div is transparent to mouseclicks on places that do not
    		 * contain any text. setting the width triggers IE to send onclicks to the div again. */
    		for (var i = 0; i < heads.length; i++)
    		{
	    		var thdiv = heads[i].firstChild;
    			thdiv.style.width = "auto";
    			thdiv.style.width = PixelToStr(getInnerWidth(thdiv));
			}
		}
    }
	inner.style.height = PixelToStr(me.clientHeight);
	scroller.style.height = PixelToStr(me.clientHeight);
	scroller.style.marginBottom = "-" + scroller.style.height;
	scroller.style.width = PixelToStr(me.clientWidth);
	inner.style.width = PixelToStr(me.clientWidth - scroller.offsetWidth + scroller.clientWidth);

    // IE doesnt remove or add scrollbars during the javascript execution so all width and heigth calculations depending on this must be delayed.
	if (document.all && secondTime == null)
	{
	    setTimeout("TableListLayoutInner(document.getElementById('" + me.id +"'), 'true')", 100);
	}
	else
	{
    	scroller.style.height = PixelToStr(inner.clientHeight);
    	scroller.style.marginBottom = "-" + scroller.style.height;
    	inner.style.width = PixelToStr(me.clientWidth - scroller.offsetWidth + scroller.clientWidth);
        TableListDoScroll(me);
	}
}

function TableListDoScroll(me)
{
	var inner = document.getElementById(me.id + "_inner");
	var scroller = document.getElementById(me.id + "_scroller");
	var content = document.getElementById(me.id + "_content");
	if (content != null)
	{
	
	    content.style.top = -scroller.scrollTop + "px";
		var row = content.lastChild.firstChild;
		for (var i = 0; i < row.childNodes.length; i++)
		{
		    var thdiv = row.childNodes[i].firstChild;
		    thdiv.style.top = scroller.scrollTop + "px";
		}
		// Do the same thing again to prevent firefox from flickering with the last column header
	    content.style.top = -scroller.scrollTop + "px";
	}
}

function TableListOnscroll(e)
{
	var source;
	if (e == null)
	{
		e = window.event;
		source = e.srcElement;
	}
	else
	{
		source = e.target;
	}
	var me = source;
	while (me.className != "DStlMain")
	{
	    me = me.parentNode;
	    if (me == null)
	    {
	        return;
	    }
	}
	TableListDoScroll(me);
}

function TableListKeydown(e)
{
	var source;
	if (e == null)
	{
		e = window.event;
		source = e.srcElement;
	}
	else
	{
		source = e.target;
	}
	
	var content = source;
	while (!containsClass(content, "DStlContent"))
	{
	    content = content.parentNode;
	    if (content == null)
	    {
	        return;
	    }
	}
	
	var rows = content.lastChild.childNodes;
	var heads = content.lastChild.firstChild.childNodes;
	var focusRow = parseInt(content.getAttribute("focusRow"));
	var lastSelected = parseInt(content.getAttribute("lastSelected"));
	var lastRow = rows.length -1;
	while (lastRow > 0 && rows[lastRow].getAttribute("viewState") == null)
	{
	    lastRow--;
	}
	var focusHead = parseInt(content.getAttribute("focusHead"));
	var multiSelect = content.getAttribute("multiSelect") == "true";
	var visibleRowCount = rows.length > 1 ? Math.floor((content.parentNode.clientHeight - rows[0].offsetHeight) / rows[1].offsetHeight) : 1;
	
	if (e.keyCode == 13) // Enter
	{
	    if (isFinite(focusHead) && containsClass(heads[focusHead], "DStlFocusHead"))
	    {
			TableListHeadDoSort(content, heads[focusHead])
	    }
	}
	else if (e.keyCode == 32) // Space
	{
	    if(isFinite(focusRow) && containsClass(rows[focusRow], "DStlFocusRow") && e.ctrlKey && multiSelect)
	    {
			switchClass(rows[focusRow], "DStlSelected");
			content.setAttribute("lastSelected", focusRow);
			TableListFireConstraint(content);
	    }
	    else if (isFinite(focusHead) && containsClass(heads[focusHead], "DStlFocusHead"))
	    {
			TableListHeadDoSort(content, heads[focusHead])
	    }
	}
	else if (e.keyCode == 37) // Left
	{
	    if(isFinite(focusRow))
	    {
	        removeClasses(rows[focusRow], "DStlFocusRow");
	    }
	    if (heads.length <= 0)
	    {
			return;
		}
	    if (isFinite(focusHead))
	    {
			removeClasses(heads[focusHead], "DStlFocusHead");
	    }
	    focusHead = (isFinite(focusHead) && focusHead > 0) ? focusHead - 1 : heads.length - 1;
		addClasses(heads[focusHead], "DStlFocusHead");
		TableListScrollHeadIntoView(content, focusHead);
		content.setAttribute("focusHead", focusHead);
		if (e.preventDefault)
		{
			e.preventDefault();
		}
		return false;
	}
	else if (e.keyCode == 39) // Right
	{
	    if(isFinite(focusRow))
	    {
	        removeClasses(rows[focusRow], "DStlFocusRow");
	    }
	    if (heads.length <= 0)
	    {
			return;
		}
	    if (isFinite(focusHead))
	    {
			removeClasses(heads[focusHead], "DStlFocusHead");
	    }
	    focusHead = (isFinite(focusHead) && focusHead < heads.length - 1) ? focusHead + 1 : 0;
		addClasses(heads[focusHead], "DStlFocusHead");
		TableListScrollHeadIntoView(content, focusHead);
		content.setAttribute("focusHead", focusHead);
		if (e.preventDefault)
		{
			e.preventDefault();
		}
		return false;
	}
	else if (e.keyCode == 38) // Up
	{
		TableListKeyMoveFocusRow(focusHead, focusRow, lastRow, heads, rows, content, -1, e);
	}
	else if (e.keyCode == 40) // Down
	{
		TableListKeyMoveFocusRow(focusHead, focusRow, lastRow, heads, rows, content, +1, e);
	}
	else if (e.keyCode == 33) // PageUp
	{
		var jump = focusRow - visibleRowCount < 1 ? 1 - focusRow : -visibleRowCount;
		TableListKeyMoveFocusRow(focusHead, focusRow, lastRow, heads, rows, content, jump, e);
	}
	else if (e.keyCode == 34) // PageDown
	{
		var jump = focusRow + visibleRowCount > lastRow ? lastRow - focusRow : visibleRowCount;
		TableListKeyMoveFocusRow(focusHead, focusRow, lastRow, heads, rows, content, jump, e);
	}
	else if (e.keyCode == 36) // Home
	{
		TableListKeyMoveFocusRow(focusHead, focusRow, lastRow, heads, rows, content, 1 - focusRow, e);
	}
	else if (e.keyCode == 35) // End
	{
		TableListKeyMoveFocusRow(focusHead, focusRow, lastRow, heads, rows, content, lastRow - focusRow, e);
	}
}

function TableListKeyMoveFocusRow(focusHead, focusRow, lastRow, heads, rows, content, jump, e)
{
	if(isFinite(focusHead))
	{
	    removeClasses(heads[focusHead], "DStlFocusHead");
	}

	if(!isFinite(focusRow))
	{
		focusRow = 1;
	}
	if (lastRow <= 0)
	{
	    return;
	}
	if (focusRow == 1 && lastRow == 1 && !e.shiftKey && !e.ctrlKey)
	{
	    // Special case, dont try (and fail) to move the focus row else it would be
	    // imposible to select something in a single row table with just the arrow keys.
		TableListMoveFocusRow(content, 1, e)
	}
	else
	{
		var to = focusRow + jump;
	    if(to <= lastRow && to >= 1)
	    {
			TableListMoveFocusRow(content, to, e)
	    }
	    else if (jump > 0 && rows.length - 1 > lastRow)
	    {
			TableListScrollRowIntoView(content, rows.length - 1)
	    }
	}
}

function TableListMoveFocusRow(content, to, e)
{
	var rows = content.lastChild.childNodes;
	var focusRow = parseInt(content.getAttribute("focusRow"));
	var lastSelected = parseInt(content.getAttribute("lastSelected"));
	var lastRow = rows.length -1;
	while (lastRow > 0 && rows[lastRow].getAttribute("viewState") == null)
	{
	    lastRow--;
	}
	var multiSelect = content.getAttribute("multiSelect") == "true";
	
    if (!isFinite(focusRow))
    {
        focusRow = 1;
        addClasses(rows[focusRow], "DStlFocusRow");
		content.setAttribute("focusRow", focusRow);
    }

    if (e.shiftKey && multiSelect)
    {
		if (!isFinite(lastSelected))
		{
			lastSelected = focusRow;
			addClasses(rows[lastSelected], "DStlSelected");
		}
		if (focusRow > lastSelected && to < focusRow)
		{
			var first = (lastSelected > to ? lastSelected : to) + 1;
			var last = focusRow;
			for(var i = first; i <= last; i++)
			{
			   removeClasses(rows[i], "DStlSelected");
			}
		}
		if (focusRow < lastSelected && to > focusRow)
		{
			var first = focusRow;
			var last = (lastSelected < to ? lastSelected : to) - 1;
			for(var i = first; i <= last; i++)
			{
			   removeClasses(rows[i], "DStlSelected");
			}
		}
    }
    else if (e.ctrlKey && multiSelect)
    {
        //do nothing only move the focus
    }
    else
    {
        if (multiSelect)
        {
            for(var i = 1; i < rows.length; i++)
            {
                removeClasses(rows[i], "DStlSelected");
            }
        }
        else
        {
            removeClasses(rows[focusRow], "DStlSelected");
        }
    }
        
    removeClasses(rows[focusRow], "DStlFocusRow");
    focusRow = to;
	addClasses(rows[focusRow], "DStlFocusRow");
	content.setAttribute("focusRow", focusRow);
    TableListScrollRowIntoView(content, focusRow);
    
    if (e.shiftKey && multiSelect)
    {
        TableListSelectLastToFocus(lastSelected, focusRow, rows);
        TableListFireConstraint(content);
    }
    else if (e.ctrlKey && multiSelect)
    {
        // do nothing only move the focus
    }
    else
    {
        lastSelected = focusRow;
        addClasses(rows[focusRow], "DStlSelected");
        if (multiSelect)
        {
			TableListFireConstraint(content);
		}
		else
		{
			TableListFireConstraint(rows[focusRow]);
		}
    }
    content.setAttribute("lastSelected", lastSelected);

}

function TableListSelectLastToFocus(lastSelected, focusRow, rows)
{
    var first = focusRow < lastSelected ? focusRow : lastSelected + 1; 
    var last = focusRow > lastSelected ? focusRow : lastSelected - 1;
    for(var i = first; i <= last; i++)
    {
	        addClasses(rows[i], "DStlSelected");
    }
}

function TableListScrollRowIntoView(content, row)
{
	var rows = content.lastChild.childNodes;
	var me = content;
	while (me.className != "DStlMain")
	{
	    me = me.parentNode;
	}
	var inner = document.getElementById(me.id + "_inner");
	var scroller = document.getElementById(me.id + "_scroller");
	
	var top = rows[row].offsetTop;
	var topd = top - rows[0].offsetHeight - scroller.scrollTop;
	var botd = (top + rows[row].offsetHeight) - (inner.clientHeight + scroller.scrollTop);
	var scrolldiff = botd > 0 ? botd : 0;
	if (scrolldiff > topd)
	{
		scrolldiff = topd;
	}
	scroller.scrollTop = scroller.scrollTop + scrolldiff;		
}

/* For the head it would be possible to use heads[focusHead].scrollIntoView(),
 * but this works buggy in IE */
function TableListScrollHeadIntoView(content, head)
{
	var heads = content.lastChild.firstChild.childNodes;
	var me = content;
	while (me.className != "DStlMain")
	{
	    me = me.parentNode;
	}
	var inner = document.getElementById(me.id + "_inner");
	
	var left = heads[head].offsetLeft;
	var leftd = left - inner.scrollLeft;
	var rightd = (left + heads[head].offsetWidth) - (inner.clientWidth + inner.scrollLeft);
	var scrolldiff = rightd > 0 ? rightd : 0;
	if (scrolldiff > leftd)
	{
		scrolldiff = leftd;
	}
	inner.scrollLeft = inner.scrollLeft + scrolldiff;		
}

function TableListOnfocus(e)
{
	var source;
	if (e == null)
	{
		e = window.event;
		source = e.srcElement;
	}
	else
	{
		source = e.target;
	}

	var content = source;
	while (!containsClass(content, "DStlContent"))
	{
	    content = content.parentNode;
	    if (content == null)
	    {
	        return;
	    }
	}
	
	addClasses(content, "DStlFocus");

	var rows = content.lastChild.childNodes;
	var heads = content.lastChild.firstChild.childNodes;
	var focusRow = parseInt(content.getAttribute("focusRow"));
	var focusHead = parseInt(content.getAttribute("focusHead"));
	var lastRow = rows.length -1;
	while (lastRow > 0 && rows[lastRow].getAttribute("viewState") == null)
	{
	    lastRow--;
	}
	
	if(isFinite(focusHead))
	{
	    addClasses(heads[focusHead], "DStlFocusHead");
	    return;
	} 
	if (lastRow <= 0)
	{
	    return;
	}
    if (!isFinite(focusRow))
    {
        focusRow = 1;
		content.setAttribute("focusRow", focusRow);
    }
    addClasses(rows[focusRow], "DStlFocusRow");
}

function TableListOnblur(e)
{
	var source;
	if (e == null)
	{
		e = window.event;
		source = e.srcElement;
	}
	else
	{
		source = e.target;
	}

	var content = source;
	while (!containsClass(content, "DStlContent"))
	{
	    content = content.parentNode;
	    if (content == null)
	    {
	        return;
	    }
	}
	
	removeClasses(content, "DStlFocus");
	
	var rows = content.lastChild.childNodes;
	var heads = content.lastChild.firstChild.childNodes;
	var focusRow = parseInt(content.getAttribute("focusRow"));
	var focusHead = parseInt(content.getAttribute("focusHead"));
	
	if (isFinite(focusRow) && containsClass(rows[focusRow], "DStlFocusRow"))
	{
		removeClasses(rows[focusRow], "DStlFocusRow");
		content.setAttribute("focusHead", null);
	}
	if(isFinite(focusHead))
	{
	    removeClasses(heads[focusHead], "DStlFocusHead");
	}
}

function TableListOnwheel(e){
	var source;
	if (e == null)
	{
		e = window.event;
		source = e.srcElement;
	}
	else
	{
		source = e.target;
	}

	var me = source.parentNode; // in firefox source can also be a text node and has no className.
	while (!containsClass(me, "DStlMain"))
	{
	    me = me.parentNode;
	    if (me == null)
	    {
	        return;
	    }
	}
	
	var delta = 0;
	if (e.wheelDelta)
	{
		delta = e.wheelDelta/120; 
		if (window.opera) delta = -delta;
	} 
	else if (e.detail) 
	{
		delta = -e.detail/3;
	}
	if (delta)
	{
		var scroller = document.getElementById(me.id + "_scroller");
		scroller.scrollTop = scroller.scrollTop - 50 * delta;
	}
		
    if (e.preventDefault)
    {
		e.preventDefault();
	}
    e.returnValue = false;
    return false;
}


function TableListInit(myId)
{
	var me = document.getElementById(myId);
	var inner = document.getElementById(myId + "_inner");
	var scroller = document.getElementById(myId + "_scroller");
	var content = document.getElementById(me.id + "_content");

	scroller.onscroll = TableListOnscroll;
	
	if (content != null && content.getAttribute("initialized") == null)
	{
		content.setAttribute("initialized", "true");
		
		inner.style.position = "relative";
		inner.style.overflowX = "auto";
		inner.style.overflowY= "hidden";
		content.style.position = "relative";
		scroller.style.float = "right";
		scroller.style.overflowY= "auto";
		var row = content.lastChild.firstChild;
		for (var i = 0; i < row.childNodes.length; i++)
		{
		    var thdiv = row.childNodes[i].firstChild;
		    thdiv.style.position = "relative";
		    thdiv.style.whiteSpace = "";
			var text = me.getAttribute("headText" + i);
			if (text != null)
			{
				thdiv.innerHTML = text;
			}
			row.childNodes[i].onclick = TableListTHOnclick;
			row.childNodes[i].ondblclick = TableListTHOnclick;
		}
		
		if (row.childNodes.length > 0 && me.getAttribute("target") == null)
		{
			content.setAttribute("focusHead", 0);
		}

		row = row.nextSibling;
		while (row != null)
		{
			if (row.getAttribute("viewState") != null)
			{
				row.onclick = TableListOnclick;
			}
			row = row.nextSibling;
		}
		
        content.onkeydown = TableListKeydown;
        content.onfocus = TableListOnfocus;
        content.onblur = TableListOnblur;
        
        inner.onmousewheel = TableListOnwheel;
        if (inner.addEventListener)
			inner.addEventListener('DOMMouseScroll', TableListOnwheel, true);
		
		TableListLayoutInner(me, null);
	}
}

function TableListSet(myId, property)
{
	if (property == "innerHTML")
	{
		var inner = document.getElementById(myId + "_inner");
	    while (inner.firstChild != null)
	    {
	        inner.removeChild(inner.firstChild);
	    }
	    ParseHtmlTo(inner, DSCurrentData);
	}
	else if (property == "init")
	{
			TableListInit(myId);
    }
}

function TableListSetViewState(myId)
{
	var content = document.getElementById(myId+ "_content");
	content.setAttribute("viewState", DSCurrentData);
}

function TableListGetViewStates(myId)
{
	var inner = document.getElementById(myId + "_inner");
	while (inner.firstChild != null)
	{
	    inner.removeChild(inner.firstChild);
	}
	AddNewBusy(inner);
}

function TableListOnclick(e)
{	
	var source;
	if (e == null)
	{
		e = window.event;
		source = e.srcElement;
	}
	else
	{
		source = e.target;
	}
	
	while (source.tagName != "TD")
	{
		source = source.parentNode;
	}
	if (source.childNodes.length > 1 || source.firstChild.tagName != null)
	{
		// the cell contains something else than text
		return;
	}
	source = source.parentNode;
	
	
	var content = source;
	while (!containsClass(content, "DStlContent"))
	{
	    content = content.parentNode;
	    if (content == null)
	    {
	        return;
	    }
	}
	content.focus();
	var multiSelect = content.getAttribute("multiSelect") == "true";
	
	var rows = source.parentNode.childNodes;
	for (var to = 0; to < rows.length; to++)
	{
		if (rows[to] == source)
		{
			if (e.ctrlKey && multiSelect)
			{
				switchClass(rows[to], "DStlSelected");
				TableListMoveFocusRow(content, to, e);
				TableListFireConstraint(content);
			}
			else
			{
				TableListMoveFocusRow(content, to, e);
			}
			break;
		}
	}
	
	if (e.preventDefault)
	{
		e.preventDefault();
	}
	return false;
}

function TableListFireConstraint(source)
{
	var me = source;
	// Somehow IE invents a node in the tree that doesnt have a getAttribute function when a component is put under a notebook
	while (!me.getAttribute || me.getAttribute("target") == null)
	{
		me = me.parentNode;
	}

    
	var target = me.getAttribute("target");
    var rc = new RequestContext(me.id, target);

	var i = document.getElementById(target);
	eval(i.getAttribute("GetViewStates"));
	
	var content = document.getElementById(me.id + "_content");
	var vs = content.getAttribute("viewState");
	if (vs != null)
	{
		rc.AddSecureVS(vs); 
	}
    
    if (containsClass(source, "DStlContent"))
    {
		var rows = source.lastChild.childNodes;
		for (var i = 1; i < rows.length; i ++)
		{
			var rvs = rows[i].getAttribute("viewState");
			if (rvs != null && containsClass(rows[i], "DStlSelected"))
			{
				rc.AddSecureVS(rvs);
			}
		}
    }
    else
    {
		rc.AddSecureVS(source.getAttribute("viewState"));
	}
	rc.Fire();
}

function TableListTHOnclick(e)
{
	var source;
	if (e == null)
	{
		e = window.event;
		source = e.srcElement;
	}
	else
	{
		source = e.target;
	}
	while (source.tagName != "TH")
	{
	    source = source.parentNode;
	    if (source == null)
	    {
	        return;
	    }    
	}
	var content = source
	while (content.tagName != "TABLE")
	{
	    content = content.parentNode;
	}
	content.focus();
	TableListHeadDoSort(content, source)
}

function TableListHeadDoSort(content, head)
{	
	var sortDirection = head.getAttribute("sortDirection");
	
	var row = head.parentNode;
	for(var i = 0; i < row.childNodes.length; i++)
	{
	    var th = row.childNodes[i];
	    th.setAttribute("sortDirection", null);
	    if (th.firstChild.lastChild.className != null && th.firstChild.lastChild.className.indexOf("DStlSortArrow") >= 0)
	    {
	        th.firstChild.removeChild(th.firstChild.lastChild);
	    }
	}
	
	if (sortDirection == "down")
	{
	    sortDirection = "up";
   	    ParseHtmlTo(head.firstChild, "<SPAN class=\"DStlSortArrow DStlSortUp\" UNSELECTABLE = on>&nbsp;&nbsp;&nbsp;</SPAN>");
	}
	else
	{
	    sortDirection = "down";
	    ParseHtmlTo(head.firstChild,"<SPAN class=\"DStlSortArrow DStlSortDown\" UNSELECTABLE = on>&nbsp;&nbsp;&nbsp;</SPAN>");
	}
	
	var me = content;
	while (me.className != "DStlMain")
	{
	    me = me.parentNode;
	}
	var rows = content.lastChild.childNodes;
	var lastRow = rows.length -1;
	while (lastRow > 0 && rows[lastRow].getAttribute("viewState") == null)
	{
	    lastRow--;
	}
	var focusRow = parseInt(content.getAttribute("focusRow"));
	
	TableListLayoutInner(me, null);
	
    if(isFinite(focusRow))
	{
		rows[focusRow].setAttribute("focusRow", "true");
	}
	
	TableListSort(content, head.cellIndex, sortDirection);
	
    if(isFinite(focusRow))
	{
		focusRow = null;
		for (var i = 1; i <= lastRow; i++)
		{
		    if (rows[i].getAttribute("focusRow") != null)
		    {
				rows[i].removeAttribute("focusRow");
				focusRow = i;
				break;
		    }
		}
		content.setAttribute("focusRow", focusRow);
		if (focusRow != null)
		{
			TableListScrollRowIntoView(content, focusRow);
		}
	}
    content.setAttribute("lastSelected", null);
    
	head.setAttribute("sortDirection", sortDirection);
}

function TableListSort(content, col, direction)
{
    var temp = new Array();
    
	var row = content.lastChild.firstChild;
	var cell = row.childNodes[col];
	var firstSortType;
	var currentSortType = null;
	while (cell != null)
	{
		var st;
		if (cell.getAttribute("sortType") == "NUMBER")
		{
			st = new TableListSortTypeNumber();
		}
		else
		{
			if (cell.align == "right")
			{
	            st = new TableListSortTypeAlignRight();
			}
			else
			{
	            st = new TableListSortTypeAlignLeft();
			}
		}
		if (currentSortType == null)
		{
			firstSortType = st;
		}
		else
		{
			currentSortType.next = st;
		}
		currentSortType = st;
		cell = cell.nextSibling;
	}
	var sumrow = null;

	row = row.nextSibling;
	var index = 0;
	while (row != null)
	{
		if (row.className == "DStlSum")
		{
		    sumrow = row;
		}
		else
		{
		    var td = row.childNodes[col];
    	    temp[index] = new TableListSortItem(firstSortType, row, td);
	    	index++;
		}
		row = row.nextSibling;
	}
	
    temp.sort(TableListSortMain);
    
    var body = content.lastChild;
    if (direction == "up")
    {
        for (var i = temp.length - 1; i >= 0; i--)
        {
            body.appendChild(temp[i].row);
        }
    }
    else
    {
        for (var i = 0; i < temp.length; i++)
        {
            body.appendChild(temp[i].row);
        }
    }
    if (sumrow != null)
    {
            body.appendChild(sumrow);
    }
}

function TableListSortMain(a, b)
{
	var result = 0;
	var sortType = a.sortType;
	var sortvalA = a.sortval;
	var sortvalB = b.sortval;
	while (sortType != null)
	{
		result = sortType.Compare(sortvalA, sortvalB);
		if (result != 0)
		{
			return result;
		}
		sortType = sortType.next;
		sortvalA = sortvalA.GetNext(sortType);
		sortvalB = sortvalB.GetNext(sortType);
	}
	return 0;	
}

function TableListSortTypeNumber()
{
    this.Compare = function(a, b)
    {
		if (a.val < b.val)
		{
			return -1;
		}
		else
		{
			if (a.val > b.val)
			{
				return 1;
			}
			else
			{
				return 0;
			}
		}
    }
    
    this.GetValFromCell = function(cell)
    {
		var result = cell.getAttribute("sortValue");
		if (result == null)
		{
			result = cell.innerHTML;
			cell.setAttribute("sortValue", result);
		}
		result = parseFloat(result);
		if (!isFinite(result))
		{
			result = Number.NEGATIVE_INFINITY;
		}
		return result;
    }
}

function TableListSortTypeAlignLeft()
{
    this.Compare = function(a, b)
    {
		if (a.val < b.val)
		{
			return -1;
		}
		else
		{
			if (a.val > b.val)
			{
				return 1;
			}
			else
			{
				return 0;
			}
		}
    }
    
    this.GetValFromCell = function(cell)
    {
		var result = cell.getAttribute("sortValue");
		if (result == null)
		{
			result = cell.innerHTML;
			cell.setAttribute("sortValue", result);
		}
		return result;
    }
}

function TableListSortTypeAlignRight()
{
    this.Compare = function(a, b)
    {
		var diff = a.val.length - b.val.length;
		if (diff != 0)
		{
			return diff;
        }
		if (a.val < b.val)
		{
			return -1;
		}
		else
		{
			if (a.val > b.val)
			{
				return 1;
			}
			else
			{
				return 0;
			}
		}
    }
    
    this.GetValFromCell = function(cell)
    {
		var result = cell.getAttribute("sortValue");
		if (result == null)
		{
			result = cell.innerHTML;
			cell.setAttribute("sortValue", result);
		}
		return result;
    }
}

function TableListSortValue(cell, sortType)
{
    this.cell = cell;
    this.val = sortType.GetValFromCell(cell);
    this.next = null;
    this.GetNext = function(sortType)
    {
		if (this.next == null && cell.nextSibling != null)
		{
			this.next = new TableListSortValue(cell.nextSibling, sortType);
		}
		return this.next;
    }
}

function TableListSortItem(sortType, row, cell)
{
	this.sortType = sortType;
    this.row = row;
    this.sortval = new TableListSortValue(cell, sortType);
}


function GridDoLayout(myId)
{
	var me = document.getElementById(myId);
	
	me.style.width = PixelToStr(DSLayoutWidth);
	me.style.height = PixelToStr(DSLayoutHeight);
	
	GridLayoutInner(me, null);	
}

function GridLayoutInner(me, secondTime)
{
	var inner = document.getElementById(me.id + "_inner");
	var scroller = document.getElementById(me.id + "_scroller");
	var content = document.getElementById(me.id + "_content");
	if (content == null)
	{
	    scroller.firstChild.style.height = "1px";
	    scroller.firstChild.style.width = "1px";
	}
	else
	{
	    scroller.firstChild.style.height = PixelToStr(content.offsetHeight);
	    scroller.firstChild.style.width = PixelToStr(content.offsetWidth);
	    
    	if (document.all)
    	{
    		/* Somehow IE decides that a relative div is transparent to mouseclicks on places that do not
    		 * contain any text. setting the width triggers IE to send onclicks to the div again. */
			var row = content.lastChild.firstChild;
			for (var i = 0; i < row.childNodes.length; i++)
			{
			    var thdiv = row.childNodes[i].firstChild;
    			thdiv.style.width = "auto";
			}
			
			row = row.nextSibling;
			while (row != null)
			{
			    var thdiv = row.childNodes[0].firstChild;
    			thdiv.style.width = "auto";
	    		
				row = row.nextSibling;
			}
	
			row = content.lastChild.firstChild;
			for (var i = 0; i < row.childNodes.length; i++)
			{
			    var thdiv = row.childNodes[i].firstChild;
    			thdiv.style.width = PixelToStr(getInnerWidth(thdiv));
			}
			
			row = row.nextSibling;
			while (row != null)
				{
				var thdiv = row.childNodes[0].firstChild;
    			thdiv.style.width = PixelToStr(getInnerWidth(thdiv));
	    		
				row = row.nextSibling;
			}
		}
    }
	scroller.style.height = PixelToStr(me.clientHeight);
	inner.style.marginTop = "-" + scroller.style.height;
	scroller.style.width = PixelToStr(me.clientWidth);

    // IE doesnt remove or add scrollbars during the javascript execution so all width and heigth calculations depending on this must be delayed.
	if (document.all && secondTime == null)
	{
	    setTimeout("GridLayoutInner(document.getElementById('" + me.id +"'), 'true')", 100);
	}
	else
	{
		inner.style.height = PixelToStr(me.clientHeight - scroller.offsetHeight + scroller.clientHeight);
		inner.style.width = PixelToStr(me.clientWidth - scroller.offsetWidth + scroller.clientWidth);
        GridDoScroll(me);
	}
}

function GridDoScroll(me)
{
	var inner = document.getElementById(me.id + "_inner");
	var scroller = document.getElementById(me.id + "_scroller");
	var content = document.getElementById(me.id + "_content");
	if (content != null)
	{
	
	    content.style.top = -scroller.scrollTop + "px";
	    content.style.left = -scroller.scrollLeft + "px";
		var row = content.lastChild.firstChild;
		for (var i = 0; i < row.childNodes.length; i++)
		{
		    var thdiv = row.childNodes[i].firstChild;
		    thdiv.style.top = scroller.scrollTop + "px";
		}
		while (row != null)
		{
		    var thdiv = row.childNodes[0].firstChild;
		    thdiv.style.left = scroller.scrollLeft + "px";
			row = row.nextSibling;
		}
		// Do the same thing again to prevent firefox from flickering with the last column header
	    content.style.top = -scroller.scrollTop + "px";
	    content.style.left = -scroller.scrollLeft + "px";
	}
}

function GridOnscroll(e)
{
	var source;
	if (e == null)
	{
		e = window.event;
		source = e.srcElement;
	}
	else
	{
		source = e.target;
	}
	var me = source;
	while (me.className != "DSgrMain")
	{
	    me = me.parentNode;
	    if (me == null)
	    {
	        return;
	    }
	}
	GridDoScroll(me);
}

function GridHeadKeydown(e)
{
	var source;
	if (e == null)
	{
		e = window.event;
		source = e.srcElement;
	}
	else
	{
		source = e.target;
	}
	
	var content = source;
	while (!containsClass(content, "DSgrContent"))
	{
	    content = content.parentNode;
	    if (content == null)
	    {
	        return;
	    }
	}
	
	var handled = false;
	
	var rows = content.lastChild.childNodes;
	var heads = content.lastChild.firstChild.childNodes;
	var focusHead = parseInt(content.getAttribute("focusHead"));
	
	if (e.keyCode == 13) // Enter
	{
	    if (isFinite(focusHead) && containsClass(heads[focusHead], "DSgrFocusHead"))
	    {
			GridHeadDoSort(content, heads[focusHead])
	    }
	    handled = true;
	}
	else if (e.keyCode == 32) // Space
	{
		if (isFinite(focusHead) && containsClass(heads[focusHead], "DSgrFocusHead"))
	    {
			GridHeadDoSort(content, heads[focusHead])
	    }
	    handled = true;
	}
	else if (e.keyCode == 37) // Left
	{
		GridMoveFocusHead(content, (isFinite(focusHead) && focusHead > 0) ? focusHead - 1 : heads.length - 1);
	    handled = true;
	}
	else if (e.keyCode == 39) // Right
	{
		GridMoveFocusHead(content, (isFinite(focusHead) && focusHead < heads.length - 1) ? focusHead + 1 : 0);
	    handled = true;
	}
	if (handled)
	{
		if (e.preventDefault)
		{
			e.preventDefault();
		}
		if (e.stopPropagation)
		{
			e.stopPropagation();
		}
		e.cancelBubble = true;
		return false;
	}
}

function GridKeydown(e)
{
	var source;
	if (e == null)
	{
		e = window.event;
		source = e.srcElement;
	}
	else
	{
		source = e.target;
	}
	
	var content = source;
	while (!containsClass(content, "DSgrContent"))
	{
	    content = content.parentNode;
	    if (content == null)
	    {
	        return;
	    }
	}
	
	var rows = content.lastChild.childNodes;
	var heads = content.lastChild.firstChild.childNodes;
	var Row = parseInt(content.getAttribute("Row"));
	var Col = parseInt(content.getAttribute("Col"));
	var focusHead = parseInt(content.getAttribute("focusHead"));
	var cellSelect = content.getAttribute("cellSelect") == "true";
	var visibleRowCount = rows.length > 1 ? Math.floor((content.parentNode.clientHeight - rows[0].offsetHeight) / rows[1].offsetHeight) : 1;
	
	if (e.keyCode == 13) // Enter
	{
	    if (!isFinite(focusHead) && isFinite(Col))
	    {
			GridMoveFocusHead(content, Col);
	    }
		var focusHead = parseInt(content.getAttribute("focusHead"));
	    if (isFinite(focusHead))
	    {
			GridHeadDoSort(content, heads[focusHead])
	    }
	}
	else if (e.keyCode == 32) // Space
	{
	    if (!isFinite(focusHead) && isFinite(Col))
	    {
			GridMoveFocusHead(content, Col);
	    }
		var focusHead = parseInt(content.getAttribute("focusHead"));
	    if (isFinite(focusHead))
	    {
			GridHeadDoSort(content, heads[focusHead])
	    }
	}
	else if (e.keyCode == 37) // Left
	{
		if (isFinite(Col))
		{
			Col = Col - 1;
		}
		else
		{
			if (isFinite(focusHead))
			{
				Col = focusHead -1;
			}
			else
			{
				Col = 0;
			}
		}
		
		if (heads.length > 1)
		{
			if (cellSelect)
			{
				GridMoveSelected(content, null, Col >=1 ? Col : 1);
			}
			else
			{
				GridMoveFocusHead(content, Col >=0 ? Col : 0);
			}
		}
		if (heads.length > 1 && cellSelect)
		{
		}
		if (e.preventDefault)
		{
			e.preventDefault();
		}
		return false;
	}
	else if (e.keyCode == 39) // Right
	{
		if (isFinite(Col))
		{
			Col = Col + 1;
		}
		else
		{
			if (isFinite(focusHead))
			{
				Col = focusHead + 1;
			}
			else
			{
				Col = heads.length - 1;
			}
		}
		Col = Col < heads.length ? Col : heads.length - 1;
		if (heads.length > 1)
		{
			if (cellSelect)
			{
				GridMoveSelected(content, null, Col);
			}
			else
			{
				GridMoveFocusHead(content, Col);
			}
		}
		if (e.preventDefault)
		{
			e.preventDefault();
		}
		return false;
	}
	else if (e.keyCode == 38) // Up
	{
		GridKeyMoveSelected(cellSelect, Row, rows, content, -1);
	}
	else if (e.keyCode == 40) // Down
	{
		GridKeyMoveSelected(cellSelect, Row, rows, content, +1);
	}
	else if (e.keyCode == 33) // PageUp
	{
		GridKeyMoveSelected(cellSelect, Row, rows, content, -visibleRowCount);
	}
	else if (e.keyCode == 34) // PageDown
	{
		GridKeyMoveSelected(cellSelect, Row, rows, content, visibleRowCount, e);
	}
	else if (e.keyCode == 36) // Home
	{
		GridKeyMoveSelected(cellSelect, Row, rows, content, content, 1 - Row);
	}
	else if (e.keyCode == 35) // End
	{
		GridKeyMoveSelected(cellSelect, Row, rows, content, rows.length - 1 - Row);
	}
}

function GridKeyMoveSelected(cellSelect, Row, rows, content, jump)
{
	var to = isFinite(Row) ? Row + jump : 1;
	if(to < 1)
	{
		to = 1;
	}
	if (rows.length <= to)
	{
	    to = rows.length - 1;
	}
	GridMoveSelected(content, to, null)
}

function GridMoveFocusHead(content, head)
{
	var heads = content.lastChild.firstChild.childNodes;
	var focusHead = parseInt(content.getAttribute("focusHead"));
    if (isFinite(focusHead))
    {
		removeClasses(heads[focusHead], "DSgrFocusHead");
	}
	
	focusHead = head;
	
    if (isFinite(focusHead))
    {
		addClasses(heads[focusHead], "DSgrFocusHead");
		content.setAttribute("focusHead", focusHead);
		GridScrollHeadIntoView(content, focusHead);
	}
}

function GridMoveSelected(content, row, col)
{
	var heads = content.lastChild.firstChild.childNodes;
	var rows = content.lastChild.childNodes;
	var Row = parseInt(content.getAttribute("Row"));
	var Col = parseInt(content.getAttribute("Col"));
	var cellSelect = content.getAttribute("cellSelect") == "true";
	
	if (Row == row && row != null && (!cellSelect || Col == col && col != null))
	{
		return;
	}
    if (isFinite(Row))
    {
		removeClasses(rows[Row].firstChild, "DSgrSelectedHead");
		if (cellSelect)
		{
			if (isFinite(Col))
			{
				removeClasses(rows[Row].childNodes[Col], "DSgrSelectedCell");
				removeClasses(heads[Col], "DSgrSelectedHead");
			}
		}
		else
		{
			removeClasses(rows[Row], "DSgrSelectedRow");
		}
    }
	
	if (row != null)
	{
		Row = row;
	}
	if (col != null)
	{
		Col = col;
	}
	   
    if (!isFinite(Row) && rows.length > 1)
    {
		Row = 1;
	}
	content.setAttribute("Row", Row);
	if (cellSelect)
	{
	    if (isFinite(Row) && !isFinite(Col) && rows[Row].childNodes.length > 1)
		{
			Col = 1;
		}
		content.setAttribute("Col", Col);
		if (isFinite(Row) && isFinite(Col))
		{
			addClasses(rows[Row].firstChild, "DSgrSelectedHead");
			addClasses(heads[Col], "DSgrSelectedHead");
			addClasses(rows[Row].childNodes[Col], "DSgrSelectedCell");
			GridScrollIntoView(content, Row, Col);
			GridTryFireConstraint(content);
		}
	}
	else
	{
		if (isFinite(Row))
		{
			addClasses(rows[Row].firstChild, "DSgrSelectedHead");
			addClasses(rows[Row], "DSgrSelectedRow");
			GridScrollRowIntoView(content, Row);
			GridTryFireConstraint(content);
		}
	}
}

// if row == 0 no left-right scrollong is done, if col == 0 no up-down scrolling is done.
function GridScrollIntoView(content, row, col)
{
	var me = content;
	while (me.className != "DSgrMain")
	{
	    me = me.parentNode;
	}
	var inner = document.getElementById(me.id + "_inner");
	var scroller = document.getElementById(me.id + "_scroller");
	
	if (row != null && row > 0)
	{
		var rows = content.lastChild.childNodes;
		var top = rows[row].offsetTop;
		var topd = top - rows[0].offsetHeight - scroller.scrollTop;
		var botd = (top + rows[row].offsetHeight) - (inner.clientHeight + scroller.scrollTop);
		var scrolldiff = botd > 0 ? botd : 0;
		if (scrolldiff > topd)
		{
			scrolldiff = topd;
		}
		scroller.scrollTop = scroller.scrollTop + scrolldiff;
	}
	
	if (col != null && col > 0)
	{
		var heads = content.lastChild.firstChild.childNodes;
		var left = heads[col].offsetLeft;
		var leftd = left - heads[0].offsetWidth - scroller.scrollLeft;
		var rightd = (left + heads[col].offsetWidth) - (inner.clientWidth + scroller.scrollLeft);
		var scrolldiff = rightd > 0 ? rightd : 0;
		if (scrolldiff > leftd)
		{
			scrolldiff = leftd;
		}
		scroller.scrollLeft = scroller.scrollLeft + scrolldiff;		
	}
}

function GridScrollRowIntoView(content, row)
{
	GridScrollIntoView(content, row, 0);	
}

function GridScrollHeadIntoView(content, head)
{
	GridScrollIntoView(content, 0, head);	
}

function GridHeadOnfocus(e)
{
	var source;
	if (e == null)
	{
		e = window.event;
		source = e.srcElement;
	}
	else
	{
		source = e.target;
	}

	var content = source;
	while (!containsClass(content, "DSgrContent"))
	{
	    content = content.parentNode;
	    if (content == null)
	    {
	        return;
	    }
	}

	var heads = content.lastChild.firstChild.childNodes;
	var Col = parseInt(content.getAttribute("Col"));
	var focusHead = parseInt(content.getAttribute("focusHead"));
	
	if (!isFinite(focusHead))
	{
		if (isFinite(Col))
		{
			focusHead = Col;
		}
		else
		{
			focusHead = heads.length > 1 ? 1 : 0;
		} 
	}
	addClasses(heads[focusHead], "DSgrFocusHead");
	content.setAttribute("focusHead", focusHead);
	if (e.stopPropagation)
	{
		e.stopPropagation();
	}
}

function GridHeadOnblur(e)
{
	var source;
	if (e == null)
	{
		e = window.event;
		source = e.srcElement;
	}
	else
	{
		source = e.target;
	}

	var content = source;
	while (!containsClass(content, "DSgrContent"))
	{
	    content = content.parentNode;
	    if (content == null)
	    {
	        return;
	    }
	}
	
	var heads = content.lastChild.firstChild.childNodes;
	var focusHead = parseInt(content.getAttribute("focusHead"));
	if(isFinite(focusHead))
	{
	    removeClasses(heads[focusHead], "DSgrFocusHead");
	}
	if (e.stopPropagation)
	{
		e.stopPropagation();
	}
}

function GridOnfocus(e)
{
	var source;
	if (e == null)
	{
		e = window.event;
		source = e.srcElement;
	}
	else
	{
		source = e.target;
	}

	var content = source;
	while (!containsClass(content, "DSgrContent"))
	{
	    content = content.parentNode;
	    if (content == null)
	    {
	        return;
	    }
	}
	
	addClasses(content, "DSgrFocus");

	var heads = content.lastChild.firstChild.childNodes;
	var focusHead = parseInt(content.getAttribute("focusHead"));
	var cellSelect = content.getAttribute("cellSelect") == "true";
	
	if (!cellSelect && isFinite(focusHead))
	{
	    addClasses(heads[focusHead], "DSgrFocusHead");
	} 
}

function GridOnblur(e)
{
	var source;
	if (e == null)
	{
		e = window.event;
		source = e.srcElement;
	}
	else
	{
		source = e.target;
	}

	var content = source;
	while (!containsClass(content, "DSgrContent"))
	{
	    content = content.parentNode;
	    if (content == null)
	    {
	        return;
	    }
	}
	
	removeClasses(content, "DSgrFocus");
	
	var heads = content.lastChild.firstChild.childNodes;
	var focusHead = parseInt(content.getAttribute("focusHead"));
	var cellSelect = content.getAttribute("cellSelect") == "true";
	
	if (!cellSelect && isFinite(focusHead))
	{
	    removeClasses(heads[focusHead], "DSgrFocusHead");
	}
}

function GridOnwheel(e){
	var source;
	if (e == null)
	{
		e = window.event;
		source = e.srcElement;
	}
	else
	{
		source = e.target;
	}

	var me = source;
	while (!containsClass(me, "DSgrMain"))
	{
	    me = me.parentNode;
	    if (me == null)
	    {
	        return;
	    }
	}
	
	var delta = 0;
	if (e.wheelDelta)
	{
		delta = e.wheelDelta/120; 
		if (window.opera) delta = -delta;
	} 
	else if (e.detail) 
	{
		delta = -e.detail/3;
	}
	if (delta)
	{
		var scroller = document.getElementById(me.id + "_scroller");
		scroller.scrollTop = scroller.scrollTop - 50 * delta;
	}
		
    if (e.preventDefault)
    {
		e.preventDefault();
	}
    e.returnValue = false;
    return false;
}


function GridInit(myId)
{
	var me = document.getElementById(myId);
	var inner = document.getElementById(myId + "_inner");
	var scroller = document.getElementById(myId + "_scroller");
	var content = document.getElementById(me.id + "_content");

	scroller.onscroll = GridOnscroll;
	
	if (content != null && content.getAttribute("initialized") == null)
	{
		var cellSelect = content.getAttribute("cellSelect") == "true";
		content.setAttribute("initialized", "true");
		
		inner.style.position = "relative";
		inner.style.overflowX = "hidden";
		inner.style.overflowY= "hidden";
		content.style.position = "relative";
		scroller.style.overflowX= "auto";
		scroller.style.overflowY= "auto";
		var row = content.lastChild.firstChild;
		row.childNodes[0].firstChild.style.zIndex = 1;
		for (var i = 0; i < row.childNodes.length; i++)
		{
		    var thdiv = row.childNodes[i].firstChild;
		    thdiv.style.position = "relative";
		    thdiv.style.whiteSpace = "";
			thdiv.onclick = GridTHOnclick;
			thdiv.ondblclick = GridTHOnclick;
		}
		
		row = row.nextSibling;
		while (row != null)
		{
		    var thdiv = row.childNodes[0].firstChild;
		    thdiv.style.position = "relative";
		    thdiv.style.whiteSpace = "";
		    
			row.onclick = GridOnclick;

			row = row.nextSibling;
		}

        content.onkeydown = GridKeydown;
        content.onfocus = GridOnfocus;
        content.onblur = GridOnblur;

		if (cellSelect)
		{
			var headRow = content.lastChild.firstChild;
	        headRow.onkeydown = GridHeadKeydown;
		    headRow.onfocus = GridHeadOnfocus;
			headRow.onblur = GridHeadOnblur;
		}
		
        inner.onmousewheel = GridOnwheel;
        if (inner.addEventListener)
			inner.addEventListener('DOMMouseScroll', GridOnwheel, true);
		
		GridLayoutInner(me, null);
	}
}

function GridSet(myId, property)
{
	if (property == "innerHTML")
	{
		var inner = document.getElementById(myId + "_inner");
	    while (inner.firstChild != null)
	    {
	        inner.removeChild(inner.firstChild);
	    }
	    ParseHtmlTo(inner, DSCurrentData);
	}
	else if (property == "init")
	{
			GridInit(myId);
    }
}

function GridSetViewState(myId)
{
	var content = document.getElementById(myId+ "_content");
	content.setAttribute("viewState", DSCurrentData);
}

function GridGetViewStates(myId)
{
	var inner = document.getElementById(myId + "_inner");
	while (inner.firstChild != null)
	{
	    inner.removeChild(inner.firstChild);
	}
	AddNewBusy(inner);
}

function GridOnclick(e)
{	
	var source;
	if (e == null)
	{
		e = window.event;
		source = e.srcElement;
	}
	else
	{
		source = e.target;
	}

	var content = source;
	while (!containsClass(content, "DSgrContent"))
	{
	    content = content.parentNode;
	    if (content == null)
	    {
	        return;
	    }
	}
	content.focus();
	var cellSelect = content.getAttribute("cellSelect") == "true";
	var rows = content.lastChild.childNodes;
	
	var col = source.cellIndex;
	while(source.tagName != "TR")
	{
		source = source.parentNode;
		if (source == null)
		{
			return;
		}
	}
	var row = 0;
	for (; row < rows.length; row++)
	{
		if (rows[row] == source)
		{
			break;
		}
	}
	
	if (row == 0 || row >= rows.length)
	{
		return;
	}
	
	GridMoveSelected(content, row, col);
	
	if (e.preventDefault)
	{
		e.preventDefault();
	}
	return false;
}

function GridTryFireConstraint(content)
{
	var me = content;
	// Somehow IE invents a node in the tree that doesnt have a getAttribute function when a component is put under a notebook
	while (!me.getAttribute || me.getAttribute("target") == null)
	{
		me = me.parentNode;
		if (me == null)
		{
			return;
		}
	}

	var rows = content.lastChild.childNodes;
	var heads = content.lastChild.firstChild.childNodes;
	var Row = parseInt(content.getAttribute("Row"));
	var Col = parseInt(content.getAttribute("Col"));
	var cellSelect = content.getAttribute("cellSelect") == "true";
	
	var rowVS = null;
	var colVS = null;
	if (isFinite(Row) && Row > 0)
	{
		rowVS = rows[Row].getAttribute("viewState");
	}
	else
	{
		return;
	}
	
	if (cellSelect)
	{
		if (isFinite(Col) && Col > 0)
		{
			colVS = heads[Col].getAttribute("viewState");
		}
		else
		{
			return;
		}
	}
	
	var target = me.getAttribute("target");
    var rc = new RequestContext(me.id, target);

	if (rowVS != null)
	{
		rc.AddSecureVS(rowVS); 
	}
	if (colVS != null)
	{
		rc.AddSecureVS(colVS); 
	}
	var vs = content.getAttribute("viewState");
	if (vs != null)
	{
		rc.AddSecureVS(vs); 
	}
	
	var i = document.getElementById(target);
	eval(i.getAttribute("GetViewStates"));
	
	rc.Fire();
}

function GridTHOnclick(e)
{
	var source;
	if (e == null)
	{
		e = window.event;
		source = e.srcElement;
	}
	else
	{
		source = e.target;
	}
	while (source.tagName != "TH")
	{
	    source = source.parentNode;
	    if (source == null)
	    {
	        return;
	    }    
	}
	var content = source
	while (content.tagName != "TABLE")
	{
	    content = content.parentNode;
	}
	
	var cellSelect = content.getAttribute("cellSelect") == "true";
	if (cellSelect)
	{
		content.lastChild.firstChild.focus();
	}
	else
	{
		content.focus();
	}
	GridMoveFocusHead(content, source.cellIndex);
	
	GridHeadDoSort(content, source);
	
	if (e.stopPropagation)
	{
		e.stopPropagation();
	}
    if (e.preventDefault)
    {
		e.preventDefault();
	}
	e.cancelBubble = true;
    e.returnValue = false;
    return false;
}

function GridHeadDoSort(content, head)
{	
	var sortDirection = head.getAttribute("sortDirection");
	
	var row = head.parentNode;
	for(var i = 0; i < row.childNodes.length; i++)
	{
	    var th = row.childNodes[i];
	    th.setAttribute("sortDirection", null);
	    if (th.firstChild.lastChild.className != null && th.firstChild.lastChild.className.indexOf("DStlSortArrow") >= 0)
	    {
	        th.firstChild.removeChild(th.firstChild.lastChild);
	    }
	}
	
	if (sortDirection == "down")
	{
	    sortDirection = "up";
   	    ParseHtmlTo(head.firstChild, "<SPAN class=\"DStlSortArrow DStlSortUp\" UNSELECTABLE = on>&nbsp;&nbsp;&nbsp;</SPAN>");
	}
	else
	{
	    sortDirection = "down";
	    ParseHtmlTo(head.firstChild,"<SPAN class=\"DStlSortArrow DStlSortDown\" UNSELECTABLE = on>&nbsp;&nbsp;&nbsp;</SPAN>");
	}
	
	var me = content;
	while (me.className != "DSgrMain")
	{
	    me = me.parentNode;
	}
	var rows = content.lastChild.childNodes;
	var heads = content.lastChild.firstChild.childNodes;
	var Row = parseInt(content.getAttribute("Row"));
	var Col = parseInt(content.getAttribute("Col"));
	var cellSelect = content.getAttribute("cellSelect") == "true";
	
	GridLayoutInner(me, null);
	
    if(isFinite(Row))
	{
		rows[Row].setAttribute("selectedRow", "true");
	}
    if(isFinite(Col))
	{
		heads[Col].setAttribute("selectedCol", "true");
	}
	
	GridSort(content, head.cellIndex, sortDirection);
	
    if(isFinite(Row))
	{
		Row = null;
		for (var i = 1; i < rows.length; i++)
		{
		    if (rows[i].getAttribute("selectedRow") != null)
		    {
				rows[i].removeAttribute("selectedRow");
				Row = i;
				break;
		    }
		}
		content.setAttribute("Row", Row);
		if (Row != null)
		{
			GridScrollRowIntoView(content, Row);
		}
	}

	head.setAttribute("sortDirection", sortDirection);
}

function GridSort(content, col, direction)
{
    var temp = new Array();
    
	var row = content.lastChild.firstChild;
	var cell = row.childNodes[col];
	var firstSortType;
	var currentSortType = null;
	while (cell != null)
	{
		var st;
		if (cell.getAttribute("sortType") == "NUMBER")
		{
			st = new TableListSortTypeNumber();
		}
		else
		{
			if (cell.align == "right")
			{
	            st = new TableListSortTypeAlignRight();
			}
			else
			{
	            st = new TableListSortTypeAlignLeft();
			}
		}
		if (currentSortType == null)
		{
			firstSortType = st;
		}
		else
		{
			currentSortType.next = st;
		}
		currentSortType = st;
		cell = cell.nextSibling;
	}
	var sumrow = null;

	row = row.nextSibling;
	var index = 0;
	while (row != null)
	{
		if (containsClass(row, "DSgrSumRow"))
		{
		    sumrow = row;
		}
		else
		{
		    var td = row.childNodes[col];
    	    temp[index] = new TableListSortItem(firstSortType, row, td);
	    	index++;
		}
		row = row.nextSibling;
	}
	
    temp.sort(TableListSortMain);
    
    var body = content.lastChild;
    if (direction == "up")
    {
        for (var i = temp.length - 1; i >= 0; i--)
        {
            body.appendChild(temp[i].row);
        }
    }
    else
    {
        for (var i = 0; i < temp.length; i++)
        {
            body.appendChild(temp[i].row);
        }
    }
    if (sumrow != null)
    {
            body.appendChild(sumrow);
    }
}



function SplitterComponentStartSplit(e)
{
	var source;
	if (e == null)
	{
		e = window.event;
		source = e.srcElement;
	}
	else
	{
		source = e.target;
	}
	
	var me = source;
	while (me.className != "DSspMain")
	{
		me = me.parentNode;
		if (me == null)
		{
			return;
		}
	}

    var split = document.getElementById(me.id + "_Split");
	split.style.position = "relative";
    split.style.zIndex = 20;
    split.style.backgroundColor = "#000000";
    setOpacity(split.style, 50);
	split.style.top = "0px";
	split.style.left = "0px";
    
    if (split.setCapture != null)
    {
        split.setCapture(true);
        split.onmousemove = SplitterComponentBarMove;
        split.onmouseup = SplitterComponentBarUp;
        split.onlosecapture = SplitterComponentBarBlur;
    }
    else
    {   
        var barmove = new BarMoveHandler(split);
        var barexit = new BarExitHandler(split);
        var barstop = new BarStopHandler(split);
        barexit.stop = barstop;
        barexit.move = barmove;
        barstop.exit = barexit;
        barstop.move = barmove;
        document.documentElement.addEventListener("mousemove", barmove, true);
        window.addEventListener("mouseout", barexit, true);
        window.addEventListener("blur", barexit, true);
        document.documentElement.addEventListener("mouseup", barstop, true);
    }
    
    split.setAttribute("diff", 0);
	var f1 = document.getElementById(me.id + "_Field1").firstChild; // TD.DIV
	if (me.getAttribute("HorizontalBar") == "true")
	{
		split.setAttribute("nullPoint", e.clientY);
	}
	else
	{
		split.setAttribute("nullPoint", e.clientX);
	}
}

function BarMoveHandler(bar)
{
    this.bar = bar;
    this.handleEvent = function(e)
    {
        e.preventDefault();
        e.stopPropagation();
        MoveBar(bar, e);
    }
}

function BarExitHandler(bar)
{
    this.bar = bar;
    this.handleEvent = function(e)
    {
        if (e.relatedTarget != null)
        {
            return;
        }
        document.documentElement.removeEventListener("mousemove", this.move, true);
        window.removeEventListener("mouseout", this, true);
        window.removeEventListener("blur", this, true);
        document.documentElement.removeEventListener("mouseup", this.stop, true);
        ExitBar(bar);
    }
}

function BarStopHandler(bar)
{
    this.bar = bar;
    this.handleEvent = function(e)
    {
        e.preventDefault();
        e.stopPropagation();
        document.documentElement.removeEventListener("mousemove", this.move, true);
        window.removeEventListener("mouseout", this.exit, true);
        window.removeEventListener("blur", this.exit, true);
        document.documentElement.removeEventListener("mouseup", this, true);
        BarStop(bar);
    }
}

function SplitterComponentBarMove(e)
{
    var e = window.event;
    MoveBar(this, e);
}

function MoveBar(bar, e)
{    
	var me = bar;
	while (me.className != "DSspMain")
	{
		me = me.parentNode;
		if (me == null)
		{
			return;
		}
	}
	
	var nullPoint = bar.getAttribute("nullPoint");
	var diff;
	if (me.getAttribute("HorizontalBar") == "true")
	{
	    diff = e.clientY - parseInt(nullPoint);
	    diff = SplitterComponentLimitDiff(me, diff);
	    bar.style.top = diff + "px";
	}
	else
	{
	    diff = e.clientX - parseInt(nullPoint);
	    diff = SplitterComponentLimitDiff(me, diff);
	    bar.style.left = diff + "px";
	}
	bar.setAttribute("diff", diff);
}

function SplitterComponentBarBlur()
{
    this.onmousemove = null;
    this.onmouseup = null;
    ExitBar(this);
}

function ExitBar(bar)
{
	bar.style.position = "";
    bar.style.zIndex = 0;
    bar.style.backgroundColor = "";
    bar.style.opacity = "";
    bar.style.filter = "";
	bar.style.top = "0px";
	bar.style.left = "0px";
}

function SplitterComponentBarUp()
{
    BarStop(this);
}

function BarStop(bar)
{
	var me = bar;
	while (me.className != "DSspMain")
	{
		me = me.parentNode;
		if (me == null)
		{
			return;
		}
	}
	if (bar.setCapture != null)
	{
        bar.onlosecapture = null;
        bar.onmousemove = null;
        bar.onmouseup = null;
	    bar.releaseCapture();
	}
	ExitBar(bar);
  	SplitterComponentShift(me, parseInt(bar.getAttribute("diff")));
}	

function SplitterComponentLimitDiff(me, diff)
{
	var f1 = document.getElementById(me.id + "_Field1").firstChild; // TD.DIV
	var f2 = document.getElementById(me.id + "_Field2").firstChild; // TD.DIV
	if (me.getAttribute("HorizontalBar") == "true")
	{
		var lh1 = ToPixel(f1.style.height);
		var lh2 = ToPixel(f2.style.height);
		if (diff > 0 && diff > lh2)
		{
			diff = lh2;
		} 
		if (diff < 0 && diff < -lh1)
		{
			diff = -lh1;
		} 
	}
	else
	{
		var lw1 = ToPixel(f1.style.width);
		var lw2 = ToPixel(f2.style.width);
		if (diff > 0 && diff > lw2)
		{
			diff = lw2;
		} 
		if (diff < 0 && diff < -lw1)
		{
			diff = -lw1;
		} 
	}
	return diff;
}
	
function SplitterComponentShift(me, diff)
{
    if (diff == 0)
    { 
        return;
    }
    
	var f1 = document.getElementById(me.id + "_Field1").firstChild; // TD.DIV
	var split = document.getElementById(me.id + "_Split"); // DIV
	var f2 = document.getElementById(me.id + "_Field2").firstChild; // TD.DIV
	var splitpos = me.getAttribute("SplitPosition");
	if (me.getAttribute("HorizontalBar") == "true")
	{
		var lw = ToPixel(f1.style.width);
		var lh1 = ToPixel(f1.style.height);
		var lh2 = ToPixel(f2.style.height);
		
		DSLayoutHeight = lh1 + diff;
		DSLayoutWidth = lw;
		f1.style.overflow = "hidden";
		f1.style.height = PixelToStr(DSLayoutHeight);
		var t1 = f1.firstChild.getAttribute("doLayout");
		if (t1 != null)
		{
			eval(t1);
		}
		f1.style.overflow = "auto";
		
		DSLayoutHeight = lh2 - diff;
		DSLayoutWidth = lw;
		f2.style.overflow = "hidden";
		f2.style.height = PixelToStr(DSLayoutHeight);
		var t2 = f2.firstChild.getAttribute("doLayout");
		if (t2 != null)
		{
			eval(t2);
		}
		f2.style.overflow = "auto";
		splitpos = (lh1 + diff + 2) * 1000 / (lh1 + lh2 + 4);
	}
	else
	{
		var lh = ToPixel(f1.style.height);
		var lw1 = ToPixel(f1.style.width);
		var lw2 = ToPixel(f2.style.width);
		
		DSLayoutWidth = lw1 + diff;
		DSLayoutHeight = lh;
		f1.style.overflow = "hidden";
		f1.style.width = PixelToStr(DSLayoutWidth);
		var t1 = f1.firstChild.getAttribute("doLayout");
		if (t1 != null)
		{
			eval(t1);
		}
		f1.style.overflow = "auto";
		
		DSLayoutWidth = lw2 - diff;
		DSLayoutHeight = lh;
		f2.style.overflow = "hidden";
		f2.style.width = PixelToStr(DSLayoutWidth);
		var t2 = f2.firstChild.getAttribute("doLayout");
		if (t2 != null)
		{
			eval(t2);
		}
		f2.style.overflow = "auto";
		splitpos = (lw1 + diff + 2) * 1000 / (lw1 + lw2 + 4);
	}
	me.setAttribute("SplitPosition", splitpos);
}

function SplitterComponentDoLayout(myId)
{
	var me = document.getElementById(myId);
	var f1 = document.getElementById(myId + "_Field1").firstChild; // TD.DIV
	var split = document.getElementById(myId + "_Split"); // DIV
	var f2 = document.getElementById(myId + "_Field2").firstChild; // TD.DIV
	var splitpos = me.getAttribute("SplitPosition");
	var h = DSLayoutHeight;
	var w = DSLayoutWidth;
	if (me.getAttribute("HorizontalBar") == "true")
	{
		DSLayoutHeight = Math.round(h * splitpos / 1000) - 2;
		DSLayoutWidth = w;
		f1.style.overflow = "hidden";
		f1.style.width = PixelToStr(DSLayoutWidth);
		f1.style.height = PixelToStr(DSLayoutHeight);
		var t = f1.firstChild.getAttribute("doLayout");
		if (t != null)
		{
			eval(t);
		}
		f1.style.overflow = "auto";
		
		split.style.overflow = "hidden";
		split.style.width = PixelToStr(w);
		split.style.height = PixelToStr(4);

		DSLayoutHeight = h - 2 - Math.round(h * splitpos / 1000);
		DSLayoutWidth = w;
		f2.style.overflow = "hidden";
		f2.style.width = PixelToStr(DSLayoutWidth);
		f2.style.height = PixelToStr(DSLayoutHeight);
		var t = f2.firstChild.getAttribute("doLayout");
		if (t != null)
		{
			eval(t);
		}
		f2.style.overflow = "auto";
	}
	else
	{
		DSLayoutHeight = h;
		DSLayoutWidth = Math.round(w * splitpos / 1000) - 2;
		f1.style.overflow = "hidden";
		f1.style.width = PixelToStr(DSLayoutWidth);
		f1.style.height = PixelToStr(DSLayoutHeight);
		var t = f1.firstChild.getAttribute("doLayout");
		if (t != null)
		{
			eval(t);
		}
		f1.style.overflow = "auto";

		split.style.overflow = "hidden";
		split.style.width = PixelToStr(4);
		split.style.height = PixelToStr(h);

		DSLayoutHeight = h;
		DSLayoutWidth = w - 2 - Math.round(w * splitpos / 1000);
		f2.style.overflow = "hidden";
		f2.style.width = PixelToStr(DSLayoutWidth);
		f2.style.height = PixelToStr(DSLayoutHeight);
		var t = f2.firstChild.getAttribute("doLayout");
		if (t != null)
		{
			eval(t);
		}
		f2.style.overflow = "auto";
	}
	
	split.onmousedown = SplitterComponentStartSplit;
}

function SplitterComponentGetViewStates(myId)
{
	var me = document.getElementById(myId);
	
	var i = document.getElementById(me.getAttribute("child1"));
	eval(i.getAttribute("GetViewStates"));

	i = document.getElementById(me.getAttribute("child2"));
	eval(i.getAttribute("GetViewStates"));
}


function SplitterAdapterSetViewState(myId)
{
	var me = document.getElementById(myId);
	
	me.setAttribute("viewState", DSCurrentData);
}

function SplitterAdapterGetViewStates(myId)
{
	var me = document.getElementById(myId);

	var partner = document.getElementById(me.getAttribute("partner"));
	if (partner != null)
	{
		DSCurrentRequestContext.AddSecureVS(partner.getAttribute("viewState"));
	}
	
	var target = me.getAttribute("forwardTarget");
	if (target != null)
	{
		var i = document.getElementById(target);
		eval(i.getAttribute("GetViewStates"));
	}	
}


function LayoutDoLayout(myId)
{
	var me = document.getElementById(myId);
	var h = DSLayoutHeight;
	var w = DSLayoutWidth;
	me.style.overflow = "hidden";
	me.style.width = PixelToStr(w);
	me.style.height = PixelToStr(h);
	var columns = parseInt(me.getAttribute("columns"));
	var rows = Math.ceil(me.childNodes.length / columns);
	var posX = 0;
	var posY = 0;
	for (var i = 0; i < me.childNodes.length; i++)
	{
		var x = i % columns;
		var y = Math.floor(i / columns);
		var newX = Math.round((x + 1) * w / columns);
		var newY = Math.round((y + 1) * h / rows);
		
		DSLayoutWidth = newX - posX;
		DSLayoutHeight = newY - posY;
		me.childNodes[i].style.width = PixelToStr(DSLayoutWidth);
		me.childNodes[i].style.height = PixelToStr(DSLayoutHeight);
		var t = me.childNodes[i].firstChild.getAttribute("doLayout");
		if (t != null)
		{
			eval(t);
		}
		if (x == columns - 1)
		{
			posX = 0;
			posY = newY;
		}
		else
		{
			posX = newX;
		}
	}
}

function LayoutGetViewStates(myId)
{
	var me = document.getElementById(myId);
	
	var cell = me.firtsChild;
	while(cell != null)
	{
		if (cell.tagName == "DIV")
		{
			eval(cell.firstChild.getAttribute("GetViewStates"));
		}
		cell = cell.nextSibling;
	}
}


function DataSetCacheSetViewState(myId)
{
	var me = document.getElementById(myId);
	
	me.setAttribute("viewState", DSCurrentData);
}

function DataSetCacheSet(myId, property)
{
	if (property == "register")
	{
		DSDataSetChaches = new DSDataSetChache(myId, DSDataSetChaches);
	}
}

function DSDataSetChache(myId, DSDataSetChaches)
{
	this.Id = myId;
	this.next = DSDataSetChaches;
}


function DataSetCacheGetViewStates(myId)
{
	var me = document.getElementById(myId);

	var i = document.getElementById(me.getAttribute("forwardTarget"));
	eval(i.getAttribute("GetViewStates"));
}


function TimerGetViewStates(myId)
{
	var me = document.getElementById(myId);

	var timer = me.getAttribute("TimerID");
	if (timer != null && timer != "")
	{
		clearInterval(timer);
	}
	var i = document.getElementById(me.getAttribute("forwardTarget"));
	eval(i.getAttribute("GetViewStates"));
}

function TimerSetViewState(myId)
{
	var me = document.getElementById(myId);
	
	var vs = DSCurrentData
	me.setAttribute("viewState", vs);
	var target = me.getAttribute("forwardTarget");
	if (vs != null && vs != "" && target != null && target != "")
	{
			var timer = setInterval(function()
			{	
				var target = me.getAttribute("forwardTarget");
			    var rc = new RequestContext(myId, target);
				var vs2 = me.getAttribute("viewState");
				if (vs2 != null)
				{
					rc.AddSecureVS(vs2); 
				}
				eval(document.getElementById(target).getAttribute("GetViewStates"));
				rc.Fire();
			}
			, parseInt(me.getAttribute("intervalms")));
		me.setAttribute("TimerID", timer);
	}
}


function TranslatorGetViewStates(myId)
{
	var me = document.getElementById(myId);

	var i = document.getElementById(me.getAttribute("forwardTarget"));
	eval(i.getAttribute("GetViewStates"));
}


function LookupTranslatorGetViewStates(myId)
{
	var me = document.getElementById(myId);

	var i = document.getElementById(me.getAttribute("forwardTarget"));
	eval(i.getAttribute("GetViewStates"));
}


function TitleDoLayout(myId)
{
	var me = document.getElementById(myId);
	
	DSLayoutHeight = DSLayoutHeight - me.offsetHeight;
	
	me.style.overflow = "hidden";
	me.style.width = "0px";
	me.style.width = PixelToStr(DSLayoutWidth - me.offsetWidth);
	TitleDoAllignment(me);
	
	var client = me.nextSibling;
	client.style.width = PixelToStr(DSLayoutWidth);
	client.style.height = PixelToStr(DSLayoutHeight);
	client.style.overflow = "auto";
		
	var t = client.firstChild.getAttribute("doLayout");
	if (t != null)
	{
		eval(t);
	}
}

function TitleDoAllignment(me)
{
	var table = me.firstChild;
	if (table != null && table.tagName == "TABLE")
	{
		table.style.width = PixelToStr(getInnerWidth(me));
	}
}

function TitleGetViewStates(myId)
{
	var me = document.getElementById(myId);

	var i = document.getElementById(me.getAttribute("forwardTarget"));
	eval(i.getAttribute("GetViewStates"));
}

function TitleSet(myId, property)
{
	var me = document.getElementById(myId);
	
	if (property == "text")
	{	
		while(me.hasChildNodes())
		{
			me.removeChild(me.lastChild);
		}
		ParseHtmlTo(me, DSCurrentData);
		TitleDoAllignment(me);
	}
}


function NotitiePageDoLayout(myId)
{
	var me = document.getElementById(myId);
	
	me.style.overflow = "auto";
	me.style.width = "0px";
	me.style.height = "1px"; //We cannot set the height to 0
	me.style.width = PixelToStr(DSLayoutWidth - me.offsetWidth);
	me.style.height = PixelToStr(DSLayoutHeight - (me.offsetHeight - 1));
	
}

function NotitiePageGetViewStates(myId)
{
	var me = document.getElementById(myId);

	me.innerHTML = "";
	AddNewBusy(me);
}

function NotitiePageSet(myId, property)
{
	var me = document.getElementById(myId);
	
	if (property == "text")
	{	
		me.innerHTML = DSCurrentData;
	}
}


function InfoPageDoLayout(myId)
{
	var me = document.getElementById(myId);
    
	me.style.width = PixelToStr(DSLayoutWidth);
	me.style.height = PixelToStr(DSLayoutHeight);
	
	var inner = document.getElementById(myId + "_inner");
	if (inner.firstChild != null && inner.firstChild.className == "DSipEMTest")
	{
		InfoPageLayoutInner(inner);
	}
	
}

function InfoPageGetViewStates(myId)
{
	var inner = document.getElementById(myId + "_inner");
	inner.innerHTML = "";
	AddNewBusy(inner);
}

function InfoPageSet(myId, property)
{
	var me = document.getElementById(myId);
	
	if (property == "inner")
	{	
		var inner = document.getElementById(myId + "_inner");
		inner.innerHTML = DSCurrentData;
		InfoPageLayoutInner(inner);
	}
}

function InfoPageLayoutInner(inner)
{
	var emWidth = inner.firstChild.offsetWidth / 1.6;
	var emHeight = inner.firstChild.offsetHeight;
	inner.removeChild(inner.firstChild);
	
	row = inner.firstChild.firstChild.firstChild;
	while (row != null)
	{
		var left = 0;
		for (var i = 1; i < row.childNodes.length; i += 2)
		{
			var field = row.childNodes[i];
			var digits = field.getAttribute("digits");
			if (field.firstChild.className != "DSipBoolean")
			{
				var fieldW = digits * emWidth + 0.9;
				var fieldH = emHeight * 2; 
				var img = field.firstChild.firstChild;
				if (img.tagName == "IMG")
				{
					img.onload = function()
					{
						var imgW =  img.offsetWidth;
						var imgH = img.offsetHeight;
						var scale = Math.min(isFinite(fieldW / imgW) ? (fieldW / imgW) : 1,
											 isFinite(fieldH / imgH) ? (fieldH / imgH) : 1);
						if (scale < 1)
						{
							alert (PixelToStr(Math.round(imgW * scale)) + ";" + PixelToStr(Math.round(imgH * scale)));
							img.style.width = PixelToStr(Math.round(imgW * scale));
							img.style.height = PixelToStr(Math.round(imgH * scale));
						}
						img.onload = null;
					}
					field.firstChild.style.overflow = "hidden";
				}
				field.firstChild.style.width = PixelToStr(Math.round(fieldW));
				// height is controlld by the style sheets.
			}
		}
		row = row.nextSibling;
	}
}


function BorderDoLayout(myId)
{
	var me = document.getElementById(myId);
	var h = DSLayoutHeight;
	var w = DSLayoutWidth;
	
	var headContainer = document.getElementById(myId + "_Head");
	var bodyContainer = document.getElementById(myId + "_Body");
	
	headContainer.style.overflow = "auto";
	bodyContainer.style.overflow = "auto";
	
	if (me.getAttribute("horizontal") != null)
	{
		DSLayoutHeight = -1;
	}
	else
	{
		DSLayoutWidth = -1;
	}
	eval(headContainer.firstChild.getAttribute("doLayout"));

	if (me.getAttribute("horizontal") != null)
	{
		headContainer.style.width = PixelToStr(w);
		headContainer.style.height = PixelToStr(headContainer.firstChild.offsetHeight);
		DSLayoutHeight = h - headContainer.offsetHeight;
	}
	else
	{
		headContainer.style.height = PixelToStr(h);
		headContainer.style.width = PixelToStr(headContainer.firstChild.offsetWidth);
		DSLayoutWidth = w - headContainer.offsetWidth;
	}
	
	bodyContainer.style.width = PixelToStr(DSLayoutWidth);
	bodyContainer.style.height = PixelToStr(DSLayoutHeight);
	
	var t = bodyContainer.firstChild.getAttribute("doLayout");
	if (t != null)
	{
		eval(t);
	}
}

function BorderGetViewStates(myId)
{
	var me = document.getElementById(myId);

	var i = document.getElementById(me.getAttribute("headPanel"));
	eval(i.getAttribute("GetViewStates"));
}


function ThreeWayPanelDoLayout(myId)
{
	var me = document.getElementById(myId);
	var h = DSLayoutHeight;
	var w = DSLayoutWidth;
	
	var headContainer = document.getElementById(myId + "_Head");
	var bodyContainer = document.getElementById(myId + "_Body");
	
	headContainer.style.overflow = "auto";
	bodyContainer.style.overflow = "auto";
	
	DSLayoutHeight = -1;
	eval(headContainer.firstChild.getAttribute("doLayout"));

    headContainer.style.width = PixelToStr(w);
	headContainer.style.height = PixelToStr(headContainer.firstChild.offsetHeight);
	DSLayoutHeight = h - headContainer.offsetHeight;
	
	bodyContainer.style.width = DSLayoutWidth;
	bodyContainer.style.height = DSLayoutHeight;
	
	var t = bodyContainer.firstChild.getAttribute("doLayout");
	if (t != null)
	{
		eval(t);
	}
}

function ThreeWayPanelGetViewStates(myId)
{
	var me = document.getElementById(myId);

	var i = document.getElementById(me.getAttribute("headPanel"));
	eval(i.getAttribute("GetViewStates"));
	
	i = document.getElementById(me.getAttribute("leftPanel"));
	eval(i.getAttribute("GetViewStates"));

	i = document.getElementById(me.getAttribute("rightPanel"));
	eval(i.getAttribute("GetViewStates"));

}


function NotebookScrollLeftOnClick(myId)
{
	var me = document.getElementById(myId);
	var head = document.getElementById(me.id +"_head");
	var heads = head.firstChild;
	var headrow = document.getElementById(me.id + "_HR");
	var left = (heads.style.marginLeft.length == 0) ? 0 : ToPixel(heads.style.marginLeft);

	var i = 0;
	if (headrow.childNodes.length  == 0)
	{
		return;
	}
	var w = headrow.childNodes[i].offsetWidth;
	var l = left 
	while ((l + w) < 0)
	{
		i = i + 1;
		l = l + w;
		if (i >= headrow.childNodes.length)
		{
			w = 100000;
		}
		else
		{
			w = headrow.childNodes[i].offsetWidth; 
		}
	}
	w = - l;
		
	var newleft = left + w;
	if (newleft > 0)
	{
		newleft = 0;
	}
	heads.style.marginLeft = newleft + "px";	
}

function NotebookScrollRightOnClick(myId)
{
	var me = document.getElementById(myId);
	var head = document.getElementById(me.id +"_head");
	var heads = head.firstChild;
	var width = parseInt(head.getAttribute("scrollSpace"));
	var headrow = document.getElementById(me.id + "_HR");
	var left = (heads.style.marginLeft.length == 0) ? 0 : ToPixel(heads.style.marginLeft);
	
	var i = 0;
	if (headrow.childNodes.length == 0)
	{
		return;
	}
	var w = headrow.childNodes[i].offsetWidth; 
	var l = left;
	while ((l + w) <= 0)
	{
		i = i + 1;
		l = l + w;
		if (i >= headrow.childNodes.length)
		{
			w = 100000;
		}
		else
		{
			w = headrow.childNodes[i].offsetWidth; 
		}
	}
	
	var headrowwidth = 0;
	for (i = 0; i < headrow.childNodes.length; i++)
	{
	    headrowwidth = headrowwidth + headrow.childNodes[i].offsetWidth;
	}

	var newleft = left - w;
	if (newleft < (width - headrowwidth))
	{
		newleft = width - headrowwidth;
	}
	heads.style.marginLeft = newleft + "px";	
}

function NotebookScrollInToView(me, headnr)
{
	var head = document.getElementById(me.id +"_head");
	var heads = head.firstChild;
	var width = parseInt(head.getAttribute("scrollSpace"));
	var headrow = document.getElementById(me.id + "_HR");
	var left = (heads.style.marginLeft.length == 0) ? 0 : ToPixel(heads.style.marginLeft);
	
	var minleft;
	var maxleft;
	var i = 0;
	if (headrow.childNodes.length == 0)
	{
		return;
	}
	var w = 0; 
	var l = 0;
	for (i = 0; i < headnr; i++)
	{
	    l = l + headrow.childNodes[i].offsetWidth;
	}
    minleft = - l;
    maxleft = width - (l + headrow.childNodes[headnr].offsetWidth);

	var newleft = left;
	if (newleft > maxleft)
	{
	    newleft = maxleft;
	}
	if (newleft < minleft)
	{
	    newleft = minleft;
	}
	heads.style.marginLeft = newleft + "px";	
}

function NotebookScrollerDownLeft(e)
{
	var source;
	if (e == null)
	{
		e = window.event;
		NotebookScrollerEventSource = e.srcElement;
	}
	else
	{
		NotebookScrollerEventSource = e.target;
	}
	NotebookScrollerUp();
	NotebookScrollLeftOnClick(NotebookScrollerEventSource.getAttribute("parentId"));
	NotebookScrollerEventTimeout = setTimeout("NotebookScrollerTimeoutLeft();", 500);
}

function NotebookScrollerTimeoutLeft()
{
	NotebookScrollLeftOnClick(NotebookScrollerEventSource.getAttribute("parentId"));
	NotebookScrollerEventTimeout = setTimeout("NotebookScrollerTimeoutLeft();", 100);
}

function NotebookScrollerDownRight(e)
{
	var source;
	if (e == null)
	{
		e = window.event;
		NotebookScrollerEventSource = e.srcElement;
	}
	else
	{
		NotebookScrollerEventSource = e.target;
	}
	NotebookScrollerUp();
	NotebookScrollRightOnClick(NotebookScrollerEventSource.getAttribute("parentId"));
	NotebookScrollerEventTimeout = setTimeout("NotebookScrollerTimeoutRight();", 500);
}

function NotebookScrollerTimeoutRight()
{
	NotebookScrollRightOnClick(NotebookScrollerEventSource.getAttribute("parentId"));
	NotebookScrollerEventTimeout = setTimeout("NotebookScrollerTimeoutRight();", 100);
}

function NotebookScrollerUp()
{
	if (NotebookScrollerEventTimeout != null)
	{
		clearTimeout(NotebookScrollerEventTimeout);
		NotebookScrollerEventTimeout = null;
	}
}

function AddScrollerEvents(btn, direction)
{
	if (direction == "Left")
	{
		btn.onmousedown = NotebookScrollerDownLeft;
	}
	else
	{
		btn.onmousedown = NotebookScrollerDownRight;
	}	
	btn.onmouseout = NotebookScrollerUp;
	btn.onmouseleave = NotebookScrollerUp;
	btn.onmouseup = NotebookScrollerUp;
}

function NotebookOnclick(event)
{
    var myId = this.getAttribute("myId");
   	var head = document.getElementById(myId + "_head");
   	head.focus();
    NotebookSwitch(myId, this.parentNode.cellIndex + "");
  	document.getElementById(myId + "_head").focus();
  	return false;

}

function NotebookKeydown(e)
{
	var source;
	if (e == null)
	{
		e = window.event;
		source = e.srcElement;
	}
	else
	{
		source = e.target;
	}
	
	var head = source;
	while (head.className.indexOf('DSnbHead DS') < 0)
	{
	    head = head.parentNode;
	    if (head == null)
	    {
	        return;
	    }
	}
	var me = head;
	while (me.className != 'DSnbMain')
	{
	    me = me.parentNode;
	}
	
	var tab = me.getAttribute("CurrentTab");
	if (tab != "N")
	{
	    tab = parseInt(tab);
        var tabHeadRow = document.getElementById(me.id + "_HR");
	    if (e.keyCode == 39) {
	        if (tab < (tabHeadRow.childNodes.length - 1))
	        {   
               NotebookSwitch(me.id, tab + 1);
	        }
	    }
	    if (e.keyCode == 37) {
	        if (tab > 0)
	        {   
               NotebookSwitch(me.id, tab - 1);
	        }
	    }
	}
}

function NotebookOnblur(e)
{
	var source;
	if (e == null)
	{
		e = window.event;
		source = e.srcElement;
	}
	else
	{
		source = e.target;
	}
	
	var head = source;
	while (!containsClass(head, 'DSnbHead'))
	{
	    head = head.parentNode;
	    if (head == null)
	    {
	        return;
	    }
	}
	replaceClass(head, "DSnbFocus", "DSnbBlur")
}

function NotebookOnfocus(e)
{
	var source;
	if (e == null)
	{
		e = window.event;
		source = e.srcElement;
	}
	else
	{
		source = e.target;
	}
	
	var head = source;
	while (!containsClass(head, 'DSnbHead'))
	{
	    head = head.parentNode;
	    if (head == null)
	    {
	        return;
	    }
	}
	replaceClass(head, "DSnbBlur", "DSnbFocus")
}

function NotebookAddHeaderEvents(me)
{
	var tabHeadRow = document.getElementById(me.id + "_HR");
	for (var i = 0; i < tabHeadRow.childNodes.length; i++)
	{
	    var tabHead = tabHeadRow.childNodes[i].firstChild;
	    tabHead.setAttribute("myId", me.id);
	    tabHead.onclick = NotebookOnclick;
	}
	var head = document.getElementById(me.id +"_head");
    head.onkeydown = NotebookKeydown;
    head.onfocus = NotebookOnfocus;
    head.onblur = NotebookOnblur;
    
	var scroller = document.getElementById(me.id +"_scroller");
	AddScrollerEvents(scroller.firstChild, "Left");
	AddScrollerEvents(scroller.lastChild, "Right");
}

function NotebookDoLayout(myId)
{
	var me = document.getElementById(myId);
	
	me.style.overflow = "hidden";
	me.style.margin = "0px";
	me.style.width = PixelToStr(DSLayoutWidth);
	me.style.height = PixelToStr(DSLayoutHeight);

	var head = document.getElementById(me.id +"_head");
	var scroller = document.getElementById(me.id +"_scroller");
	
	var headHeight = head.offsetHeight;
	head.style.overflow = "hidden";
	head.style.width = PixelToStr(DSLayoutWidth);
	head.style.height = PixelToStr(headHeight);
	var heads = head.firstChild;
	if (heads.firstChild.firstChild.offsetWidth > DSLayoutWidth)
	{
		scroller.style.height = PixelToStr(headHeight);
		var scrollerWidth = scroller.firstChild.offsetWidth + scroller.lastChild.offsetWidth;
		scroller.parentNode.style.marginLeft =  ( -scrollerWidth) + "px";
		scroller.parentNode.style.width = PixelToStr(scrollerWidth);
		scroller.parentNode.style.marginTop = ( -headHeight) + "px";
		scroller.parentNode.style.height = PixelToStr(headHeight);
		head.setAttribute("scrollSpace", DSLayoutWidth - scrollerWidth); 
	}
	else
	{
		scroller.parentNode.style.marginLeft = PixelToStr(0);
		scroller.parentNode.style.width = PixelToStr(0);
		scroller.parentNode.style.marginTop = ( -headHeight) + "px";
		scroller.parentNode.style.height = PixelToStr(headHeight);
		head.style.width = PixelToStr(DSLayoutWidth);
        heads.style.marginLeft = "0px";
		head.setAttribute("scrollSpace", DSLayoutWidth); 
   	}
   	
   	var upperEdge = document.getElementById(me.id + "_upperEdge");
   	upperEdge.style.marginBottom = (- headHeight) + "px";
   	upperEdge.style.marginTop = (headHeight - upperEdge.offsetHeight) + "px";
	upperEdge.style.marginLeft = "0px";
	upperEdge.style.marginRight = "0px";
	
	var tab = me.getAttribute("CurrentTab");
	if (tab != "N")
	{
		DSLayoutHeight = DSLayoutHeight - headHeight;
		if (DSLayoutHeight < 0)
		{
			DSLayoutHeight = 0;
		}
		
		var tabPage = document.getElementById(me.id + "_tab" + tab);
		NotebookLayoutTab(tabPage, DSLayoutWidth, DSLayoutHeight);
	}
}

function NotebookLayoutTab(tabPage, w, h)
{
	var body = tabPage.firstChild; //DIV.DIV;
	if (body == null || body.tagName != "DIV")
	{
		return;
	}
	
	var container = tabPage.parentNode //DIV.DIV
	
	if (w != 0 || h != 0)
	{
		w = w - 3 - 3 - 4;//(container.offsetWidth - container.clientWidth);
		h = h - 3 - 3 - 2;//(container.offsetHeight - container.clientHeight);
		if (w >= 0 || h >= 0)
		{
	    	container.style.height = PixelToStr(h);
	    	container.style.width = PixelToStr(w);	
	    	container.style.overflow = "hidden";
            
			body.style.display = "block";
			body.style.overflow = "auto";
			body.style.height = PixelToStr(h);
			body.style.width = PixelToStr(w);	

			DSLayoutWidth = w;
			DSLayoutHeight = h;
			var fc = body.firstChild;
			// fc could also be a busy img so check fc.getAttribute
			if (fc != null && fc.getAttribute != null)
			{
				var t = fc.getAttribute("doLayout");
				if (t != null)
				{
					eval(t);
				}
			}
			return;
		}
	}
	
	body.style.display = "none";
}

function NotebookSetViewState(myId)
{
	var me = document.getElementById(myId);
	
	if (me.getAttribute("viewState") == null)
	{
	    NotebookAddHeaderEvents(me);
	}
	else
	{
		var tabPage = document.getElementById(me.id + "_tab" + "0");
		while (tabPage != null)
		{
			if (tabPage.getAttribute("loadState") == "valid")
			{
				tabPage.setAttribute("loadState", "invalid");
			}
			tabPage = tabPage.nextSibling;
		}
	}
	me.setAttribute("viewState", DSCurrentData);
}

function NotebookGetViewStates(myId)
{
	var me = document.getElementById(myId);

	var tab = me.getAttribute("CurrentTab");
	DSCurrentRequestContext.AddUnsecureVS(me.id + "_tab", tab);
	
	if (tab != "N")
	{
		var tabPage = document.getElementById(me.id + "_tab" + tab);
		var i = document.getElementById(tabPage.getAttribute("DSComponent"));
		eval(i.getAttribute("GetViewStates"));
	}
}

function NotebookSet(myId, property)
{
	var me = document.getElementById(myId);
	
	if (property == "CurrentTab")
	{	
		var newTab = DSCurrentData;
		NotebookSetCurrentTab(me, newTab);
		var tabPage = document.getElementById(me.id + "_tab" + newTab);
		// Actualy the page isn't yet valid, but we know it will be valid soon and there is no other notebook code running when it is valid
		tabPage.setAttribute("loadState", "valid");
	}
	
	var TC = "TabContent";
	if (property.substr(0, TC.length) == TC)
	{
		var newtab = property.substr(TC.length);
		if (newtab != "N")
		{
			var tabPage = document.getElementById(me.id + "_tab" + newtab);
			while (tabPage.firstChild != null)
			{
			    tabPage.removeChild(tabPage.firstChild);
			}
	    	ParseHtmlTo(tabPage, DSCurrentData);
			tabPage.setAttribute("loadState", "valid");
		}
		NotebookSetCurrentTab(me, newtab);
	}
}

function NotebookSetCurrentTab(me, newtab)
{
	var tab = me.getAttribute("CurrentTab");
	if (tab != "N" && newtab != tab)
	{
		var tabPage = document.getElementById(me.id + "_tab" + tab);
		NotebookLayoutTab(tabPage, 0, 0);
		var tabHead = document.getElementById(me.id + "_HR").childNodes[parseInt(tab)].firstChild;
		replaceClass(tabHead, "DSnbActive", "DSnbInActive")
	}
	me.setAttribute("CurrentTab", newtab);
	if (newtab != "N")
	{
		var tabPage = document.getElementById(me.id + "_tab" + newtab);
		var tabHead = document.getElementById(me.id + "_HR").childNodes[parseInt(newtab)].firstChild;
	    var head = document.getElementById(me.id +"_head");
		replaceClass(tabHead, "DSnbInActive", "DSnbActive")
		NotebookLayoutTab(tabPage, ToPixel(me.style.width), ToPixel(me.style.height) - head.offsetHeight);
	}
}

function NotebookSwitch(myId, newTab)
{
	var me = document.getElementById(myId);
	var tab = me.getAttribute("CurrentTab");
	NotebookScrollInToView(me, parseInt(newTab))
	if (newTab == tab)
	{
		return;
	}
	
	var tabPage = document.getElementById(me.id + "_tab" + newTab);
	var loadState = tabPage.getAttribute("loadState");
	
	if (loadState != "valid")
	{
	    var rc;
		if (loadState == "invalid")
		{
    	    rc = new RequestContext(me.id, target);
			NotebookSetCurrentTab(me, newTab);
			var target = tabPage.getAttribute("DSComponent");
			var i = document.getElementById(target);
			rc.AddUnsecureVS(me.id + "_call", "ConstraintOnly");
			eval(i.getAttribute("GetViewStates"));
	
		}
		else if (loadState == "none")
		{
    	    rc = new RequestContext(me.id, me.id + "_new" + newTab);
    	    if (tabPage.firstChild == null || tabPage.firstChild.tagName != "DIV")
    	    {
				tabPage.appendChild(document.createElement("DIV"));
			}	
			AddNewBusy(tabPage.firstChild);
			NotebookSetCurrentTab(me, newTab);
			rc.AddUnsecureVS(me.id + "_call", "Render");
		}
		rc.AddSecureVS(me.getAttribute("viewState"));
		rc.AddUnsecureVS(me.id + "_tab", "" + newTab);
		rc.Fire();
	}
	else
	{
		NotebookSetCurrentTab(me, newTab);
	}
}


function SearchSelectionPanelDoLayout(myId)
{
	var me = document.getElementById(myId);
	
	var td2 = document.getElementById(myId + "_td2");
	td2.firstChild.onclick = SearchSelectionPanelOnClick;
    me.onkeydown = SearchSelectionPanelKeydown;
}

function SearchSelectionPanelGetViewStates(myId)
{
	var me = document.getElementById(myId);
	var td2 = document.getElementById(myId + "_td2");
	var target = td2.getAttribute("downTarget");
	if (target != null)
	{
		var i = document.getElementById(target);
		eval(i.getAttribute("GetViewStates"));
	}
}

function SearchSelectionPanelSetViewState(myId)
{
	var me = document.getElementById(myId);

	var td2 = document.getElementById(me.id + "_td2");
	td2.setAttribute("viewState", DSCurrentData)
}

function SearchSelectionPanelSet(myId, property)
{
	var me = document.getElementById(myId);
	
	if (property == "SearchDisabled")
	{	
		var td2 = document.getElementById(myId + "_td2");
		td2.firstChild.disabled = DSCurrentData == "true";
	}
}

function SearchSelectionPanelKeydown(e)
{
	var eOld = e;
	if (e == null)
	{
		e = window.event;
	}
	if (e.keyCode == 13) // Enter
	{
		return SearchSelectionPanelOnClick(eOld);
	}
}

function SearchSelectionPanelOnClick(e)
{
	var source;
	if (e == null)
	{
		e = window.event;
		source = e.srcElement;
	}
	else
	{
		source = e.target;
	}
	var fieldData = " #";
	if (e.ctrlKey)
	{
		fieldData = "F#";
	}
	
	var me = source;
	while (!me.className || me.className != "DSsspMain")
	{
		me = me.parentNode;
		if (me == null)
		{
			return;
		}
	}
	
	var td2 = document.getElementById(me.id + "_td2");
	if (td2.firstChild.disabled)
	{
		return;
	}
	
	var field = document.getElementById(me.id + "_td1").firstChild;
	while (field != null)
	{
	
		if (field.className == "DSsspWidget")
		{
			var input = field.firstChild;
			while(input != null)
			{
				if (input.type == "text")
				{
					fieldData = fieldData + ";" + StringMapEscape(input.value);
				}
				if (input.type == "select-one")
				{
					fieldData = fieldData + ";" + input.selectedIndex;
				}
				input = input.nextSibling;
			}
		}
		field = field.nextSibling;
	}
	
	var target = td2.getAttribute("downTarget");
	if (target != null)
	{
		var i = document.getElementById(target);
	    var rc = new RequestContext(me.id, target);
		eval(i.getAttribute("GetViewStates"));
		rc.AddSecureVS(td2.getAttribute("viewState"));
		rc.AddSecureVS(td2.getAttribute("fieldsState"))
		rc.AddUnsecureVS(me.id + "_fieldData", fieldData);
		rc.Fire();
	}
	if (e.preventDefault)
    {
		e.preventDefault();
	}
    e.returnValue = false;
    return false;
}


function IndicatorDoLayout(myId)
{
	var me = document.getElementById(myId);
	
	me.style.width = PixelToStr(DSLayoutWidth);
	me.style.height = PixelToStr(DSLayoutHeight);
	me.style.overflow = "hidden";
	
	var img = document.getElementById(me.getAttribute("image"));
	
	if (img != null)
	{
		img.style.width = PixelToStr(DSLayoutWidth);
		img.style.height = PixelToStr(DSLayoutHeight);
	}
}

function IndicatorGetViewStates(myId)
{
	var me = document.getElementById(myId);
	var img = document.getElementById(me.getAttribute("image"));
	if (img != null)
	{
		me.setAttribute("image", null);
		me.removeChild(img);
	}
	AddNewBusy(me);
}

function IndicatorSetViewState(myId)
{
	var me = document.getElementById(myId);

}

function IndicatorSet(myId, property)
{
	var me = document.getElementById(myId);
	
	if (property == "imageId")
	{	
		var img = document.getElementById(me.getAttribute("image"));
		if (img != null)
		{
			me.removeChild(img);
		}
		img = document.createElement("IMG");
		img.id = me.id + "_img";
		me.appendChild(img);
		me.setAttribute("image", img.id);
		
		var url = DSHttpRequestUrlBase + "xx=custom&id=" + DSCurrentData;
		url += "&w=" + ToPixel(me.style.width);
		url += "&h=" + ToPixel(me.style.height);
		img.src = url;
		
		if (me.getAttribute("clickTarget") != null)
		{
			img.onclick = IndicatorOnClick;
		}
		img.style.width = me.style.width;
		img.style.height = me.style.height;
/*		// HACK: IE does not invalidate the width and heigth of an image properly
		var w = me.offsetWidth;
		var h = me.style.height;
		me.style.height = "";
		me.style.height = h;
*/	}
}

function IndicatorOnClick(e)
{
	me = this.parentNode;
	var target = me.getAttribute("clickTarget");
	if (target != null)
	{
	    var rc = new RequestContext(me.id, target);
		var i = document.getElementById(target);
		var viewStates = eval(i.getAttribute("GetViewStates"));
		rc.Fire();
	}
}



function GraphDoLayout(myId)
{
	var me = document.getElementById(myId);
	
	var innerw = GraphToInnerWidth(me, DSLayoutWidth)
	var innerh = GraphToInnerHeight(me, DSLayoutHeight);
	me.setAttribute("innerw", innerw);
	me.setAttribute("innerh", innerh);
	
	me.style.width = PixelToStr(DSLayoutWidth);
	me.style.height = PixelToStr(DSLayoutHeight);
	if (me.offsetWidth != DSLayoutWidth)
	{
	    me.style.width = PixelToStr(innerw);
	}
	if (me.offsetHeight != DSLayoutHeight)
	{
	    me.style.height = PixelToStr(innerh);
	}
	me.style.overflow = "hidden";

	var img = document.getElementById(me.getAttribute("image"));
	if (img != null)
	{
	    GraphScaleImage(img, innerw, innerh);
    }
}

function GraphScaleImage(img, w, h)
{
	img.style.width = PixelToStr(w);
	img.style.height = PixelToStr(h);
	
    var map = document.getElementById(img.useMap.substring(1));
    if (map == null)
    {
        return;
    }
    var area = map.firstChild;
	while (area != null)
	{
	    var fractCoords = area.getAttribute("fractCoords").split(";");
		var sep = "";
		var Coords = "";
	   	for (j = 0; j < 4; j++)
		{
		    Coords = Coords + sep + Math.round(parseFloat(fractCoords[j]) * ((j % 2) == 0 ? w : h));
		    sep = ",";
		}
        area.coords = Coords;
		area = area.nextSibling;
	}
}

function GraphGetViewStates(myId)
{
	var me = document.getElementById(myId);
	var img = document.getElementById(me.getAttribute("image"));
	if (img != null)
	{
		me.setAttribute("image", null);
		me.removeChild(img);
	}
	AddNewBusy(me);
}

function GraphSetViewState(myId)
{
	var me = document.getElementById(myId);
	var innerw = parseInt(me.getAttribute("innerw"));
	var innerh = parseInt(me.getAttribute("innerh"));
	me.setAttribute("orgWidth", innerw);
	me.setAttribute("orgHeight", innerh);
	var rc = new RequestContext(me.id, me.id + "_img");
	rc.AddUnsecureVS(me.id + "_size", innerw + "," + innerh);
	rc.AddSecureVS(DSCurrentData);
	rc.Fire();
}

function GraphToInnerWidth(me, w)
{
    return w - ToPixel(getStyle(me, "padding-left")) - ToPixel(getStyle(me, "padding-right"));
}

function GraphToInnerHeight(me, h)
{
    return h - ToPixel(getStyle(me, "padding-top")) - ToPixel(getStyle(me, "padding-bottom"));
}

function GraphSet(myId, property)
{
	var me = document.getElementById(myId);
	
	if (property == "imageId")
	{	
		var img = document.getElementById(me.getAttribute("image"));
		if (img != null)
		{
			me.removeChild(img);
		}
		img = document.createElement("IMG");
		img.id = me.id + "_img";
		me.appendChild(img);
		me.setAttribute("image", img.id);
		
		var url = DSHttpRequestUrlBase + "xx=custom&id=" + DSCurrentData;
		img.src = url;
		img.style.width = PixelToStr(parseInt(me.getAttribute("innerw")));
		img.style.height = PixelToStr(parseInt(me.getAttribute("innerh")));
	}
	else if (property == "hitTests")
	{
		var map = document.getElementById(myId + "_Map");
		var img = document.getElementById(me.getAttribute("image"));
		
		var orgw = parseInt(me.getAttribute("orgWidth"));
		var orgh = parseInt(me.getAttribute("orgHeight"));
		
		var i = map.firstChild;
		while (i != null)
		{
			var temp = i;
			i = temp.nextSibling;
			map.removeChild(temp);
		}

		var areas = DSCurrentData.split(";");
		for (i = 0; i < areas.length; i++)
		{
			var area = document.createElement("AREA");
			var prop = areas[i].split("=", 2);
			area.title = prop[0];
			area.coords = prop[1];
			var cos = prop[1].split(",");
			var sep = "";
			var fractCoords = "";
			for (j = 0; j < 4; j++)
			{
			    fractCoords = fractCoords + sep + (parseInt(cos[j]) / ((j % 2) == 0 ? orgw : orgh));
			    sep = ";";
			}
			area.setAttribute("fractCoords", fractCoords);
			area.shape = "rect";
			area.setAttribute("nr", i);
			area.href = "#";
			if (me.getAttribute("clickTarget") != null)
			{
				area.onclick = GraphOnClick;
			}
			else
			{
				area.onclick = function (e)
				{
					return false;
				};
			}
			map.appendChild(area);
		}
		img.useMap = "#" + map.name;
		
		if (img.offsetWidth != orgw || img.offsetHeight != orgh)
		{
		    GraphScaleImage(img, img.offsetWidth, img.offsetHeight)
		}
	}
	else if (property.substr(0, 1) == "c")
	{
		me.setAttribute(property, DSCurrentData);
	}
}

function GraphOnClick(e)
{
	var me = this.parentNode.parentNode;
	
	var target = me.getAttribute("clickTarget");
	if (target != null)
	{
   	    var rc = new RequestContext(me.id, target);
		var i = document.getElementById(target);
		eval(i.getAttribute("GetViewStates"));
		rc.AddSecureVS(me.getAttribute("c" + this.getAttribute("nr")));
		rc.Fire();
	}
	return false;
}

function PieDoLayout(myId)
{
	var me = document.getElementById(myId);
	
	var innerw = PieToInnerWidth(me, DSLayoutWidth)
	var innerh = PieToInnerHeight(me, DSLayoutHeight);
	me.setAttribute("innerw", innerw);
	me.setAttribute("innerh", innerh);
	
	me.style.width = PixelToStr(DSLayoutWidth);
	me.style.height = PixelToStr(DSLayoutHeight);
	me.style.lineHeight = me.style.height;
	if (me.offsetWidth != DSLayoutWidth)
	{
	    me.style.width = PixelToStr(innerw);
	}
	if (me.offsetHeight != DSLayoutHeight)
	{
	    me.style.height = PixelToStr(innerh);
	}
	me.style.overflow = "hidden";

	var chart = document.getElementById(me.getAttribute("chart"));
	var legend = document.getElementById(me.getAttribute("legend"));
	if (chart != null)
	{
	    PieScaleImage(chart, legend != null ? innerw - legend.offsetWidth : innerw, innerh);
    }
}

function PieScaleImage(img, w, h)
{
	if (h > w)
	{
		img.style.marginTop = PixelToStr((h - w) / 2);
		h = w;
	}
	else
	{
		img.style.marginTop = "auto";
	}
	img.style.width = PixelToStr(w);
	img.style.height = PixelToStr(h);
	
    var map = document.getElementById(img.useMap.substring(1));
    if (map == null)
    {
        return;
    }
    var area = map.firstChild;
	while (area != null)
	{
	    var fractCoords = area.getAttribute("fractCoords").split(";");
		var sep = "";
		var Coords = "";
	   	for (j = 0; j < fractCoords.length; j++)
		{
		    Coords = Coords + sep + Math.round(parseFloat(fractCoords[j]) * ((j % 2) == 0 ? w : h));
		    sep = ",";
		}
        area.coords = Coords;
		area = area.nextSibling;
	}
}

function PieGetViewStates(myId)
{
	var me = document.getElementById(myId);
	var chart = document.getElementById(me.getAttribute("chart"));
	if (chart != null)
	{
		me.setAttribute("chart", null);
		me.removeChild(chart);
	}
	var legend = document.getElementById(me.getAttribute("legend"));
	if (legend != null)
	{
		me.setAttribute("legend", null);
		me.removeChild(legend);
	}
	AddNewBusy(me);
}

function PieSetViewState(myId)
{
	var me = document.getElementById(myId);
	me.setAttribute("viewState", DSCurrentData); 
	var innerw = parseInt(me.getAttribute("innerw"));
	var innerh = parseInt(me.getAttribute("innerh"));
	var rc = new RequestContext(me.id, me.id + "_img");
	rc.AddUnsecureVS(me.id + "_size", innerw + "," + innerh);
	rc.AddSecureVS(DSCurrentData);
	var colorMap = me.getAttribute("colorMap");
	if (colorMap != null)
	{
		rc.AddSecureVS(colorMap);
	}
	rc.Fire();
}

function PieToInnerWidth(me, w)
{
    return w - ToPixel(getStyle(me, "padding-left")) - ToPixel(getStyle(me, "padding-right"));
}

function PieToInnerHeight(me, h)
{
    return h - ToPixel(getStyle(me, "padding-top")) - ToPixel(getStyle(me, "padding-bottom"));
}

function PieSet(myId, property)
{
	var me = document.getElementById(myId);
	
	if (property == "LegendName")
	{	
		var legend = document.getElementById(me.getAttribute("legend"));
		if (legend != null)
		{
			me.removeChild(legend);
		}
		if (DSCurrentData.length > 0)
		{
			legend = document.createElement("IMG");
			legend.id = me.id + "_legend";
			legend.className = "DSpieLegend";
			legend.style.float = "right";
			legend.style.verticalAlign = "top";
			me.insertBefore(legend, document.getElementById(me.id + "_MapC"));
			me.setAttribute("legend", legend.id);
		
			var url = DSHttpRequestUrlBase + "xx=custom&id=" + DSCurrentData;
			legend.src = url;
			legend.onload = function()
			{
				var chart = document.getElementById(me.getAttribute("chart"));
				if (chart != null)
				{
				    PieScaleImage(chart, parseInt(me.getAttribute("innerw")) - legend.offsetWidth, parseInt(me.getAttribute("innerh")));
				}
			}
		}
	}
	else if (property == "HitTestsLegend")
	{
		var mapL = document.getElementById(myId + "_MapL");
		var legend = document.getElementById(me.getAttribute("legend"));
		
		var i = mapL.firstChild;
		while (i != null)
		{
			var temp = i;
			i = temp.nextSibling;
			mapL.removeChild(temp);
		}

		var areas = DSCurrentData.split(";");
		for (i = 0; i < areas.length; i++)
		{
			var area = document.createElement("AREA");
			var prop = areas[i].split("=", 2);
			area.title = prop[0];
			area.coords = prop[1];
			area.shape = "rect";
			area.setAttribute("nr", i);
			area.href = "#";
			if (me.getAttribute("clickTarget") != null)
			{
				area.onclick = PieOnClick;
			}
			else
			{
				area.onclick = function (e)
				{
					return false;
				};
			}
			mapL.appendChild(area);
		}
		legend.useMap = "#" + mapL.name;
	}
	else if (property == "ChartName")
	{	
		var chart = document.getElementById(me.getAttribute("chart"));
		var legend = document.getElementById(me.getAttribute("legend"));
		if (chart != null)
		{
			me.removeChild(chart);
		}
		if (DSCurrentData.length > 0)
		{
			chart = document.createElement("IMG");
			chart.id = me.id + "_chart";
			chart.className = "DSpieChart";
			chart.style.float = "left";
			me.insertBefore(chart, me.firstChild);
			me.setAttribute("chart", chart.id);
		
			var url = DSHttpRequestUrlBase + "xx=custom&id=" + DSCurrentData;
			chart.src = url;
			if (document.getElementById(me.id + "_MapL") != null)
			{
				if (legend != null)
				{
				    PieScaleImage(chart, parseInt(me.getAttribute("innerw")) - legend.offsetWidth, parseInt(me.getAttribute("innerh")));
				}
			}
			else
			{
			    PieScaleImage(chart, parseInt(me.getAttribute("innerw")), parseInt(me.getAttribute("innerh")));
			}
		}
	}
	else if (property == "OriginalSize")
	{
		var size = DSCurrentData.split(",", 2);
		me.setAttribute("orgWidth", size[0]);
		me.setAttribute("orgHeight", size[1]);
	}
	else if (property == "HitTestsChart")
	{
		if (DSCurrentData.length > 0)
		{
			var mapC = document.getElementById(myId + "_MapC");
			var chart = document.getElementById(me.getAttribute("chart"));
		
			var orgw = parseInt(me.getAttribute("orgWidth"));
			var orgh = parseInt(me.getAttribute("orgHeight"));
		
			var i = mapC.firstChild;
			while (i != null)
			{
				var temp = i;
				i = temp.nextSibling;
				mapC.removeChild(temp);
			}

			var areas = DSCurrentData.split(";");
			for (i = 0; i < areas.length; i++)
			{
				var area = document.createElement("AREA");
				var prop = areas[i].split("=", 2);
				area.title = prop[0];
				area.shape = "poly";
				area.coords = prop[1];
				var cos = prop[1].split(",");
				var sep = "";
				var fractCoords = "";
				for (j = 0; j < cos.length; j++)
				{
				    fractCoords = fractCoords + sep + (parseInt(cos[j]) / ((j % 2) == 0 ? orgw : orgh));
					sep = ";";
				}
				area.setAttribute("fractCoords", fractCoords);
				area.setAttribute("nr", i);
				area.href = "#";
				if (me.getAttribute("clickTarget") != null)
				{
					area.onclick = PieOnClick;
				}
				else
				{
					area.onclick = function (e)
					{
						return false;
					};
				}
				mapC.appendChild(area);
			}
			chart.useMap = "#" + mapC.name;
			if (chart.offsetWidth != orgw || chart.offsetHeight != orgh)
			{
				if (document.getElementById(me.id + "_MapL") != null)
				{
					if (legend != null)
					{
					PieScaleImage(chart, parseInt(me.getAttribute("innerw")) - legend.offsetWidth, parseInt(me.getAttribute("innerh")));
					}
				}	
				else
				{
				    PieScaleImage(chart, parseInt(me.getAttribute("innerw")), parseInt(me.getAttribute("innerh")));
				}
			}
		}
	}
	else if (property == "Values" || property == "colorMap")
	{
		me.setAttribute(property, DSCurrentData);
	}
}

function PieOnClick(e)
{
	var me = this.parentNode.parentNode;
	
	var target = me.getAttribute("clickTarget");
	if (target != null)
	{
   	    var rc = new RequestContext(me.id, target);
		var i = document.getElementById(target);
		var viewStates = eval(i.getAttribute("GetViewStates"));
		rc.AddSecureVS(me.getAttribute("Values"));
		rc.AddSecureVS(me.getAttribute("viewState"));
		rc.AddUnsecureVS(me.id + "_nr", this.getAttribute("nr"));
		rc.Fire();
	}
	return false;
}


function FilterDeckSet(myId, property)
{
	var me = document.getElementById(myId);
	var TC = "TabContent";
	if (property == "newTab")
	{
		var newTab = parseInt(DSCurrentData);
		if (newTab >= 0)
		{
			var loadState = me.childNodes[newTab].getAttribute("loadState");
		
			var rc = new RequestContext(me.id, me.id + "_tab" + newTab);
			rc.AddUnsecureVS(me.id + "tabState", loadState);
			rc.AddUnsecureVS(me.id + "tab", newTab);
			rc.AddSecureVS(me.getAttribute("viewState"));
			if (loadState != "none")
			{
				var tab = me.childNodes[newTab];
				FilterDeckShowTab(me, tab);
				tab.setAttribute("loadState", "invalid");
				var target = tab.getAttribute("DSComponent");
				var i = document.getElementById(target);
				eval(i.getAttribute("GetViewStates"));
			}
			rc.Fire();
		}
	}
	else if (property == "currentTab")
	{
		var currentTab = DSCurrentData;
		var newTab = parseInt(currentTab);
		var tab = me.childNodes[newTab];
		FilterDeckShowTab(me, tab);
	}
	else if (property.substr(0, TC.length) == TC)
	{
		var currentTab = property.substr(TC.length);
		var newTab = parseInt(currentTab);
		var tab = me.childNodes[newTab];
		while (tab.hasChildNodes())
		{
			tab.removeNode(tab.lastChild);
		}
  	    ParseHtmlTo(tab, DSCurrentData);
		FilterDeckShowTab(me, tab);
	}
}

function FilterDeckShowTab(me, tab)
{
	if (tab.style.display != "block")
	{
		var child = me.firstChild;
		while (child != null)
		{
			child.style.display = "none";
			child = child.nextSibling;
		}
	}
	tab.style.display = "block";
	tab.setAttribute("loadState", "valid");
	DSLayoutWidth = parseInt(me.getAttribute("layoutWidth"));
	DSLayoutHeight = parseInt(me.getAttribute("layoutHeight"));
	FilterDeckDoLayout(me.id);
}

function FilterDeckGetViewStates(myId)
{
	var me = document.getElementById(myId);
	var currentTab = FilterDeckGetCurrentTab(me);
	
	DSCurrentRequestContext.AddUnsecureVS(me.id + "currentTab", currentTab);

	var tab = me.childNodes[currentTab];
	tab.setAttribute("loadState", "invalid");
	var target = tab.getAttribute("DSComponent");
	var i = document.getElementById(target);
	eval(i.getAttribute("GetViewStates"));
}

function FilterDeckGetCurrentTab(me)
{
	for (var i = 0; i < me.childNodes.length; i++)
	{
		var child = me.childNodes[i];
		if (child.style.display == "block" && child.getAttribute && child.getAttribute("DSComponent") != null)
		{
			return i;
		}
	}
	return -1;
}

function FilterDeckDoLayout(myId)
{
	var me = document.getElementById(myId);
	me.setAttribute("layoutWidth", DSLayoutWidth);
	me.setAttribute("layoutHeight", DSLayoutHeight);
	
	var tab = FilterDeckGetCurrentTab(me);
	if (tab >= 0)
	{
		var fc = me.childNodes[tab].firstChild;
		// fc could also be a busy img so check fc.getAttribute
		if (fc != null && fc.getAttribute != null)
		{
			var t = fc.getAttribute("doLayout");
			if (t != null)
			{
				eval(t);
			}
		}
	}
}

function FilterDeckSetViewState(myId)
{
	var me = document.getElementById(myId);
	me.setAttribute("viewState", DSCurrentData); 
}


function AddNewBusy(node)
{
	RemoveAllBusiesFrom(node);
	
	DSCurrentRequestContext.busyList.add(node);
}

function RemoveAllBusiesFrom(elem)
{
	var i = elem.firstChild;
	while (i != null)
	{
		var temp = i;
		i = temp.nextSibling;
		if (temp.tagName == "IMG" && temp.getAttribute("IsBusy") == "true")
		{
		    elem.removeChild(temp);
		}
	}
}

//private (used by BusyList)
function BusyItem(elem, n)
{
	this.link = elem;
	this.next = n;
}

//private
function BusyList(rc)
{
	this.requestContext = rc;
	this.clear = function()
	{
		if (this.timer == null)
		{
			return;
		}
		clearTimeout(this.timer);
		this.timer = null;
		
		if (this.putted)
		{
			var ll = this.items;
			while (ll != null)
			{
				RemoveAllBusiesFrom(ll.link);
				ll = ll.next;
			}
		}
		this.items = null;
	}
	
	this.add = function(elem)
	{
		this.items = new BusyItem(elem, this.items);
	}
	
	this.items = null;
	this.putted = false;
	
	this.startTimer = function()
	{
		var me = this;
		this.timer = setTimeout(function()
		{
			me.putted = true;
			var ll = me.items;
			while (ll != null)
			{
				var img = document.createElement("IMG");
				img.src = document.getElementById("FactoryContainer").getAttribute("Busy");
				img.title = "Cancel";
				img.tabIndex = "0";
				img.setAttribute("IsBusy", "true");
				img.onclick = function()
				{
					if (httpRequestMap) 
						httpRequestMap.CancelHttpRequest(me.requestContext.name);
				}
				ll.link.appendChild(img);
			
				ll = ll.next;
			}
		}, 300);
	}
}

function StringMapEscape(s)
{
	return s.replace(/~/g, "~c").replace(/;/g, "~b").replace(/=/g, "~e");
}

function StringMapUnEscape(s)
{
	return s.replace(/~e/g, "=").replace(/~b/g, ";").replace(/~c/g, "~");
}

function Get_Cookie(name) {
	var cookies = document.cookie;
	if (cookies == null || cookies.length == 0)
	{
		return null;
	}
	var search = name + "=";
	offset = cookies.indexOf(search)
	if (offset < 0)
	{
		return null;
	}
	offset += search.length;
	end = cookies.indexOf(";", offset);
	if (end < 0)
	{
		end = cookies.length;
	}
	return cookies.substring(offset, end);
}

function ToPixel(val)
{
	var r = parseInt(val.substring(0, val.length -2));
	return isFinite(r) ? r : 0;
}

function PixelToStr(val)
{
	if (val > 0)
	{
		return val + "px";
	}
	return "0px";
}

/*
function OuterWidthToBorder(node, w)
{
    return w - ToPixel(node.currentStyle.marginLeft) - ToPixel(node.currentStyle.marginRight);
}

function OuterHeightToBorder(node, h)
{
    return h - ToPixel(node.currentStyle.marginTop) - ToPixel(node.currentStyle.marginBottom);
}
*/

/*
	Example call of the function:
	
	getStyle(document.getElementById("container"), "font-size");
*/

// The regular version
function getStyle(oElm, strCssRule){
	var strValue = "";
	if(document.defaultView && document.defaultView.getComputedStyle){
		strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule);
	}
	else if(oElm.currentStyle){
		strCssRule = strCssRule.replace(/\-(\w)/g, function (strMatch, p1){
			return p1.toUpperCase();
		});
		strValue = oElm.currentStyle[strCssRule];
	}
	return strValue;
}

function setOpacity(style, value)
{
	style.opacity = value/100;
	style.filter = 'alpha(opacity=' + value + ')';
}

function ParseHtmlTo(elem, html)
{
    var td = document.createElement("TD");
    td.innerHTML = html;
    var child = td.firstChild;
    while(child != null)
    {
		td.removeChild(child);
		elem.appendChild(child);
		child = td.firstChild;
    }
}

function replaceClass(elem, currentClass, newClass) 
{
    var c = elem.className.split(" ");
    var total = "";
    var delim = "";
    for (var i = 0; i < c.length; i++)
    {
		if (c[i] == currentClass)
		{
			total = total + delim + newClass;
		}
		else
		{
			total = total + delim + c[i];
		}
		delim = " ";	
	}
	elem.className = total;
}

function switchClass(elem, aClass)
{
    var c = elem.className.split(" ");
    var total = "";
    var delim = "";
    for (var i = 0; i < c.length; i++)
    {
		if (c[i] == aClass)
		{
			aClass = null;
		}
		else
		{
			total = total + delim + c[i];
			delim = " ";	
		}
	}
	if (aClass != null)
	{
		total = total + delim + aClass;
	}
	elem.className = total;
}

function containsClass(elem, className)
{
	if (!elem.className)
	{
		return false;
	}
    var c = elem.className.split(" ");
    for (var i = 0; i < c.length; i++)
    {
		if (c[i] == className)
		{
			return true;
		}
	}
	return false;
}

function addClasses(elem, classes)
{
    var add = classes.split(" ");
    var total = elem.className;
    var current = total.split(" ");
    var delim = total.length > 0 ? " " : "";
    var changed = false;
    for (var i = 0; i < add.length; i++)
    {
        var a = add[i];
        for (var j = 0; j < current.length; j++)
        {  
            if (a == current[j])
            {
                a = null;
                break;
            }
        }
        if (a != null)
        {
            changed = true;
            total += delim + a;
            delim = " ";
        }
    }
    if (changed)
    {
		elem.className = total;       
    }
}

function removeClasses(elem, classes)
{
    var rem = classes.split(" ");
    var total = "";
    var current = elem.className.split(" ");
    var delim = "";
    var changed = false;
    for (var i = 0; i < current.length; i++)
    {
        var c = current[i];
        for (var j = 0; j < rem.length; j++)
        {  
            if (c == rem[j])
            {
                c = null;
                changed = true;
                break;
            }
        }
        if (c != null)
        {
            total += delim + c;
            delim = " ";
        }
    }
    if (changed)
    {
		elem.className = total;       
    }
}

function getInnerWidth(elem)
{

	return elem.offsetWidth - ToPixel(getStyle(elem, "padding-left")) - ToPixel(getStyle(elem, "padding-right"))
							- ToPixel(getStyle(elem, "border-left-width")) - ToPixel(getStyle(elem, "border-right-width"))
							- ToPixel(getStyle(elem, "margin-left")) - ToPixel(getStyle(elem, "margin-right"));
}

//-->

