/*
 * template.ajax.js Version 1.0 (Jan Sugarek)
 * - USE: system_report.js v1.0, selftest.ajax.js v1.0
 * - sucast noveho projektu SATS (Sugarek's Ajax Template System)
 * - ide o ajaxove funkcie na spracovanie xml dat zo servra
 * - hlavne funkcie su nacitanie a nastavenie pozadovanej sablony a
     doplenie dat podla sablony
 * - aktualna verzia obsahuje funkcie len na doplnovanie dat do elementov
 * - bude doplnene o funkcie vytvorenia elementov podla sablony
 *
 * v1.0 20.7.2008
 */

// url na ktorej ziskame data
var template_url_request = "request/template.request.php";

// xmlHTTP objekct
var template_xml_http = createXmlHttpRequestObject();

// objekty
var template_update_interval = 10000;

var template_cache = new Array(); // cache pamat pre xml_http poziadakvy
var template_todo = new  Array(); // cache pamat pre ulohy na nastavenie sablony a dat

var template_buffered = null; // buffer pre nacitanie sablony, typu objekt element

var template_should_set = false; // sablona ktora ma byt nastavena
var template_data_should_set = false; // data ktore maju byt nastavene

var template_actual_location = false; // miesto kam sa data idu nastavovat
var template_actual_set = false; // aktualne nastavena sablona
var template_wait_interval = 200; // cakaci interval
var template_dataset_attempt = 20; // max pocet pokus o nastavenie dat.

// inicializacna funcia pre template ajax
function template_init(e_console)
{
	// inicializacia documentu kde budu ulozene nacitane sablony
	template_buffered = document.createElement('template_buffered');
}


/*
 * Tato funkcia je urcena na volanie z inych skriptov.
 * Ide o pridanie poziadavky na nastaveni sablony a dat
 */
function template_todo_add(template_location, template_name, template_data)
{
	var arr_new = new Array();
	arr_new.push(template_location);
	arr_new.push(template_name);
	arr_new.push(template_data);

	template_todo.push(arr_new);

	template_do();
}

/*
 * Funkicia zoberie zaznam template_todo a vyvola nastavenie sablony a dat
 */
function template_do()
{
	if(template_todo.length > 0 )
	{
		arr_set = template_todo.shift();
		if(arr_set.length == 3)
		{
			template_actual_location = arr_set.shift();
			template_should_set = arr_set.shift();
			template_data_should_set = arr_set.shift();

			template_set();
			template_set_data(0);
		}
		else
		{
			template_do();
		}
	}
}

/*
 * Funckia vyhlada sablonu ktora sa ma nastavit, ak nenajde vyvola jej stiahnute zo servra
 */
function template_set()
{
	if(template_should_set == template_actual_set) return;


	var find = template_buffered.getElementsByTagName(template_should_set);
	if(find.length)
	{
		e_location = document.getElementById(template_actual_location);
		if(e_location)
		{
			e_location.innerHTML = find.item(0).innerHTML;
			template_actual_set = template_should_set;
		}
		else
			report_error('template.ajax.js: Nemozem nastaviť šablónu, pretože zadané umiestnenie neexistuje.');
	}
	else
	{
		template_get_xml();
	}
}

function template_load(template_name)
{
	var find = template_buffered.getElementsByTagName(template_name);
	if(find.length) return;

	params = "template="+template_name;
	template_cache.push(params);
	template_request();
}
/*
 * Funkcia vytvori poziadavku na nacitanie sablony
 *
 * VSTUP:  nazov sablony
 */
function template_get_xml()
{
	params = "template="+template_should_set;
	template_cache.push(params);
	template_request();
}

/*
 * odoslanie poziadavky na server
 * neobsahuje automaticke cycklicke funkcie
 * cykli sa len v pripade nedostupnosti servra resp nedostupnosti xml_http objektu
 * poziadavku odosle iba v pripade ak sa nejaka nachadza v template_cache
 */
function template_request()
{
	if(template_xml_http)
	{
		try
		{
			if(template_xml_http.readyState == 4 || template_xml_http.readyState == 0)
			{
				if(template_cache.length > 0)
				{
					params = template_cache.shift();
				}
				else
				{
					return;
				}
				template_xml_http.open("POST", template_url_request, true);
				template_xml_http.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
				template_xml_http.onreadystatechange = template_handle_response;
				template_xml_http.send(params);
			}
			else
			{
				setTimeout("template_request();", template_wait_interval);
			}
		}
		catch(e)
		{
			report_error('template.ajax.js: ' + e.toString(), true);
		}
	}
}



function template_handle_response(){
	if(template_xml_http.readyState == 4){
		if(template_xml_http.status == 200){
			try{
				template_read_response();
			}
			catch(e){
				if(e.length == 0)
					selftest_start(template_url_request);
				else{
					report_error('template.ajax.js: ' + e.toString(), true);
				}
			}
		}
		else{
			selftest_start(template_url_request);
		}
	}
}


/*
 * Funkcia precita zo servra poziadavku na stiahnutie sablony
 * Ak ziadne chyby tak serializuje XML a vytvori innerHTML a pripoji do template_buffered
 */
function template_read_response(){
	// precitanie odpovede a zistenie ci obsahuje chybove hlasky
	var response = template_xml_http.responseText;

	//document.getElementById('t_logtosys').innerHTML = response;


	if( response.indexOf("ERRNO") >= 0 || response.indexOf("error:") >= 0 || response.length == 0)
	{
		if(response.length == 0)
			selftest_start(template_url_request);
		else
			throw(response);

		return;
	}

	response = template_xml_http.responseXML.documentElement;

	// precitanie chyby
	var error_messages = response.getElementsByTagName('error');
	if(error_messages && error_messages.length)
	{
		report_error(template_url_request + ': ' + error_messages.item(0).firstChild.data, true);
		return;
	}

	// precitanie sablony

	var template = response.getElementsByTagName('template');
	if(template.length)
	{
		var name = template.item(0).getElementsByTagName('name');
		var data = template.item(0).getElementsByTagName('data');

		if(name.length && data.length)
		{
			name = name.item(0).firstChild ? name.item(0).firstChild.data : false;
			data = data.item(0);
			var data_count = data.childNodes.length;
			if(name && data_count)
			{
				template_new = document.createElement(name);

				var data_node_string = "";
				for(var i = 0; i <data_count; i++)					data_node_string += xml_to_string(data.childNodes[i]);
				template_new.innerHTML = data_node_string;
				template_buffered.appendChild(template_new)

				if(template_should_set == name) template_set();
			}
		}
	}
}

/*
 * Funkcia nastavi data do sablony. Kedze sablona este nemusi byt nastavena, preto
 * sa tato funkcia pokusi nastavit data niekolkokrat - maximalne template_dataset_attempt-krat
 * TATO FUNKCIA SA NEVOLA PRIAMO ALE PROSTREDNICTVOM template_todo_add() ktora zavola cyklicku template_do() a ta vola set_data
 *
 * VSTUP:  attempt_number - udava cislo pokusu
 * VYSTUP: doplnene data do stranky, inac ziadny vystup cez return
 */
function template_set_data(attempt_number)
{


	// osetrenie proti zacykleniu, trieda sa pokusi nastavit data do sablony max template_dataset_attempt
	if(attempt_number >= template_dataset_attempt)
	{
		report_error('template.ajax.js: Bol dosiahnutý max. počet opakovaní. Nepodarilo sa nastaviť dáta do šablóny, pretože šablóna nebola nastavená.', true);
		return;
	}


	if(template_actual_set != template_should_set){
		setTimeout("template_set_data(" + attempt_number + ");", template_wait_interval);
		return;
	}


	data = template_data_should_set;
	if(data)
	{
		// parsovanie dat pre cistenie objektov
		var clear = data.getElementsByTagName('clear');
		for(var j = 0; j < clear.length; j++)
		{
			var id = clear.item(j).getElementsByTagName('id');
			if(id.length)
			{
				id = id.item(0).firstChild ? id.item(0).firstChild.data : false;
				if(id)
				{
					var elem = document.getElementById(id);
					if(elem)
					{
						elem.innerHTML = "";
					}
				}
			}
		}

		// parsovanie dat pre vlozenie sablony do sablony a nastavenie id
		var insert = data.getElementsByTagName('insert');
		for(var j = 0; j < insert.length; j++)
		{
			var location = insert.item(j).getElementsByTagName('location');
			var template = insert.item(j).getElementsByTagName('template');
			var setid    = insert.item(j).getElementsByTagName('setid');

			if(location.length && template.length && setid.length)
			{
				location = location.item(0).firstChild ? location.item(0).firstChild.data : false;
				template = template.item(0).firstChild ? template.item(0).firstChild.data : false;

				if(location && template)
				{
					var find = template_buffered.getElementsByTagName(template);
					var elem_location = document.getElementById(location);

					if(find.length && elem_location)
					{
						var find = find.item(0);
						for(var k = 0; k < find.childNodes.length; k++)
						{
							elem_location.appendChild(find.childNodes[k].cloneNode(true));
						}
						for(var i = 0; i < setid.length; i++)
						{
							var id     = setid.item(i).getElementsByTagName('id');
							var id_new = setid.item(i).getElementsByTagName('id_new');
							if(id.length && id_new.length)
							{
								id     =     id.item(0).firstChild ?     id.item(0).firstChild.data : false;
								id_new = id_new.item(0).firstChild ? id_new.item(0).firstChild.data : false;

								if(id && id_new)
								{
									var elem_to_change = document.getElementById(id);
									if(elem_to_change)
									{
										elem_to_change.setAttribute('id', id_new);
									}
								}
							}
						}
					}
				}
			}
		}

		// parsovanie dat na nastavenie stylov elementov
		var set_style = data.getElementsByTagName('set_style');
		for(var j = 0; j < set_style.length; j++)
		{
			var id         = set_style.item(j).getElementsByTagName('id');
			var class_name = set_style.item(j).getElementsByTagName('class_name');

			if(id.length && class_name.length)
			{
				id         =         id.item(0).firstChild ?         id.item(0).firstChild.data : false;
				class_name = class_name.item(0).firstChild ? class_name.item(0).firstChild.data : "";

				if(id)
				{
					var elem = document.getElementById(id);
					if(elem) elem.className = class_name;
				}
			}
		}

		// parsovanie dat na nastavenie atributov
		var set_attribute = data.getElementsByTagName('set_attribute');
		for(var j = 0; j < set_attribute.length; j++)
		{
			var id        = set_attribute.item(j).getElementsByTagName('id');
			var attribute = set_attribute.item(j).getElementsByTagName('attribute');
			var value     = set_attribute.item(j).getElementsByTagName('value');

			if(id.length && attribute.length && value.length)
			{
				id        =        id.item(0).firstChild ?        id.item(0).firstChild.data : false;
				attribute = attribute.item(0).firstChild ? attribute.item(0).firstChild.data : false;
				value     =     value.item(0).firstChild ?     value.item(0).firstChild.data : "";
				if(id && attribute)
				{
					var elem = document.getElementById(id);
					if(elem) elem.setAttribute(attribute, value);
				}
			}
		}

		// parsovanie dat na nastavenie disabled=true
		var set_disable = data.getElementsByTagName('set_disable');
		for(var j = 0; j < set_disable.length; j++)
		{
			var id = set_disable.item(j).getElementsByTagName('id');

			if(id.length)
			{
				id = id.item(0).firstChild ? id.item(0).firstChild.data : false;
				if(id)
				{
					var elem = document.getElementById(id);
					if(elem) elem.disabled = true;
				}
			}
		}

		// parsovanie dat na povolenie editacie
		var set_enable = data.getElementsByTagName('set_enable');
		for(var j = 0; j < set_enable.length; j++)
		{
			var id = set_enable.item(j).getElementsByTagName('id');

			if(id.length)
			{
				id = id.item(0).firstChild ? id.item(0).firstChild.data : false;
				if(id)
				{
					var elem = document.getElementById(id);
					if(elem) elem.disabled = false;
				}
			}
		}

		// parsovanie dat na nastavenie obsahu input form
		var set_input = data.getElementsByTagName('set_input');
		for(var j = 0; j < set_input.length; j++)
		{
			var input    = set_input.item(j).getElementsByTagName('input');
			var value    = set_input.item(j).getElementsByTagName('value');

			if(input.length && value.length)
			{
				input = input.item(0).firstChild ? input.item(0).firstChild.data : false;
				value = value.item(0).firstChild ? value.item(0).firstChild.data : "";

				if(input)
				{
					var elem = document.getElementById(input);
					if(elem) elem.value = value;
				}
			}
		}

		// parsovanie dat na nastavenie innerHTML
		var set_text = data.getElementsByTagName('set_text');
		for(var j = 0; j < set_text.length; j++)
		{
			var id    = set_text.item(j).getElementsByTagName('id');
			var value = set_text.item(j).getElementsByTagName('value');

			if(id.length && value.length)
			{
				id    =    id.item(0).firstChild ?    id.item(0).firstChild.data : false;
				value = value.item(0).firstChild ? value.item(0).firstChild.data : "";

				if(id)
				{
					var elem = document.getElementById(id);
					if(elem)
					{
						var specials = set_text.item(j).getElementsByTagName('allow');

						if(specials.length)
							elem.innerHTML = value;
						else
							elem.innerHTML = htmlspecialchars(value);
					}
				}
			}
		}

		// parsovanie dat na pripojenie textu do elementu
		var append_text = data.getElementsByTagName('append_text');
		for(var j = 0; j < append_text.length; j++)
		{
			var id    = append_text.item(j).getElementsByTagName('id');
			var text = append_text.item(j).getElementsByTagName('text');

			if(id.length && text.length)
			{
				id   =   id.item(0).firstChild ?   id.item(0).firstChild.data : false;
				text = text.item(0).firstChild ? text.item(0).firstChild.data : "";

				if(id)
				{
					var elem = document.getElementById(id);
					if(elem) elem.appendChild(document.createTextNode(htmlspecialchars(text)));
				}
			}
		}

		// parsovanie udajov na spustanie skriptov pomocou setTimeout
		var run = data.getElementsByTagName('run');
		for(var j = 0; j < run.length; j++)
		{
			var cmd     = run.item(j).getElementsByTagName('cmd');
			var timeout = run.item(j).getElementsByTagName('timeout');

			if(cmd.length && timeout.length)
			{
				cmd     =     cmd.item(0).firstChild ?     cmd.item(0).firstChild.data : false;
				timeout = timeout.item(0).firstChild ? timeout.item(0).firstChild.data : false;
				if(cmd && timeout)
				{
					setTimeout(cmd, (typeof timeout == 'number' ? timeout : parseInt(timeout)));
				}
			}
		}

		// parsovanie dat na nastavenie focus na element
		// odporuca sa v jednom xml subore zadavat focus len pre jeden element
		// ak bude viacero nastaveni tak focus bude na posledny
		var set_focus = data.getElementsByTagName('set_focus');
		for(var j = 0; j < set_focus.length; j++)
		{
			var id = set_focus.item(j).getElementsByTagName('id');

			if(id.length)
			{
				id = id.item(0).firstChild ? id.item(0).firstChild.data : false;
				if(id)
				{
					var elem = document.getElementById(id);
					if(elem) elem.focus();
				}
			}
		}

		loading_stop();

	}

	template_data_should_set = false;
}
