/*
*	objAJAX
*	© XPERTS IT SOLUTIONS - http://xperts.intro.pk
*	Waqas Mehmood, admin@intro.pk
*/
function objAJAX()
{
		var this_Browser = this;		//to use the current object/instance
	//BrowserFunctions
		this.Navigate = function(strUrl, Data, Method)
		{
			//ToDo: navigate to other page, also include referrer(prev page), Cookies || Cookie SIMULAION
			
			this.SetUrl(strUrl);
			if(Data)this.SetData(Data);
			if(Method)this.SetMethod(Method);
			this.ReturnData=false;
			this.sendRequest();					//Send the Request
			
		};
	//--BrowserFunctions
	
	//Misc Functions
		this.RefreshXmlRequest = function(){		//refresh the xmlRequest object, according to data provided
			this.XmlRequest = new getNewHTTPObject();
			
			this.XmlRequest.onreadystatechange = function()
			{//this function is called when the state is changed
				//alert('onreadyStateChange!');
				this_Browser.onreadystatechange();
			};
		  if (this.Auth){
			this.XmlRequest.open(this.Method, this.Url(), true, this.Auth_user, this.Auth_password);
		  }else{
			this.XmlRequest.open(this.Method, this.Url(), true);
		  }
		  
		  if(this.Method=="POST")
		  {
			this.XmlRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
		  }
		  
		  //this.XmlRequest.setRequestHeader("Referer", "http://www.google.com/");
		  
		  //this.XmlRequest.setRequestHeader("COOKIE", "PHPSESSID: hc8rd42j67s31nmv2milpd2gn0;");
		  //document.cookie ='PHPSESSID: hc8rd42j67s31nmv2milpd2gn0;';
		};
		this.sendRequest = function(){
		  this.RefreshXmlRequest();
		  this.XmlRequest.send(this.plainData());
		  //Throbber
			if(this.Throbber){
				document.getElementById(this.Throbber).style.display = "";		//show Throbber while loading.
			}
		  //--Throbber
		};
		this.onreadystatechange = function(){
			if (this.XmlRequest.readyState == "4"){
				var statusMsg = "Browser:'" + this.BrowserID + "' - onreadyStateChange!\n\nreadyState: "+this.XmlRequest.readyState+"\nstatus: "+this.XmlRequest.status;	//ToDo: StateChange
				//also hide throbber in case of completion
				
				this.httpStatus=this.XmlRequest.status;	//Update Status
				
				//Throbber, must hide when readystate is 4
					if(this.Throbber){
						document.getElementById(this.Throbber).style.display = "none";
					}
				//--Throbber
				
				//Interactivity
					if(this.UrlBox){
						document.getElementById(this.UrlBox).value = this.Url();
					}
					if(this.ResponseBox){
						document.getElementById(this.ResponseBox).value = this.XmlRequest.responseText;
					}
				//--Interactivity
				
				switch(this.XmlRequest.status)
				{
				  case 200: // OK, Success
						this.httpResponseText = this.XmlRequest.responseText;
					    if(this.XmlRequest.responseXML){
							this.httpResponseXml = this.XmlRequest.responseXML;
						}
						this.triggerSUCCESS(statusMsg);
				  break;
				  //case 304: // NOT MODIFIED, There was no new data to return.
				  //case 400: // BAD REQUEST, The request was invalid.  An accompanying error message will explain why. This is the status code will be returned during rate limiting.
				  //case 401: // NOT AUTHORIZED, Authentication credentials were missing or incorrect.
				  case 403: // FORBIDDEN,The request is understood, but it has been refused.  An accompanying error message will explain why. This code is used when requests are being denied due to update limits.
					this.triggerERROR("(FORBIDDEN)\n"+statusMsg);
				  break;
				  case 404: // NOT FOUND, The URI requested is invalid or the resource requested, such as a user, does not exists.
					this.triggerERROR("(Not Found)\n"+statusMsg);
				  break;
				  //case 406: //NOT ACCEPTABLE, Returned by the Search API when an invalid format is specified in the request.
				  //case 420: //ENHANCE YOUR CALM: Returned by the Search and Trends API  when you are being rate limited.
				  //case 500: // INTERNAL SERVER ERROR
				  //case 502: // BAD GATEWAY, Twitter is down or being upgraded.
				  case 503: // SERVICE UNAVAILABLE, The Twitter servers are up, but overloaded with requests. Try again later.
					//aTwitterHelper._localizedError(aTwitterHelper.mServiceName, "resp" + aXmlRequest.status);
					this.triggerERROR("(Service Unavailable)\n"+statusMsg);
				  break;
				  default:
				  this.triggerERROR("(Unknown Error)\n"+statusMsg);
				  break;
				}
				
				
				
			}
		};
		this.triggerSUCCESS = function(msg){
			if(this.SuccessFunction){
				this.SuccessFunction(this);
			}else{
				alert("Success!\nBrowser:"+this.BrowserID+"\n\n" + msg);
			}
		}
		this.triggerERROR = function(msg){
			if(this.ErrorFunction){
				this.ErrorFunction(this);
			}
			else{
			  alert("ERROR!\nBrowser:"+this.BrowserID+"\n\n" + msg);
			}
		}
	//--Misc Functions
		
	
	//Getters
		this.Url = function(){
			var strUrl = this.strUrl + '';
			return(strUrl);
		};
		this.plainData = function(){
			return this.plainHttpData(this.arrData);
		};
	//--Getters
	
	//Setters
		this.SetAuth = function(auth, a_user, a_pass){//POST/GET
			if(auth)
			{
				this.Auth=true;
				this.Auth_user = a_user;
				this.Auth_password = a_pass;
			}else{
				this.Auth=false;
				this.Auth_user = "";
				this.Auth_password = "";
			}
			
		};
		this.SetUrl = function(_value){//POST/GET
			this.strUrl = _value;
		};
		
		//var: this.arrData
		this.SetData = function(_value){//POST/GET
			this.arrData = this.arrayOrNewArray(_value);
		};
		this.SetRawData = function(_value){//POST/GET
			this.SetData(this.getArrQuery(_value));
		};
		this.SetMethod = function(_value){//POST/GET
			if((_value+'').toUpperCase()==='POST')
				this.Method = '' + "POST";
			else
				this.Method = '' + "GET";
		};
	//--Setters
	
		
	//Private functions
		this.plainHttpData = function(arrData){//returns data in querystring format
			var strData='';
			for(var k in arrData){
				if(strData){strData += '&';}
				strData += URLEncode(k) + '=' + URLEncode(arrData[k]);
			}
			return strData;
		};
		
		this.isArray = function (obj) {
			if(!obj) return false;
		   if (obj.constructor.toString().indexOf("Array") == -1)
			  return false;
		   else
			  return true;
		}
		this.toArray = function(_value){
			if(!(_value)){
					return new Array(_value);
			}
			
			if(this.isArray(_value)){
				return _value;
			}else{
					return new Array(_value);
			}
		};
		this.arrayOrNewArray = function(_value){
			if(this.isArray(_value)){
				return _value;
			}else{
					return new Array();
			}
		};
		this.getArrQuery = function(str) {
			var assoc = new Array();
			
				if(!str)return assoc;
			
			var keyValues = str.split('&');
			for (var i in keyValues) {
				var key = keyValues[i].split('=');
				assoc[URLDecode(key[0])] = URLDecode(key[1]);		//Query is url encoded
			}
			return assoc;
		}
	//--Private functions
		
		
		
		
		
	//Defaults
		this.BrowserID = 'jsvb';					//Browser ID, Javascript Virtual Browser
		this.SetAuth(false);
		this.SetUrl("");							//str
		this.SetData(new Array());
		this.SetMethod("Get");						//str: POST / GET
		this.ReturnData=false;
		this.XmlRequest = false;					//Initialize the XML REQUEST as FALSE
		
		//Interactivity
			this.Throbber=false;
			this.UrlBox = false;
			this.ResponseBox = false;
		//--Interactivity
		
		//httpStatus
			this.httpStatus=false;
			this.httpResponseText=false;
			this.httpResponseXml=false;
		//--httpStatus
		
	//--Defaults
		
	//Events, these events are triggered
		this.SuccessFunction = false;		//actual error is tracked from within the returned data
		this.ErrorFunction = false;
	//Events
	
}

/*  --  --  --  --  --  --  --  --  --  --  --  --  */

function getNewHTTPObject()
{
        var xmlhttp;

        /** Special IE only code ... */
        /*@cc_on
          @if (@_jscript_version >= 5)
              try
              {
                  xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
              }
              catch (e)
              {
                  try
                  {
                      xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
                  }
                  catch (E)
                  {
                      xmlhttp = false;
                  }
             }
          @else
             xmlhttp = false;
        @end @*/

        /** Every other browser on the planet */
        if (!xmlhttp && typeof XMLHttpRequest != 'undefined')
        {
            try
            {
                xmlhttp = new XMLHttpRequest();
            }
            catch (e)
            {
                xmlhttp = false;
            }
        }

        return xmlhttp;
}

//URL ENCODE/DECODE
function URLEncode(plaintext)
{
	// The Javascript escape and unescape functions do not correspond
	// with what browsers actually do...
	var SAFECHARS = "0123456789" +					// Numeric
					"ABCDEFGHIJKLMNOPQRSTUVWXYZ" +	// Alphabetic
					"abcdefghijklmnopqrstuvwxyz" +
					"-_.!~*'()";					// RFC2396 Mark characters
	var HEX = "0123456789ABCDEF";

	var encoded = "";
	for (var i = 0; i < plaintext.length; i++ ) {
		var ch = plaintext.charAt(i);
	    if (ch == " ") {
		    encoded += "+";				// x-www-urlencoded, rather than %20
		} else if (SAFECHARS.indexOf(ch) != -1) {
		    encoded += ch;
		} else {
		    var charCode = ch.charCodeAt(0);
			if (charCode > 255) {
			    alert( "Unicode Character '" 
                        + ch 
                        + "' cannot be encoded using standard URL encoding.\n" +
				          "(URL encoding only supports 8-bit characters.)\n" +
						  "A space (+) will be substituted." );
				encoded += "+";
			} else {
				encoded += "%";
				encoded += HEX.charAt((charCode >> 4) & 0xF);
				encoded += HEX.charAt(charCode & 0xF);
			}
		}
	} // for

	return(encoded);
};
function URLDecode(encoded)
{
   // Replace + with ' '
   // Replace %xx with equivalent character
   // Put [ERROR] in output if %xx is invalid.
   var HEXCHARS = "0123456789ABCDEFabcdef"; 
   var plaintext = "";
   var i = 0;
   while (i < encoded.length) {
       var ch = encoded.charAt(i);
	   if (ch == "+") {
	       plaintext += " ";
		   i++;
	   } else if (ch == "%") {
			if (i < (encoded.length-2) 
					&& HEXCHARS.indexOf(encoded.charAt(i+1)) != -1 
					&& HEXCHARS.indexOf(encoded.charAt(i+2)) != -1 ) {
				plaintext += unescape( encoded.substr(i,3) );
				i += 3;
			} else {
				alert( 'Bad escape combination near ...' + encoded.substr(i) );
				plaintext += "%[ERROR]";
				i++;
			}
		} else {
		   plaintext += ch;
		   i++;
		}
	} // while
   return plaintext;
};
//--URL ENCODE/DECODE


