var test = "posities: ";
function showTest(mark) {
test = test + " END";
	alert(mark + test);
	test = "posities: ";
}

//onerror = showTest();
var errornaam = "";
var error1 = "";
var error2 = "";


function pasop() {
	alert("fout in" + errornaam + " 1=" + error1 + " 2=" + error2);
}

browser = new browserIs;
lijst = new ObjectList;

function signaal(tekst) {
	alert(tekst);
}

function ObjectList() {
	this.n = 0;
	this.objekten = new Array(0);

	this.add = ObjectList_add;
	this.remove = ObjectList_remove;
	this.run = ObjectList_run;
	this.runInterval = ObjectList_runInterval;
	this.show = ObjectList_showList;
	this.get = ObjectList_get;
	this.getPositie = ObjectList_getPositie;
	this.elementAt = ObjectList_elementAt;

}

function ObjectList_add(id, type, interval, eigenschappen, volgendereeks) {
	var reeks = new ObjektReeks(id, type, interval, eigenschappen, volgendereeks);
	if (this.n == this.objekten.length) this.objekten[this.objekten.length] = reeks;
	else {
		var i = 0;
		while (this.objekten[i] != null) i++;
		this.objekten[i] = reeks;
	}
	this.n++;
}

function ObjectList_remove(id) {
	var i = 0;
	var klaar = false;
	while (!klaar) {
		if (i == this.objekten.length) klaar = true;
		else if (this.objekten[i] == null) i++;
		else if (this.objekten.base.id != id) i++;
		else {
			this.objekten[i] = null;
			this.n--;
			klaar = true;
		}
	}
}	

function ObjectList_get(id) {
	var resultaat = null;
	var klaar = false;
	var n = 0;
	var i = 0;
	while (klaar == false) {
		if (n < this.n) { 
			if (this.objekten[i] != null) {
				n++;
				if (id == this.objekten[i].base.id) {
					klaar = true;
					resultaat = this.objekten[i];
				} else i++;
			} else i++;
		} else klaar = true;
	}
	return resultaat;
}


function ObjectList_getPositie(id) {
	var resultaat = null;
	var klaar = false;
	var n = 0;
	var i = 0;

	while (klaar == false) {
		if (n < this.n) { 
			if (this.objekten[i] != null) {
				n++;
				if (id == this.objekten[i].base.id) {
					klaar = true;
					resultaat = i;
				} else i++;
			} else i++;
		} else klaar = true;
	}

	if (n > this.n) return -1;
	else return resultaat;
}

function ObjectList_elementAt(i) {
	return this.objekten[i];
}

function ObjectList_run(id) {
	this.get(id).base.setItv("runReeks(" + this.getPositie(id) + ")");
}

function runReeks(positie) {
	var r = lijst.elementAt(positie);

 	var teller = 0;
	while ((teller < r.reeks.length) && ((r.reeks[teller].base.intervalId != null)  | (r.reeks[teller].base.gestopt == true))) teller++; 

	if (teller == r.reeks.length) {
		r.base.clearItv();
	} else {
		r = r.reeks[teller]; 
		r.base.setItv("runObjekt(" + positie + "," + teller + ")");
		r.plaats();
		r.show(true);
	}

}

function ObjectList_showList(id, aan) {
//alert("obj.js - objectlist_showlist: id=" + id);
	var r = lijst.elementAt(this.getPositie(id));
	for (teller = 0; teller < r.reeks.length; teller++) {
		rr = r.reeks[teller];
		rr.plaats();
		rr.punt = 0;
		rr.show(aan);
	}
}

function ObjectList_runInterval(id, interval, intervallengte) {
//maakt de interval met nummer INTERVAL zichtbaar.
//als INTERVAL < 0 dan wordt de bestaande interval opnieuw zichtbaar gemaakt

	var r = lijst.elementAt(this.getPositie(id));
	var teller = parseInt(r.firstvisible);
	if (intervallengte > 0) r.intervallengte = intervallengte;
	var stop = teller + parseInt(r.intervallengte);
	if (interval >= 0) {	// eerst bestaande zichtbare interval uitzetten
		if (teller >= 0) { //bestaande zichtbare interval uitzetten
			while ((teller < r.reeks.length) && (teller < stop)) {
				rr = r.reeks[teller]; 
				rr.show(false);
				teller = teller + 1;
			}
		}
		// dan nieuwe interval zichtbaar maken
		teller = interval * r.intervallengte;
	}

	if ((teller < r.reeks.length) && (teller >= 0)) { // (nieuwe) interval zichtbaar maken
		r.firstvisible = teller;
		stop = teller + parseInt(r.intervallengte);
		while ((teller < r.reeks.length) && (teller < stop)) {
			rr = r.reeks[teller]; 
			rr.plaats();
			rr.punt = 0;
			rr.show(true);
			teller = teller + 1;
		}

	}
}

function runObjekt(reekspos, objektpos) {
	var obj = lijst.elementAt(reekspos).reeks[objektpos];
	if (obj.punt < obj.punten.length) {
		obj.plaats();
	} else {
		obj.base.clearItv();
		obj.punt = 0;
		if (obj.base.trigger != "-") {
			lijst.run(obj.base.trigger);
		}
		obj = lijst.elementAt(reekspos);
		if ((obj.reeks.length - objektpos == 1) && (obj.trigger != "")) lijst.run(obj.trigger);
	}
}

function ObjektBase(id, interval, volgendereeks) {
	this.id = id;
	this.interval = parseInt(interval);
	this.intervalId = null;
	this.gestopt = false;
	this.trigger = volgendereeks;
	this.setItv = ObjektBase_setInterval;
	this.clearItv = ObjektBase_clearInterval;
}

function ObjektBase_setInterval(functiecode) {
	this.intervalId = setInterval(functiecode, this.interval);
}

function ObjektBase_clearInterval() {
	clearInterval(this.intervalId);
	this.intervalId = null;
	this.gestopt = true;
}

function Objekt(id, punten, interval, volgendereeks) {
	this.base = new ObjektBase(id, interval, volgendereeks);
	this.punten = punten;
	this.punt = 0;
	this.plaats = Objekt_plaats;
	this.show = Objekt_show;
}

function Objekt_plaats() {
test = test + "[" + this.base.id + "(";
	var obj = alsObjekt(this.base.id);
	obj.left = parseInt(this.punten[this.punt].x);
	obj.top = parseInt(this.punten[this.punt].y);
test = test + obj.left + "," + obj.top + ")]";
	this.punt += 1;
}

/*
function Objekt_show(aan, netscape4) {
	var obj = alsObjekt(this.base.id);

	if (netscape4) {
		if (aan) obj.visibility = "show";
		else obj.visibility = "hide";
	} else {
		if (aan) obj.visibility = "visible";
		else obj.visibility = "hidden";
	}
}
*/

function Objekt_show(aan) {
	showObj(alsObjekt(this.base.id), aan);
}

function show(id, aan) {
	var obj = alsObjekt(id);
	showObj(alsObjekt(id), aan);
}

function showObj(obj, aan) {
	if (browserIs.ns4) {
		if (aan) obj.visibility = "show";
		else obj.visibility = "hide";
	} else {
		if (aan) obj.visibility = "visible";
		else obj.visibility = "hidden";
	}
}

function ObjektReeks(id, type, interval, eigenschappen, volgendereeks) {
	this.base = new ObjektBase(id, interval);
	this.reeks = null;
	this.trigger = volgendereeks;

	this.firstvisible = -1;
	this.intervallengte = 0;

	var ids = eigenschappen.split(/	* *	*,	* *	*/);  //(tab* spatie* tab* , tab* spatie* tab*)

	if (type == "val") {
		this.reeks = valObjecten(ids);
	} else if (type == "lijn") {
		this.reeks = lijnObjecten(ids);
	} else if (type == "boog") {
		this.reeks = boogObjecten(ids);

	} else if (type == "pop") {
		this.reeks = popObjecten(ids, false);
	} else if (type == "randompop") {
		this.reeks = popObjecten(ids, true);
	} else {

		// overige typen
	}
}

//********** HIERONDER AFFE HULPFUNCTIES *************


function Punt(x, y) {
	this.x = x;
	this.y = y;
}

function valObjecten(ids) {
	var reeks = new Array();
	for (obj = 0; obj < ids.length - 1; obj += 7) {
		reeks[reeks.length] = new Objekt(ids[obj], valPunten(ids[obj + 1], ids[obj + 2], ids[obj + 3], ids[obj + 4]), ids[obj + 5], ids[obj + 6]);
	}
	return reeks;
}

function popObjecten(ids, random) {
	var reeks = new Array();
	for (obj = 0; obj < ids.length - 1; obj += 4) {
		reeks[reeks.length] = new Objekt(ids[obj], popPunt(ids[obj + 1], ids[obj + 2]), 0, ids[obj + 3]);
	}
	if (random) {
		seed = new Date().getTime();
		for (i = 0; i < reeks.length; i++) {
			seed = randomInt(0, reeks.length - 1, seed);
			var wissel = reeks[seed];
			reeks[seed] = reeks[i];
			reeks[i] = wissel;
		}
	}
	return reeks;
}

function randomInt(onderlimiet, bovenlimiet, seed) {
	// seed factor (bijv. baseren op date.getTime) toegevoegd vanwege statische reeks in MSIE 
	return ((Math.floor(Math.random() * 10000 + seed)) % (bovenlimiet - onderlimiet)) + onderlimiet;
}

function lijnObjecten(ids) {
	var reeks = new Array();
	for (obj = 0; obj < ids.length - 1; obj += 8) {
		reeks[reeks.length] = new Objekt(ids[obj], lijnPunten(ids[obj + 1], ids[obj + 2], ids[obj + 3], ids[obj + 4], ids[obj + 5]), ids[obj + 6], ids[obj + 7]);
	}
	return reeks;
}

function boogObjecten(ids) {
	var reeks = new Array();
	for (obj = 0; obj < ids.length - 1; obj += 10) {
		reeks[reeks.length] = new Objekt(ids[obj], boogPunten(ids[obj + 1], ids[obj + 2], ids[obj + 3], ids[obj + 4], ids[obj + 5], ids[obj + 6], ids[obj + 7]), ids[obj + 8], ids[obj + 9]);
	}
	return reeks;
}

function valPunten(startx, starty, traject, accelleratie) {
// werkt voor accelleraties > 1 en < ± 2.5 en positieve trajecten
	startx = parseInt(startx);
	starty = parseInt(starty);
	traject = parseInt(traject)
	accelleratie = parseFloat(accelleratie);
	var puntental = 2;
	while (Math.pow(accelleratie, puntental) < traject) puntental = puntental + 1;
	var punten = new Array(puntental + 1);
	punten[0] = new Punt(startx, starty);
	var bodem = traject + starty;
	punten[puntental] = new Punt(startx, bodem);

	var overschot = Math.round(Math.pow(accelleratie, (puntental))) - traject;
	var part = 0;
	
	for (i = puntental - 1; i > 0; i = i - 1){
		if (overschot > 0) {
			part = Math.ceil(overschot / 2);
			overschot = overschot - part;
		} else part = 0;
		punten[i] = new Punt(startx, starty + Math.round(Math.pow(accelleratie, i)) - part);
	}

	var stuiter = punten[puntental -1].y - punten[puntental - 2].y;

	while (stuiter > 0) {
		stuiter = Math.floor(stuiter / 2);
		punten[punten.length] = new Punt(startx, bodem - stuiter);
		punten[punten.length] = new Punt(startx, bodem);
	} 

	return punten;
}

function popPunt(x, y) {
	var punt = new Array(1);
	punt[0] = new Punt(x, y);
	return punt;
}	

function lijnPunten(x1, y1, xn, yn, stap) {
	var afstand = Math.abs(xn - x1);
	var unitx = Math.abs(xn - x1);
	var unity = Math.abs(yn - y1);
	var punten = new Array();
	var stappen = Math.round(Math.sqrt(Math.pow(unitx, 2) + Math.pow(unity, 2)) / stap);

	unitx = unitx / stappen;
	unity = unity / stappen;

	if (x1 > xn) unitx = -unitx;
	if (y1 > yn) unity = -unity;

	punten[0] = new Punt(x1, y1);
	var x = 0;
	var y = 0;

	while (Math.abs(x) < afstand) {
		x += unitx;
		y += unity;
		punten[punten.length] = new Punt(Math.round(parseInt(x1) + parseFloat(x)), Math.round(parseInt(y1) + parseFloat(y)));
	}
	punten[punten.length - 1] = new Punt(xn, yn);

	return punten;
}	

function boogPunten(x1, y1, x2, y2, hoek, metklok, stap) {
	// 1. parameters typeren
	x1 = parseInt(x1);
	y1 = parseInt(y1);
	x2 = parseInt(x2);
	y2 = parseInt(y2);
	hoek = parseInt(hoek);
	if (metklok.indexOf("true") < 0) metklok = false;
	else metklok = true;
	stap = parseFloat(stap);

	// 2. oorsprong bepalen (x0,y0)
	var koorde = wortel(kwadraat(x2 - x1) + kwadraat(y2 - y1));
	var straal = radius(koorde, hoek);
	var x0 = x1 + (0.5 * (x2 - x1));
	var y0 = y1 + (0.5 * (y2 - y1));

	// 3. loodlijn op midden koorde oprichten die eindigt in de oorsprong
	var overstaande = wortel(kwadraat(straal) - kwadraat(0.5 * koorde));
	var hoekje = inGraden(Math.acos((x2 - x1) / koorde));
	var xinc = Math.cos(inRads(90 - hoekje)) * overstaande;
	var yinc = Math.cos(inRads(hoekje)) * overstaande;
	var geval = 0;

	if (y1 > y2) geval += 1; 
	if (metklok) geval += 2;
	if (hoek > 180) geval += 4;

	if ((geval > 1) && (geval < 6)) {
		y0 += yinc;		
		if ((geval == 3) || (geval == 5)) x0 += xinc;
		else x0 -= xinc;		
	} else {
		y0 -= yinc;
		if ((geval == 0) || (geval == 6)) x0 += xinc;
		else x0 -= xinc;
	}

	var punten = new Array(afgerond((hoek / stap) + 1));

	var startx = x1;
	var starty = y1;
	var eindx;
	var eindy;

	// startkwadrant berekenen
	var kwad = 0;
	if (x0 < startx) {
		if (y0 < starty) kwad = 90;
	} else if (y0 <= starty) kwad = 180;
	else if (x0 > startx) kwad = 270;

	// beginhoek berekenen
	if ((kwad == 90) || (kwad == 270)) beginhoek = kwad + 90 - inGraden(Math.acos(Math.abs(starty - y0) / straal));
	else beginhoek = kwad + inGraden(Math.acos(Math.abs(starty - y0) / straal));

	for (i = 0; i < punten.length; i++) {
		punten[i] = new Punt(afgerond(x0 + (Math.sin(inRads(beginhoek)) * straal)), afgerond(y0 - (Math.cos(inRads(beginhoek)) * straal)));
		if (metklok) beginhoek += stap;
		else beginhoek -= stap;
	}

//geef(x0, y0, punten);

	return punten;
}

function geef(startx, starty, ptn) {
	var tkst = "[" + startx + "," + starty + "]\n   ";
	for (z = 0; z < ptn.length; z++) {
		tkst = tkst + "(" + ptn[z].x + "," + ptn[z].y + "), "
	}
	signaal(tkst);
}

function inRads(graden) {
	return  graden * Math.PI / 180;
}

function inGraden(rads) {
	return rads / (Math.PI/180);
}

function radius(koorde, hoek) {
	return (0.5 * koorde) / Math.cos(inRads(90 - (0.5 * hoek)));
}

function kwadraat(n) {
	return Math.pow(n, 2);
}

function wortel(n) {
	return Math.sqrt(n);
}

function afgerond(n) {
	return Math.round(n);
}

function alsObjekt(id) {
	if (browser.ie) return eval(id + ".style");
	else if (browser.ns4) return eval("document." + id);
	else return document.getElementById(id).style;
}

function zichtbaar(id) {
	var waarde = alsObjekt(id).visibility
	if ((waarde == "hide") || (waarde == "hidden")) return false;
	else return true;
}	

function browserIs() {
	var agent = window.navigator.userAgent.toLowerCase();
	this.major = parseInt(navigator.appVersion);
	this.minor = parseFloat(navigator.appVersion);
	this.ns = ((agent.indexOf('mozilla') != -1) &&
	(agent.indexOf('spoofer') == -1) &&
	(agent.indexOf('compatible') == -1) &&
	(agent.indexOf('opera') == -1) &&
	(agent.indexOf('webtv') == -1));
	this.ns2 = (this.ns && (this.major == 2));
	this.ns3 = (this.ns && (this.major == 3));
	this.ns4 = (this.ns && (this.major == 4));
	this.ns6 = (this.ns && (this.major >= 5));
	this.ie = (agent.indexOf("msie") != -1);
	this.ie3 = (this.ie && (this.major < 4));
	this.ie4 = (this.ie && (this.major >= 4));
	this.ie5 = (this.ie && (this.major == 4) && (agent.indexOf("msie 5.0") != -1));
	this.ieX = (this.ie && !this.ie3 && !this.ie4);
}


