function urlEncode (str)
{
 try
 {
  str = (str+'').toString();
  return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/\*/g, '%2A').replace(/~/g, '%7E');  // equivalent to PHP's rawurlencode
//  return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/\*/g, '%2A').replace(/%20/g, '+').replace(/~/g, '%7E');    // equivalent to PHP's urlencode
 }
 catch (e) {}

 return str;
}

function urlDecode (str)
{
 try
 {
  return decodeURIComponent(str);  // equivalent to PHP's rawurldecode
//  return decodeURIComponent(str.replace(/\+/g, '%20'));  // equivalent to PHP's urldecode
 }
 catch (e) {}

 return str;
}

function _urlEncode (str)
{
 try
 {
  var hexStr = function (dec) {return '%' + (dec < 16 ? '0' : '') + dec.toString(16).toUpperCase();};

  var ret = '', unreserved = /[\w.-]/;  // A-Za-z0-9_.- // Tilde is not here for historical reasons; to preserve it, use rawurlencode instead

  str = (str+'').toString();

  for (var i = 0, dl = str.length; i < dl; i++)
  {
   var ch = str.charAt(i);
   if (unreserved.test(ch)) {ret += ch;}
   else
   {
    var code = str.charCodeAt(i);
    if (0xD800 <= code && code <= 0xDBFF)  // High surrogate (could change last hex to 0xDB7F to treat high private surrogates as single characters); https://developer.mozilla.org/index.php?title=en/Core_JavaScript_1.5_Reference/Global_Objects/String/charCodeAt
    {
     ret += ((code - 0xD800) * 0x400) + (str.charCodeAt(i+1) - 0xDC00) + 0x10000;
     i++;  // skip the next one as we just retrieved it as a low surrogate
    }
    else if (code === 32) {ret += '+';}          // %20 in rawurlencode       // We never come across a low surrogate because we skip them, unless invalid
    else if (code < 128) {ret += hexStr(code);}  // 1 byte                    // Reserved assumed to be in UTF-8, as in PHP
    else if (code >= 128 && code < 2048)         // 2 bytes
    {
     ret += hexStr((code >> 6) | 0xC0);
     ret += hexStr((code & 0x3F) | 0x80);
    }
    else if (code >= 2048)                       // 3 bytes (code < 65536)
    {
     ret += hexStr((code >> 12) | 0xE0);
     ret += hexStr(((code >> 6) & 0x3F) | 0x80);
     ret += hexStr((code & 0x3F) | 0x80);
    }
   }
  }

  return ret;
 }
 catch (e) {}

 return str;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//  Title:          XmlHttp Helper functions                                                                             //
//  Author:         zig                                                                                                  //
//  Revised:        Ratty                                                                                                //
//  Version:        0.6a                                                                                                 //
//  Last Update:    11-09-2006                                                                                           //
//  Usage:          call sendRequest(), with a url, an action object and optionally the synchronisation type.            //
//                  Edit showReceived() and do whatever needs doing with the results in the case of that action number.  //
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

var xmlHttpActions = {action: 0};

var xmlhttp = null;

function showReceived(xml)  // do something with results
{
 if (isDef(xmlHttpActions) && isDef(xmlHttpActions.action))  // xmlHttpActions.action is returned "undefined" in IE
 {
  switch(xmlHttpActions.action)
  {
   case 1:
    // Do something
   break
  
   case 2:
    // Do something else
   break
  
   default:
    // Do default something
  }
 } 
}

function sendRequest(url, action, sync, get)  // send xml http request
{
 if (sync == null || typeof(sync) != 'boolean') sync = true;  // default is a synchronous request
 if (get == null || typeof(get) != 'boolean') get = false;  // default is a POST request

 xmlHttpActions = action;
 xmlhttp = getDomXmlRequest();
 xmlhttp.onreadystatechange = xmlhttpChange;
 if (get)
 {
  xmlhttp.open("GET", url, !sync);
  xmlhttp.send(null);
 }
 else
 {
  var params = url.split('?');

  if (params.length == 1) params = '';
  else if (params.length == 2)
  {
   url = params[0];
   params = params[1];
  }
  else return false;

  xmlhttp.open("POST", url, !sync);

  xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=UTF-8");
//  xmlhttp.setRequestHeader("Content-length", params.length);
//  xmlhttp.setRequestHeader("Connection", "close");

  xmlhttp.send(params);
 }

 if (sync == true) return xmlhttp.responseText;
 return true;
}

/*
function getDomXmlRequest()  // create xml http request
{
 var ua = navigator.userAgent.toLowerCase();
 if (ua.indexOf('msie') == -1) request = new XMLHttpRequest();
 else if (ua.indexOf('msie 5') == -1) request = new ActiveXObject("Msxml2.XMLHTTP");
 else request = new ActiveXObject("Microsoft.XMLHTTP");

 return request;
}

function getDomXmlRequest()  // create xml http request
{
 try {ajaxRequest = new XMLHttpRequest();}  // Opera 8.0+, Firefox, Safari
 catch (e)
 {
  try {ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");}  // Internet Explorer Browsers
  catch (e)
  {
   try {ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");}
   catch (e){return false;}  // Something went wrong
  }
 }

 return ajaxRequest;
}
*/

function getDomXmlRequest()  // create xml http request
{
 if (typeof(XMLHttpRequest) != 'undefined') return new XMLHttpRequest();
// else return null;

 var ax=['Msxml2.XMLHTTP.6.0', 'Msxml2.XMLHTTP.5.0', 'Msxml2.XMLHTTP.4.0', 'Msxml2.XMLHTTP.3.0', 'Msxml2.XMLHTTP', 'Microsoft.XMLHTTP'];
 for (var i=0; i<ax.length; i++)
 {
  try {return new ActiveXObject(ax[i]);}
  catch (e) {}
 }

 return null;
}

function xmlhttpChange()  // xml http request changed
{
 if (xmlhttp.readyState == 4)
 {
  if (xmlhttp.status==200) showReceived(getDomFromXml(xmlhttp.responseText));
  else alert("Problem retrieving response.");
 }
}

function getDomFromXml(xmlString)  // return xml doc object from xml string
{
 if (typeof ActiveXObject != 'undefined')
 {
  var dom = new ActiveXObject("Microsoft.XMLDOM");
  dom.async = false;
  dom.loadXML(xmlString);
 }
 else if (document.implementation && document.implementation.createDocument)
 {
  parser = new DOMParser();
  var dom = parser.parseFromString(xmlString, "text/xml");
 }
 return dom;
}

