/* anim_action.js */
/* erfordert brow_sen.js !!! */
/* action-Klasse: definiert Zeitraum und Art einer Animation für ein HTML-Element */
/* Neue Version, fuer Browser IE4, NS4 UND NS5(=Netscape 6)! */
/* Arnd Wiese, letzte Aenderung: 30.05.2001 */

////////////////////////
// globale Variablen:
var jetzt = new Date();
var startZeit = jetzt.getTime();
var timerInterval = 50;

////////////////////////
// globale Funktionen:

function getAbsTime()
{
	 var jetzt = new Date();
	 return (jetzt.getTime() - startZeit);
}

// diese Funktion wird per "onLoad" (im Body-Tag) aufgerufen:
function startAnimationTimer()
{
	// fuer Netscape 6:
	var isNS6 = ((!document.all && isBrowserNew) ? true : false);
	if ( isNS6 )
	{ 
		for ( i=0; i < actionArray.length; i++ )  // Positionsvariablen der Action-Objekte konvertieren  
		{
			actionArray[i].getKoordsFromRelElem();
		}	
	}
	// ENDE fuer Netscape 6
	
	var jetzt = new Date();
	startZeit = jetzt.getTime();  // startZeit ist global
	
	animationTimer();  // Timer anstossen
}

function animationTimer()
{
	aktTime = getAbsTime();

	for ( i=0; i < actionArray.length; i++ )
	{
		actionArray[i].doAnim(aktTime);
	}
	window.setTimeout("animationTimer()",timerInterval); 
}

///////////////////////////////////////////////////
// CAction Methoden:
function CAction_doAnim(aktTime)
{
	if ( !(this.autostart) ) return;
	
	//this.aktRelTime = aktTime - this.timeBegin;
	this.aktRelTime = getLoopTime(this.elemID,aktTime) - this.timeBegin;
	
	// wegen Loop:
	if ( this.aktRelTime < this.lastAktRelTime ) this.aktVisible = -1;  // falls Loop-Ruecksprung erfolgt, dann Visibility neu setzen
	this.lastAktRelTime = this.aktRelTime; 
	
	if ( this.aktRelTime > this.timeLen )
	{
		this.setZIndex();
	    if ( this.aktX != this.endX || this.aktY != this.endY )
	    { 
			this.aktX = this.endX;
			this.aktY = this.endY;
			this.updateSpanPosition();
			this.setVisible(this.beginVis);  // sicherheitshalber
		} 
	}
	else if ( this.aktRelTime >= 0 )  // Bewegung
	{
		this.setZIndex();
		this.move();
		this.setVisible(this.beginVis);
	} 
}

function CAction_moveStraight()
{
	var streckVerh = this.aktRelTime / this.timeLen;
	var zurueckgelegtX = Math.round(this.wegX * streckVerh);
	var zurueckgelegtY = Math.round(this.wegY * streckVerh);
	this.aktX = this.beginX + (zurueckgelegtX * this.richtX);
	this.aktY = this.beginY + (zurueckgelegtY * this.richtY);
	
	this.updateSpanPosition();
}

function CAction_moveSpiral()
{
	var streckVerh = this.aktRelTime / this.timeLen;
    var aktRadius = (1.0 - streckVerh) * this.radius;  // aktueller Radius
	var t = ((-this.links) * streckVerh * 2.0 * Math.PI) + this.spiralGradPlus;
	this.aktX = Math.ceil(aktRadius * Math.cos(t)) + this.endX;
	this.aktY = Math.ceil(aktRadius * Math.sin(t)) + this.endY;

	this.updateSpanPosition();
}

// initialisiert fuer Spirale zusaetzliche Variablen: this.radius und this.spiralGradPlus:
function CAction_initSpiral()
{
	this.radius = Math.sqrt(Math.pow(this.spiralX,2) + Math.pow(this.spiralY,2));
	if ( this.spiralX > 0 ) this.spiralGradPlus = Math.PI + Math.atan(this.spiralY/this.spiralX);
	else if ( this.spiralX < 0 ) this.spiralGradPlus = Math.atan(this.spiralY/this.spiralX);
	else  // this.spiralX == 0
	{
		if ( this.spiralY > 0 ) this.spiralGradPlus = -Math.PI / 2.;
		else this.spiralGradPlus = Math.PI / 2.;
	}
}

// initialisiert fuer Bogen zusaetzliche Variablen: this.radius und this.spiralGradPlus:
function CAction_initBogen()
{
	// spiralX, spiralY ist im folgenden der Mittelpunkt des Kreises

	var vekX = (this.endX - this.beginX) / 2.;
	var vekY = (this.endY - this.beginY) / 2.;
		
	// Berechnung des Kreis-Mittelpunkts per Verbindungs-Orthogonale:
	if ( this.links == 1 )
	{
		this.spiralX = this.beginX + Math.round(vekX - vekY);
		this.spiralY = this.beginY + Math.round(vekY + vekX);
	}
	else
	{
		this.spiralX = this.beginX + Math.round(vekX + vekY);
		this.spiralY = this.beginY + Math.round(vekY - vekX);
	}
	
	// Radius ermitteln:
	this.radius = Math.sqrt((Math.pow((this.endX - this.beginX),2.) + Math.pow((this.endY - this.beginY),2.)) / 2.);
	
	var dX = this.beginX - this.spiralX;
	var dY = this.beginY - this.spiralY;

	var atan = Math.atan(Math.abs(dY/dX));
	
	if ( dX > 0 )
	{
		if ( dY >= 0 ) this.spiralGradPlus = atan;
		else this.spiralGradPlus = -atan;
	}
	else if ( dX < 0 )
	{
		if ( dY >= 0 ) this.spiralGradPlus = Math.PI - atan;
		else this.spiralGradPlus = Math.PI + atan;
	}
	else  // dX == 0
	{
		if ( dY >= 0 ) this.spiralGradPlus = Math.PI / 2.; 
		else this.spiralGradPlus = -(Math.PI / 2.); 
	}
}

function CAction_moveBogen()
{
	var streckVerh = this.aktRelTime / this.timeLen;

	var gradPlus = streckVerh * Math.PI/2.; 

	var t = this.spiralGradPlus + this.links * gradPlus;

	this.aktX = Math.ceil(this.radius * Math.cos(t)) + this.spiralX;
	this.aktY = Math.ceil(this.radius * Math.sin(t)) + this.spiralY;
	
	this.updateSpanPosition();
}

function CAction_setVisible(vis)
{
	if ( vis )
	{ 
		if ( this.aktVisible != 1 )
		{
			var elemStyle = getElemStyle(this.elemID);
			if ( elemStyle.visibility != "visible" )
			{
				elemStyle.visibility = "visible";
				this.aktVisible = 1;
			}
		}	
	}
	else
	{
		if ( this.aktVisible != 0 )
		{
			getElemStyle(this.elemID).visibility = "hidden";
	        this.aktVisible = 0;
		}
	}
}

function CAction_setZIndex()
{
	if ( this.zIndexAlreadySet ) return;
	// z-index wurde noch nicht gesetzt; jetzt setzen:
	getElemStyle(this.elemID).zIndex = this.zindex;
	this.zIndexAlreadySet = true;
}	

function CAction_updateSpanPosition()
{
    getElemStyle(this.elemID).left = this.aktX;
	getElemStyle(this.elemID).top = this.aktY;
}

// Koordinaten von den relativ positionierten Schwesternelementen uebernehmen:
function CAction_getKoordsFromRelElem()
{
	// nur fuer Netscape 6:
	if ( !isBrowserNew ) return;
	
	var relObj = getElem(this.elemID);

	var offsetX = getLeftOffset( relObj );
	var offsetY = getTopOffset( relObj );

	this.beginX += offsetX;
	this.beginY += offsetY;
	this.endX += offsetX;
	this.endY += offsetY;
	this.aktX += offsetX;
	this.aktY += offsetY;
	
	this.elemID += "abs";
	
	// falls Bogen-Bewegung, dann nochmal initialisieren, weil Koordinaten geaendert wurden:
	if ( this.bewegung == "bogen" || this.bewegung == "bogen2" ) this.initBogen();
}

// Hilfsfunktionen:
function getLeftOffset( obj )
{
	if (obj.offsetParent) return (obj.offsetLeft + getLeftOffset(obj.offsetParent));
	else return (obj.offsetLeft);
}
function getTopOffset( obj )
{
	if (obj.offsetParent) return (obj.offsetTop + getTopOffset(obj.offsetParent));
	else return (obj.offsetTop);
}

///////////////////////////////////////////////////
// CAction Deklaration/Konstruktor:
function CAction(elemID,bewegung,timeBegin,timeLen,vis,beginX,beginY,endX,endY,links,autostart,breite,hoehe,zindex,extraString)
{
    if ( CAction.arguments.length != 15 ) { alert("Fehler: Konstruktor CAction wurde nicht mit 15 Parms aufgerufen!"); return null; }
    
	this.elemID = elemID;  // string
	this.bewegung = bewegung;  // string: "straight", "spiral1", etc.
	
	this.timeBeginOrig = timeBegin * 100;  // int, in 1/10 sec	
	this.timeBegin = this.timeBeginOrig;
	this.timeLen = timeLen * 100;  // int, in 1/10 sec 

	this.beginVis = vis;  // bool

	this.aktVisible = -1;  // -1 = Visibility-Status des Span-Objekts noch nicht bekannt, 
	                       //  0 = hidden, 1 = visible

	this.beginX = beginX;  // int
	this.beginY = beginY;  // int
	this.endX = endX;  // int
	this.endY = endY;  // int
	
	// Variablen fuer Spirale:
	this.spiralX = endX - beginX;
	this.spiralY = endY - beginY;
	this.radius = 0;
	this.spiralGradPlus = 0;
	
	this.breite = breite;
	this.hoehe = hoehe; 
	this.links = ( links ) ? 1 : -1;
	this.autostart = autostart;
	
	this.zindex = zindex;
	this.zIndexAlreadySet = false;  // bool
	
	this.lastAktRelTime = 0;  // wegen Loop
	
	this.aktionsName = extraString.replace(/^\s+/,"");
	this.aktionsName = this.aktionsName.replace(/\s+$/,"");  
	
	/////////////////////////
	// abgeleitete Variablen (fuer Geschwindigkeitssteigerung):
	this.wegX = Math.abs(this.endX - this.beginX);
	this.wegY = Math.abs(this.endY - this.beginY);
	this.richtX = ( this.endX > this.beginX ) ? 1 : -1;
	this.richtY = ( this.endY > this.beginY ) ? 1 : -1;
	
	/////////////////////////
	// Verlaufsvariablen:
	this.aktX = beginX;
	this.aktY = beginY;
	this.aktRelTime = 0;
	
	/////////////////////////
	// obige Funktionen als Methoden dieser Klasse definieren:
	this.getKoordsFromRelElem = CAction_getKoordsFromRelElem;
	this.doAnim = CAction_doAnim; 
	this.setVisible = CAction_setVisible;
	this.setZIndex = CAction_setZIndex;
	this.updateSpanPosition = CAction_updateSpanPosition;
	this.initSpiral = CAction_initSpiral;
	this.initBogen = CAction_initBogen;

	switch ( this.bewegung )
	{
	case "straight":
		this.move = CAction_moveStraight;
	break;
	case "spiral":  // Spirale im Uhrzeigersinn
		this.move = CAction_moveSpiral;
		this.links = -1;
		this.initSpiral();
	break;
	case "spiral2":  // Spirale gegen den Uhrzeigersinn
		this.move = CAction_moveSpiral;
		this.links = 1;
		this.initSpiral();
	break;
	case "bogen":  // Bogen im Uhrzeigersinn
		this.move = CAction_moveBogen;
		this.links = -1;
		this.initBogen();
	break;
	case "bogen2":  // Bogen gegen den Uhrzeigersinn
		this.move = CAction_moveBogen;
		this.links = 1;
		this.initBogen();
	break;
	default:
		alert("CAction-Konstruktor: Wert von 'bewegung' ist ungueltig!");
	break;
	} 
}
///// Ende CAction Deklaration/Konstruktor /////

// CLoop Deklaration/Konstruktor:
function CLoop(elemID,begin,len,anzahl)
{
	this.elemID = elemID;
	if ( isBrowserNew ) this.elemID += "abs";
	
	this.begin = begin * 100;
	this.len = len * 100;
	this.anzahl = anzahl;  // Anzahl der Spruenge vom Ende zum Beginn des Loop-Zeitraums
	
	this.end = this.begin + this.len; 
	this.lastEnd = this.begin + ((anzahl+1) * this.len);  
	
	this.getLoopTime = CLoop_getLoopTime;
}	
///// Ende CLoop Deklaration/Konstruktor /////

function CLoop_getLoopTime(aktTime)
{
	if ( aktTime > this.begin && aktTime <= this.lastEnd )
	{
		return ( this.begin + ((aktTime - this.begin) % this.len) );
	}
	else return aktTime;
}

function getLoopTime(elemID,aktTime)
{
	var i = 0;
	var loopTime = aktTime;
	for ( i=loopArray.length-1; i>=0; i-- )
	{
		if ( loopArray[i].elemID == elemID ) 
		{
			loopTime = loopArray[i].getLoopTime(aktTime);
			if ( loopTime != aktTime ) return loopTime;			
		} 
	}
	return aktTime;  // kein Loop fuer dieses Element vorhanden 
}

function triggerAktion( nameDerAktion )
{
	var iTrig = 0;
	var aktionsName = nameDerAktion.replace(/^\s+/,"");
	aktionsName = aktionsName.replace(/\s+$/,"");
	for ( iTrig=0; iTrig < actionArray.length; iTrig++ )
	{
		if ( aktionsName == actionArray[iTrig].aktionsName )
		{
			actionArray[iTrig].timeBegin = getAbsTime() + actionArray[iTrig].timeBeginOrig;
			actionArray[iTrig].aktVisible = -1;
			actionArray[iTrig].autostart = true;		
		}
	}
}
///////////////////////////////////////////////////
actionArray = new Array();
var i_anim = 0;
loopArray = new Array();
var i_loop = 0;
//EOF