//////////////////////////
// SISU Ajax interface  //
// @author: Laborint OĆ? //
//////////////////////////

// DEBUG
function printfire()
{
	if(typeof console != 'undefined' && typeof(console.log) == 'function') {
		console.log(arguments[0]);
	}
	else if (document.createEvent && typeof dispatchEvent != 'undefined')
    {
        printfire.args = arguments;
        var ev = document.createEvent("Events");
        ev.initEvent("printfire", false, true);
        dispatchEvent(ev);
    }
    else if(typeof Console != 'undefined' && typeof(Console.addEntry) == 'function')
    {
        Console.addEntry({message: arguments[0], level: "notice"});
    }
}

p = printfire;

var url = 'http://'+window.location.host;
var current_url = window.location.href.split('/');
if (window.location.pathname != '/') {
	window.location.replace('http://'+window.location.host+'#'+window.location.pathname.substr(1)+encodeHistory(window.location.search));
}
document.write('<script type="text/javascript" src="/javascript/dhtmlHistory.js"></script>');
var params = 'prototype=1';
var initial_url = '';
responseHandlers = {};
oldContent = {};

function generateCacheId() {
	return +(new Date());
}
var cache_id = generateCacheId();

var GlobalHandlers = {
	onCreate: function(){		
		p('REQUEST PROCCESSING...');
	},

	onComplete: function() {
		if(Ajax.activeRequestCount == 0){
			p('REQUEST COMPLETE');
		}
	},
	
	onFailure: function() {
		p('REQUEST FAILURE');
	}	
};

function encodeHistory(str) {
	return encodeURIComponent(str).replace(/%2F/g, "/").replace(/%3D/g, "=")/*.replace(/%26/g, "&")*/.replace(/%/g, "+");
}

function decodeHistory(str) {
	return decodeURIComponent(str.replace(/[+]/g, "%"));
}

var onContentLoad = Class.create();
onContentLoad.prototype = {

	callHandler: function (name) {
		p('CALL: '+name);
		var handler = responseHandlers;
		if(handler[name])
			return handler[name].apply(null, $A(arguments).slice(1));
	},	
		
	initialize: function () {
		this.init_history();
		this.interceptLinks(document);
	},
	
	init_history: function() {
		dhtmlHistory.initialize();
		dhtmlHistory.addListener(this.updateUI.bind(this));		
		
		var initialLocation = dhtmlHistory.getCurrentLocation();
		if (initialLocation == null) {
			initialLocation = initial_url;
		}
		// Workaround, XMLHTTPRequests don't work when DOM isn't complete?
		setTimeout(function() { this.updateUI(initialLocation, null) }.bind(this), 10);
	},
			
	updateUI: function(newLocation, historyData) {
		var newLocation = decodeHistory(newLocation);
		var showResponse = this.showResponse.bind(this);				
		var new_cache_id = generateCacheId();
		var sisu_request = new Ajax.Request( newLocation, {method: 'get', 
			parameters: params + "&cache_id=" + cache_id + "&new_cache_id=" + new_cache_id, 
			onComplete: function() { cache_id = new_cache_id; return showResponse.apply(null, arguments); } } );	
	},
	
	makeLinkInterceptor: function(elem) {
		var callHandler = this.callHandler.bind(this);
		var self = this;
		var showResponse = this.showResponse.bind(this);
		
		return function() {		
			var dest_url = this.href.split('/');				
			// check if the href is inside this website & host is followed by a 2 character element
			if (current_url[2] == dest_url[2] && dest_url[3].length == 2) {
				var hash_url = this.href.substr(url.length + 1);
				dhtmlHistory.add(encodeHistory(hash_url), {message: ''});
				
				var new_cache_id = generateCacheId();				
				var sisu_request = new Ajax.Request( this.href, {method: 'get',
					parameters: params + "&cache_id=" + cache_id + "&new_cache_id=" + new_cache_id,
					onComplete: function() { cache_id = new_cache_id; return showResponse.apply(null, arguments); } } );

				Try.these(callHandler("onPageChange", elem));
				return false;
			}
			return true;
		}
	},
	
	interceptLinks: function (parent) {
		$A(parent.getElementsByTagName("a")).each(function(elem) {
			elem.onclick = this.makeLinkInterceptor(elem);			
		}.bind(this));
	},
		
	getReplacer: function(id, value) {
		return function() {
			$(id).innerHTML = value;			
			this.interceptLinks($(id));
			oldContent[id] = value;
		}.bind(this);
	},
	
	showResponse: function (originalRequest) {
		p('RESPONSE BEGIN');						
		//it seems that server has some header element length problems
		//this causes a Internal Server error when processing bigger data chunks
		//so we dont use the autoEVAL feature of prototype
		data = eval('('+originalRequest.responseText+')');
		
		Try.these(this.callHandler("_construct_", data));
		for (var item in data) {
			var a = data[item];
			var cmd = a[1];
			var value = a[0];					
			
			if(cmd == "replace") {
				var element = $(item);				
				if(element && oldContent[item] != value) {
					Try.these(this.callHandler("beforeReplace", element, value));
										
					var replacer = this.getReplacer(item, value);
					if(!this.callHandler("replace", element, replacer))
						replacer();
					
					Try.these(this.callHandler("afterReplace", element, value));
				}
			} else {
				this.callHandler(cmd, item, value);
			}		
		}
		Try.these(this.callHandler("_destruct_", data));		
		p('RESPONSE END');
	}
	
}
Ajax.Responders.register(GlobalHandlers);