/******************************************************************************
 * 
 * Das GUI-Objekt(Singleton), stellt einer Seite gewisse Daten global zur Ver-
 * fügung.
 * Diese Daten werden in zwei Gruppen gegliedert: "Objekte" und "Funktionen".
 * 
 * "Objekte":
 * Bei Objekten kann es sich um jedes beliebige JavaScript-Objekt handeln.
 * Dieses wird dann unter einem zur Laufzeit der Seite global abrufbaren
 * Bezeichner (Id) im GUI-Objekt mit der Methode "registerObject()"
 * hinterlegt.
 * 
 * 
 * "Funktionen":
 * Diese sind klassische anonyme JavaScript Funktionen und werden mit der
 * Methode "registerFunction()" einem oder mehreren Events zugeordnet.
 * Zur Zeit implementierte Events sind "onStart", "onResize", "onClick".
 * 
 * (Denkbare Erweiterung hierbei könnten auch Events wie "onAjaxCall" sein, 
 * welche dann beispielsweise bei jedem AJAX Aufruf der irgendwo auf der
 * Seite passiert ausgeführt wird)
 * 
 * HINWEIS: Die Reihenfolge der Registrierung der Funktionen legt ihre Aus-
 * führung beim Event fest!
 * 
 * Bei jeder Ausführung eines Events wird der anonymen Funktion das GUI-Objekt
 * als erster Funktionsparameter mit übergeben. Somit stehen innerhalb der
 * anonymen Funktion auch alle registrierten Funktionen und Objekte zur
 * Verfügung. Der zweite Parameter ist der Event selbst.
 * 
 * 
 * HINWEIS: Mit Unterstrich versehene Funktionen sind private Funktionen.
 * 
 ******************************************************************************/

if(!GUI) {

	var GUI = Singleton.create({
		
		initialize: function() {
			this.registeredFunctions = $H({ 'onStart': [], 'onResize': [], 'onClick': [] });
			this.registeredObjects = $H();
			
			this.options = {
				'debug': false
				};
			this.actualEvent = null;
			
			Event.observe(document, "dom:loaded", this._onStart.bindAsEventListener(this));
			Event.observe(document, 'click', this._onClick.bindAsEventListener(this));
			Event.observe(window, 'resize', this._onResize.bindAsEventListener(this));
			},
			
			
		/*
		 * Öffentliche Methode zur Registrierung einer anonymen Funktion, die
		 * bei einem oder mehreren bestimmten Events ausgeführt werden soll.
		 * 
		 *  @param String		Kommaseparierte Liste der gewünschten
		 *  					Events.
		 *  @param Funktion		Die beim Event auszuführende Funktion.
		 *  @param String		Position; soll die Funktion von oben
		 *  					("top") oder von unten (Standard) in den
		 *  					internen Stack geschrieben werden, somit
		 *  					kann noch die Ausführungsreihenfolge be-
		 *  					einflusst werden.
		 */
		registerFunction: function(events, f, pos){
			var eventNames = events.strip().split(','); 
			
			eventNames.each(function(eventName){
				switch (pos){
					case 'top':
						this.registeredFunctions.get(eventName).unshift(f);
						break;
					
					default:
						this.registeredFunctions.get(eventName).push(f);
					}
				}.bind(this));
			},
			
			
		/*
		 * Öffentliche Methode zur Registrierung eines allgemeinen Objektes.
		 * 
		 *  @param String		Bezeichner, damit kann per Getter eine andere
		 *  					Funktion wieder auf den registrierten Inhalt
		 *  					zugreifen.
		 *  @param Object		Das Objekt, welches registriert werden soll.
		 *  					Per "getRegisteredObject()" kann anschliessend
		 *  					von jeder beliebigen Stelle auf der Seite auf
		 *  					den registrierten Inhalt zugegriffen werden.
		 */
		registerObject: function(id, object){
			this.registeredObjects.set(id, object);
			},
			
			
		getRegisteredObject: function(id){
			return this.registeredObjects.get(id);
			},
			
			
		_doInitSequence: function(){
			/*
			 Hier kann Code hinterlegt werden, der noch vor allen anderen
			 Events auf der Seite ausgeführt wird. (frühest möglicher Ausführungs-
			 zeitpunkt ist der "onLoad"-Event der Seite.
			 
			 Hier ein Beispiel, welches der GUI einen überall verfügbaren
			 Modalen Dialog ermöglicht:
			 
			 
			 this.registerFunction('onStart', function(gui, event){
				var body	= $(document.body);
				var overlay	= new Element('div', { 'class': 'gui-overlay', 'style': 'z-index: 10000' }).hide();
				body.insert({ 'top': overlay });
				
				gui.registerObject('body', body);
				gui.registerObject('overlay', overlay);
				gui.registerObject('dialog', new Dialog(body, { 'overlay': overlay }));
				}, 'top');
			
			this.registerFunction('onStart,onResize', function(gui, event){
				var overlay		= gui.getRegisteredObject('overlay');
				var viewport	= document.viewport.getDimensions();
				
				overlay.setStyle({ 'width': ''.concat(viewport.width, 'px'), 'height': ''.concat(viewport.height, 'px') });
				});
				
			 */
			},
			
			
		_onStart: function(event){
			this._doInitSequence();
			this._executeFunctions('onStart', event);
			},
			
			
		_onResize: function(event){
			this._executeFunctions('onResize', event);
			},
			
			
		_onClick: function(event){
			this._executeFunctions('onClick', event);
			},
			
			
		_executeFunctions: function(eventType, event){
			this.actualEvent = event;
			
			var funktions = this.registeredFunctions.get(eventType);
				
				funktions.each(function(f){
					try {
						f(this, event);
					}
					
					catch(e){
						if (this.options.debug)
							alert('Cy:con GUI Error in '.concat(eventType, '-Handler.\n\n', e, '\n\nTried to execute: ', f));
					}
				}.bind(this));
			}
		});
	}

if (typeof(Cycon) === 'undefined')
	Cycon = new Object();

// Benutze den Singleton
Cycon.GUI = GUI.get();

