var AnzahlObjekte = 4; // Anzahl der Ebenen in der HTML-Datei (beginnend mit dot0); tatsächlich animiert werden 1 weniger (die erste Ebene (dot0) bleibt unsichtbar an der Startposition)
var DOTSIZE = 11; // Größe der Objekte (wichtig für das Abprallen unten und rechts)
var DELTAT = 0.01; // Geschwindigkeit
var SEGLEN = 10; // Abstand zwischen den einzelnen Objekten
var SPRINGK = 10; // Straffheit der "Gummischnur" (über 15 unbrauchbar)
var MASS = 1.5 // Gewicht der Objekte (ändert die Länge der "Gummischnur")
var GRAVITY = 50; // Gravitation (Tendenz der Objekte nach unten)
var RESISTANCE = 15; // Innere Trägheit der "Gummischnur" (unter 5 unbrauchbar)
var STOPVEL = 0.5; // Wie schnell kommen die Objekte zum Stillstand. Bei zu hohem Wert erreichen sie nicht einmal die hängende Position, bei zu niedrigem Wert zucken sie endlos 0.1
var STOPACC = 0.5; // Ähnlich STOPVEL. Hier wird aber die Beschleunigung gemessen (dort die Geschwindigkeit)
var BOUNCE = 0.75; // Stärke des Abprallens vom Fensterrand
var XPosition = 0; // Startposition der Objekte
var YPosition = 0;
var dots = new Array();

function init() { // erzeugt die Variablen dots[1], dots[2],... mittels der Funktion dot(i)
	MM_showHideLayers('dot1','','show','dot2','','show','dot3','','show','animation','','hide','verankern','','show');
	var i = 0;
	for (i = 0; i < AnzahlObjekte; i++) {
		dots[i] = new dot(i);
	}
	for (i = 0; i < AnzahlObjekte; i++) {
		dots[i].obj.style.left = dots[i].X + "px"; // Firefox verlangt bei Doctype XHTML die Angabe von Zahl + "px"
		dots[i].obj.style.top = dots[i].Y + "px";
	}
	startanimate();
}

function dot(i) {
this.X = XPosition;
this.Y = YPosition;
this.dx = 0;
this.dy = 0;
this.obj = document.getElementById("dot" + i);
}

function startanimate() {
	aktiv = setInterval("animate()", 20);
}

function stopanimate () {
	clearInterval(aktiv);
	MM_showHideLayers('dot1','','hide','dot2','','hide','dot3','','hide','animation','','show','verankern','','hide');
}

function MoveHandlerNetscape(UnnoetigeEreignisVariable) {
	XPosition = UnnoetigeEreignisVariable.pageX?UnnoetigeEreignisVariable.pageX:UnnoetigeEreignisVariable.screenX; // screenX misst möglicherweise vom Bildschirmrand (nicht vom Fensterrand); pageX ist daher genauer
	YPosition = UnnoetigeEreignisVariable.pageY?UnnoetigeEreignisVariable.pageY:UnnoetigeEreignisVariable.screenY; // Safari misst screenY vom unteren Rand; pageY ist hier also lebenswichtig
	return true;
}

function MoveHandler() {
	XPosition = window.event.clientX + document.body.scrollLeft;
	YPosition = window.event.clientY + document.body.scrollTop;
}

if (document.all) {document.onmousemove = MoveHandler;} // document.all: MSIE (in der Hoffnung, dass alle Browser, die auf document.all reagieren, auch bei document.onmousemove MSIE-kompatibel sind)
else {document.captureEvents(Event.MOUSEMOVE); document.onmousemove = MoveHandlerNetscape;}

function vec(X, Y) {
	this.X = X;
	this.Y = Y;
}

// adds force in X and Y to spring for dot[i] on dot[j]
function springForce(i, j, spring) {
	var dx = (dots[i].X - dots[j].X);
	var dy = (dots[i].Y - dots[j].Y);
	var len = Math.sqrt(dx*dx + dy*dy);
	if (len > SEGLEN) {
	var springF = SPRINGK * (len - SEGLEN);
	spring.X += (dx / len) * springF;
	spring.Y += (dy / len) * springF;
   }
}

function animate() {	
	dots[0].X = XPosition;
	dots[0].Y = YPosition;	
	for (i = 1 ; i < AnzahlObjekte; i++ ) {
		var spring = new vec(0, 0);
		if (i > 0) {
			springForce(i-1, i, spring);
		}
		if (i < (AnzahlObjekte - 1)) {
			springForce(i+1, i, spring);
		}
		var resist = new vec(-dots[i].dx * RESISTANCE, -dots[i].dy * RESISTANCE);
		var accel = new vec((spring.X + resist.X)/ MASS,(spring.Y + resist.Y)/ MASS + GRAVITY);
		dots[i].dx += (DELTAT * accel.X);
		dots[i].dy += (DELTAT * accel.Y);
		if (Math.abs(dots[i].dx) < STOPVEL &&
			Math.abs(dots[i].dy) < STOPVEL &&
			Math.abs(accel.X) < STOPACC &&
			Math.abs(accel.Y) < STOPACC) {
			dots[i].dx = 0;
			dots[i].dy = 0;
		}
		dots[i].X += dots[i].dx;
		dots[i].Y += dots[i].dy;
		var Fensterhoehe, Fensterbreite, height, width;
		Fensterhoehe = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight; // Reihenfolge ist wichtig, weil Oper8 gibt bei document.documentElement.clientHeight 16 zurück
		Fensterbreite = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body.clientWidth;
		GescrollteStreckeOben = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ? document.body.scrollTop : window.pageYOffset;
		GescrollteStreckeLinks = document.documentElement.scrollLeft ? document.documentElement.scrollTop : document.body.scrollLeft ? document.body.scrollLeft : window.pageXOffset;
		if (isNaN(GescrollteStreckeOben)) {GescrollteStreckeOben = 0;} // MSIE 6 im Strict Mode gibt 'undefined' zurück, wenn nicht gescrollt wurde
		if (isNaN(GescrollteStreckeLinks)) {GescrollteStreckeLinks = 0;}
		height = Fensterhoehe + GescrollteStreckeOben;
		width = Fensterbreite + GescrollteStreckeLinks;
		if (dots[i].Y >=  height - DOTSIZE - 1) {
			if (dots[i].dy > 0) {
				dots[i].dy = BOUNCE * -dots[i].dy;
			}
			dots[i].Y = height - DOTSIZE - 1;
		}
		if (dots[i].X >= width - DOTSIZE) {
			if (dots[i].dx > 0) {
				dots[i].dx = BOUNCE * -dots[i].dx;
			}
			dots[i].X = width - DOTSIZE - 1;
		}
		if (dots[i].X < 0) {
			if (dots[i].dx < 0) {
				dots[i].dx = BOUNCE * -dots[i].dx;
			}
		dots[i].X = 0;
		}
		dots[i].obj.style.left = dots[i].X + "px"; // Firefox verlangt bei Doctype XHTML die Angabe von Zahl + "px"
		dots[i].obj.style.top =  dots[i].Y + "px";
	}
}