
/* ========================================================================================================
	system_floatResize
	Globale Steuerung fuer Resize-Events
	Copyright (c) Wolfram Biedermann, Regen - Jede unerlaubte Verwendung untersagt
   ========================================================================================================
*/
/*	
	Bietet einen Rahmen, in den sich die jeweiligen Objekte einhaengen koennen. Die resize-Methoden der einzelnen Objekte werden von hier gesteuert. Bietet ausserdem Schutzmechanismen gegen Mehrfachaufruf innerhalb des Events und gegen unerwuenschte gegenseitige Unterbrechungen im Zusammenspiel mit beliebigen lokalen Eventhandlern (z.B. Galerie: kein resize, waehrend slide-Vorgang laeuft, und umgekehrt)
*/

//Debug
//var RESIZE_REQUIRED_UNCHANGED_COUNT = 3;
var RESIZE_REQUIRED_UNCHANGED_COUNT = 20;

var system_floatResize = 
{
	objects : [],
	inEvent : false,
	nextEvent : false,
	flagOnloadInit : false,
	preOnloadTracking : false,
	onReadyFunc : [],	// externe Funktionen, die bei resize-fertig augerufen werden

// ========================================================================================================
//  	Registrieren und Abfragen
// ========================================================================================================

	///////////////////////////////////////////////////////
	// Eintragen der Objekte
	// NEU: Eintragen mit einer bestimmten Prioritaet, so dass das Objekt an eine bestimmte Stelle einsortiert wird.
	// Vorgaben fuer Priritaet gibt es nicht. PHP verwendet 0 als Defaultprioritaet.
	// preOnloadTrack (Flag): Bedeutet, dass das entsprechende Objekt bereits VOR Onload
	// Groessenaenderungen verfolgen soll. Wird fuer saubere Darstellung gebraucht (hauptsaechlich dynwrapper)
	//
	registerObj : function ( obj, priority, preOnloadTrack )
	{
		var resize_obj = {};
		var neuerPlatz, i;
		var count = system_floatResize.objects.length;

		resize_obj["obj"] = obj;
		resize_obj["priority"] = priority;
		resize_obj["unchanged_counter"] = 0;
		resize_obj["preonload_track"] = preOnloadTrack;

// Von oben her neuen Platz suchen
// Bei gleichen Prioritaeten zaehlt die Reihenfolge des Eintrages
// Abgearbeitet wird spaeter von oben nach unten, also die zuletzt eingetragenen zuerst
		for( neuerPlatz = count; neuerPlatz > 0; neuerPlatz-- ) {
			if( system_floatResize.objects[neuerPlatz-1]["priority"] <= priority ) 
		break;
		}
// Array von neuerPlatz an um 1 hochfahren
		for( i = count ; i > neuerPlatz; i-- )
			system_floatResize.objects[i] = system_floatResize.objects[i-1];

		system_floatResize.objects[neuerPlatz] = resize_obj;

// Jedes Objekt kann eine Methode resizeInit() besitzen. Sie merkt z.B. die vorhandene Groesse fuer den spaeteren Vergleich alt-neu
// Oder irgendwas sonst
// !! Beachte bei der Erstellung der resizeInit-Funktionen, dass sich die Seite noch im Aufbau befindet und daher jede Groessenermittlung
// nur vorlaeufig sein kann
		if( obj.resizeInit )
			obj.resizeInit();
	},

	///////////////////////////////////////////////////////
	// isInEvent
	// externe Abfrage, ob wir uns gerade in einem Event-Handling befinden
	// ermoeglicht lokalen Funktionen, ihre Aktionen darauf abzustimmen bzw. stoerende Aktionen zu vermeiden
	//
	isInEvent : function () {
	return system_floatResize.inEvent;
	},

	///////////////////////////////////////////////////////
	// isOnloadInit
	// externe Abfrage, ob Onload schon gelaufen
	//
	isOnloadInit : function () {
	return system_floatResize.flagOnloadInit;
	},

	///////////////////////////////////////////////////////
	// activateEventhandler
	// Aktiviert den Eventhandler (auch extern vor der Zeit aufrufbar, also vor onload)
	// Kann z.B. eingesetzt werden, wenn bei langer Ladezeit bis onload schon Groessenaenderungen moeglich erscheinen
	// Kann zusammen mit Pre-Onload-Tracking laufen. Eventhandling unterbricht in diesem Falle das Tracking
	//
	activateEventhandler : function () {
		window.onresize = system_floatResize.eventhandler;
	},

// ========================================================================================================
//  	onReady-Funktionen
// ========================================================================================================

	///////////////////////////////////////////////////////
	// Funktion registrieren
	// Gibt den Index als Handle zurueck fuer evtl unregister
	// simples Auffuellen der Tabelle, also nachher sequentiell abarbeiten, keine Prioritaeten
	//
	registerOnReadyFunc : function ( func ) {
		var i = system_floatResize.onReadyFunc.length;
		system_floatResize.onReadyFunc[i] = func;
	return i;
	},

	///////////////////////////////////////////////////////
	// Funktion entregistrieren
	//
	unregisterOnReadyFunc : function ( ix ) 
	{
		var i, geloescht = false;
		for( i = ix; i < system_floatResize.onReadyFunc.length-1; i++ ) {
			system_floatResize.onReadyFunc[i] = system_floatResize.onReadyFunc[i+1];
			geloescht = true;
		}
		if( geloescht )
			system_floatResize.onReadyFunc.length--;
	},

	///////////////////////////////////////////////////////
	// onReady-Funktionen ausfuehren
	//
	doOnReadyFunc : function () {
		var i;
		for( i = 0; i < system_floatResize.onReadyFunc.length; i++ ) {
			system_floatResize.onReadyFunc[i]();
		}
	},

// ========================================================================================================
//  	Onload
// ========================================================================================================

	///////////////////////////////////////////////////////
	// onloadInit
	// Ruft die onload-Init-Funktionen auf und setzt einen kompletten Resize-Event
	//
	onloadInit : function () {
		var i;

		system_floatResize.flagOnloadInit = true;	// Zuerst auf true schalten und damit das Pre-Onload-Tracking abstellen
		for( i = 0; i < system_floatResize.objects.length; i++ )	{
			if( system_floatResize.objects[i]["obj"] )	// Eigentlich duerfte hier nie false sein... (!)
				if( system_floatResize.objects[i]["obj"].onloadInit )
					system_floatResize.objects[i]["obj"].onloadInit();
		}
// Ab jetzt normale Reaktion auf Resize-Events
		system_floatResize.activateEventhandler();
//		window.onresize = system_floatResize.eventhandler;
		system_floatResize.eventhandler();
	},

// ========================================================================================================
//  	Pre-Onload-Tracking
// ========================================================================================================

	///////////////////////////////////////////////////////
	// startPreOnloadTracking
	// "ausserordentliche" Ereignisverfolgung waehrend des Seitenladens starten
	//
	startPreOnloadTracking : function ( interval ) {
		system_floatResize.preOnloadTracking = true;
		system_floatResize.doPreOnloadTracking( interval );
	},

	///////////////////////////////////////////////////////
	// stopPreOnloadTracking
	// "ausserordentliche" Ereignisverfolgung waehrend des Seitenladens stoppen
	//
	stopPreOnloadTracking : function ()	{
		system_floatResize.preOnloadTracking = false;
	},

	///////////////////////////////////////////////////////
	// doPreOnloadTracking
	// "ausserordentliche" Ereignisverfolgung waehrend des Seitenladens
	//
	doPreOnloadTracking : function ( interval )
	{
		var i, changed;

// onload beendet Tracking automatisch
		if( system_floatResize.flagOnloadInit )
	return;
// ueber stopPreOnloadTracking() gesetzt
		if( !system_floatResize.preOnloadTracking )
	return;

		if( ! system_floatResize.hasLocalProtection() ) 
		{
// Einfaches steppen durch die Objekttabelle, und wo das tracking-Flag gesetzt ist, abarbeiten
			for( i = system_floatResize.objects.length -1 ; i >= 0; i-- ) {
// Wenn ein echter Aufruf des Eventhandlers erfolgt ist, hier einfach aufhoeren
				if( system_floatResize.inEvent )
			break;
// Objekt und Funktion existiert ueberhaupt ? (array kann durch gleichzeitiges Einsortieren beu registerObj inkosistent sein)
				if( system_floatResize.objects[i]["obj"] )
					if( system_floatResize.objects[i]["obj"].resize )
						if( system_floatResize.objects[i]["preonload_track"] )
							changed = system_floatResize.objects[i]["obj"].resize();
			}
		}
		window.setTimeout( "system_floatResize.doPreOnloadTracking()", interval );
	},

// ========================================================================================================
//  	Eventhandling
// ========================================================================================================

	///////////////////////////////////////////////////////
	// hasLocalProtection
	// Abfrage der lokalen Schutzfunktionen
	//
	hasLocalProtection : function () 
	{
		var i, rueck = false;

		for( i = 0; i < system_floatResize.objects.length; i++ ) {
			if( system_floatResize.objects[i]["obj"] )	// Eigentlich duerfte hier nie false sein... (!)
				if( system_floatResize.objects[i]["obj"].isLocallyProtected )	// Methode existiert?
					if( rueck = system_floatResize.objects[i]["obj"].isLocallyProtected() )
		break;
		}
	return rueck;
	},

	///////////////////////////////////////////////////////
	// eventhandler
	//
	eventhandler : function ()
	{
		var i;

		if( system_floatResize.inEvent ) {
			system_floatResize.nextEvent = true;
	return;
		}
		system_floatResize.inEvent = true;
		for( i = 0; i < system_floatResize.objects.length; i++ ) {		// Counter zuruecksetzen
			system_floatResize.objects[i]["unchanged_counter"] = 0;
		}
		system_floatResize.execute();
	},

	///////////////////////////////////////////////////////
	// execute
	// Die eigentliche Ausfuehrungsfunktion
	//
	execute : function ()
	{
		var i = 0;
		var ready = true;
		var changed = false;
		var locally_protected = false;

// Lokalen Schutz ermitteln (jedes Objekt kann die Methode .isLocallyProtected() haben )
		if( locally_protected = system_floatResize.hasLocalProtection() )
			ready = false;

// Wenn auch nur eine Funktion den lokalen Schutz gesetzt hat, hier gar nichts ausfuehren, sondern auf den naechsten Timeout warten
		if( ! locally_protected ) 
		{	
// Abwaerts gehen, von hoechster Prioritaet zu niederster
			for( i = system_floatResize.objects.length -1 ; i >= 0; i-- )
			{
				if( system_floatResize.objects[i]["obj"] )	{ // Eigentlich duerfte hier nie false sein... (!)
					if( system_floatResize.objects[i]["obj"].resize ) {
// Obligatorische Methode resize() mit der Rueckgabe true fuer veraendert, false fuer unveraendert
						changed = system_floatResize.objects[i]["obj"].resize();
						if( !changed ) {
							system_floatResize.objects[i]["unchanged_counter"]++;
						}
						else {
							system_floatResize.objects[i]["unchanged_counter"] = 0;
						}
// nach ca. 1 sec. (20x bei 50 ms) unveraenderter Abfragen aufhoeren, es sei denn, es kam noch ein neuer Event herein
// (nextEvent). ein Folgevent setzt die uveraendert-Zaehler wieder auf 0
// Der Mechanismus soll sicherstellen, dass solange der Benutzer die Fenstergroesse aendert, 
// pausenlos abgefragt wird, aber im Ruhezustand keine Rechnerlast entsteht.
						if( system_floatResize.nextEvent )
							system_floatResize.objects[i]["unchanged_counter"] = 0;
						if( system_floatResize.objects[i]["unchanged_counter"] < RESIZE_REQUIRED_UNCHANGED_COUNT )
							ready = false;
					}
				}
			}
			system_floatResize.nextEvent = false;
		}
		
		if( !ready ) 
			window.setTimeout( "system_floatResize.execute()", 50 );
		else {
// 				var h = document.body.offsetTop;
// 				alert( h );
// 						  window.FB.Canvas.setSize({ width: 700, height: h+50 });

			system_floatResize.doOnReadyFunc();
			system_floatResize.inEvent = false;		// globaler Aufrufschutz fuer den Mechanismus
//  		alert( "fertig" );
		}
	}
};
