/*!\brief	Class that implements the API layer for BSAjax calls.
 * \note	inherits from BS.com.HTTP
 */
BS.com.BSApi = function ()
{
	BS.com.HTTP.call(this);
	this.hA.push(['Accept', 'text/serialize,*/*']);
}

BS.com.BSApi.prototype = {
	/*!\brief	Callback to unserialize data and execute CustomEvent.
	 * \param	s		synchronous (default false)
	 */
	_parseCB: function (s)
	{
		if (!this || !this.http || this.http.readyState != 4) return;

		if (!this.http.responseText) throw new 'Text missing error';

		var		t = new BS.com.BSApi.US;
		var		arr = t.unserialize(this.http.responseText);

		if (s === true) return arr;
		this._execCE(arr);
	},

	/*!\brief	parses xml response and adds error handling
	 * \param	data	xml response data
	 * \param	f	callback for handling error
	 *			(optional); if returns false, no error
	 *			message is thrown.
	 * \param	s	scope for callback (optional)
	 */
	responseParse: function (data, f, s)
	{
		if (isset(data['response']['success'])) {
			if (isset(data['return'])) return data['return'];
			else return;
		}
		else if (isset(data['response']['error'])) {
			var e = new Array();
			var d = data['response']['error'];

			if (f)
				if (!s && !f(d)) return;
				else if (s && !f.call(s, d)) return;

			for (var x=0; x<d.length; x++) e.push(d[x]['message']);

			throw e;
		}
		else throw new Array('invalid response<br>' +
				     _bsArr.toString(data));
	},

	/*!\brief	loop through err array and add to output string
	 * \param	d	div to show errors
	 * \param	e	array of error strings
	 * \param	w	width of message space (default null)
	 */
	showMsg: function (d, e, w)
	{
		var			msg, str = '';

		if (!w) w = '600';

		for (x=0; x < e.length; x++) str += e[x] + "<BR>";

		msg = '<div class="err-msg" style="width: ' + w + 'px;">';
		msg += '<span name="error">' + str + '</span></div>';

		d.innerHTML = msg;
	}
};

_bsObj.inherit(BS.com.HTTP, BS.com.BSApi);

BS.com.BSApi.US = function () { };

BS.com.BSApi.US.prototype = {
	unserialize: function (s)
	{
		this.__c = 0;
		this.__s = s;
		try { return this[this.__s.substr(this.__c, 1)](); }
		catch (e) {
			var str = "Sorry, an error occurred while processing your request. We'd appreciate if you could report the error shown below. Thanks!";
			str += '<ul>';
			str += '<li><b>LOCATION: </b>' + window.location.href + '</li>';
			str += '<li><b>ERROR: </b>' + e.name + ': ' + e.message + '</li>';
			str += '<li><b>DETAILS: </b><textarea rows="3" cols="36">' + s + '</textarea></li>';
			str += '</ul>';

			_bsAlert.show('Oops!', str);
			log(s);
		}
	},

	__uCommonAO: function (tmp)
	{
		var	a, k;
		++this.__c;
		a = this.__s.indexOf(":", ++this.__c);
		k = parseInt(this.__s.substr(this.__c, (a - this.__c))) + 1;
		this.__c = a + 2;
		while(--k)
			tmp[this[this.__s.substr(this.__c, 1)]()] =
				this[this.__s.substr(this.__c, 1)]();
		return tmp;
	},

	b: function ()
	{
		var	b = this.__s.substr((this.__c + 2), 1) === "1" ? true : false;
		this.__c += 4;
		return b;
	},

	i: function ()
	{
		var	sli = this.__s.indexOf(";", (this.__c + 1)) - 2,
			n = Number(this.__s.substr((this.__c + 2), (sli - this.__c)));
		this.__c = sli + 3;
		return n;
	},

	s: function ()
	{
		var 	sls, sli;
		this.__c += 2;
		sls = this.__s.substr(this.__c, (this.__s.indexOf(":", this.__c) - this.__c));
		sli = parseInt(sls);
		sls = this.__c + sls.length + 2;
		this.__c = sls + sli + 2;
		return this.__s.substr(sls, sli);
	},

	a: function ()
	{
		var	a = this.__uCommonAO([]);
		++this.__c;
		return a;
	},

	O: function ()
	{
		var 	tmp = ["s", this.__s.substr(++this.__c, (this.__s.indexOf(":", (this.__c + 3)) - this.__c))].join(""),
			a = tmp.indexOf("\""),
			l = tmp.length - 2,
			o = tmp.substr((a + 1), (l - a));
		if (eval(["typeof(", o, ") === 'undefined'"].join("")))
			eval(["function ", o, "(){};"].join(""));
		this.__c += l;
		eval(["tmp = this.__uCommonAO(new ", o, "());"].join(""));
		++this.__c;
		return tmp;
	},

	N: function ()
	{
		this.__c += 2;
		return '';
	}
};
BS.com.BSApi.US.prototype.d = BS.com.BSApi.US.prototype.i;

BS.utl.bsapi = _bsMm.oNew(BS.com.BSApi);

BS.com.BSApi.Idle = function (url)
{
	if (!(this.url = url)) throw 'AssertErr: missing url';

	this.mm = new BS.com.Delete();

	this.bsapi = this.mm.oNew(BS.com.BSApi);

	this.nullCE = this.mm.ceNew('null', this);

	this.persistCE = this.mm.ceNew('persist', this);
	this.persistCE.addCB(this._persistCB);
};

BS.com.BSApi.Idle.prototype = {
	DEFAULT_INTERVAL:	15*60*1000,
	lastCE:			null,

	_delete: function () { this.mm._delete(); },

	_persistCB: function (type, data, args) { this.ping(this.lastCE); },

	ping: function (ce)
	{
		if (!ce) ce = this.nullCE;
		this.bsapi.get(this.url, ce);
	},

	persist: function (interval, ce)
	{
		if (!interval) interval = this.DEFAULT_INTERVAL;

		this.lastCE = (ce) ? ce : null;

		this.persistCE.setInterval(interval);
	},

	persistEnd: function () { this.persistCE.clearInterval(); }
};

_bsBsapi = BS.utl.bsapi;

