// Copyright (c) 2003-2005 Juerg Lehni, Lineto.com. All rights reserved.
// Copying and reuse is strictly prohibited.

var loaders = {};
for (var i = 0; i < 6; i++) {
	loaders['loader' + i] = {frame: parent['loader' + i], object: null, history: {} }
}

var loadId = 0;
function startLoading(object) {
	var loader = null;
	for (var i in loaders) {
		var l = loaders[i];
		if (l.object == object) {
			l.object = "canceled";
		} else if (!l.object) {
			loader = l;
			break;
		}
	}
	if (loader) {
		loader.object = object;
		object.loader= loader;
		loader.loadId = loadId++;
		return loader;
	} else {
		// smth's wrong, reinit:
		for (var i in loaders) {
			if (l[i].object) l[i].object.loader = null;
			l[i].object = null;
		}
		return startLoading(object);
	}
}

function stopLoading(l) {
	if (l) {
		l = loaders[typeof l == "string" ? l : l.name];
		if (l && l.object) {
			l.object.loader = null;
			l.object = null;
			l.loadId = null;
		}
	}
}

function load(object, url, params) {
	// if url is null, object is assumed to be a form to post
	var l = startLoading(object);
	if (object.onBeginLoad) object.onBeginLoad();
	l.history[l.loadId] = [object, url];
	if (!params) params = {};
	params.loadId = l.loadId;
	addQueryParams(params);
	if (url == null) { // form
		object.target = l.frame.name;
		for (var i in params)
			object[i].value = params[i];
		object.submit();
	} else {
		url += (url.indexOf('?') == -1 ? '?' : '&');
		for (var i in params) url += '&' + i + '=' + params[i];
		l.frame.location = url;
	}
}

function getLoader(loader, loadId) {
	var l = loaders[loader.name];
	if (l) {
		if (!l.loadId && loadId) {
			var h = l.history[loadId];
			l.object = h[0];
			l.url = h[1];
			if (!l.url) return null;
		} else l.url = null;
		if (l.object == "canceled") l.object = null;
	}
	return l && l.object ? l : null;
}

var jsFiles = {};
function loadJs(file, notify, param) {
	var f = jsFiles[file];
	if (!f) {
		f = {file: file, loading: true, notify: []};
		if (!param) param = f;
		if (notify) f.notify[0]={name: notify, param: param};
		var l = startLoading(f);
		if (l) {
			l.frame.location = urlPrefix + '/loadJs?file=' + file;
			jsFiles[file] = f;
			return f;
		} else alert('Cannot load "' + url + '": All loaders are occupied!');
	} else if (notify) {
		if (f.loading) push(f.notify, notify);
		else this[notify](param);
	}
}

function hasJs(file) {
	return jsFiles[file] != null && !jsFiles[file].loading;
}

function setJs(loader, js) {
	var l = getLoader(loader);
	if (l) {
		var f = l.object;
		f.js = js;
		f.loading = false;
//		try {
			eval(f.js);
			var ns = f.notify;
			for (var i in ns) { if (this[ns[i].name]) this[ns[i].name](ns[i].param); }
//		} catch (e) {
//			alert(f.file + ': ' + e);
//			delete jsFiles[f.file];
//		}
		f.js=null;
	}
}

var sendData = null;
function sendBack(action, data) {
	if (!sendData) sendData = [];
	push(sendData, action);
	push(sendData, data);
}

// HttpRequest

function HttpRequest() {
	this.obj = document.cbe.createChild(false);
	if (arguments.length > 0)
		this.init(arguments[0], arguments[1], arguments[2], arguments[3]);
}

HttpRequest.prototype.init = function(action, method, target, enctype) {
	// if target is not set, use a loader internally:
	if (!target) {
		this.loader = startLoading(this);
		target = this.loader.frame.name;
	} else this.loader = null;
	this.name = 'f' + getNow();
	var s = '<form name="' + this.name + '"';
	if (action) s += ' action="' + action + '"';
	if (method) s += ' method="' + method + '"';
	if (target) s += ' target="' + target + '"';
	if (enctype) s += ' enctype="' + enctype + '"';
	this.html = s + '">';
}

HttpRequest.prototype.add = function(name, value) {
	this.html += '<input type="hidden" name="' + name + '" value="' + value + '">';
}

HttpRequest.prototype.send = function() {
	if (this.loader) {
		// add default params
		var ps = { loadId: this.loader.loadId };
		addQueryParams(ps);
		for (var i in ps) this.add(i, ps[i]);
	}
	this.html += '</form>';
	this.obj.innerHtml(this.html);
	var form = cbeGetFormByName(this.name);
	if (form) {
		form.submit();
		return true;
	}
	return false;
}
