
//#require "logging.js"
//#require "testing.js"
function logError(msg) {
	alert(msg);
}
function noaction() {}

function isdefined(v) {
	return (v != undefined);
}

function copyToArray(iter) {
	var cpy = new Array();
	for (var i=0; i<iter.length; i++) {
		cpy.push(iter[i]);
	}
	return cpy;
}
$A = copyToArray;


// From prototype.js
Function.prototype.tie = function() {
	var __method = this;
	var _args = copyToArray(arguments);
	var _obj = _args.shift();
	return function() {
		return __method.apply(_obj, _args.concat(copyToArray(arguments)));
	};
}


/*
Function.prototype.setBoundValues = function(method, obj, args) {
	this.__method = method;
	this.__obj = obj;
	this.__args = args;
}

Function.prototype.tie = function() {
	function caller() {
		return arguments.callee.__method.apply(arguments.callee.__obj, arguments.callee.__args.concat($A(arguments)));
	}
	var method = this;
	var args = $A(arguments);
	var obj = args.shift();
	caller.setBoundValues(method, obj, args);
	return caller;
}
*/

/*testSuite.add(function() {
	function C(i) {
		this.i = i;
	}
	var np = null;
	C.prototype.f = function() {
		np = this.i;
	}
	C.prototype.g = function(a) {
		np = this.i + a;
	}

	var c = new C(1);
	var f = c.f.tie(c);
	f();
	assert(np == 1);
	var g = c.g.tie(c);
	g(1);
	assert(np = 2);
});*/

/*
function copyToArray(iter) {
	return Array.prototype.slice.apply(iter);
}
*/

function dump(obj) {
	if (obj instanceof Object) {
		var str = '{';
		for (var i in obj) {
			str += i + ':' + typeof(obj[i]) + ', ';
		}
		str += '}';
		return str;
	}
	else {
		return "<external object>" + typeof obj;
	}
}

var ActiveX_XMLDOM = "MSXML2.DOMDocument";
var ActiveX_XMLHTTP = "MSXML2.XMLHTTP";
var ActiveX_XSLStylesheet = "MSXML2.FreeThreadedDOMDocument";
var ActiveX_XSLTemplate = "MSXML2.XSLTemplate";

function firstUp(s) {
	if (!s) {
		return s;
	}
	return s.substr(0,1).toUpperCase() + s.substr(1);
}


// Zeitmessung von Funktionen (besonders für IE)


var enable_timing = 0;

// Infrastruktur

function Counter(name) {
	this.name = name;
	this.calls = 0;
	this.time = 0;
}

Counter.prototype.avg = function() {
	return this.time / this.calls;
}

Counter.bytime = function(left, right) {
	return right.time - left.time;
}

Counter.byavgtime = function(left, right) {
	return right.avg() - left.avg();
}

var timing = new function() {
	this.names = [];
	this.counters = [];
}

timing.add = function(name, delta) {
	if (this.counters[name] === undefined) {
		this.names.push(name);
		this.counters[name] = new Counter(name);
	}
	var counter = this.counters[name];
	counter.calls++;
	counter.time += delta;
}

timing.stats = function(head) {
	var i;
	var msg = head + " (timing stats):\n";

	var cts = [];
	for (i=0; i<this.names.length; i++) {
		cts.push(this.counters[this.names[i]]);
	}

	cts.sort(Counter.bytime);
	for (i=0; i<cts.length; i++) {
		var c = cts[i];
		msg += c.time + "ms: " + c.name + " (" + c.calls + " calls, avg " + c.avg().toFixed(1) + "ms)\n";
	}
	alert(msg);
}


/** Timing function wrapper
 * usage: foo.prototype.xyz = timed("foo:xyz", function(a, b, c) { ... })
 */
function timed(name, fun) {
	if (!enable_timing) {
		return fun;
	}
	return function() {
		var start = (new Date()).getTime();
		var result = fun.apply(this, arguments);
		var span = (new Date()).getTime() - start;
		timing.add(name, span);
		return result;
	}
}

