/*
 * Try - all arguments must be functions
 */
var _txId=0;

var Try = {
  these: function() {
    var returnValue;
    for (var i = 0; i < arguments.length; i++) {
      var lambda = arguments[i];
      try {
        returnValue = lambda();
        break;
      } catch (e) {}
    }
    return returnValue;
  }
};

Object.extend = function(destination, source) {
  for (property in source) {
    destination[property] = source[property];
  }
  return destination;
};


var Query =
{
  getTransport: function() 
  {
    return Try.these(
      function() {return new ActiveXObject('Msxml2.XMLHTTP')},
      function() {return new ActiveXObject('Microsoft.XMLHTTP')},
      function() {return new XMLHttpRequest()}
    ) || false;
  },

/*
	fnCallback is called when ready state is complete
*/

  request: function(path,fnCallback,params,lparam)
  {
  	var _transID = 'ajax'+_txId++;
  	
  	Query.transport[_transID] = Query.getTransport();
	if(!Query.transport[_transID]) return null;

	Query.states[_transID]=null;
	Query.params[_transID]=params;
	Query.reqdata[_transID]={p:path,f:fnCallback,r:params,l:lparam};

	Query.transport[_transID].onreadystatechange = function()
	{
		Query.states[_transID] = Query.transport[_transID].readyState;
		
		if( Query.transport[_transID].readyState==Query.RS_COMPLETE )
		{
			if( Query.transport[_transID].status == 200 )
			{
				fnCallback(Query.transport[_transID].responseXML,lparam,Query.params[_transID]);

				Query.transport[_transID] = null;
				Query.params[_transID] = null;
				Query.states[_transID] = null;
				Query.reqdata[_transID] = null;
			}
			else if( Query.transport[_transID].status >= 12000 )
			{
				switch(Query.transport[_transID].status){
				// The following case labels are wininet.dll error codes that may be encountered.
				// Server timeout
				case 12002:
				// 12029 to 12031 correspond to dropped connections.
				case 12029:
				case 12030:
				case 12031:
				// Connection closed by server.
				case 12152:
				// See above comments for variable status.
				case 13030:
					// let's retry
					Query.request( Query.reqdata[_transID].p, Query.reqdata[_transID].f, Query.reqdata[_transID].r, Query.reqdata[_transID].l );
					Query.transport[_transID] = null;
					Query.params[_transID] = null;
					Query.states[_transID] = null;
					Query.reqdata[_transID] = null;
				}
			}
			else if( Query.transport[_transID].status >= 400 )
			{
				Messages.mbOk("Request failed: "+Query.transport[_transID].status,'error');

				Query.transport[_transID] = null;
				Query.params[_transID] = null;
				Query.states[_transID] = null;
				Query.reqdata[_transID] = null;
			}
		}
	};

	var query = '';
	var c=0;
	for( var k in params )
	{
		if( c++>0 ) query += '&';
		query += k+'=';

		if( is_array(params[k]) )
		{
			for( var l=0; l<params[k].length; l++ )
			{
				if( l++>0 ) query += ',';
				query += escape(params[k][l]);
			}
		}
		else
		{
			query += escape(params[k]);
		}
	}

	Query.transport[_transID].open('POST', C4P.vdir+'/'+path, true );
	Query.transport[_transID].setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
	Query.transport[_transID].send(query);

//	if( params['action']=='saveObject' ) {
//		Debug.add(query);
//	}
	
	return true;
  },

  /* send data - don't care about checking response */

  sendData: function(path,params)
  {
  	var _transID = 'ajax'+_txId++;
  	Query.transport[_transID] = Query.getTransport();
	if(!Query.transport[_transID]) return null;
	Query.transport[_transID].onreadystatechange = function()
	{
		if( Query.transport[_transID].readyState==Query.RS_COMPLETE )
		{
			if( Query.transport[_transID].status == 200 )
			{
				Query.transport[_transID] = null;
			}
			else if( Query.transport[_transID].status >= 400 )
			{
				Messages.mbOk("SendData failed: "+Query.transport[_transID].status,'error' );
				Query.transport[_transID] = null;
			}
		}
	};
	var query = '';
	var c=0;
	for( var k in params )
	{
		if( c++>0 ) query += '&';
		query += k+'='+escape(params[k]);
	}

	Query.transport[_transID].open('POST', C4P.vdir+'/'+path, true );
	Query.transport[_transID].setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
	Query.transport[_transID].send(query);
	return true;
  },
  transport: new Array(),
  params: new Array(),
  states: new Array(),
  reqdata: new Array(),
  RS_INIT:	0,
  RS_LOADING: 1,
  RS_LOADED: 2,
  RS_INTERACTIVE: 3,
  RS_COMPLETE: 4
}


var Data = {
	check: function(response,dbg,errors)
	{
		if( !response )
		{
			Debug.add('no response in '+dbg);
			Messages.hide();
			return false;
		}
		var d = response.getElementsByTagName('data');
		if(d.length==0)
		{
			Debug.add('no data in '+dbg);
			Messages.hide();
			return false;
		}
		if( d[0].getAttribute('error') )
		{
			var e = d[0].getAttribute('error');
			var de=true;
			if( errors ) {
				e = errors[e]?errors[e]:e;
				de=false;
			}
			if( d[0].getAttribute('nodebug') ) de=false;
			if( dbg )
				str = "<h1>An error occurred in "+dbg+"</h1>"+'<div class="error">'+e+'</div>';
			else
				str = "<h1>An error occurred:</h1>"+'<div class="error">'+e+'</div>';
			Messages.mbOk(str,'error');
			if(de)Debug.add(str);
//			JForm.saveError = true;
			return false;
		}
		if( d[0].getAttribute('msg') )
		{
			Messages.mbOk(d[0].getAttribute('msg'),'warn');
			return d;
		}
		return d;
	},
	
	get: function( d, n )
	{
		var reg = /jc\('([^']+)',([,a-z_0-9]+)\)/i;
		var r = n.match(reg);

		if( r )
		{
			var del = r[1];
			if( del=="\\n" ) del = "\n";
			var res ='', tmp;
			var list = r[2].split(',');
			for( var i=0; i<list.length; i++ )
			{
				tmp = Data.get( d, list[i] );
				if( tmp!=undefined && tmp!='' )
				{
					if( res!='' ) res += del;
					res += tmp;
				}
			}
			return res;
		}

		reg = /time\(([a-z_0-9]+)\)/i;
		r = n.match(reg);

		if( r )
		{
			var src = r[1];
			var tmp = Data.get( d, src );
			return tmp;
		}

		for( var i=0; i<d.childNodes.length; i++ )
			if( d.childNodes[i].getAttribute('name')==n )
				return d.childNodes[i].getAttribute('value');
	},
	
	getDataId: function( d, n )
	{
		for( var i=0; i<d.childNodes.length; i++ )
			if( d.childNodes[i].getAttribute('name')==n )
				return d.childNodes[i].getAttribute('data_id');
	}
};

