
// -- http_request

function http_request(parent, data, structure_root, keep) {
	this.inheritFrom = collection_list_item;
	this.inheritFrom();

	this.inheritFrom = structure_class;
	this.inheritFrom();
	
	this.parent = parent; // parent collector
	this.data = data; // user data
	this.keep = keep; // udrzet xml strukturu po smrti?

	this.request = null;

	this.evt_oncreate = null;
	this.evt_ondone = null;
	
	this.time_start = null;
	this.time_end = null;

	this.construct(structure_root);
}

clone_add(http_request.prototype, structure_class.prototype); // inherit

http_request.prototype.construct = function(structure_root) {
	var self = this;
	if (window.ActiveXObject) {
		this.request = new ActiveXObject("Microsoft.XMLHTTP");
	} else {
		this.request = new XMLHttpRequest();
	}
	
	this.request.onreadystatechange = function() {
		self.state_changed();
	}
	
	if (structure_root == null) {
		this.flush();
	} else {
		this.root = structure_root;
	}
}

http_request.prototype.destroy = function() {
	if (!this.keep) this.flush();
	//this.request.onreadystatechange = null;
	context.object_destroy(this);
}

http_request.prototype.state_changed = function() {
	switch (this.request.readyState) {
		case 4 : // complete
			if (this.evt_ondone != null)
				this.evt_ondone(this.data, this);
			
			this.parent.dequeue(this);
			break;
	}
}

http_request.prototype.make = function() {
	if (this.parent != null) {
		if (this.evt_oncreate != null)
			this.evt_oncreate(this.data, this);
		
		this.request.open("POST", this.parent.interface_ref, true);
		this.request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
		//this.request.send('input=' + encodeURIComponent(this.compose('request_data')));
		this.request.send(this.compose('request_data'));
		if (this.request.overrideMimeType != null) this.request.overrideMimeType('text/xml');
		
	} else {
		context.error("Unable to process request, no parent collector specified!");
	}
}

http_request.prototype.get_response = function() {
	xml = this.request.responseXML;
	
	if (xml != null) {
		if (xml.normalize != null) xml.normalize();
		
		var head = xml.getElementsByTagName("head")[0];
		var body = xml.getElementsByTagName("body")[0];
		var f;

		if (head != null && body != null) {
			// error flags
			var error_flags = head.getElementsByTagName("error_flag");
			if (context.catch_error_flags(error_flags)) {
				// nic
			
			} else {
				// je chyba?
				var errors = head.getElementsByTagName("error");
				if (errors.length == 0) {
					
					return new Array(head, body);
					
				} else {
					var error_str = "";
					
					for (f = 0; f < errors.length; f++) {
						if (f != 0) error_str += "\r\n";
						error_str += context.element_value(errors[f]);
					}
					
					context.error(error_str);
				}
			}
		} else {
			context.error("Document does not contain base elements! output: " + this.request.responseText);
		}
	} else {
		context.error("Invalid response document! output: " + this.request.responseText);
	}
	
	return null;
}

http_request.prototype.debug_data = function(show_res) {
	var put, head, major = null;
	
	if ((head = this.root.get_child("head")) != null)
		major = head.get_child("major");
	
	var compose = this.compose("request_data");
    compose = compose.split("<").join("&lt;");
    compose = compose.split(">").join("&gt;");
	
	put  = "<tr>";
	put += "<td>" + (major == null ? "unknown" : major.value) + "</td>";
	put += "<td>" + compose + "</td>";
	put += "<td>" + (this.time_end != null && this.time_start != null ? ("time: " + (this.time_end - this.time_start)) : "running") + "</td>";
	
	var resp;
	if (!show_res) resp = "running";
	else {
		var resp = this.request.responseText;
	    resp = resp.split("<").join("&lt;");
	    resp = resp.split(">").join("&gt;");
	}
	
	put += "<td>" + resp + "</td>";
	put += "</tr>";
	
	return put;
}

// -- http_request_collector

function http_request_collector(interface_ref) {
	this.inheritFrom = collection_list;
	this.inheritFrom();

	this.interface_ref = interface_ref;
	this.first = null;
	this.end = null;
	
	this.debug = false;
	this.debug_container = null;
	this.debug_history = null;
	this.debug_history_inner = null;
	
	this.construct();
}

clone_add(http_request_collector.prototype, collection_list.prototype); // inherit

http_request_collector.prototype.construct = function() {
	if (this.debug) {
		this.debug_container = context.createElement("DIV");
		this.debug_container.style.padding = "20px";
		
		this.debug_history = context.createElement("DIV");
		this.debug_history.style.padding = "20px";
		
		this.debug_history.innerHTML = "<strong>request collector history</strong><br/><br/>";
		
		this.debug_history_inner = context.createElement("TABLE");
		this.debug_history_inner.border = 1;
		
		this.debug_history.appendChild(this.debug_history_inner);
		context.document_ref.body.appendChild(this.debug_container);
		context.document_ref.body.appendChild(this.debug_history);
	}
}

http_request_collector.prototype.debug_update = function(req, add_flag) {
	if (this.debug) {
		
		if (add_flag) req.time_start = (new Date()).getTime();
		else req.time_end = (new Date()).getTime();
		
		var put;
		
		put  = "<strong>request collector debug</strong><br/><br/>";
		put += "active requests: " + this.count + "<br/><br/>";
		
		if (this.first != null) {
			put += "<table border='1'>";
		
			var loop = this.first;
			while (loop != null) {
				put += loop.debug_data(false);
			
				loop = loop.next;
			}
			
			put += "</table>";
		}
		
		this.debug_container.innerHTML = put;
		
		if (!add_flag) this.debug_history_inner.innerHTML += req.debug_data(true);
	}
}

http_request_collector.prototype.enqueue = function(data, evt_oncreate, evt_ondone, structure_root, keep) {
	var req = new http_request(this, data, structure_root, keep);
	
	req.evt_oncreate = evt_oncreate;
	req.evt_ondone = evt_ondone;
	
	this.enqueue_ref(req);
}

http_request_collector.prototype.enqueue_ref = function(req) {
	if (this.collection_add(req) != null) {
		this.debug_update(req, true);
		req.make();
	}
}

http_request_collector.prototype.dequeue = function(req) {
	if ((req = this.collection_rem(req)) != null) {
		this.debug_update(req, false);
		req.destroy();
		req = null;
		
	} else {
		context.error("Unable to dequeue, nothing in request collector!");
	}
}
