/*globaler AjaxHistoryManager speichert Browserhistorie, Copyright Benedikt Morschheuser 2009*/
/*benötigt blank.html im root!*/
var AjaxHistoryManager = new Class({ 
	Implements: [Events, Options],
	options: {
	},
	initialize: function(){ //initalisiert JS-Objekt 
		this.isFirstLoad = true;//zum erkennen, ob es sich um das laden der Seite oder einen click auf der Seite handelt. Sobald erster Click auf Seite hier verarbeitet wird -> false
		this.browserURL = document.URL.toString().split('#')[0];
		this.initHistoryManager();
		
		this.leistungsHistory = new Array();//Historie der Leistungen
		this.navHistory = new Array();//Navigationhistorie, [0]= Matrix anzeigen true
		
	},
	doLeistungsClick:function(newURLString){
		this.isFirstLoad = false;//müsste hier schon false sein, aber besser noch mal
		this.leistungsHistory.include(newURLString);
		this.saveHistory('select',this.buildLeistungsHistory());
	},
	buildLeistungsHistory: function(){//baut String z.b. L21;L44;L53
		var output= "";
		this.leistungsHistory.each(function(item, index){
			if(item!=""){
				output+=item+";"
			}
		}.bind(this));
		return output;
	},
	doNavClick: function(art,wert){
		this.isFirstLoad = false;//müsste hier schon false sein, aber besser noch mal
		if(art=="matrix"){
			if(wert==true){
				this.navHistory[0]=true;
				this.deleteHistory('matrix');
			}else{
				this.navHistory[0]=false;
				this.saveHistory('matrix','hide');
			}
		}
		
	},
	initHistoryManager: function(){
		this.HM = new HistoryManager(); 
		//History Events: der erste Teil ist der Hashname z.B. select 
		this.HM.addEvent('initalisierungFertig',function(waitForReloadJson){
			if(!waitForReloadJson){
				if(loadingStatus!="siteReady"){
					loadingStatus = "siteReady";
					loadingPage();
				}
			}
			this.isFirstLoad = false;
		}.bindWithEvent(this)); 
		
		//Leistungen
		this.HM.addEvent('select-added',function(new_value){ 
				if(this.isFirstLoad){
					//tu nix anderes
				}
				this.leistungsHistory.empty();
				var strgTeile = new_value.split(";");
				strgTeile.pop();//letztes, leeres Element löschen
				strgTeile.each(function(item, index){
					this.leistungsHistory.include(item);
				}.bind(this));
				this.reloadMatrix();
				
		}.bindWithEvent(this)); 	
		this.HM.addEvent('select-changed',function(new_value){
			    this.leistungsHistory.empty();
				var strgTeile = new_value.split(";");
				strgTeile.pop();//letztes, leeres Element löschen
				strgTeile.each(function(item, index){
					this.leistungsHistory.include(item);
				}.bind(this));
				this.reloadMatrix();
				
		}.bindWithEvent(this)); 
		this.HM.addEvent('select-removed',function(last_value){ // bei löschen des select aus URL, gibt diesen letzten Eintrag zurück
				this.leistungsHistory.empty();//Löscht Historie der Leistungen
				this.reloadMatrix();
				 
		}.bindWithEvent(this));
		
		//JSON-EVENTS
		this.HM.addEvent('select-jsonContentLoaded',function(jsonObj){ 
			//baue Elemente in Matrix ein
			var matrixID_CSSString= pageLoadManager.gui_elements.get('gui_element_matrix');
			if($(matrixID_CSSString.toString())){//falls ID auf Seite vorhanden
				var html_element=$(matrixID_CSSString.toString()); 
				pageLoadManager.htmlGUIObjects.get('gui_element_matrix').buildMatrix(jsonObj);//Hole entsprechendes JS Objekt und baue Matrix
			}
			//setze loadingStatus auf siteReady, falls noch nicht ready
			if(loadingStatus!="siteReady"){
				loadingStatus = "siteReady";
				loadingPage();
			}
		}.bindWithEvent(this));
		
		//Nav->Matrix
		this.HM.addEvent('matrix-added',function(new_value){ 
			if(this.isFirstLoad){
				var matrixID_CSSString= pageLoadManager.gui_elements.get('gui_element_matrix');
				if($(matrixID_CSSString.toString())){//falls ID auf Seite vorhanden
					var html_element=$(matrixID_CSSString.toString());
					pageLoadManager.htmlGUIObjects.get('gui_element_matrix').animateMatrix_show_hide();//Matrix animiert ausblenden
				}
			}
			this.navHistory[0]=new_value;
		}.bindWithEvent(this)); 
		this.HM.addEvent('matrix-changed',function(new_value){//gibt es nicht, da nur hinzufügen oder löschen
		}.bindWithEvent(this)); 
		this.HM.addEvent('matrix-removed',function(last_value){ //löscht den Eintrag und gibt letzten Eintrag zurück
			this.navHistory[0]=null; 
		}.bindWithEvent(this)); 
		this.HM.start();
	},
	reloadMatrix:function(){
		//sende JSON für Matrix
		var matrixURL=this.browserURL;
		pageLoadManager.pageReloadwithJson(this.HM,matrixURL,'matrix','&leistungen='+this.leistungsHistory.toString(),'select-jsonContentLoaded');
	},
	saveHistory: function(historyID,historyString){//historyString z.B. 'select','L42;L21;L22' ...
		this.HM.set(historyID,historyString);//fügt historyString der Historie hinzu oder ändert aktuelle Historie in neu
	},
	deleteHistory: function(historyID){//LeistungsHistory z.B. L42;L21;L22 ...
		this.HM.remove(historyID);//löscht den Eintrag
	}
});

/*
Delete duplicates
license: MIT-style license
authors:
- Guillermo Rauch
- Thomas Aylott
- Scott Kyle*/
Array.implement({

	unique: function(){
		return [].combine(this);
	}

});
/*
---
description: A Class that provides a cross-browser history-management functionaility, using the browser hash to store the application's state

license: MIT-style

authors:
- Arieh Glazer
- Dave De Vos
- Digitarald

requires:
- core/1.2.4: Class
- core/1.2.4: Class.Extras
- core/1.2.4: Element

provides: [HashListner]

...
*/

var HashListener = new Class({
	Implements : [Options,Events],
	options : {
		blank_page : 'http://www.mc-kurzurlaub.de/blank.html',
		start : false
	},
	iframe : null,
	currentHash : '',
	firstLoad : true,
	handle : false,
	useIframe : (Browser.Engine.trident && (typeof(document.documentMode)=='undefined' || document.documentMode < 8)),
	ignoreLocationChange : false,
	initialize : function(options){
		var s_f, 
			self=this,
			cached_storage;
			
		this.setOptions(options);
		
		// Disable Opera's fast back/forward navigation mode
		if (Browser.Engine.presto && window.history.navigationMode) {
			window.history.navigationMode = 'compatible';
		}

		
		 // IE8 in IE7 mode defines window.onhashchange, but never fires it...
        if (
			window.onhashchange &&
            (typeof(document.documentMode) == 'undefined' || document.documentMode > 7)
		   ){
				// The HTML5 way of handling DHTML history...
				window.onhashchange = function () {
					var hash = self.getHash();
					if (hash == self.currentHash) {
						return;
					}
					self.fireEvent('hash-changed',hash);
				}
        } else  {
			if (this.useIframe){
				this.initializeHistoryIframe();
			} 
        } 
		
		window.addEvent('unload', function(event) {
			self.firstLoad = null;
		});
		
		if (this.options.start) this.start();
	},
	initializeHistoryIframe : function(){
		var hash = this.getHash(), self = this, doc;
		this.iframe = new IFrame({
			src		: this.options.blank_page,
			styles	: { 
				'position'	: 'absolute',
				'top'		: 0,
				'left'		: 0,
				'width'		: '1px', 
				'height'	: '1px',
				'visibility': 'hidden'
			}
		}).inject(document.body);
    	
		doc	= (this.iframe.contentDocument) ? this.iframe.contentDocumnet  : this.iframe.contentWindow.document;
		doc.open();
		doc.write('<html><body id="state">' + hash + '</body></html>');
		doc.close();
		return;
	},
	checkHash : function(){
		var hash = this.getHash(), ie_state, doc;
		if (this.ignoreLocationChange) {
			this.ignoreLocationChange = false;
			return;
		}

		if (this.useIframe){
			doc	= (this.iframe.contentDocument) ? this.iframe.contentDocumnet  : this.iframe.contentWindow.document;
			ie_state = doc.body.innerHTML;
			
			if (ie_state!=hash){
				this.setHash(ie_state);
				hash = ie_state;
			} 
		}		
		
		if (this.currentLocation == hash) {
			return;
		}
		
		this.currentLocation = hash;
		
		this.fireEvent('hash-changed',hash);
	},
	setHash : function(newHash){
		window.location.hash = this.currentLocation = newHash;
		
		this.fireEvent('hash-changed',newHash);
	},
	getHash : function(){
		var m;
		if (Browser.Engine.geko){
			m = /#(.*)$/.exec(window.location.href);
			return m && m[1] ? m[1] : '';
		}else{
			return window.location.hash.substr(1);
		}
	},
	setIframeHash: function(newHash) {
		var doc	= (this.iframe.contentDocument) ? this.iframe.contentDocumnet  : this.iframe.contentWindow.document;
		doc.open();
		doc.write('<html><body id="state">' + newHash + '</body></html>');
		doc.close();
		
	},
	updateHash : function (newHash){
		if ($type($(newHash))) {
			this.debug_msg("Exception: History locations can not have the same value as _any_ IDs that might be in the document,"
					 	+ " due to a bug in IE; please ask the developer to choose a history location that does not match any HTML"
						+ " IDs in this document. The following ID is already taken and cannot be a location: " + newLocation);
		}
		
		this.ignoreLocationChange = true;
		
		if (this.useIframe) this.setIframeHash(newHash);
		else this.setHash(newHash);
	},
	start : function(){
		this.handle = this.checkHash.periodical(100, this);
	},
	stop : function(){
		$clear(this.handle);
	}
});
/*
---
description: A Class that provides a cross-browser history-management functionaility, using the browser hash to store the application's state

license: MIT-style

authors:
- Arieh Glazer

requires:
- HistoryManager/0.4.1: HashListner

provides: [HistoryManager]

...
*/
var HistoryManager = new Class({
	Extends : HashListener,
	state : new Hash({}), 
	fromHash : false,
	fromHandle :false,
	firstload: true,//by BMo design
	initialize : function(options){
		this.parent(options);		
		this.addEvent('hash-changed',this.updateState.bind(this));
	},
	updateState : function (hash){
		var self = this;
		hash = new Hash(JSON.decode(decodeURIComponent(hash)));
		
		this.state.each(function(value,key){
			var nvalue;

			if (hash.has(key)){
				nvalue = hash.get(key);
				self.state.set(key,nvalue);
				self.fireEvent(key+'-changed',nvalue);
			}else{
				nvalue = self.state.get(key);
				self.fireEvent(key+'-removed',nvalue);
				self.state.erase(key);
			}
			
			hash.erase(key);
		});
		
		hash.each(function(value,key){
			self.state.set(key,value);
			self.fireEvent(key+'-added',value);
		});
		
		if(this.firstLoad){//by BMo wird gefeuert nach init und erstes mal url auslesen, so wie events dafür gefeuert wurden
			this.firstload =false;
			var waitForReloadJson = false;
			if(hash.getLength()>0){
				waitForReloadJson = true;
			}
			self.fireEvent('initalisierungFertig',waitForReloadJson);
		}
		
	},
	set : function(key,value){
		var newState = new Hash(this.state);
		
		newState.set(key,value);

		this.updateHash(newState.toJSON());
		
		return this;
	},
	remove : function(key){
		var newState = new Hash(this.state);
		
		newState.erase(key);
		
		this.updateHash(newState.toJSON());
		
		return this;
	}
});
