// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// DemoSS object
// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
DemoSS=function(xml_url, server_api, interface_func) {
	// constructor of object for Demo SpeakSurvey
	// data
	this.scenario = new XML_text(xml_url);
	this.server_api = server_api; // DWR class on server
	this.interface_cb = interface_func; // function for web-interface redrawing
	
	this.languages = new Array('en', 'it', 'de', 'fr'); // correct languages
	this.lang = 'ua';
	this.session_id = 'not set';
	this.pin = '0000';
	this.commands = new Array();
	this.action_choices = new Array();
	this.default_freq = 1; // duration between server requests
	this.call_id = null;
	this.was_last_action = false;
	this.last_portrait_name = "portrait";
};

DemoSS.prototype.init=function(lang, post_func) {
	// initialization of object
	this.language(lang);
	this.add_command('first');
	this.current_viewable = this.current_command();
	// register session on server
	var self = this;
	this.server_api.register_session(
		function(result) {
		  	self.cb_register_session(result, post_func);
		}
	);
	
};

DemoSS.prototype.cb_register_session=function(result, post_func) {
// callback on register session
	var isErr = 0;
	if ( ! result ) {
		isErr = 1;
	} else if ( result == "busy" ) {
		this.add_command('busy');
		this.current_viewable = this.current_command();
	} else {
		var res = result.split(","); 
		if ( res[0] && res[1] && res[2] ) {
			this.serial_id = res[0]; // save session serial ID
			this.session_id = res[1];
			this.pin = res[2];
			this.start_commands(); // starting get info from server
		} else { isErr = 1; }
	}
	// check for error	
	if ( isErr ) {
		window.alert("Create session error: "+result);
	}
	post_func(); // after init initialization
};

DemoSS.prototype.language=function(lang) {
	// FIXME only valid languages
	if ( lang !== undefined) {
		var default_lang = 'en';
		for (var i=0; i<this.languages.length; i=i+1) {
			if ( this.languages[i] == lang ) {
				default_lang = lang;
				break;
			}
		}
		this.lang = default_lang;
	} else {
		return this.lang; 
	}
};

DemoSS.prototype.is_last_action=function(id) { 
// check for last action 
	var action = this.scenario.getTagInGroupById('action', id, 'actions');
	if ( ! action ) {
		window.alert("Action [" + id + "] not found");
		return false;
	}
	var last_node = getNodeByTag(action, 'last_action');
	if ( last_node ) {
		return true;
	}
	return false;
};

DemoSS.prototype.get_action_text=function(id, tag) {
// get text for tag in actions by language 
	var text = 'text for language not found';
	var action = this.scenario.getTagInGroupById('action', id, 'actions');
	if ( ! action ) {
		window.alert("Action not found");
		return;
	}
	// search for tag
	var tag_node = getNodeByTag(action, tag);
	if ( ! tag_node ) {
		//window.alert("Tag not found");
		return;
	}
	// search for text by language
	for (var i=0; i<tag_node.childNodes.length; i=i+1) {
		var node = tag_node.childNodes[i];
		if ( node.nodeName == 'text') {
			var lang = node.attributes.getNamedItem("language").value;
			if ( lang == this.language() ) {
				text = node.firstChild.data;
				break;
			}
		}
	}
	return text;
};

DemoSS.prototype.get_action_text_show_id=function(id, tag) {
// get text show attribute 
	var action = this.scenario.getTagInGroupById('action', id, 'actions');
	if ( ! action ) { return; }
	// search for tag
	var tag_node = getNodeByTag(action, tag);
	if ( ! tag_node ) { return;	}
	// search for text show attribute
	var attrs = tag_node.attributes;
	if (! attrs ) {	return; }
	if ( attrs.getNamedItem("show") ) {
		return attrs.getNamedItem("show").value;
	}
	return;
};

DemoSS.prototype.get_action_image=function(id) { 
// get text for tag in actions by language 
	var action = this.scenario.getTagInGroupById('action', id, 'actions');
	if ( ! action ) {
		window.alert("Action not found");
		return;
	}
	// search for image in img_question, if and if_choice
	var iq_node = getNodeByTag(action, 'img_question');
	if ( ! iq_node ) {
		//window.alert("img_question tag not found");
		return;
	}
	// TODO add if && if_choice
	var found_if = false;
	do {
		found_if = false;
		var if_node = getNodeByTag(iq_node, 'if');
		if ( if_node ) {
			found_if = true;
			var action_id = if_node.attributes.getNamedItem("action").value;
			if ( ! action_id ) {
				window.alert("action attribute not found in if");
				return;
			}
			var past_choice = this.action_choices[action_id]; // FIXME temp
			//window.alert("a_id: " + action_id + ", past_choice: " + past_choice);
			var if_choice = getNodeByTagAndId(if_node, "if_choice", past_choice);
			if ( if_choice ) {
				iq_node = if_choice; 
			} else {
				window.alert("Error if - if_choice declaration");
				return;
			}
		}
	} while ( found_if );
	// get image
	var img_node = getNodeByTag(iq_node, 'image');
	if ( ! img_node ) {
		window.alert("imgage tag not found");
		return;
	}
	return img_node;
};

DemoSS.prototype.get_image_src=function(image_el) { 
// get src attribut from image tag element 
	return image_el.attributes.getNamedItem("src").value;
};

DemoSS.prototype.get_action_image_id=function(id) {
// FIXME OLD must be removed 
// get text for tag in actions by language 
	var action = this.scenario.getTagInGroupById('action', id, 'actions');
	if ( ! action ) {
		window.alert("Action not found");
		return;
	}
	// search for image
	var tag_node = getNodeByTag(action, 'image');
	if ( ! tag_node ) {
		//window.alert("Image tag not found");
		return;
	}
	return tag_node.attributes.getNamedItem("id").value;
};

DemoSS.prototype.get_action_id_by_step=function(step_id) {
// search action_id by step_id
	var step = this.scenario.getTagInGroupById('step', step_id, 'steps');
	if ( !step ) {
		window.alert("Step not found");
		return;
	}
	var action = step.attributes.getNamedItem("action");
	if ( action ) {
		return action.value;
	} else {
		return "no action";
	}
};


DemoSS.prototype.need_show_portrait=function(action_id) {
// FIXME check for <show_portrait/> for step_id
	var action_el = this.scenario.getTagInGroupById('action', action_id, 'actions');
	if ( action_el ) {
		var show_portrait = getNodeByTag(action_el, "show_portrait");
		if ( show_portrait ) {
			this.last_portrait_name = show_portrait.attributes.getNamedItem("id").value;
			return true;
		}
	}
	return false;
};

// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Command element
// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
DemoSSCommand=function(state, step, db_id, next_step, choice, viewable) {
	this.state = state; // name of command, example "step"
	this.step = step; // step number
	if ( !db_id ) {
		db_id = -1;
	}
	this.db_id = db_id; // events.id
	this.next_step = next_step; // next_step number
	this.choice = choice; // next_step number
	this.viewable = viewable; 
};

DemoSS.prototype.add_command=function(state, step, db_id, next_step, choice) {
	// check for viewable
	var viewable = true;
	if ( state === 'step' ) {
		var action_id = DemoSS.get_action_id_by_step(step);
		if ( action_id ) {
			// save in this.action_choices
			this.action_choices[action_id] = choice;
			//window.alert("action_ID: " + action_id + ", choice: " + this.action_choices[action_id]);
		}
		var next_action_id = DemoSS.get_action_id_by_step(next_step);
		if ( next_action_id === 'no action' ) {
			viewable = false;
		} else {
			// check for last action in survey
			if ( next_action_id && this.is_last_action(next_action_id) ) {
				this.was_last_action = true;
				//window.alert("Detect last action!");
			}
		}
	}
	// add command to array
	this.commands.push(new DemoSSCommand(state, step, db_id, next_step, choice, viewable));
};

DemoSS.prototype.get_command=function(index) {
	// get state from command array by index
	if ( index < 0 ) { return false; }
	return this.commands[index];
};

DemoSS.prototype.current_command=function() {
	// get current state
	var last_index = this.commands.length - 1;
	return this.get_command(last_index);
};

DemoSS.prototype.prev_command=function() {
	// get previous state
	var last_index = this.commands.length - 2;
	return this.get_command(last_index);
};

DemoSS.prototype.start_commands=function() {
	this.freq = this.default_freq;
	this.was_server_answer = true; // create new request only if server answer
	this.server_error_count = 0; // qntt skip server error in cycles
	this.get_command_from_server();
};

DemoSS.prototype.stop_commands=function() {
	this.freq = 0;
	window.clearInterval(this.repeater);
};

DemoSS.prototype.get_command_from_server=function() {
	// clear settled timer
	if ( this.repeater ) {
		window.clearInterval(this.repeater);
	}
	// check for frequency
	if ( this.freq >0) {
		//window.alert("get_command");
		var self = this;
		var curr_command = this.current_command();
		if ( this.was_server_answer ) {
			this.was_server_answer = false; // wait for server answer
			this.server_api.get_commands(curr_command.db_id, this.session_id, {
			  callback:function(result) {
			  	self.cb_server_command(result);
			  	window.status = "";
			  	self.was_server_answer = true;
			  },
			  errorHandler:function(errorString, exception) {
			    self.was_server_answer = true;
			    window.status = "CB_error: " + errorString;
			  }
			});
		} else {
			// server not answer
			this.server_error_count = this.server_error_count + 1;
			if ( this.server_error_count > 5 ) {
				self.was_server_answer = true; // try send new request
				this.server_error_count = 0;
			}
		}
		this.repeater = window.setInterval("DemoSS.get_command_from_server()", this.freq*1000);
	}
};

DemoSS.prototype.cb_server_command=function(result) {
	if ( !result ) { // check for empty callback
		return;
	}
	var lines = result.split("\n"); // sequence of commands
	for (var i=0; i<lines.length; i=i+1) {
		var line = lines[i];
		if ( ! line ) {
			continue;
		}
		var res_array = line.split(',');
		var state = res_array[0];
		var step = res_array[1];
		var db_id = res_array[2];
		var next_step = res_array[3];
		var choice = res_array[4];
		var call_id = res_array[5]; // FIXME bad idea, better additional call to server
		//window.alert("RES: " + res_array[0] +' '+ res_array[1] +' '+ res_array[2]);
		// check for exist command
		var last_command = this.current_command();
		if ( last_command.db_id == db_id ) {
			return;
		}
		// add new command
		this.add_command(state, step, db_id, next_step, choice);
		// save call_id for this session
		if ( this.call_id === null && call_id ) {
			this.call_id = call_id;
		}
		// check for viewable command
		last_command = this.current_command();
		if ( last_command.viewable ) {
			this.current_viewable = last_command;
		}
		if ( state == 'last' ) { // check for last state and stop queries to server
			this.stop_commands();
		} 
	}
	this.interface_cb(); // redraw web-interface
};

// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// XML data loader
// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
XML_text=function(xml_url) {
	var xmlDoc; 
    if (window.XMLHttpRequest) { // Mozilla, Safari,...
		xmlDoc = new XMLHttpRequest();
		if (xmlDoc.overrideMimeType) {
	    	xmlDoc.overrideMimeType('text/xml');
		}
    } else if (window.ActiveXObject) { // IE
		try {
    		xmlDoc = new ActiveXObject("Msxml2.XMLHTTP");
		} catch (e) {
	    	try {
				xmlDoc = new ActiveXObject("Microsoft.XMLHTTP");
	    	} catch (e) {}
		}
    }
	xmlDoc.open("GET", xml_url, false); // load sync
	xmlDoc.send(null);
	this.xmlDoc = xmlDoc.responseXML;
	return true;
};

XML_text.prototype.getArrayByTag=function(tag) {
	return this.xmlDoc.getElementsByTagName(tag)[0];
};

XML_text.prototype.getTagInGroupById=function(tag, id, group) {
// method return tag with id in group 
	var actions = this.getArrayByTag(group);
	for (var i=0; i<actions.childNodes.length; i=i+1) {
		var node = actions.childNodes[i];
		var name = node.nodeName;
		if ( name !== tag ) {
			var goNext = true;
			// next check image -> img
			// for crazy Konqueror 3.5.x
			if ( tag == 'image' && name == 'img' ) {
				goNext = false;
			}
			if ( goNext ) {
				continue;
			}
		}
		var node_id = node.attributes.getNamedItem("id").value;
		if ( node_id == id ) {
			return node;
		}
	}
	return;
};

// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Useful functions
// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function getNodeByTag(nodes, tag) {
	for (var i=0; i<nodes.childNodes.length; i=i+1) {
		var tag_node = nodes.childNodes[i];
		if ( tag_node.nodeName == tag ) {
			return tag_node;
		}
		// next check image -> img
		// for crazy Konqueror 3.5.x
		if ( tag == 'image' && tag_node.nodeName == 'img' ) {
			return tag_node;
		}
	}
	return;
}

function getNodeByTagAndId(nodes, tag, id) {
	for (var i=0; i<nodes.childNodes.length; i=i+1) {
		var tag_node = nodes.childNodes[i];
		if ( tag_node.nodeName == tag ) {
			var attr_id = tag_node.attributes.getNamedItem("id").value;
			if ( attr_id == id ) {
				return tag_node;
			}
		}
		// next check image -> img
		// for crazy Konqueror 3.5.x
//		if ( tag == 'image' && tag_node.nodeName == 'img' ) {
//			return tag_node;
//		}
	}
	return;
}
