// $Id: ReqLib.js,v 1.2 2009-11-20 11:59:16 jbesson Exp $

function ReqLib(name, props) {

	// check all the mandatory properties were given
	var i;
	var mandProps = [
		'reqType',
		'type',
		'refresh',
		'url',
		'respType'
	];
	for (i = 0; i < mandProps.length; i++) {
		if (typeof props[mandProps[i]] == 'undefined') {
			alert(name + " is broken for ReqLib: " + mandProps[i] + " is not defined");
			non_existant_function();
		}
	}

	// public vars in a container object
	var __pub = {
		items : [],
		urls  : {
			normal : getBaseURL('committed') + '?action=' + props.url,
			dirty  : getBaseURL('dirty')     + '?action=' + props.url,
			hist   : getBaseURL('hist')      + '?action=' + props.url
		}
	};

	// public vars that have defaults but can be overidden
	var overPubProps = [];
	for (i = 0; i < overPubProps.length; i++) {
		if (typeof props[overPubProps[i]] != 'undefined') {
			__pub[overPubProps[i]] = props[overPubProps[i]];
		}
	}

	// private vars
	var _par           = {};
	var _timer         = null;
	var _id            = null;
	var _renderOk      = true;
	var _respOk        = true;
	var _renderTimer   = null;
	var _centreChanged = false;
	var _count         = 0;

	// private vars from the supplied props
	var _reqType  = props.reqType;
	var _type     = props.type;
	var _refresh  = props.refresh;
	var _respType = props.respType;

	// private vars that have defaults but can be overidden
	var _ajaxMethod = 'GET';
	if (typeof props.ajaxMethod != 'undefined') {
		_ajaxMethod = props.ajaxMethod;
	}
	var _renderDelay = 300;
	if (typeof props.renderDelay != 'undefined') {
		_renderDelay = props.renderDelay;
	}
	var _refreshIcon = false;
	if (typeof props.refreshIcon != 'undefined') {
		_refreshIcon = props.refreshIcon;
	}

	// array of central object types, should we want to loop over them all
	if (_reqType == 'central') {
		centralReqObjs.push(name);
	}

//!!!!! this doesn't work! ??????
try {
	if (document.jsOverrides) {
		var os = document.jsOverrides[name];
		if (os) {
			for (i = 0; i < os.length; i++) {
				eval(os[i]);
			}
		}
	}
} catch(e) {}

function regPar(o) {

	_par = o;

	// store mapping between name and object
	reqObjs[_par.pub.name] = _par;
}

function canPoll(skip_par) {

	if (!skip_par && typeof _par.canPoll == 'function') {
		return _par.canPoll();
	}

	if (State.loading || (_reqType == 'central' && State.centre != _par)) {
		return false;
	}
	return true;
}

function canReq(skip_par) {

	if (!skip_par && typeof _par.canReq == 'function') {
		return _par.canReq();
	}

	if (State.loading) {
		return false;
	}
	return true;
}

function canResp(skip_par) {
	if (!skip_par && typeof _par.canResp == 'function') {
		return _par.canResp();
	}

	if (State.loading || (_reqType == 'central' && State.centre != _par)) {
		return false;
	}
	return true;
}

function getCount() {

	return _count;
}

function incrCount() {

	_count++;
}

function getId() {

	return _id;
}

function setId(id) {

	_id = id;
}

function setRenderDelay(delay) {

	_renderDelay = delay;
}

function poll() {

	if (_timer != null) {
		clearTimeout(_timer);
		_timer = null;
	}
	if (_refresh) {
		_timer = setTimeout(poll, _refresh);
	}

	if (!canPoll()) {
		return;
	}

	_count++;

	var newId = _par.makeId();
	var oldId = _id;

	_id = newId;

	if (_refreshIcon) {
		refreshIcon(true);
	}

	if (_centreChanged || oldId != newId) {
		_par.hint('new');
	} else {
		_par.hint('update');
	}
	_centreChanged = false;

	var ajax, url;
	if (_ajaxMethod == 'POST') {
		url = _par.makeURL();
	} else {
		url = _par.makeURL() + '&c=' + _count;
	}
	DEBUG(_par.pub.name + ' poll: ' + url, '#eecc66');

	if (window.XMLHttpRequest) {
		ajax = new XMLHttpRequest();
	} else if (window.ActiveXObject) {
		try {
			ajax = new ActiveXObject("Msxml2.XMLHTTP");
		} catch(e) {
			ajax = new ActiveXObject("Microsoft.XMLHTTP");
		}
	}

	ajax.open(_ajaxMethod, url, true);
	ajax.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;');

	ajax.onreadystatechange = function() {
		if (ajax.readyState == 4 && ajax.status == 200) {
			_resp(ajax);
		}
	}

	if (_ajaxMethod == 'POST') {
		var postParams = _par.makePOST() + '&c=' + _count;
		ajax.setRequestHeader('Content-length', postParams.length);
		ajax.setRequestHeader('Connection', 'close');
		ajax.send(postParams);
	} else {
		ajax.send(null);
	}
}

function req() {

	if (_renderDelay && (!State.pageMem.recovering)) {
		_renderOk = false;
		_respOk   = false;
		if (_renderTimer != null) {
			clearTimeout(_renderTimer);
		}
		_renderTimer = setTimeout(_setRenderOk, _renderDelay);
	} else {
		_renderOk = true;
		_respOk   = true;
	}

	if (_reqType == 'central') {
		if (State.centre != _par) {
			_centreChanged = true;
		} else {
			_centreChanged = false;
		}

		setCentre(_par);
	}

	poll();

	if (State.isLobbyPage) {
		pageMemStore();
	}
}


function _resp(req) {

	// For consistency, we parse the login cookie even
	// if we're going to ignore this response
	State.parseLogin();
	if (!canResp()) {
		return;
	}

	DEBUG(_par.pub.name + ' resp', '#4444bb');

	var resp = req.responseText;

	// check response id and extract data
	var data = '';
	var expectedId = _count;
	var pipeIdx, respId;

	pipeIdx = resp.indexOf('|');
	if (pipeIdx > -1) {
		respId = resp.substring(0, pipeIdx);
		if (respId == expectedId) {
			data = resp.substring(pipeIdx + 1);
		}
	}
	if (data.length == 0) {
		return;
	}

	if (_respType == 'arr') {

		__pub.items = eval("new Array(" + data + ")");

	} else if (_respType == 'list') {

		var items = eval("new Array(" + data + ")");

		_par.List.suckListData(items, 0);

	} else if (_respType == 'multiLists') {
		var items = eval("new Array(" + data + ")");

		_par.suckListData(items);
	}

	_respOk = true;

	if (_renderOk) {
		_render();
	}
}

function synchronousResp(resp) {

	DEBUG(_par.pub.name + ' synchronousResp', '#4444bb');

	if (_timer != null) {
		clearTimeout(_timer);
		_timer = null;
	}
	if (_refresh) {
		_timer = setTimeout(poll, _refresh);
	}

	_id = _par.makeId();

	if (_respType == 'arr') {

		__pub.items = resp;

	} else if (_respType == 'list') {

		_par.List.suckListData(resp, 0);

	} else if (_respType == 'multiLists') {

		_par.suckListData(resp);
	}

	_render();
}

function _setRenderOk() {

	_renderOk = true;

	if (_respOk) {
		_render();
	}
}

function _render() {

	if (_refreshIcon) {
		refreshIcon(false);
	}

	_par.render();
}

	var _this = {
		pub : __pub,
		regPar : regPar,
		getCount : getCount,
		incrCount : incrCount,
		getId : getId,
		setId : setId,
		canPoll : canPoll,
		canReq : canReq,
		canResp : canResp,
		req : req,
		synchronousResp : synchronousResp,
		poll : poll,
		setRenderDelay : setRenderDelay
	};

	return _this;
}
