/**
 * Class AjaxPage
 * 
 * Replaces all links on the page by Ajax handlers to seemlessly refreh the page.
 * @copyright  Christian Schiffler 2010
 * @author     Christian Schiffler <http://www.cyberspectrum.de>
 */

var AjaxPage = new Class({
	Implements: [Options],
	instance:null,
	dummyFormElement:new Element('div'),
	lock: false,
	hashJump: false,
	lasturl:null,
	lastSlide: null,
	RequestClass: new Class({
		Extends: Request,
		options: {
			evalScripts: false,
			evalResponse: false
		},
		success: function(text, xml)
		{
			var js;
			text = text.stripScripts(function(script){js = script;});
			js = js.replace(/<!--|\/\/-->|<!\[CDATA\[\/\/>|<!\]\]>/g, '');
			this.onSuccess(text, xml, js);
		}
	}),
	initialize:function(options)
	{
		if(AjaxPage.instance)
			return null;
		AjaxPage.instance=this;
		this.setOptions(options);
		this.sBaseHref = document.getElementsByTagName("base")[0].getAttribute("href");
		this.grabLinks();

/*		var hashChanged=function(){
			if(AjaxPage.instance.lock)
				return;
			var multipleHash = window.location.hash.substr(1).match(/(.*)\|(.*)/);
			if(multipleHash)
				AjaxPage.instance.loadPage(multipleHash[1], multipleHash[2]);
			else
				AjaxPage.instance.loadPage(window.location.hash.substr(1));
		}.bind(this);
		window.addEvent('hashchange', hashChanged);
		*/
		
		function handler(newHash, initial){
			if(AjaxPage.instance.lock)
				return;
				
			if(newHash){
				var multipleHash = window.location.hash.substr(1).match(/(.*)\|(.*)/);
				if(multipleHash)
					AjaxPage.instance.loadPage(multipleHash[1], multipleHash[2]);
				else
					AjaxPage.instance.loadPage(window.location.hash.substr(1));
			}else{
				if(!initial)
					AjaxPage.instance.loadPage('http://www.tablo.de/');
			}
		}
		mooHash.init(handler, document.getElementById('ajaxIFrame'));

		// if we have already a hash, we want to "boot" into that page now
		if(window.location.hash)
		{
			var multipleHash = window.location.hash.substr(1).match(/(.*)\|(.*)/);
			if(multipleHash)
				this.hashJump = multipleHash[2];
			else
				this.hashJump = window.location.hash.substr(1);
				
			mooHash.go(window.location.hash.substr(1));
		}
	},
	moveToSlide: function(slide, from)
	{
	// xtra fragen wozu wir das gebraucht haben.... habe ich das etwa anderweitig umgangen?
	// Sehe jetzt keine Probleme wenn mans weglässt
	
	//if(this.lastSlide == slide)
		//return;
		
		if(this.hashJump){
			$('content-inner').setStyle('left', (($(this.hashJump).offsetLeft) * -1));
		}else{
			if(this.lastSlide == null){
				$('content-inner').set('tween', {duration: 1500})
							.tween('left', [0, -1000]);
			}else{
				$('content-inner').set('tween', {duration: 1500})
							.tween('left', (slide?$(slide).offsetLeft:0) * -1);
			}
		}
		this.lastSlide = slide;
		this.hashJump = false;
	},
	grabLinks:function(container)
	{
		if(!container)
			container=$(document.body);
		var sBaseHref=this.sBaseHref;
		var filterUrl=this.options.filterUrl;
		$$(container.getElements('a'))
		.filter(function(e){
						href=e.getAttribute('href');
						return (href!=null)
									&& (href.indexOf('.html')>0)
									&& (!href.match(/#/))
									&& (!href.test(/^http:/) || (href.indexOf(sBaseHref)===0))
									&& (!filterUrl || filterUrl(href));
							})
		.each(function(e){
			if(e.getAttribute('href'))
			{
				e.addEvent('click', function(e){if(e)e.stop();AjaxPage.instance.lock=true;AjaxPage.instance.loadPage(this.getAttribute('href'));});
			}
		});
		var onSuccess=this.pageLoaded.bind(this);
		var dummyFormElement=this.dummyFormElement;
		
		// now track all forms as well.
		$$(container.getElements('form')).each(function(e){
			var r=new Form.Request(e, dummyFormElement, {requestOptions:{evalScripts: false, evalResponse: false}});
			r.request.addEvent('success', function(tree, elements, html, js){
				myjs = js.replace(/<!--|\/\/-->|<!\[CDATA\[\/\/>|<!\]\]>/g, '');
				onSuccess(html, null, myjs);
			});
		});
	},
	loadPage:function(url, slideHash)
	{
		
/*		function iframeLoadSite(historyURL){
			if(Browser.Engine.trident){
				// iFrame reinholen für IE
				window.ajaxFrame = $('ajaxIFrame');
				
				if(window.ajaxFrame.readyState == "complete"){
					window.ajaxFrame.src = historyURL;
				}else{
					iframeLoadSite(historyURL);
				}
			}
		}*/
	
		url = url.replace(this.sBaseHref, '');
		
		if(this.lasturl == url)
		{
			this.moveToSlide(slideHash);
			return;
		}else{
			this.lastSlide = null;
			this.hashJump = slideHash;
		}
		this.lasturl = url;
		if(!slideHash){
			if(url != ''){
				window.location.hash = url;
			}
		}else{
			window.location.hash = url + "|" + slideHash;
		}
		
/*		(function(){ iframeLoadSite(url); }).delay(1000);*/
		var objRequest = new this.RequestClass({
			'link': 'chain',
			'method': 'get',
			url: this.sBaseHref + url,
			onSuccess: this.pageLoaded.bind(this)
		}).send();
	},
	pageLoaded:function(text, xml, js)
	{
		this.lock=false;
		// replace the elements and then run javascript.
		if(this.options.replaceElements)
		{
			var el=Elements.from(text);
			var scanbuf=[];
			var multipleHash = window.location.hash.substr(1).match(/(.*)\|(.*)/);
			this.options.replaceElements.each(function(repl){
				if(typeof(repl)==='object' && (repl instanceof Array))
				{
					var oel=repl[0];
					var nel=repl[1];
				} else {
					var oel=repl;
					var nel=repl;
				}
				scanbuf.push(nel);
				var e=null;
				for(var i=0;i<el.length;i++)
				{
					if(el[i].id==nel)
					{
						e=el[i];
						break;
					}
				}
				if(e)
				{
					var oe=document.getElementById(oel);
					var cloneContent = $(oel).getElementById('content').clone();
					$(e).replaces(oe);

						var replaceContent = $(e).getElementById('content');
						cloneContent.getChildren()[0].set('id', 'cloned-inner');
						cloneContent
							.set('id', 'cloned')
							.setStyles({
								position: 'absolute',
								width: 1000,
								top: 0,
								left: 0,
								height:700,
								overflow: 'hidden'})
							.inject(replaceContent.getParent(),'top')
							.set('tween', {duration: 1500})
							.tween('left', -1000);
						replaceContent
							.setStyles({position: 'absolute', width: 1000, top: 0, left: 1000})
							.set('tween', {duration: 1500})
							.tween('left', 0);
						(function(){cloneContent.destroy();replaceContent.set('style', '');replaceContent.getParent().setStyle('height', 'auto');}).delay(1500);

					$(oe).destroy();
				}
			});
			$(window).removeEvents('domready');

			var update= function()
			{
				// let the freshly loaded items initialize themselves.
				if(Browser.Engine.trident) $(window).fireEvent('domready');
				if(multipleHash)
				{
					this.moveToSlide(multipleHash[2]);
				}
			}.bind(this);
			
			//regrab aus update herausgenommen, da die Leute zu schnell im Menü rumklicken
			var regrab = function(){
				// now regrab everything
				var f=this.grabLinks.bind(this);
				scanbuf.each(function(repl){f(document.getElementById(repl));});
				var newTitle = text.match(/<title>(.*)<\/title/);
				document.title = newTitle[1].replace(/&nbsp;/g, ' ');
			}.bind(this);
			
			if(multipleHash){
				if(js){
					$exec(js);
				}
				update();
				regrab();
			}else{
				// lazy js initialization for tween to finish.
				regrab();
				(function(){if(js){$exec(js);}update();}).delay(1600);
			}
		}
	}
});

// now start up our AjaxPage handler. Remember to do this only once!
window.addEvent('domready', function(){
	new AjaxPage({
		replaceElements: [['wrapper-xt', 'wrapper-xt']],
		filterUrl:function(url){
			// return false for all urls that shall get filtered away, true for all that shall get fetched via ajax
			// in our example here: fetch all urls via ajax that do not contain the portion "?file=".
			// NOTE: the restrictions defined in AjaxPage.grabLinks() still apply.
			return (!href.match(/\?file=/));
		}
	});
});
