
//======================================================// Request //=

namespace ('Request');


//---------------------------------------------------/ Request.Base /-

Request.Base = function () {
	this.session = null;
};

// xmlData should get overwritten in all derived requests. Provided xml should fail in Pluriform in all situations.
Request.Base.prototype.xmlData = '<error  msg="uninitialised xmlData" />';

Request.Base.prototype.init = function (session) {
	this.session = session;
	// can't be put in the constructor as the notifiers end up being re-used by the subclasses
	// should be called first in the constructor of derived classes
	this.notifiers = {
		onProcessing: new EventHook (),
		onGridData: new EventHook ()
	}
};

Request.Base.prototype.validate = function () {
	return true;
};

Request.Base.prototype.notifyGridData = function (data) {
	this.notifiers.onGridData.notify (data);
};

Request.Base.prototype.notifyProcessing = function () {
	if (this.notifiers.onProcessing) {
		this.notifiers.onProcessing.notify ();
		this.notifiers.onProcessing = null;
	}
};

Request.Base.prototype.postponedXmlData = function () {
	var dialog = this.session.getActiveDialog ();
	return dialog.xmlData (this.notifiers);
};

Request.Base.prototype.send = function () {
	this.session.queue.send (this);
};

Request.Base.prototype.sendNow = function () {
	this.session.queue.sendNow (this);
};

Request.Base.prototype.repeat = function () {
	this.session.queue.repeat (this);
};

Request.Base.prototype.xmlPost = function () {
	return XML.element ('session', {'id': this.session.id}, (this.xmlData ? this.xmlData : ''), false);
};

Request.Base.prototype.dispatch = function () {
	XMLHttpPostRequest (Framework.resolveUrl (), this.xmlPost (), callback (this, this.onResponse), callback (this, this.onError));
};

Request.Base.prototype.onResponse = function (responses) {
	Framework.processResponses (this, responses);
};

Request.Base.prototype.onError = function (status, statustext, response) {
	Framework.fatalError ('xmlhttprequest failed', 'status: ' + status + (statustext ? '(' + statustext + ')' : ''), response);
};


//------------------------------------------/ Request.FrameworkBase /-

Request.FrameworkBase = function () {
};

Request.FrameworkBase.prototype = new Request.Base ();

Request.FrameworkBase.prototype.send = function () {
	Framework.queue.send (this);
};

Request.FrameworkBase.prototype.xmlPost = function () {
	return XML.element ('framework', {}, (this.xmlData ? this.xmlData : ''), false);
};


//-----------------------------------------------/ Request.Callback /-
// Request.Callback is a special kind of request which does not
// communicate with the server, but instead calls a callback function.
// It can be used to facilitate actions that need to respect the
// queue-order of requests, but don't need communication with the server.

Request.Callback = function (session, handler) {
	this.init (session);
	this.handler = handler;
};

Request.Callback.prototype = new Request.Base ();

Request.Callback.prototype.dispatch = function () {
	this.handler ();
	Framework.processResponses (this, '[]');
};


//------------------------------------------------/ Request.Session /-


Request.Session = function (framework, profile, language) {
	this.init ();
	var query = window.location.search.substring (1);
	this.xmlData = XML.element ('session', {'framework': framework, 'profile': profile, 'language': language, 'querystring': query}, null, true);
};

Request.Session.prototype = new Request.FrameworkBase ();
Request.Session.prototype.status = 'Creating new session...';


//------------------------------------------------/ Request.Context /-


Request.Context = function (ctxid) {
	this.init ();
	this.xmlData = XML.element ('context', {'id': ctxid}, null, true);
};

Request.Context.prototype = new Request.FrameworkBase ();
Request.Context.prototype.status = 'Requesting context session...';


//---------------------------------------------/ Request.ClientInfo /-

Request.ClientInfo = function (info) {
	this.init ();
	this.xmlData = XML.element ('clientinfo', info, null, true);
};

Request.ClientInfo.prototype = new Request.FrameworkBase ();
Request.ClientInfo.prototype.status = 'Sending browser info...';


//--------------------------------------------/ Request.InitSession /-

Request.InitSession = function (session, entrypoint) {
	this.init (session);
	var params = {
		'entrypoint': entrypoint,
		'querystring': window.location.search.substring (1)
	};
	this.xmlData = XML.element ('initsession', params, null, true);
};

Request.InitSession.prototype = new Request.Base ();
Request.InitSession.prototype.status = 'Initialising web framework session...';


//------------------------------------------------/ Request.Connect /-

Request.Connect = function (session) {
	this.init (session);
	this.xmlData = XML.element ('connect', null, null, true);
};

Request.Connect.prototype = new Request.Base ();
Request.Connect.prototype.status = 'Connecting to web framework session...';


//---------------------------------------------------/ Request.Meta /-

Request.Meta = function (session) {
	this.init (session);
};

Request.Meta.prototype = new Request.Base ();
Request.Meta.prototype.status = 'Requesting dialog meta...';
Request.Meta.prototype.xmlData = '<meta />';


//-------------------------------------------------/ Request.Dialog /-

Request.Dialog = function (session, dialog, control) {
	this.init (session);
	this.control = control;
	this.xmlData = dialog.xmlData (this.notifiers);
};

Request.Dialog.prototype = new Request.Base ();
Request.Dialog.prototype.status = 'Sending dialog update...';


//-----------------------------------------------/ Request.Navigate /-

Request.Navigate = function (session, object, params) {
	this.init (session);
	var parmxml = '';
	for (var idx in params) {
		parmxml += XML.element ('param', {'name': idx, 'value': params[idx]});
	}
	this.xmlData = this.postponedXmlData () + XML.element ('navigate', {'object': object}, parmxml, false);
};

Request.Navigate.prototype = new Request.Base ();
Request.Navigate.prototype.status = 'Navigating to object/navigation...';

Request.Navigate.prototype.validate = function () {
	return !this.session.isModal ();
};


//------------------------------------------------/ Request.History /-

Request.History = function (session, transaction) {
	this.init (session);
	this.xmlData = this.postponedXmlData () + XML.element ('history', {'transaction': transaction}, null, true);
};

Request.History.prototype = new Request.Base ();
Request.History.prototype.status = 'Navigating to history...';

Request.History.prototype.validate = function () {
	return !this.session.isModal ();
};


//-------------------------------------------------/ Request.Logoff /-

Request.LogOff = function (session, all) {
	this.init (session);
	this.xmlData = this.postponedXmlData () + XML.element ('logoff', {'all': all}, null, true);
};

Request.LogOff.prototype = new Request.Base ();
Request.LogOff.prototype.status = 'Logging off...';


//-----------------------------------------------/ Request.Settings /-

Request.Settings = function (session) {
	this.init (session);
	this.xmlData = this.postponedXmlData () + XML.element ('settings', null, null, true);
};

Request.Settings.prototype = new Request.Base ();
Request.Settings.prototype.status = 'Navigating to settings...';


//--------------------------------------------------/ Request.LogOn /-

Request.LogOn = function (session, username, password) {
	this.init (session);
	this.xmlData = XML.element ('logon', {'username': username, 'password': password}, null, true);
};

Request.LogOn.prototype = new Request.Base ();
Request.LogOn.prototype.status = 'Logging on...';


//-----------------------------------------------/ Request.FrameAct /-

Request.FrameAct = function (session, name, msg) {
	this.init (session);
	this.xmlData = XML.element ('frameact', {'name': name}, msg, false);
};

Request.FrameAct.prototype = new Request.Base ();
Request.FrameAct.prototype.status = 'Relaying message...';

Request.FrameAct.prototype.send = function () {
	Framework.queue.send (this);
};

//--------------------------------------------------/ Request.PFUrl /-

Request.PFUrl = function (session, ctx, url) {
	this.init (session);
	this.xmlData = XML.element ('pfurl', {'context': ctx, 'url': url}, null, true);
};

Request.PFUrl.prototype = new Request.Base ();
Request.PFUrl.prototype.status = 'Opening Pluriform link...';

