﻿/**
 * Eve.RegisterCards
 *
 * WAS STELLT DIESE DATEI ZUR VERFUEGUNG?
 *
 * 		- Registerkarten-Funktionen
 *
 * WAS BENOETIGT DIESE DATEI?
 *
 * 		- jquery.js (jQuery-Framework)
 *		- Eve.js
 * 
 * BEISPIEL FUER DIE HTML-INITIALISIERUNG:
 *
 * 		<div class="eveJs">
 *			<input type="hidden" class="eveJsCfg" value="{ 'Eve.RegisterCards' : { registerCardBtns:'.registerCardsBtn', registerCardActiveCssCls:'registerCardActive', registerCardBtnActiveCssCls:'active', listener:[{eventName:'change', functionName:'setToSameHeightAtRow', params:['eventimInfoPhotoRow']}]} }" />
 *			...
 * 		</div>
 *
 * 		Auf den Buttons muessen die IDs oder Selektoren der entsprechenden Content-
 * 		Layer notiert sein:
 * 
 * 		<a href='#' rel="{ for : 'id', activeUrl : '...' }">Beispiel Button</a>
 *
 * LINKS AUF REGISTERKARTEN
 *
 *		Es ist moeglich auch andere Links, und nicht nur den Button der Registerkarte, fuer das Umschalten
 *		einer Registerkarte zu nutzen. Dazu muss der Link nur die CSS-Klasse "RegisterCardsSwitch" und im
 *		rel-Attribut des Links die ID des Tabs enthalten:
 *
 *		<a href="[UrlMitTabEinsprung]" rel="[TABID]" class="RegisterCardsSwitch">...</a>
 *
 *		Durch setzen einer weiteren CSS-Klasse "RegisterCardsTabOnly" wird nur das Tab umgeschaltet und nicht
 *		der Link im href-Attribut ausgefuehrt.
 *
 * ELEMENTE UND REGISTERKARTEN VERLINKEN
 *
 *		Durch das setzen einer CSS-Klasse "LinkedToRegisterCard-[TABID]" auf ein beliebiges DOM-Element, kann dieses
 *		mit dem Anzeige verhalten der Registerkarte verbunden werden. Ist die Registerkarte "aktiv" wird auch das DOM-Element
 *		angezeigt, ist sie inaktiv, dann das DOM-Element ebenfalls.
 *
 *		<div class="LinkedToRegisterCard-[TABID]">
 *			...
 *		</div>
 *
 *		Dieses Verhalten kann auch invertiert, durch setzen einer weiteren CSS-Klasse "ShowThisIfRegisterCardIsHidden", 
 *		invertiert werden.
 *
 * LETZTE AENDERUNGEN:
 *		2010-01-08 11:25	Die Methode setUpEventHandler() in die Eve.js ausgelagert und globalisiert. (hans-peter.beck@eventim.de)
 *		2009-08-31 12:45	Dem Registerkarten-Content-Container wurde nun direkt auf das DOM-Element die Methode "activate"
 *							zur Verfuegung gestellt, um eine Registerkarte aktivieren zu koennen (hans-peter.beck@eventim.de).
 *		2009-08-14 16:00	In der Methode initialize() eine neues Feature eingebunden, so dass andere Elemente, die die CSS-Klasse
 *							"LinkedToRegisterCard-[TABID]" haben, gemeinsam mit der Registerkarte sichtbar und unsichtbar gemacht 
 *							wird. Uber die CSS-Klasse "ShowThisIfRegisterCardIsHidden" kann dieses Verhalten invertiert werden.
 *							(hans-peter.beck@eventim.de)
 *		2009-08-07 15:00	In der Methode initialize() die Registerkarten-Container-Suche per ID nicht mehr auf den Gesamtcontainer
 *							beschraenkt (hans-peter.beck@eventim.de).
 *		2009-08-03 15:00	Die Aenderung von 2009-07-30 17:00 erweitert, ist nun zusaetzlich die CSS-Klasse "RegisterCardsTabOnly"
 *							auf dem Element, dann wird der im href stehende Link nicht ausgefuehrt. Weiterhin wurde der
 *							Event dafuer von "mousedown" auf "click" umgestellt (hans-peter.beck@eventim.de).
 *		2009-07-30 17:00	Es ist nun moeglich Elemente mit der CSS-Klasse "RegisterCardsSwitch" und im "rel"-Attribut
 *							mit der ID einer Registerkarte zu versehen. Wird dieses Element gefunden, kann man damit nun
 * 							auch die entsprechende Registerkarte aktivieren (hans-peter.beck@eventim.de).
 *		2009-07-16 17:00	Die Registerkarten-Inhalts-Container mit einem Event-Handler versehen, so dass man sich per
 *							JavaScript direkt auf dem Objekt mit einem trigger und einem Callback registrieren kann. 
 *							Wird dieser gefeuert, so wird auch der Callback gefeuert (hans-peter.beck@eventim.de).
 *		2009-05-11 18:00	Die Methode .onBtnClick mit HBX-Tracking ausgestattet (hans-peter.beck@eventim.de).
 *		2009-04-14			Komplette Ueberarbeitung (hans-peter.beck@eventim.de)
 * 		2008-09-26			Erstellt (hans-peter.beck@eventim.de)
 *
 * Copyright 2008-2009 by CTS Eventim AG.
 */
 
 
/**
 * Klasse fuer Registerkarten-Funktionen. Wichtig: Auf den Links muss im rel-Attribut die ID der zugehoerigen Registerkarte
 * vermerkt sein, sonst kann keine Zuordnung erfolgen und der Button wird ausgeblendet.
 *
 * Wird die aktuelle Klasse instanziert, so sucht diese im Quellcode nach DOM-Elementen mit der CSS-Klasse "RegisterCardsSwitch"
 * und einem Wert im "rel"-Attribut, welcher einer ID einer Registerkarte entspricht. Diese Elemente werden mit einem 'mousedown'
 * Trigger zum aktivieren der jeweiligen Registerkarte versehen.
 *
 * @class	Eve.RegisterCards
 * @base	Eve
 * @constructor
 * @param	{object}	options							Optionshash:
 * @param	{element}	options.containerEl				DOM-Element in dem die Registerkarten und die Buttons dafuer bereits existieren oder erstellt werden sollen.
 * @param	{string}	options.btnContainer			Selektor, z. B. '.xyz li', in dem die einzelnen Buttons in Form eines <a>-Tags abgelegt sind.
 * @param	{string}	options.activeCls				Optional:
 *															CSS-Klasse des Conatainers eines Buttons, wenn dieser aktiv sein soll (Default "active").
 * @param	{string}	options.useUrlIfActiveCls		Optional:
 *															CSS-Klasse des aktiven Buttons mit Link, wechselt der Button wieder in einen inaktiven Zustand
 *															wird diese CSS-Klasse wieder entfernt.
 * @param	{boolean}	options.isInstant				Optional:
 *															Wenn true, dann wurde die aktuelle Klasse per MouseOver initialisiert, daher wird dieser Event entfernt.
 */
Eve.RegisterCards = function(options) {
	
	// Wenn es das Element nicht gibt, dann abbrechen.
	if(!(this.el = options.containerEl || false)) return;
	
	// Wenn kein Button-Container angegeben wurde, dann abbrechen.
	if(!(this.btnContainer = options.btnContainer || false)) return;
	
	// Evtl. mouseover-Initialisierung entfernen.
	this.removeInstant(this.el, options.isInstant || false);
	
	// Weiter Konfigurationen
	this.activeCls         = options.activeCls || 'active';
	this.useUrlIfActive    = options.useUrlIfActive || false;
	this.useUrlIfActiveCls = options.useUrlIfActiveCls || false;
	
	// Initialisieren der Registerkarten.
	this.initialize();
};

Eve.RegisterCards.prototype = {
	
	/**
	 * Sucht nach Button-Containern und dessen Links.
	 *
	 * @member	Eve.RegisterCards
	 */
	initialize : function() {
		
		var tmpThis = this;
		
		// Ermitteln der ButtonContainer
		this.btnContainerEl = [];
		this.activeBtnContainer = false;
		
		// In jedem Container nach dem Link suchen ...
		jQuery(this.el).find(this.btnContainer).each(function() {
			
			// Wurde kein Link gefunden, dann Abbruch.
			if (!(this.btnEl = (jQuery(this).find('a').get(0) || false))) return;
			
			// Ist auf dem Link kein Rel-Attribut, dann Abbruch.
			if (!(this.btnCfg = (this.btnEl.getAttribute('rel') || false))) return;
			
			// Versuchen die Config in ein Objekt umzuwandeln ...
			try {
		
				eval("this.btnCfg = " + this.btnCfg + ";");
				
			} catch(e) {
				
				// Fehler > Abbruch
				return;
			};
			
			var tmpForId = this.btnCfg['for'];
			
			// Im Link muss nun ein Rel-Attribut sein in dem die ID
			// der dazugehoerigen Registerkarte vermerkt wurde.
			if (!(this.cardEl = (jQuery('#' + tmpForId).get(0) || false))) return;
			
			// Im Container noch merken, falls denn das useUrlIfActive aktiv ist.
			if ((this.btnCfg.activeUrl || false)) this.activeUrl = this.btnCfg.activeUrl || false;
			
			// Event setzen
			jQuery(this.btnEl).bind('mousedown', tmpThis.onBtnClick.scope(tmpThis, [this]));
			jQuery(this.btnEl).bind('click', function() { return false; });
			
			// Ebenfalls im Prototype der aktuellen Klasse ueber die ID noch einen "Schalter" merken,
			// mit dem man die Registerkarten ansteuern kann.
			this.cardEl.activate = Eve.RegisterCards[tmpForId] = function() {
				
				jQuery(this).triggerEvent('mousedown');
				
			}.scope(this.btnEl);
			
			// Noch den Button auf der Registerkarte selbst merken, z. B. um diesen zu entfernen oder dergleichen.
			this.cardEl.btnEl = this.btnEl;
			
			// Ermitteln ob der aktuelle Container vielleicht aktiv ist ...
			if (jQuery(this).hasClass(tmpThis.activeCls)) tmpThis.activeBtnContainer = this;
			
			// Andernfalls die Registerkarte merken und vorbereiten.
			tmpThis.btnContainerEl.push(this);
			
			// Registerkarte mit EventHandler versehen
			//
			// Hinweis: Belegt ein DOM-Element mit einem Eventhandler, der bei Click gefeuert wird und folgend
			// darauf registrierte Callbacks ausfuehrt. Achtung: Dieses feature funktioniert nicht,
			// wenn 'instantCards' : true ist, bzw. erst verzoegert!
			tmpThis.setUpEventHandler(this.cardEl);
			
			// Im Quelltext koennen nun noch Elemente sein, die nur/nicht angezeigt werden duerfen/sollen, wenn die
			// jeweilige Register-Karte aktiv/inaktiv ist.
			//
			// Weiterhin ist eine Klasse enthalten, die anzeigt ob bei aktiver Registerkarte das Element ebenfalls
			// angezeigt werdne soll ("ShowThisIfRegisterCardIsVisible") oder speziell nur dann angezeigt werden soll, 
			// wenn die Registerkarte nicht sichtbar ist ("ShowThisIfRegisterCardIsHidden").
			//
			// Ueber eine weitere Klasse "LinkedToRegisterCard-[ID]" wird die ID der verlinkten Registerkarte
			// uebergeben.
			var tmpCardEl = this.cardEl; // Fuer Funktion privat verfuegbar machen.
			
			jQuery('.LinkedToRegisterCard-' + tmpForId).each(function() {
			
				// Merken ob auf onShow oder onHide das aktuelle Element sichtbar sein soll.
				var showIfRegisterCardIsShow = !jQuery(this).hasClass('ShowThisIfRegisterCardIsHidden');
				var onShow = ((showIfRegisterCardIsShow) ? 'show' : 'hide' );
				var onHide = ((showIfRegisterCardIsShow) ? 'hide' : 'show' );
				
				// CSS-Klasse(n) entfernen, um zu vermeiden, dass es mehrmals "verlinkt" wird.
				jQuery(this).removeClass('hidden ShowThisIfRegisterCardIsVisible ShowThisIfRegisterCardIsHidden LinkedToRegisterCard-' + tmpForId);
				
				tmpCardEl.bindEvent('show', function() { jQuery(this)[onShow](); }.scope(this));
				tmpCardEl.bindEvent('hide', function() { jQuery(this)[onHide](); }.scope(this));
			});
		});
		
		// Wenn nix gefunden wurde, dann Ende
		if (this.btnContainerEl.length <= 0) return;
		
		// Mit etwas Verzoegerung initialisieren...
		var tmpFunc = function() {
			
			// Merken, dass gerade initialisiert wird ...
			this.iniActive = true;
			
			// Initialisieren des ersten ausgewaehlten Reiters.
			jQuery((this.activeBtnContainer || this.btnContainerEl[0]).btnEl).triggerEvent('mousedown');
			
			// Nicht mehr merken, dass gerade initialisiert wird ...
			this.iniActive = false;
			
		}.defer(10, this);
		
		tmpFunc();
		
		// Nun noch nach evtl. Links suchen, die ebenfalls Registerkarten schalten wollen. Dazu koennen
		// diese Links/Objekte mit der CSS "RegisterCardsSwitch" und der ID der gewuenschten Registerkarte
		// im rel-Attribute versehen werden.
		jQuery('.RegisterCardsSwitch[rel]').each(function() {
				
			// Die CSS-Klasse runternehmen, damit nicht nochmal initialisiert wird.
			jQuery(this).removeClass('RegisterCardsSwitch');
			
			// Das Rel-Attribut ermitteln, darin steht die ID der Registerkarte, die
			// mit dem Button ansteuerbar sein soll.
			var tmpRel = this.getAttribute('rel') || false;
			
			// Wurde keine ID im rel-Attribut gefunden, dann Abbruch.
			if(!tmpRel) return;
			
			// Jetzt das Objekt mit einem onMouseDown-Event versehen, wird dieser
			// ausgeloest wird dann erst geschaut ob ein Schalter fuer eine entsprechende
			// Registerkarte vorhanden ist (es kann ja sein, dass diese erst spaeter)
			// hinzugekommen ist). Wenn ja, dann schalten!
			jQuery(this).bind('click', function() {
			
				(Eve.RegisterCards[tmpRel] || function() {})();
				
				if(jQuery(this).hasClass('RegisterCardsTabOnly')) return false;
			});
			
		});
	},
	
	
	/**
	 * Sucht nach Button-Containern und dessen Links.
	 *
	 * @member	Eve.RegisterCards
	 * @param	{element}	containerEl		Container-Element des Buttons.
	 */
	onBtnClick : function(containerEl) {
		
		// Etwas anderes fokusieren, damit der Button nicht fokusiert bleibt.
		document.body.focus();
		
		// Bevor alle Registerkarten umgekrempelt werden, erstmal gucken ob nicht vielleicht
		// der Link ausgefuehrt werden soll
		if(jQuery(containerEl.btnEl).hasClass('onNextClickGoTo')) {
			
			window.open(containerEl.activeUrl, containerEl.btnEl.getAttribute('target') || '_self', '');
			
			return false;
		};
		
		// Durch alle Container laufen und entsprechend de- oder aktivieren...
		for (var i = 0; i < this.btnContainerEl.length; i++) {
			
			var tmpContainer = this.btnContainerEl[i];
			
			if(containerEl == tmpContainer) {
				
				// Sichtbar / aktiv machen
				jQuery(tmpContainer.cardEl).show();
				jQuery(tmpContainer).addClass(this.activeCls);
				
				// CSS-Klasse fuer aktiven Link setzen
				if((tmpContainer.activeUrl || false) && (this.useUrlIfActiveCls || false)) jQuery(tmpContainer.btnEl).addClass(this.useUrlIfActiveCls).addClass('onNextClickGoTo');
				
				// Renderbug for Calendar 
				if(jQuery(tmpContainer.btnEl).hasClass('extraFunctions')){
					jQuery('#calendar').fullCalendar('render');	
				}
				
				// Event feuern
				tmpContainer.cardEl.triggerEvent('show');

				
			} else {
				
				if (containerEl != tmpContainer && jQuery(tmpContainer).hasClass(this.activeCls)) {
				
					// Unsichtbar / innaktiv machen
					jQuery(tmpContainer.cardEl).hide();
					jQuery(tmpContainer).removeClass(this.activeCls);
					
					// CSS-Klasse fuer inaktiven Link setzen
					if((tmpContainer.activeUrl || false) && (this.useUrlIfActiveCls || false)) jQuery(tmpContainer.btnEl).removeClass(this.useUrlIfActiveCls).removeClass('onNextClickGoTo');
				}
				
				// Event feuern
				tmpContainer.cardEl.triggerEvent('hide');
			}
			
		};
		
		return false;
	}
};

/** Ableiten */
Eve.RegisterCards.extendClassBy(Eve);

