/* --------------------------------------------------------------------
 * Shine: The Become Interactive Client Application Framework
 * @(#) $Id$
 * --------------------------------------------------------------------
 * Copyright (c) 2006 Become Interactive
 * http://www.becomeinteractive.co.uk
 * All rights reserved.
 * --------------------------------------------------------------------
 * This software is the confidential and proprietary information of
 * Become Interactive ("Confidential Information").
 *
 * You shall not disclose such Confidential Information and shall use
 * it only in accordance with the terms of the license agreement you
 * with the terms of the license agreement you entered into with
 * Become Interactive.
 * --------------------------------------------------------------------
 */

/**
 * com.uk.become.shine.Request
 *
 * Scripted HTTP requests on demand
 */
com.uk.become.shine.Request = function(method, uri)
{
	var r;
	var progids = [
				   'MSXML2.XMLHTTP.5.0',
				   'MSXML2.XMLHTTP.4.0',
				   'MSXML2.XMLHTTP.3.0',
				   'MSXML2.XMLHTTP',
				   'Microsoft.XMLHTTP'
				   ];
	
	this._method = method;
	this._uri = uri;
	this._req = false;
	this._loaded = false;
	this._rsInterval = null;
	this.onload = false;
	this.onerror = false;
	this.method = false;
	this.throbber = null;
	this.form = null;
	this.params = new Array();
	this.formVars = new Object();
	this._headers = new Object();
	try
		{
			r = new XMLHttpRequest();
			this._req = r;
		}
	catch(e)
		{
			for(i = 0; i < progids.length; i++)
				{
					try
						{
							r = new ActiveXObject(progids[i]);
							this._req = r;
							break;
						}
					catch(e)
						{
						}
				}
		}
	finally
		{
			return this;
		}
}
com.uk.become.shine.Request.prototype.header = function(n, v)
{
	this._headers[n] = v;
}
com.uk.become.shine.Request.prototype._throbOn = function()
{
	if(!this.throbber) return;
	if(typeof this.throbber.shineThrobDepth == 'undefined')
	{
		this.throbber.shineThrobDepth = 0;
	}
	this.throbber.shineThrobDepth++;
	if(typeof this.throbber.throbOn != 'undefined')
	{
		this.throbber.throbOn();
	}
	else
	{
		this.throbber.style.display = 'block';
	}
}
com.uk.become.shine.Request.prototype._throbOff = function()
{
	if(!this.throbber || typeof this.throbber.shineThrobDepth == 'undefined') return;
	if(this.throbber.shineThrobDepth)
	{
		this.throbber.shineThrobDepth--;
	}
	if(!this.throbber.shineThrobDepth)
	{
		if(typeof this.throbber.throbOff != 'undefined')
		{
			this.throbber.throbOff();
		}
		else
		{
			this.throbber.style.display = 'none';
		}
	}
}
com.uk.become.shine.Request.prototype._readyStateChangeHandler = function(Shine, sender, ev, data)
{
	if(sender.readyState == 4)
		{	
			window.clearInterval(this._rsInterval);
			if(this._loaded)
				{
					return false;
				}
			this._loaded = true;
			this._throbOff();
			ev = new Object();
			ev.status = sender.status;
			ev.statusText = sender.statusText;
			
			if(sender.status == 200)
				{
					if(this.onload)
						{
							ev.responseXML = sender.responseXML;
							ev.responseText = sender.responseText;
							if(typeof ev.responseXML != 'undefined' && ev.responseXML != null && typeof ev.responseXML.lastChild != 'undefined' && ev.responseXML.lastChild != null && typeof ev.responseXML.lastChild.tagName != 'undefined')
							{
								ev.responseRoot = ev.responseXML.lastChild;
							}
							else
							{
								ev.responseRoot = null;
							}
							this.onload(ev);
						}
					else
						{
							Shine.debug('Request::_readyStateChangeHandler:', 'Success: status = ' + sender.status + ' (' + sender.statusText + ')');
						}
				}
			else
				{
					if(this.onerror)
						{
							this.onerror(ev);
						}
					else
						{
							Shine.debug('Request::_readyStateChangeHandler:', 'Failed: status = ' + sender.status + ' (' + sender.statusText + ')');
						}
				}
		}
}
com.uk.become.shine.Request.prototype.open = function()
{
	var h, payload, hfv, _this = this, uri, d;
	
	if(!this._req)
		{
			Shine.debug('Request:', 'Request object has no XMLHttpRequest (' + this._method + ' ' + this._uri + ')');				
			return false;
		}
	hfv = false;
	payload = '';
	if(this.method)
		{
			this._method = 'POST';
			this.header('Content-Type', 'application/vnd.become.rpc+xml');
			payload = '<?xml version="1.0" encoding="UTF-8" ?>' + "\n";
			payload += '<methodCall>' + "\n";
			payload += ' <methodName>' + this.method + '</methodName>' + "\n";
			payload += '  <params>' + "\n";
			for(h = 0; h < this.params.length; h++)
				{
					payload += '   <param><value>';
					if(typeof this.params[h] == 'number')
						{
							payload += '<i4>' + this.params[h] + '</i4>';
						}
					else if(typeof this.params[h] == 'boolean')
						{
							payload += '<boolean>' + (this.params[h] ? '1' : '0') + '</boolean>';
						}
					else
						{
							payload += '<string>' + this.params[h] + '</string>';
						}
					payload += '</value></param>' + "\n";
				}
			payload += '  </params>' + "\n";
			payload += '</methodCall>' + "\n";
		}
	else
		{
			for(h in this.formVars)
				{
					hfv = true;					
					payload += encodeURIComponent(h) + '=' + encodeURIComponent(this.formVars[h]) + '&';
				}
			if(this.form)
			{
				hfv = true;
//				Shine.debug('Request:', 'Processing form with ' + this.form.elements.length + ' elements');
				for(i = 0; i < this.form.elements.length; i++)
				{
//					Shine.debug('Request:', 'Processing form element ' + i + ': ' + this.form.elements[i]);
					if(typeof this.form.elements[i].name == 'undefined' ||
						typeof this.form.elements[i].value == 'undefined' ||
						this.form.elements[i].name.length == 0)
					{
						continue;
					}
					if(this.form.elements[i].type == 'radio' || this.form.elements[i].type == 'checkbox')
					{
						if(!this.form.elements[i].checked) continue;
					}
					payload += encodeURIComponent(this.form.elements[i].name) + '=' + encodeURIComponent(this.form.elements[i].value) + '&';
				}
			}
			if(hfv)
				{
					payload = payload.substr(0, payload.length - 1);
					this.header('Content-Type', 'application/x-www-form-urlencoded');
				}
		}
	d = new Date();
	uri = this._uri;
	if(uri.indexOf('?') != -1)
	{
		uri += '&__ts=' + encodeURIComponent(d.getTime());
	}
	else
	{
		uri += '?__ts=' + encodeURIComponent(d.getTime());
	}
//	Shine.debug('Request:', this._method + ' ' + uri);
//	Shine.debug('Request:', payload);
	_this = this;
//	uri = 'http://tiso.maint.melo.g5.become.uk.com/test.php';
	_this._req.open(this._method, uri, true);
//	_this._req.onreadystatechange = function() { _this._readyStateChangeHandler(Shine, _this._req, false, false); }
	/* Work around WebKit bug */
	_this._req.setRequestHeader('If-Modified-Since', 'Wed, 15 Nov 1995 00:00:00 GMT');
	for(h in _this._headers)
		{
			_this._req.setRequestHeader(h, _this._headers[h]);
		}
	_this._throbOn();
	if(payload)
		{
			_this._req.send(payload);
		}
	else
		{
			_this._req.send(null);
		}
	this._rsInterval = window.setInterval(function() { _this._readyStateChangeHandler(Shine, _this._req, false, false); }, 50);
}

