var UrlHistoryManager = new Class({

	initialize: function() {

		this.justStarted = true;

		this.history = new HistoryManager();
		this.history.register(
			'pwf',
			['0'],
			function(values) {
				if (!this.justStarted || values[0].trim() != '') {
					var usedDefault = false;
					var parameters = values[0];
					
					if (parameters.match("^i[0-9]+$")) {
						return;
					}
					
					if (values[0].trim() == '') {
						parameters = defaultStatusParameters;
						usedDefault = true;
					}
					
					var link = new Element(
						'a'
					).setProperty(
						'href', '?' + parameters.replace(';', '&').replace(/\(([^\)]+)\)/g, '=$1')
					);
					
					var lg = linkGoto.bind(link);
					lg(usedDefault);
				}
				this.justStarted = false;
			}.bind(this),
			function(values) {
				return values[0];
			}.bind(this),
			'(.*)'
		);
		
		return this;
	},
	
	start: function() {
		this.history.start();
	},
	
	addUrl: function(url) {
		url = url.replace(/=([^&]+)/g, '($1)').replace('&', ';');
		
		this.history.setValue('pwf', 0, url);
	}

});

var urlHistoryManager = null; 
var loadingOverlay = null;
var spinner = null;

function toggleLoadingOverlay(show, content) {
	
	if (show) {
		if (!loadingOverlay) {
			loadingOverlay = new Element('div', {
				'id': 'loading_overlay'
			});
		}
		
		if (content) {
			content.inject(loadingOverlay);
		}
		
		loadingOverlay.setStyles({
			display: 'block',
			position: 'absolute',
			top: 0,
			left: 0,
			width: '100%',
			height: Math.max(document.html.getStyle('height').toInt(), window.getScrollHeight().toInt())+'px',
			'z-index': 1001
		}).set('opacity', 0.7).inject(document.body);

		$('pageContent').addClass('overlay');
	
	} else if (loadingOverlay) {
		loadingOverlay.setStyle('display', 'none');
		
		loadingOverlay.getChildren().each(function(i){
			i.destroy();
		});
		
		$('pageContent').removeClass('overlay');
	}
}

function toggleLoading(element) {
	
	if (element) {
		if (!spinner) {
			spinner = new Element('div', {
				'id': 'spinnerbox'
			});
			
			var spinnerbg = new Element('div', {
				'id': 'spinnerbg'
			}).inject(spinner);
			
			new Element('div', {
				'id': 'spinner'
			}).inject(spinnerbg);
		}
		
		spinner.setStyles({
			display: 'block',
			position: 'absolute',
			'z-index': 1005
		}).setStyles(element.getCoordinates()).inject(element, 'before');
	
	} else if (spinner) {
		spinner.setStyle('display', 'none');
		spinner.inject(document.body);
	}
}

function checkFork() {
	if (forkTo) {
		if (forkNW) {
			if (window.open(forkTo)) {
				$('fork').destroy();
			}
		} else {
			window.location.href = forkTo;
			$('fork').destroy();
		}
	}
}

function linkGoto(usedDefault) {
	
	var linkObj = this;
	
	if (ajaxIndicator) {
		switch(ajaxIndicator) {
			case 'spinner':
				toggleLoading(linkObj);
				break;
			case 'overlay':
				toggleLoadingOverlay(true, new Element('div', {
						id: 'ospinner'
					})
				);
				$('pageContent').removeClass('overlay');
				break;
		}
	}
	
	var link = "";
	var parameters = "";
	var anker = "";
	var useHistoryManager = true;
	
	if (linkObj.get('tag') == 'a' || linkObj.get('tag') == 'area') {
		link = linkObj.href;
		parameters = "";
		anker = "";
		
		if (usedDefault == null) {
			usedDefault = false;
		}
		
		if (m = link.match("^([^\\?#]*)?(\\?([^#]+))?(#(.*))?$")) {
			link = m[1];
			parameters = m[3];
			anker = m[5];
		}
		
		if (linkObj.hasClass('no_hm')) {
			useHistoryManager = false;
		}
	
	} else if (linkObj.get('tag') == 'input') {
		
		var form = $('pwf_form');
		
		link = form.action;
		parameters = form.toQueryString();
		
		if (link == '') {
			link = form.baseURI;
			if (m = link.match("^([^\\?#]*)?(\\?([^#]+))?(#(.*))?$")) {
				link = m[1];
			}
		}
		
		if (m = link.match("^([^\\?#]*)?(\\?([^#]+))?(#(.*))?$")) {
			link = m[1];
			parameters += '&'+m[3];
			anker = m[5];
		}
		
		// remove all unnecessary submit buttons
		$$('input[type=submit]').each(function(ie){
		
			if (ie !== linkObj) {
				var rep = ie.getParent().toQueryString();
				
				parameters = parameters.replace(rep, '').replace(/&+/g, '&').replace(/^&+/g, '').replace(/&+$/g, '');
			}
		});
		
		// remove all unnecessary search values
		$$('div.search input.empty').each(function(ie){
		
			if (ie !== linkObj) {
				var rep = ie.getParent().toQueryString();

				parameters = parameters.replace(rep, ie.get('name')+'=');
			}
		});
		
		if (linkObj.hasClass('no_hm')) {
			useHistoryManager = false;
		} else if (linkObj.getParent().hasClass('no_hm')) {
			useHistoryManager = false;
		}
	}
	
		
	var request = new Request({
		url: link,
		data: '_ajax=1&'+parameters,
		usedDefault: usedDefault,
		useHistoryManager: useHistoryManager,
		onComplete: handleResponse
	});

	if (linkObj.get('tag') == 'input' && sid) {
		if (form.swiffy && form.swiffy.files && form.swiffy.countFiles() > 0) {
		
			form.swiffy.removeEvents('allFilesUploaded');
			form.swiffy.addEvent('allFilesUploaded', (function() {
				this.send();
			}).bind(request));
			
			link += '?';
			
			if (parameters) {
				var resource = '';
				
				if (m = parameters.match("(&|\\?)_resource=([^&]*)(&.*)?$")) {
					resource = m[2];
				}
				
				if (resource != '') {
					link += '_resource=' + resource + '&';
				}
			}
			
			form.swiffy.upload({'url': link + '_upload=1&'+sid});
			return false;
		}
	}
	
	window.fireEvent('ajaxrequest');
	request.send();
	
		
	return false;
}

function handleResponse(response) {
	var res = null;
	var usedDefault = this.options.usedDefault;
	var useHistoryManager = this.options.useHistoryManager;
	
	toggleLoading();
	toggleLoadingOverlay(false);
	
	
	if (!this.isSuccess) {
		return;
	}
		
	try {
		res = JSON.decode(response);
	} catch (e) {
	}
	
	var form = $('pwf_form');
	
	var queryString = null;
	
	if (res != null) {
		
		var fork = $('fork');
		if (fork) {
			fork.destroy();
		}
		
		for(var i=0; i<res.length; i++) {
			var r = res[i];
			
			switch (r.type) {
				case 'title':
					document.title = r.content;
					break;

				case 'css':
					r.content.split(' ').each(function(cf){
						new Asset.css(cf, {id: cf});
					});
					break;

				case 'ajaxIndicator':
					ajaxIndicator = r.content;
					break;

				case 'fork':
					if (!r['nw']) {
						window.location.href = r.to;
						
					} else {
						if (!window.open(r.to)) {
							var f = new Element(
								'div', {
									id: 'fork'
								}
							).inject($('form'), 'top');
							
							if (r.hint) {
								var h = new Element(
									'span', {
										'class': 'hint',
										text: r.hint
									}
								).inject(f);
							}
						
							var a = new Element(
								'a', {
									href: r.to,
									text: r.title
								}
							).inject(f);
							if (r.nw) {
								a.set('class', 'newWindow')
							}
						}
					}
					break;

				case 'remove':
					var element = $('i'+r.id);
					//removeJsTrigger(element);
					
					if (element != null) {
						
						if (form.swiffy) {
							form.swiffy.removeUploadElements(element);
						}
						element.destroy();
					}
					break;
			
				default:
					var element = $('i'+r.id);
					if (element != null) {
						
						// disabled because scripts script is disabled at the moment
						var content = res[i]['content'];
						/*removeJsTrigger(element);
						
						var extractedScripts = extractScripts(res[i]['content']);
						
						var js = extractedScripts.js;
						var sources = extractedScripts.sources;
						var content = extractedScripts.html;
					*/
						var temp = new Element('div');
						temp.set('html', content);
						var el = temp.getFirst();
						
						
						el.replaces(element);
						
						//applyScripts(sources, js, el);
						
						
						addAjaxEvents(el);
						addNewWindowEvents(el);
						
						if (form.swiffy) {
							form.swiffy.addUploadElements(el);
						} else {
							prepareFileUploads();
						}
				}
				
			}
			
			if (res[i]['queryString']) {
				queryString = res[i]['queryString'];
			}
					
		}
		
	} else {
		if (m = response.match("<title[^>]*>((.|[\n\r])*?)</title[^>]*>")) {
			var temp = new Element('div');
			temp.set('html', m[1]);
			document.title = temp.get('text');
		}
		
		if (m = response.match("<meta[^>]+name=\"pwfQueryString\"[^>]+content=\"([^\"]*)\"[^>]*/>")) {
			
			queryString = new Element('div').set('html', m[1]).get('text');
		}
		
		if (m = response.match("<meta[^>]+name=\"pwfAjaxIndicator\"[^>]+content=\"([^\"]*)\"[^>]*/>")) {
			
			ajaxIndicator = m[1];
		}
		
		if (m = response.match("<meta[^>]+name=\"pwfForkTo\"[^>]+content=\"([^\"]*)\"[^>]*/>")) {
			
			forkTo = m[1];
		}
		
		if (m = response.match("<meta[^>]+name=\"pwfForkNW\"[^>]+content=\"([^\"]*)\"[^>]*/>")) {
			
			forkNW = m[1];
		}
		
		if (m = response.match("<meta[^>]+name=\"pwfCss\"[^>]+content=\"([^\"]*)\"[^>]*/>")) {
			
			m[1].split(' ').each(function(cf){
				new Asset.css(cf, {id: cf});
			});
		}
		
		
		var js = '';
		var sources = [];
		
		if (m = response.match("<body[^>]*>((.|[\n\r])*?)</body[^>]*>")) {
			response = m[1];
			/*var extractedScripts = extractScripts(m[1]);
			
			js = extractedScripts.js;
			sources = extractedScripts.sources;
			response = extractedScripts.html;*/
		}
		
		
		
		//removeJsTrigger();
		document.body.set('html', response);
		
		/*if (js != '' || sources.length > 0) {
			applyScripts(sources, js);
		}*/
		
		addAjaxEvents();
		addNewWindowEvents();
		
		prepareFileUploads();
		
		checkFork();
	}
	
	var scroll = document.body.getScroll();
	var size = document.body.getSize();
	var coordinates = document.body.getCoordinates();
	
	if (scroll.y + size.y > coordinates.bottom) {
		document.body.scrollTo(scroll.x, coordinates.bottom - size.y);
	}
	
			
	setFocus();
	
	/**
	 * Browser.Engine.webkit419: Safari2 has a bug with the history manager
	 */
	if (useHistoryManager && !usedDefault && !Browser.Engine.webkit419 && queryString) {
		
		urlHistoryManager.addUrl(queryString);
	}
	
	window.fireEvent('ajaxready');
}

function ajaxClick(e) {
	e = new Event(e).stop();
				
	var lg = linkGoto.bind(this);
	lg();
}

function addAjaxEvents(element) {
	
	if (!element) {
		element = document;
	}
	
	// append to all ajax elements an onclick handler
	element.getElements('a').extend(element.getElements('area')).each(function(ae){
		
		if (ae.hasClass('ajax')) {
			ae.removeEvents('click');
	 		ae.addEvent('click', ajaxClick.bind(ae));
		}
	});
	
	// append to all ajax elements an onclick handler
	element.getElements('input[type=submit]').each(function(ie){
		
		var parent = ie.getParent('div');
		if (parent) {
			
			if (parent.hasClass('ajax')) {
				ie.removeEvents('click');
		 		ie.addEvent('click', ajaxClick.bind(ie));
			}
		}
	});
	
	// append to all ajax elements an onclick handler
	var el = element.hasClass && element.hasClass('search') ? element.getParent() : element;
	el.getElements('.search input').each(function(ie){
		
		if (ie.hasClass('ajax')) {
			ie.removeEvents('keydown');
	 		ie.addEvent('keydown', function(event) { 
	 			var e = new Event(event);
	 			switch (e.key) {
	 				case 'esc':
		 				this.set('value', '');
	 				case 'enter':
	 					e.stop(); 
	 					ajaxClick.run([e],this);
	 					break;
	 			}
	 		});
		}
	});
}

function addNewWindowEvents(element) {

	if (!element) {
		element = document;
	}
	
	// append to all ajax elements an onclick handler
	element.getElements('a').extend(element.getElements('area')).each(function(ae){
		
		if (ae.hasClass('newWindow')) {
		
			var asPopup = false;
		
			var rel = ae.get('rel');
			var href = ae.get('href');
			
			if (rel && href != '') {
				var options = null;
				try {
					var data = Base64.decode(rel);
					options = JSON.decode(data);
				} catch (e) {
					return;
				}
				
				if (options.width || options.height) {
					var name = options.name || href.replace(/[^a-z]/g, '');
					var top = options.top || 50;
					var left = options.left || 50;
					
					ae.addEvent('click', (function(e){
    					window.open(this.d, this.n, "scrollbars=yes,width="+this.w+",height="+this.h+",screenX="+this.l+",screenY="+this.t);
    					return false;
    					
    				}).bind({n: name, d: href, w: options.width, h: options.height, t: top, l: left}));
    				
					asPopup = true;
				}
			}
			
			if (!asPopup) {
		 		ae.set('target', '_blank');
		 	}
		}
	});
}

function checkForQuestion() {
	if ($$('.question').length > 0) {
		toggleLoadingOverlay(true);
	}
}

window.addEvent('ajaxready', function(){
	checkForQuestion();
});

window.addEvent('domready', function() {
	addAjaxEvents();
	addNewWindowEvents();
	
	urlHistoryManager = new UrlHistoryManager();
	urlHistoryManager.start();
	
	checkFork();
	checkForQuestion();
});
