var someClass = function () {
}

someClass.prototype.mymethod = function () {
}

/************************  debug  *******************************/

debugclose  = function () {
	if (inspectwindow) {
		try {
			inspectwindow.close ();
		} catch (e) {
		}
	}
}

debugClass = function () {
}


//Function to time hoe long it takes to create 10000 objects
//After the time is displayed in the debug.out the objects are destroyed.
debugClass.prototype.addLotsOfObjects = function(){
	var objs = new Object ();
	var count = 10000;
	var start = new Date ();

	for (var i = 0; i < count; i++) {
		objs[i] = new someClass ();
	}
	this.out("Time to create new objects is "+(new Date () - start)/count);
	//document.body.innerHTML +='<p>' + ((new Date () - start)/count) + '</p>';
	for (var i = 0; i < count; i++) {
		delete objs [i]
	}
}

debugClass.prototype.docWrite = function (obj, deep, recur) {
	if (!_debug)
		return false;

	if (system.browser () == 'ie') {
		document.body.innerHTML += debug.makeStr (obj, deep, recur) + "<hr>\n";
	} else {
		var el = document.createElement ("DIV");
		el.innerHTML = debug.makeStr (obj, deep, recur) + "<hr>\n";
		document.body.appendChild (el);
	}
}

debugClass.prototype.elWrite = function (obj, deep, recur) {
	if (!_debug)
		return false;

	var el = document.createElement ("DIV");
	var str = debug.makeStr (obj, deep, recur);
	el.innerHTML = '<pre>'+debug.escapeStr (str)+"</pre><hr>\n";

	var el2 = document.getElementById ('debug');
	if (el2 == null) {
		var el2 = document.createElement ("DIV");
		document.body.appendChild (el2);
	}
	el2.appendChild (el);
}

debugClass.prototype.silWrite = function (obj, deep, recur) {
	if (!_debug)
		return false;

	if (typeof window ['sil'] === 'undefined') {
		debug.out ('no sil for debug.silWrite !');
		return false;
	}

	if (debug.sil === false)
		debug.sil = new sil ();

	var len = debug.sil.length ();
	if (len >= (debug.silmax+1)) {
		for (var i = (len-debug.silmax); i > 0; i--)
			debug.sil.shift ();
	}

	var str = debug.makeStr (obj, deep, recur);
	str = '<div><pre>'+debug.escapeStr (str)+"</pre><hr>\n</div>";

	debug.sil.add (str);

	var el = document.getElementById ('debug');
	if (el == null) {
		var el = document.createElement ("DIV");
		document.body.appendChild (el);
	}
	el.innerHTML = debug.sil.all ().join ('');
}

debugClass.prototype.alert = function (obj, deep, recur) {
	alert (debug.makeStr (obj, deep, recur));
}

debugClass.prototype.escapeStr = function (str) {
	if (typeof str != 'string')
		return '';

	return str.replace (/&/g, '&amp;').replace (/</g, '&lt;').replace (/>/g, '&gt;');
}

debugClass.prototype.newWinAlways = function (obj, deep, recur) {
	var str = debug.makeStr (obj, deep, recur);

//	if (str == '' || typeof str == 'null')
//		str = "<pre>obj = undefined?</pre>\n"
//	else
		str = '<pre>'+debug.escapeStr (str)+"</pre><hr>\n";

	debug.str2window (str);

	if (debug.scroll == true)
		inspectwindow.scrollBy (0, 5000);
	
	return true;
}

debugClass.prototype.str2window = function (str) {
	if (typeof inspectwindow != 'object')
		inspectwindow = window.open ('', '', 'width=700,height=500,resizable=yes,scrollbars=yes,fullscreen=no');

	try {
		inspectwindow.document.write(str);
	} catch (e) {
		try {
			inspectwindow = window.open ('', '', 'width=700,height=500,resizable=yes,scrollbars=yes,fullscreen=no');

			inspectwindow.document.write(str);
		} catch (e) {
			alert ('debugger: unable to open debug-window, debugger disabled');
			_debug = false;
		}
	}
}

debugClass.prototype.newWin = function (obj, deep, recur) {
	if (!_debug)
		return false;

	return debug.newWinAlways (obj, deep, recur);
}

debugClass.prototype.makeStr = function (obj, deep, recur) {
	var sigslotEnabled = (typeof sigslotClass != 'undefined' && typeof sigslot != 'undefined' && typeof sigslot.wrapnumname != 'undefined')

	try {
		var str = '';

		if (typeof deep !== 'boolean')
			deep = false;
	
		if (typeof recur !== 'boolean')
			recur = false;
	
		if (obj == null) // who'd thought it, null is actually an object !
			return ('null');
	
		switch (typeof obj) {
		case 'undefined':
			str = 'undefined';
		break;
		case 'boolean':
			if (obj == true)
				str = 'true';
			else
				str = 'false';
		break;
		case 'string':
			str = obj;
		break;
		case 'number':
			str = obj + '';
		break;
		case 'function':
			str = obj.toString ();
		break;
		default:
			if (deep)
				var maxi = 1;
			else
				var maxi = 3;
			if (!deep)
				var str = '[ ';
			else
				var str = '';
			var i = 0;
			for (var el in obj) {
				if (deep) {
					try {
						switch (typeof obj [el]) {
						case 'undefined':
							str += el + ' = ' + obj [el] + "\t";
						break;
						case 'function':
							if (sigslotEnabled && typeof obj [sigslot.wrapnumname + el] != 'undefined') {
								str += "[a sigslotted function]\t";
							} else {
								str += "[a function]\t";
							}
						break;
						default:
							if (recur) {
								str += el + " = \n" + debug.makeStr (obj [el], true) + "\n"
							} else {
								try {
									str += el + " = \n" + obj [el].toString () + "\t";
								} catch (e) {
									str += el + ' = ' + obj [el] + "\t";
								}
							}
						}
					} catch (e) {
						str += el + " = debugger-error??\t";
					}
				} else
					str += el + "\t";
				if (i == maxi) {
					str += "\n";
					i = 0;
				} else
					i++;
			}
			if (!deep)
				str += " ]";
		}
		if (debug.timed) {
			var myDate	= new Date();
			var time = myDate.getTime()
			if (debug.timed === false)
				debug.timed = time;
			str = time + ' - ' + (time - debug.timed) + " - " + str;
			debug.timed = time;
		}
	} catch (e) {
		alert ('debugger-failure: '+e.message);
	}
	return (str);
}

if (typeof _debugOutFunction == 'undefined')
	debugClass.prototype.out = debugClass.prototype.newWin;
else
	debugClass.prototype.out = debugClass.prototype [_debugOutFunction]; // _debugOutFunction is set in config.js

debugClass.prototype.showDMDebug = function (type, id, paramClientid) {
	if (type === 'innerHTML') {
		//debug.out (document.documentElement.outerHTML); // looks better!
		//debug.str2window (debug.escapeStr (document.documentElement.innerHTML.toString ()) + '<hr>');
		debug.newWinAlways (document.documentElement.innerHTML.toString ());
		return;
	}
	if(type == 'addObjects'){
		debug.addLotsOfObjects();
		return;
	}
	if(type == "profiler"){
		profiler.printResults();
		return;
	}
	if(type == "resetprofiler"){
		profiler.reset();
		return;
	}
	if(type == "win"){
		profiler.showWindow();
	}

	if (typeof type != 'string')
		type = '';

	if (typeof id != 'string')
		id = '';

	if (typeof paramClientid != 'string')
		paramClientid = '';

	if (id == '' && type == '' && paramClientid == '') {
		if (datamanager.xmlIOs) {
			for (var el in datamanager.xmlIOs) {
				if (datamanager.xmlIOs [el].typehash)
				debug.str2window ('<div style="text-decoration:underline;" onclick="window.opener.debug.showDMDebug (' + "'" + datamanager.xmlIOs [el].typehash + "'" + ')">' + datamanager.xmlIOs [el].typehash + "</div>");
			}
		} else {
			for (var el in datamanager.dataCollection) {
				debug.str2window ('<div style="text-decoration:underline;" onclick="window.opener.debug.showDMDebug (' + "'" + el + "'" + ')">' + el + "</div>");
			}
		}

		debug.str2window ('<hr><div style="text-decoration:underline;" onclick="window.opener.debug.showDMDebug ('+"'innerHTML'"+')">innerHTML</div>');
		
		//Option to time creation of 10000 objects
		debug.str2window ('<hr><div style="text-decoration:underline;" onclick="window.opener.debug.showDMDebug ('+"'addObjects'"+')">addObjects</div>');
		
		debug.str2window ('<hr><div style="text-decoration:underline;" onclick="window.opener.debug.showDMDebug ('+"'win'"+')">Show window global</div>');
		
		//PROFILER OPTIONS...
		debug.str2window ('<hr><div style="text-decoration:underline;" onclick="window.opener.debug.showDMDebug ('+"'profiler'"+')">Show Profiler Results</div>');
		debug.str2window ('<div style="text-decoration:underline;" onclick="window.opener.debug.showDMDebug ('+"'resetprofiler'"+')">Reset Profiler</div>');
	
	} else {
		if (id != '' || paramClientid != '') {
			if (type != '') {
				var tmpClientID = null;
				if (paramClientid == ''){
					tmpClientID = datamanager.dataCollection [type][id];
				} else {
					tmpClientID = paramClientid;
				}

				var IO = datamanager.IOs [tmpClientID];

				debug.str2window ('clientid = ' + IO.clientid +"<br>")
				debug.str2window ('id = ' + IO.id +"<br>")
				debug.str2window ('type(hash) = ' + IO.typehash +"<br>")
				debug.str2window ('edited = ' + IO.edited +"<br><br>")

				for (var el in IO.data) {
					if (IO.IODef.structure [el].datatype == 'list') {
						for (var el2 in IO.data [el]) {
							if (el2 != 'length') {
								debug.str2window (el + ' [' + el2 + '] =');
								if (IO.data [el][el2].id === false) {
									//use clientid
									//debug.str2window ("<div style=\"text-decoration:underline;\" onclick=\"alert ('window.opener.debug.showDMDebug (" + IO.data [el][el2].typehash + ', null, ' + el2 + ")')\">    typehash = " + IO.data [el][el2].typehash + '    clientid = ' + el2 + "</div>");
									//debug.str2window ("<div style=\"text-decoration:underline;\" onclick=\"alert ('window.opener.debug.showDMDebug (" + IO.data [el][el2].typehash + ', null, ' + el2 + ")')\">    typehash = " + IO.data [el][el2].typehash + '    clientid = ' + el2 + "</div>");
									debug.str2window ('<div style="text-decoration:underline;" onclick="window.opener.debug.showDMDebug (' + "'" + IO.data [el][el2].typehash + "'" + ', null, ' + "'" + el2 + "'" + ')">    typehash = ' + IO.data [el][el2].typehash + '    clientid = ' + el2 + "</div>");
								} else {
									debug.str2window ('<div style="text-decoration:underline;" onclick="window.opener.debug.showDMDebug (' + "'" + IO.data [el][el2].typehash + "'" + ', ' + "'" + IO.data [el][el2].id + "'" + ')">    typehash = ' + IO.data [el][el2].typehash + '    id = ' + IO.data [el][el2].id + "</div>");
								}
							}
						}
					} else {
						if (typeof IO.FKs [el] != 'undefined') {
							debug.str2window ('<div style="text-decoration:underline;" onclick="window.opener.debug.showDMDebug (' + "'" + IO.FKs [el].def.foreignHash + "'" + ', ' + "'" + IO.getKeyPlainValue (el) + "'" + ')">FK (on '+el+'):    typehash = ' + IO.FKs [el].def.foreignHash + '    id = ' + IO.getKeyPlainValue (el) + "</div>");
						} else {
							debug.str2window (el + ' = ' + IO.getKeyPlainValue (el) + "<br>");
						}
					}
				}
			} else {
				alert ('no way');
			}
		} else {
			if (type != '') {
				if (datamanager.xmlIOs) {
					debug.str2window ('<pre>'+debug.escapeStr (datamanager.xmlIOs [type].xmlDocument.xml)+"</pre><hr>\n");
				} else {
					for (var id in datamanager.dataCollection [type]) {
						debug.str2window ('<div style="text-decoration:underline;" onclick="window.opener.debug.showDMDebug (' + "'" + type + "'" + ', ' + "'" + id + "'" + ')">' + type + ' . ' + id + "</div>");
					}
				}
			} else {
				alert ('no way');
			}
		}
	}
	debug.str2window ("<hr>");
}

var debug = new debugClass ();

//debug.newWin = function () { };

debug.lastTime = false;
debug.scroll = false;
debug.timed = true;
debug.sil = false;
debug.silmax = 40;
var inspectwindow = false;
var debug2 = debug;
var leeninspect = debug.newWin;
var inspect = debug.newWin;
var leeninsect = debug.newWin;

function timeinspect(key, obj, title, iter) {
	if (!_debug)
		return false;

	var myDate		= new Date();
	var Time		= myDate.getTime();
	if (typeof obj == 'undefined')
		leeninspect(Time + " - " + key);
	else
		leeninspect(Time + " - " + key + ":" + obj);

}



var timer = function () {

	this.parameters = null;
	this.functionName = null;
	this.interval = 1000;
	this.data = null;
	this.locked = false;
}

timer.prototype.init = function (functionName, interval) {
	this.parameters = new Array();
	this.data = new Array();
	this.functionName = functionName;
	this.interval = interval;
}

timer.prototype.setParameter = function (oObj, idx) {
	this.parameters[idx] = oObj;
}

timer.prototype.setFunctionName = function (functionName) {
	this.functionName = functionName;
}

timer.prototype.setIntervalTime = function (interval) {
	this.interval = interval;
}

timer.prototype.setInterval = function (interval) {
	if (interval) {
		this.interval = interval;
	}
	setInterval(this.getEvalString(),this.interval);
}

timer.prototype.setData = function (data, idx) {	
	this.data[idx] = data;
}

timer.prototype.getData = function (idx) {	
	return this.data[idx];
}

timer.prototype.getEvalString = function () {
	var str = this.functionName;
	if (this.parameters != null) {
		var idx = 0;
		for (parameter in this.parameters) {
			if (idx == 0)
				str = str +"(timer.parameters[" + idx + "]";
			else 
				str = str + ",timer.parameters[" + idx + "]";
			idx++;
		}
	}
	str = str + ")";
	return str;
}

timer.prototype.start = function () {
	setTimeout(this.getEvalString(), this.interval);
}

timer.prototype.lock = function () {
leeninspect("lock");
	this.locked = true;
}

timer.prototype.unlock = function () {
leeninspect("unlock");
	this.locked = false;
}

timer.prototype.isLocked = function () {
	return this.locked;
}

timer.prototype.wait = function (funct) {
leeninspect("check locked:"+this.locked);
	if (this.locked) {
		setTimeout("timer.wait("+funct+")", 100);
	} else {
		eval(funct);
	}
}


/**
* PROFILER.....
* Use var l = profiler.increaseFunctionCall("FunctionName");
* at start of function
*
* Use profiler.stopTimer("FunctionName", l); at end of function
**/


var profilerClass = function(){
	this.count = new Object();
	this.countZero = new Object();
	this.timers = new Object();
	this.times = new Object();
	this.maxtimes = new Object();
	this.task = new Object();
	this.seperateTimes = new Object();
}

profilerClass.prototype.reset = function(){
	this.count = new Object();
	this.countZero = new Object();
	this.timers = new Object();
	this.times = new Object();
	this.maxtimes = new Object();
	this.task = new Object();
	this.seperateTimes = new Object();
}

profilerClass.prototype.endTask = function(eventItem){
	if(typeof this.task[eventItem.queueName] !== "undefined" && typeof this.task[eventItem.queueName][eventItem.number] !== "undefined"){
		var totaltime = new Date () - this.task[eventItem.queueName][eventItem.number];
		this.task[eventItem.queueName].averageTime = this.task[eventItem.queueName].averageTime+ totaltime;
		if( this.task[eventItem.queueName].maxTime < totaltime){
			this.task[eventItem.queueName].maxTime = totaltime;
		}
		delete (this.task[eventItem.queueName][eventItem.number]);
	}
	else{
		alert("Error ending task "+eventItem.queueName+" "+eventItem.number);
	}
	
	this.task[eventItem.queueName].count++;
}

profilerClass.prototype.addTask = function(eventItem){
	if(typeof this.task[eventItem.queueName] === "undefined"){
		this.task[eventItem.queueName] = new Object();
		this.task[eventItem.queueName].count = 0;
		this.task[eventItem.queueName].averageTime = 0;
		this.task[eventItem.queueName].maxTime = 0;
	}
	
	this.task[eventItem.queueName][eventItem.number] = new Date();
}
profilerClass.prototype.startTimer = function(functioname){
	if(typeof this.timers[functioname] === "undefined"){
		this.timers[functioname] = new Array();
	}
	var l = this.timers[functioname].length;
	this.timers[functioname][l] = new Date();
	return l;
}
profilerClass.prototype.stopTimer = function(functioname, l){
	if(typeof this.timers[functioname][l] !== "undefined"){
		var totaltime = new Date () - this.timers[functioname][l];
		if(totaltime === 0){
			if(typeof this.countZero[functioname] === "undefined"){
				this.countZero[functioname] = 0;
			}
			this.countZero[functioname]++;
		}
		else{
			this.setTotalTime(functioname, totaltime);
		}
		if(typeof this.maxtimes[functioname] === "undefined"){
			this.maxtimes[functioname] = totaltime;
		}
		else if(this.maxtimes[functioname] < totaltime){
			this.maxtimes[functioname] = totaltime;
		}
		delete (this.timers[functioname][l]);
	}
	else{
		alert("Error trying to stop timer "+functioname+" "+l);
	}
}
profilerClass.prototype.setTotalTime = function(functioname, t){
	if(typeof this.times[functioname] === "undefined"){
		this.times[functioname] = 0;
		this.seperateTimes[functioname] = new Array();
	}
	this.seperateTimes[functioname][this.seperateTimes[functioname].length] = t;
	this.times[functioname] = this.times[functioname]+t;
}
profilerClass.prototype.increaseFunctionCall = function(functioname){
	if(typeof this.count[functioname] === "undefined"){
		this.count[functioname] = 0;
	}
	this.count[functioname]++;
	return this.startTimer(functioname);
}
profilerClass.prototype.printResults = function(){
	var str = "\nFUNCTION CALLS\n";
	for(var functionname in this.count){
		str = str+functionname+" "+this.count[functionname]+"\n";
		
		if(typeof this.countZero[functionname] !== "undefined" ){
			var actcount = this.count[functionname]-this.countZero[functionname];
			if(actcount <1){
				actcount = 1;
			}
		}
		else{
			var actcount = this.count[functionname];
		}
		str = str+"\t Calls that took 0s: "+this.countZero[functionname]+"\n";
		if(typeof this.times[functionname] !== "undefined"){
			str = str+"\t Average time: "+(this.times[functionname]/actcount)/1000+" s\n";
		}
		else{
			str = str+"\t Average time: 0 s\n";
		}
		if(typeof this.seperateTimes[functionname] !=="undefined"){
			str = str+"\t Individual Times: ";
			for(var idx in this.seperateTimes[functionname]){
				str = str+this.seperateTimes[functionname][idx]+", ";
			}
			str = str+"\n";
		}
		if(typeof this.maxtimes[functionname] !== "undefined"){
			str = str+"\t Max time: "+this.maxtimes[functionname]/1000+" s\n";
		}
	}
	str=str+"\nQUEUE ITEMS\n";
	for(var qname in this.task){
		var QueueName = qname;
		if (/__sigslot__wrappednum__/.test (QueueName)) {
			signum = QueueName.replace (/^__sigslot__wrappednum__/, '').replace (/\+[0-9]+$/, '');
			var signalfunctionname = sigslot.signal [signum].funcname
		}
		if (typeof sigslot.events [signalfunctionname] !== 'undefined'){
			str = str+"\nevent "+qname+" "+signalfunctionname+" "+this.task[qname].count+"\n";
		}
		else if(typeof signalfunctionname !== "undefined" && signalfunctionname !== ""){
			str = str+"\nsignalfunction "+qname+" "+signalfunctionname+" "+this.task[qname].count+"\n";
		}
		else{
			str = str+"\n"+qname+" "+this.task[qname].count+"\n";
		}
		signalfunctionname = "";
		str = str+"\t Average time: "+(this.task[qname].averageTime/this.task[qname].count)/1000+" s\n";
		str = str+"\t Max time: "+this.task[qname].maxTime/1000+" s\n";
	}
	debug.out(str);
}
profilerClass.prototype.showWindow = function(){
	for(var x in window){
		debug.out(x);
	}
}


var profiler = new profilerClass();

