/*
 *	=============================
 *   	SETTINGS
 *	=============================
 */

var page_id = false;
var ajax_data_url = '/_fw/ajax/';

/*
 *	=============================
 *   	AJAX CLASS
 *	=============================
 */

function AJAX(){
	// Timer parameters
	this.timeline = new Array();
	this.frame    = 0;
	this.interval = null;
  	// Loader parameters
  	this.CurrentRequest  = false;
	this.request_pipeline = new Array();
	this.delayed_requests = new Array();
}

/*
 *	=============================
 *   	AJAX PUBLIC METHODS
 *	=============================
 */

AJAX.prototype.load = function(module, action, parameters){
	this.executeRequest(new AJAXRequest(module, action, parameters, this.frame));
	return false;
}

AJAX.prototype.load2 = function(module, action, parameters){
	AJAX.load(module, action, parameters);
}

AJAX.prototype.loadURL = function(url, module, action, parameters){
	var Request = new AJAXRequest(module, action, parameters, this.frame);
	Request.ajax_url = url;
	this.executeRequest(Request);
}


// load_delayed will be used whenever an event occures several times but only the last occurence should trigger an ajax request
AJAX.prototype.load_delayed = function(module, action, parameters, delay){
	this.delayed_requests[module + ":" + action] = new AJAXRequest(module, action, parameters, (this.frame+delay));
	AJAX.addTimedEvent(new AJAXAction('load_delayed', {delayed_request_id: module + ':' + action}), delay);
	return false;
}


AJAX.prototype.submitForm = function(form_id, module, action){
	var parameters = "";
	var form = document.getElementById(form_id);
	if(!form) return;
	var inputList = form.getElementsByTagName('input');
	var selectList = form.getElementsByTagName('select');
	var textareaList = form.getElementsByTagName('textarea');
	var e;
	for(var i=0;i<inputList.length;i++){
		e = inputList.item(i);
		if(e.name){
			if(parameters.length>0) parameters+= "&";
			switch(e.type){
			 	case 'checkbox':
			 		if(e.checked) parameters+= e.name + "=" +e.value;
			 		else parameters+= e.name + "=0";
			 	break;
			 	case 'radio':
					if(e.checked) parameters+= e.name+ "=" +e.value;
			 	break;
				default:
					parameters+= e.name + "=" + encodeURIComponent(e.value);
				break;
			}
		}
	}
	for(var i=0;i<selectList.length;i++){
		e = selectList.item(i);
		if(e.name){
		if(parameters.length>0) parameters+= "&";
			parameters+= e.name + "=" + encodeURIComponent(e.value);
		}
	}
	for(var i=0;i<textareaList.length;i++){
	e = textareaList.item(i);
	if(e.name){
		if(parameters.length>0) parameters+= "&";
			parameters+= e.name + "=" + encodeURIComponent(e.value);
		}
	}
	AJAX.load(module, action, parameters);
}

/*
 *	=============================
 *   	AJAX TIMER FUNCTIONS
 *	=============================
 */

AJAX.prototype.start = function(){
  if(this.interval) return;
  this.interval = window.setInterval("AJAX.executeFrame()", 50);
}

AJAX.prototype.stop = function(){
  if(this.interval){
    window.clearInterval(this.interval);
    this.interval = null;
    this.frame = 0;
	var element = document.getElementById("ajax_timer");
	if(element) element.innerHTML = this.frame + ": " + (this.timeline.length); // + " (" + ActionList.length + ")";
  }
}

AJAX.prototype.addTimedEvent = function(Event, delay){
	var time_index = this.frame + parseInt(delay);
	// TODO: check if delay is valid
	if(!this.timeline[time_index])
		this.timeline[time_index] = new Array();
	this.timeline[time_index][this.timeline[time_index].length] = Event;
	AJAX.start();
}

AJAX.prototype.executeFrame = function(){
	this.frame++;
	var AJAXAction;
	var AJAXActionList = this.timeline.shift();
	if(AJAXActionList){
    	while(AJAXActionList.length>0){
			AJAXAction = AJAXActionList.shift();
			AJAXAction.execute();
			/*if(AJAXAction.loops>0){
				Action.loops--;
				if(!this.timeline[0]) this.timeline[0] = new Array();
				this.timeline[0].push(Action);
 			}*/
		}
	}
	var element = document.getElementById("ajax_timer");
	if(element) element.innerHTML = this.frame + "/" + (this.timeline.length);
	if(this.timeline.length==0) this.stop();
}

/*
 *	=============================
 *   	AJAX POPUP
 *	=============================
 */

 AJAX.prototype.closepop = function(){
 	var OuterDiv = document.getElementById("AJAXPOP_outerdiv");
	var InnerDiv = document.getElementById("AJAXPOP_innerdiv");
	if(OuterDiv)
		OuterDiv.style.display = "none";
	if(InnerDiv)
		InnerDiv.style.display = "none";
 }

/*
 *	=============================
 *  	AJAX REQUEST
 *	=============================
 */

function AJAXRequest(module, action, parameters, time_index){
	this.ajax_url	= ajax_data_url;
	this.module		= module;
	this.action		= action;
	this.parameters = parameters;
	this.time_index = time_index;
	this.request  	= null;
}

AJAXRequest.prototype.execute = function(){

	var ajax_debugger = document.getElementById("ajax_debugger");
	if(ajax_debugger)
	  	ajax_debugger.innerHTML = 'http://' + window.location.host + this.ajax_url;

	if(this.request) return;
	// Setup parameters
	var parameters = "fw_target=" + this.module
		+ "&fw_tab=" + window.name
		+ "&fw_action=" + this.action;

	if(page_id) parameters+= "&page=" + page_id;
	if(this.parameters) parameters+= "&" + this.parameters;

	if(ajax_debugger)
	  	ajax_debugger.innerHTML = ajax_debugger.innerHTML += "?" +  parameters + "<br>";

	// Mozilla, Opera, Safari sowie Internet Explorer 7
	if (typeof XMLHttpRequest != 'undefined') {
    	this.request = new XMLHttpRequest();
	}
	if (!this.request) {
	    // Internet Explorer 6 und älter
    	try {
        	this.request  = new ActiveXObject("Msxml2.XMLHTTP");
	    } catch(e) {
	        try {
    	        this.request  = new ActiveXObject("Microsoft.XMLHTTP");
	        } catch(e) {
    	        this.request  = false;
        	}
	    }
	}

	if(!this.request) return; // TODO: ERROR MESSAGE: "BROWSER DOESN'T SUPPORT AJAX"
	this.request.open("POST", this.ajax_url, true);
	//this.request.overrideMimeType("text/xml");
	this.request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
	this.request.onreadystatechange=ajaxCheckRequestStatus;

	// TODO REMOVE
	var ajax_debugger = document.getElementById("ajax_debugger");
	if(ajax_debugger) ajax_debugger.innerHTML = "loading: "+ ajax_data_url + "?" + parameters + "<br>";

	this.request.send(parameters);
}

// TODO: can 2 requests run simultaneously?
function ajaxCheckRequestStatus(){
	if(!AJAX.CurrentRequest) return;
	AJAX.CurrentRequest.checkRequestStatus();
	// TODO: Request pipeline
	if(AJAX.CurrentRequest.request==null)
		AJAX.CurrentRequest = null;
}

AJAXRequest.prototype.checkRequestStatus = function(){
  switch(this.request.readyState){
    case 0: // NICHT INITIALISIERT
    case 1: // LADEND
    case 2: // GELADEN
    case 3: // INTERAKTIV
    break;
    case 4:
      if(this.request.status!=200){
      	// TODO: error handling
        //alert("Daten konnten nicht geladen werden");
      } else {
        this.parseXMLResponse();
		this.request = null;
      }
    break;
  }
}

/*
 *	=============================
 *  	AJAX RESPONSE
 *	=============================
 */

AJAXRequest.prototype.parseXMLResponse = function (){
	// TODO REMOVE
	var ajax_debugger = document.getElementById("ajax_debugger");
	// The following line doesn't work in IE
	if(ajax_debugger && typeof XMLHttpRequest != 'undefined')
		ajax_debugger.innerHTML = ajax_debugger.innerHTML + "\n" + this.request.responseText;

	var ActionNode;
	var AJAXActionObj;
	var xml = this.request.responseXML;

	// CHECK IF WE DOCUMENT HAS NODES
	if(!xml.hasChildNodes()) return;
	// FIRST NODE MUST BE <data>
	for(var ii=0;ii<xml.childNodes.length;ii++){
  		data_node = xml.childNodes[ii];
	  	if(data_node.nodeName=="data"){

			// CHECK IF data HAS ANY CONTENT
	  		if(data_node.childNodes.length==0) return; //??

			// PARSE CONTENT
	  		for(var i=0;i<data_node.childNodes.length;i++){
		  		ActionNode = data_node.childNodes[i];

		  		if(ActionNode.nodeName=="action"){
			  		// Execute action
			  		// TODO: check delay, loop, etc

			  		AJAXActionObj = new AJAXAction(
			  			ActionNode.getAttribute('name'),
			  			{
		  					target: ActionNode.getAttribute('target'),
		  					value: getNodeValue(ActionNode)
		  				}
			  		);
			  		AJAXActionObj.delay = ActionNode.getAttribute('delay');
			  		if(AJAXActionObj.delay>0){
						AJAX.addTimedEvent(AJAXActionObj, AJAXActionObj.delay);
			  		} else {
			  			AJAXActionObj.execute();
		    		}
		    	}
	  		}
	  	}
	}
}


/*
 *	=============================
 *  	AJAX REQUEST PIPELINE
 *	=============================
 */

AJAX.prototype.executeRequest = function(AJAXRequestObj){
	// add request to pipeline if there are incomplete requests
	if(this.request_pipeline.length>0){
		this.request_pipeline.push(AJAXRequestObj);
	} else {
		AJAX.CurrentRequest = AJAXRequestObj;
		AJAX.CurrentRequest.execute();
	}
}

/*
 *	=============================
 *   	AJAXAction CLASS
 *	=============================
 */

function AJAXAction(event, parameters){
	this.event = event;
	this.parameters = parameters;
	this.delay 	= 0;
	this.loop 	= 0;
	this.loop_interval = 1;
	this.max_num_loops = 999999;
}

/*
 *	=============================
 *   	AJAXAction::execute
 *	=============================
 */

AJAXAction.prototype.execute = function(){
	switch(this.event){
		case 'redirect':	 		this.redirect();break;
		case 'load_delayed': 		this.load_delayed();  break;
		case 'refresh_div':	 		this.refresh_div();break;
		case 'open_popup':	 		this.open_popup();break;
		case 'open_popup_green': 	this.open_popup_green();break;
		case 'close_popup':	 		AJAX.closepop();break;
		case 'eval': 				this.eval();break;
		case 'scriptaculous':		this.execute_scriptaculous_effect();break;
	}
}

// AJAXAction::redirect
AJAXAction.prototype.redirect = function (){
	window.location.href = this.parameters.value;
}

// AJAXAction::load_delayed
AJAXAction.prototype.load_delayed = function (){
	// get delayed ajax request
	var AJAXRequestObj = AJAX.delayed_requests[this.parameters.delayed_request_id];
	// time_index might have changed
	// ignore event if time_index is not equal the current frame
	// TODO: there is still a bug in this script - AJAXRequestObj can be undefined
	if(!AJAXRequestObj) return;
	if(AJAXRequestObj.time_index>AJAX.frame) return;
	// Move AJAXRequest to request pipeline
	AJAX.delayed_requests[this.parameters.delayed_request_id] = false;
	AJAX.executeRequest(AJAXRequestObj);
	return false;
}

// AJAXAction::refresh_div
AJAXAction.prototype.refresh_div = function (){
	var Element = document.getElementById(this.parameters.target);
	// TODO: error handling
	if(!Element){
		// alert('Element ' + this.parameters.target + ' not found');
		return;
	}
	Element.innerHTML = this.parameters.value;
	Element.style.zIndex = '97';
}

AJAXAction.prototype.open_popup = function(){

	var OuterDiv = document.getElementById("AJAXPOP_outerdiv");
	var InnerDiv = document.getElementById("AJAXPOP_innerdiv");
	var thickHeight;

	if (window.innerHeight) {
    	thickHeight=window.innerHeight;
  	} else if (document.body && document.body.offsetHeight) {
    	thickHeight=document.body.offsetHeight;
  	}

	if(!OuterDiv){
		OuterDiv = document.createElement("div");
		OuterDiv.id = "AJAXPOP_outerdiv";
		OuterDiv.style.position = "fixed";
		OuterDiv.style.top = 0;
		OuterDiv.style.left = 0;
		OuterDiv.style.width = "100%";
		OuterDiv.style.height = "100%";
		OuterDiv.style.background = "#CDCDCD";
		OuterDiv.style.opacity = "0.5";
		document.getElementsByTagName("body")[0].appendChild(OuterDiv);
	}
	if(!InnerDiv){
		InnerDiv = document.createElement("div");
		InnerDiv.id = "AJAXPOP_innerdiv";
		InnerDiv.style.position = "absolute";
		InnerDiv.style.left = "200px";
		InnerDiv.style.top = "80px";
		InnerDiv.style.width = "600px";
		InnerDiv.style.background = "white";
		InnerDiv.style.border = "2px solid black";
		document.getElementsByTagName("body")[0].appendChild(InnerDiv);
	}

	OuterDiv.style.display = "block";
	OuterDiv.style.zIndex = 1001;
	OuterDiv.style.height = thickHeight;
	InnerDiv.style.display = "block";
	InnerDiv.style.zIndex = 1002;

	InnerDiv.innerHTML = "<div style='float: left;width: 600px; height: 10px; font-size: 1px; behavior:url(/css/iepngfix.htc); background: url(/images/globals/thickbox2/top_bg.png) no-repeat;'></div><div style='float: left;width: 600px; behavior:url(/css/iepngfix.htc); background: url(/images/globals/thickbox2/content_bg.png) repeat-y;'><div style='float:right; margin-right: 20px;'><a href='javascript:AJAX.closepop()'><span style='display: block;color: gray; line-height: 14px;float: left;margin-right: 5px;'>Fenster schliessen</span> <img src='/images/icon_widget_close.png' border='0' /></a></div><div class='spacer'></div>"
		+ "<div>" + this.parameters.value + "</div>"
		+ "</div>"
		+ "<div style='float: left;width: 600px; height: 20px; behavior:url(/css/iepngfix.htc); background: url(/images/globals/thickbox2/footer_bg.png) no-repeat;'></div>";
}


// AJAXAction::eval
AJAXAction.prototype.eval = function(){
	eval(this.parameters.value);
}



/*
 *	=============================
 *   	SUPPLEMENTARY FUNCTIONS
 *	=============================
 */

function node2array(node){
  var a = new Array();
  var child_node;
  var param_name;
  var param_value;
  if(node.hasChildNodes()){
    for(var i=0;i<node.childNodes.length;i++){
      child_node = node.childNodes[i];
      param_name = child_node.nodeName;
      if(child_node.hasChildNodes()){
        if(child_node.firstChild.nodeType==3){ // TEXT NODE
          // TODO: FIREFOX ONLY
          param_value = "";
          for(var j=0;j<child_node.childNodes.length;j++){
          	param_value = param_value + child_node.childNodes[j].nodeValue;
          }
        } else {
          param_value = node2array(child_node);
        }
      } else {
        param_value = child_node.nodeValue;
      }
      a[param_name] = param_value;
    }
  }
  return a;
}

function getNodeValue(Node){
	var value = "";
	var ChildNode;
	if(Node.hasChildNodes){
		for(var i=0;i<Node.childNodes.length;i++){
			ChildNode = Node.childNodes[i];
			if(ChildNode.nodeType==3){ // TEXT - Firefox only
				value+= ChildNode.nodeValue;
			}
		}
	} else {
		value+= Node.nodeValue;
	}
	return value;
}

// TODO2
function json2string(obj){}


/*
 *	=============================
 *   	INIT AJAX
 *	=============================
 */

var AJAX = new AJAX();

function isAJAXIdle(){
	if(AJAX.CurrentRequest==null) return true
	return false;
}

// Setup window name
/*if(!window.name.match(/^CTAB_(.+)/)){
	AJAX.load('_AJAX','getTabName','');
}*/



