function clMouse(object) {
	this.id = object;
	this.x = 0;									// mouse position
	this.y = 0;									// mouse position
	this.down = 0;								// mouse button pressed (0=none, 1=left, 2=right)
	this.downX = 0;								// mouse pos when button pressed (used for dragging)
	this.downY = 0;								// mouse pos when button pressed (used for dragging)
	this.upX = 0;								// mouse pos when button released (used for dragging)
	this.upY = 0;								// mouse pos when button released (used for dragging)
	this.mainX = 0;								// mouse pos relative to main container
	this.mainY = 0;								// mouse pos relative to main container
	this.gotinput = 0;
}

function clKey(object) {
	this.id = object;
	this.lastkey = '';
	
	this.lastkeys = new Array();				// store pressed keys
	for(var i=0; i<(iKeyMem-1); i++) {
		this.lastkeys[i] = 32;					// fill array with " " (space-characters)
	}
}

function clTimer() {
	this.active;
	this.action;
	this.duration;
	this.delay;
	this.times;
	this.lastTick;
}

var iKeyMem = 20;				// number of key-inputs remembered

var aQueries = new Array();	
var aTimers = new Array();
var iTimedPreloadImage = 0;

var bNoRightMouse = true;		// Pointless, thou people want it sometimes.. (not working prefectly yet!)
var bNoKeyPress = true;
var bNoSelection = true;
var bFramed = true;

var wDebug;
var bDebug = false;

var mouse = new clMouse("mouse");
var key = new clKey("key");

var isIE = document.all;
var isNN = !isIE && document.getElementById;
var isN4 = document.layers;

var sSiteRoot = 'index.html';

function fnInit() {
	if(bFramed) fnMaintainFramed();
	if(bDebug) fnDebug();
	
	// put here: functions to be called on every page
	
	for(var i=0; i<arguments.length; i++) { // fnInit('function1', 'function2'); <-- those will be run here
		fnCommand(arguments[0]);
	}
}

function fnCommand(cmd) {
	if(cmd != '' && cmd != null) eval(cmd);
}

function fnPreloadImage(image) {
	if(document.images) {	
		var img = new Image();
		img.src = image;
	}
}

function fnPreloadImages() {
	for(var i=0; i<arguments; i++) {
		fnPreloadImage(arguments[i]);
	}
}

function fnTimedPreloadImage() {
	iTimedPreloadImage++;
	if(iTimedPreloadImage < (arguments.length-2)) {
		fnPreloadImage(arguments[iTimedPreloadImage]);			
	}
}

function fnTimedPreloadImages(seconds) { // seconds = delay between images to be loaded
	fnCreateTimer(argments.length-1, seconds, 'fnTimedPreloadImage(' + arguments + ')');
}

function fnTimeHandler() {	// controls timer events
	if(aTimers != null) {	// array should be alive
		for(var i=0; i<aTimers.length; i++) {
			var item = aTimers[i];
			if(item.active) {	// only the active timers
				item.lastTick += 1;
				if(item.lastTick >= item.delay) {
					item.lastTick = 0;
					if(item.duration > 0) item.times += 1;
					if(item.times >= item.duration && item.times > 0) fnStopTimer(i);
					fnCommand(item.action);	// execute the action
				}
			}
		}
	}
	setTimeout('fnTimeHandler()', 1000); // repeat every second
}

function fnGotoURL(url) {
	var query = '';
	
	if(aQueries.length > 0) {
		query = '?';
		for(var i=0; i<aQueries.length; i++) {
			query += aQueries[i][0] + '=' +  aQueries[i][1] + ((i<(aQueries.length-1))?'&':'');
		}
	}
	location.href = url + query;
	return true;
}

function fnMaintainFramed() {
	if(parent.frames.length == 1) {
		fnGotoURL(sSiteRoot);
	}
}

function fnGetQuery(name) {		// get a value from the querystring
	var sUrl = location.href;
	var sQueryString = sUrl.split('?');
	
	if(sQueryString.length == 2) {
		var sQuery = sQueryString[1].split('&');
	
		for(var i=0; i<sQuery.length; i++) {
			var item = sQuery[i].split('=');
			if(name == item[0]) return item[1];
		}
	}
	return null;
}

function fnGetInternalQuery(name) {		// get a value from the newly set querystring
	if(aQueries.length == 0) return null;
	
	for(var i=0; i<aQueries.length; i++) {
		if(name == aQueries[i][0]) return aQueries[i][0];
	}
	return null;
}

function fnUpdateQuery(name, value) {
	for(var i=0; i<aQueries.length; i++) {
		if(aQueries[i][0] == name) {
			aQueries[i][1] = value;
			return true;
		}
	}
	return null;
}

function fnAddQuery(name, value) {
	var id = aQueries.length;
	
	if(!fnGetInternalQuery(name)) {
		aQueries[id] = new Array();
		aQueries[id][0] = name;
		aQueries[id][1] = value;
	} else {
		fnUpdateQuery(name, value);
	}
}

function fnAddCurrentQuery() {	// parse the current querystring to the array
	var sUrl = location.href;
	var sQueryString = sUrl.split('?');
	
	if(sQueryString.length == 2) {
		var sQuery = sQueryString[1].split('&');
	
		for(var i=0; i<sQuery.length; i++) {
			var item = sQuery[i].split('=');
			fnAddQuery(item[0], item[1]);
		}
	}
}

function fnGetObject(id) {		// returns the actual object to work with (from id name)
	if(document.getElementById) {
		return document.getElementById(id);
	} else if(document.all) {
		return eval("document.all."+id);
	} else if(document.layers) {
		return eval("document."+id);
	} else {
		return document.all[id];
	}
}

function fnMoveObjTo(object, x, y) {
	object = fnReturnObject(object);
	
	fnObjectStyle(object).left = x;
	fnObjectStyle(object).top = y;
}

function fnMoveObjBy(object, x, y) {
	object = fnReturnObject(object);
	
	fnObjectStyle(object).left = fnObjectStyle(object).left + x;
	fnObjectStyle(object).top = fnObjectStyle(object).top + y;
}

function fnObjectStyle(object) {
	object = fnReturnObject(object);
	return (isN4)?object:object.style;
}

function fnStyleById(id) {
	return fnObjectStyle();
}

function fnChangeClassName(object, sNewClass) {
	object = fnReturnObject(object);
	object.className = sNewClass;
}

function fnReturnObject(object) {
	return (!(typeof object == 'object'))?fnGetObject(object):object;
}

function fnCreateTimer(duration, delay, action) {
	if(delay <= 0 || action == '' || action == null) return false;
	
	var tTimer = new clTimer;
	tTimer.active = true;
	
	tTimer.duration = duration;
	tTimer.delay = delay
	tTimer.action = action;
	
	tTimer.times = 0;
	tTimer.lastTick = 0;
	
	var iTimer = aTimers.length;
	aTimers[iTimer] = tTimer;
	
	if(iTimer == 0) fnTimeHandler();
	
	return iTimer;
}

function fnStartTimer(id) {
	if(isNaN(id) || !aTimers[id]) return false;
	
	aTimers[id].active = true;
	aTimers[id].lastTick = 0;
	aTimers[id].times = 0;
	
	return true;
}

function fnStopTimer(id) {
	if(isNaN(id) || !aTimers[id]) return false;
	
	aTimers[id].active = false;
	
	return true;
}

function fnResetTimer(id) {
	fnStopTimer(id);
	fnStartTimer(id);
	
	return true;
}

function fnIsArray() {
	if (typeof arguments[0] == 'object') {
		var criterion = arguments[0].constructor.toString().match(/array/i);
		return (criterion != null);
	}
	return false;
}

function fnDebug() {
	if(wDebug) wDebug.self.close();
	
	wDebug = window.open('Debug', 'DEBUG', 'width=300,height=200,scrollbars=yes');
	wDebug.document.write('<form name="form"><textarea name="command" rows="8" cols="20"></textarea><input type="button" onClick="if(command.value) opener.fnCommand(command.value);" value="Execute">');
}

function fnSetCookie(name, value, days) {
	if(document.cookie) {
		if(days) {
			var date = new Date();
			date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
			var expires = "; expires=" + date.toGMTString();
		} else {
			expires = "";
		}
		document.cookie = name + "=" + value + expires + "; path=/";
		return true;
	} else {
		return false;
	}
}

function fnGetCookie(name) {
	if(document.cookie) {
		var sNameEQ = name + "=";
		var aCookies = document.cookie.split(';');
		
		for(var i=0; i<aCookies.length; i++) {
			var sCookie = aCookies[i];
	    	while(sCookie.charAt(0) == ' ') { // trim all blank chars
				sCookie = sCookie.substring(1, c.length);
			}
			if (c.indexOf(nameEQ) == 0) return sCookie.substring(sNameEQ.length, sCookie.length);
		}
	}
	return null;
}

function fnGotInput() {
}

function fnShiftLastKey() {
	for(var i=0; i<key.lastkeys.length-1; i++) {
		key.lastkeys[i] = key.lastkeys[(i-1)];
	}
}

function fnErrorHandler(msg, url, linenumber) {
	window.status = 'ERROR ( ' + msg + ' ) LINE ( ' + linenumber + ' ) FILE ( ' + url + ' )';
	return true;
}

function fnReplace(needle, hay, haystack) {
	while(haystack.indexOf(needle) != -1) {
		haystack = haystack.replace(needle, hay);
	}
	return haystack;
}

function fnAddToDocument(text) {
	if(document.body.innerHTML) {
		document.body.innerHTML += text;
	} else {
		document.body.innerHTML = text;
	}
}

//	MOUSE and KEYBOARD events

function fnNSIEonMouseDown() {
	mouse.down = 1;
	mouse.downX = mouse.x;
	mouse.downY = mouse.y; // window.event bestaat niet in netscape
	
	if(isN4) {
		mouse.down = e.which;
	} else if(window.event.button) {
		mouse.down = window.event.button;
	} else {
		mouse.down = 0;
	}

	if(bNoRightMouse && mouse.down > 1) fnIECancelEvent();
//	if(bNoSelection && mouse.down == 1) fnIECancelEvent();
	if(mouse.gotinput) fnGotInput();
}

function fnNSIEonMouseUp() {
	mouse.down = 0;
	mouse.upX = mouse.x;
	mouse.upY = mouse.y;
}

function fnNSonMouseMove(e){
	mouse.x = e.pageX;
	mouse.y = e.pageY;
	return true;
}

function fnIEonMouseMove() {
	mouse.x = window.event.x;
	mouse.y = window.event.y;
/*

	if(document.body.scrollLeft) {
		mouse.x += document.body.scrollLeft;
	}
	if(document.body.scrollTop) {
		mouse.y += document.body.scrollTop;
	}
*/
}

function fnNSonKeyPress(e) {
	fnShiftLastKey();
	key.lastkeys[0] = String.fromCharCode(e.which);
	
	if(bNoKeyPress) return false;
	if(mouse.gotinput) fnGotInput();
}

function fnIEonKeyPress() {
	fnShiftLastKey();
	key.lastkeys[0] = window.event.keyCode;
	
	if(bNoKeyPress) fnIECancelEvent();
	if(mouse.gotinput) fnGotInput();
}

function fnIECancelEvent() {
	window.event.returnValue = false;
}

function fnIEonDragStart() {
	if(bNoRightMouse) fnIECancelEvent();
}

function fnIEonDragStop() {
}

function fnIEonContextMenu() {			// Right-Mouse catcher for IE
	if(bNoRightMouse) fnIECancelEvent();
}

function fnIEonSelectStart() {
	if(bNoSelection) fnIECancelEvent();
}

if (isIE || isNN) {
	window.document.onkeypress = fnIEonKeyPress;
	window.document.onkeydown = fnIEonKeyPress;

	window.document.ondragstart = fnIEonDragStart;
	window.document.ondragstop = fnIEonDragStop;

	window.document.onselectstart = fnIEonSelectStart;

	window.document.oncontextmenu = fnIEonContextMenu;

	window.document.onmousemove = fnIEonMouseMove;
	window.document.onmousedown = fnNSIEonMouseDown;
	window.document.onmouseup = fnNSIEonMouseUp;
} else {
	window.captureEvents(Event.MOUSEMOVE||Event.MOUSEDOWN||Event.KEYPRESS||Event.MOUSEUP);
	window.onmousedown = fnNSIEonMouseDown;
	window.onmousemove = fnNSonMouseMove;
	window.onmouseup = fnNSIEonMouseUp;
	window.onkeypress = fnNSonKeyPress;
}

window.onerror = fnErrorHandler;

// BODY: <body onLoad="fnInit();" onMouseDown="Javascript: fnNSIEonMouseDown();" onMouseUp="Javascript: fnNSIEonMouseUp();">
