var g_cdata_start = "<![CDATA[";
var g_cdata_end   = "]]>";


// numeric sorting
function numOrdA(a, b){ return (a-b); }
function numOrdD(a, b){ return (b-a); }

function doConfirm(message)
{  if (standalone)
   {  return true;
   }
   else
   {  return confirm(message);
   }
}

function removeChildren(el)
{
   if (el.hasChildNodes())
   {  while (el.childNodes.length > 0)
      {  el.removeChild(el.firstChild);
      }
   }
}

function findPos(obj) {
   curleft = curtop = 0;

   // does browser support 'offsetParent'?
   if (obj.offsetParent) {
      do {
         curleft += obj.offsetLeft;
         curtop  += obj.offsetTop;
      }  while (obj = obj.offsetParent);
   }
   return [curleft, curtop];
}

function get_modifiers(e) {
   if (!e) 
   {  e = window.event;
   }
   mods = new Object();
   mods.ctrl  =0;
   mods.alt   = 0;
   mods.shift = 0;
   mods.meta  = 0;

   if (parseInt(navigator.appVersion)>3) {

      var evt = navigator.appName=="Netscape" ? e:event;

      if (navigator.appName=="Netscape" && parseInt(navigator.appVersion)==4) {
      // NETSCAPE 4 CODE
         var mString =(e.modifiers+32).toString(2).substring(3,6);
         mods.shift = (mString.charAt(0)=="1");
         mods.ctrl  = (mString.charAt(1)=="1");
         mods.alt   = (mString.charAt(2)=="1");
         return mods;
      }
   }

   // NEWER BROWSERS [CROSS-PLATFORM]
   evt = e;
   mods.shift = evt.shiftKey;
   mods.ctrl  = evt.ctrlKey;
   mods.alt   = evt.altKey;
   mods.meta  = evt.metaKey;
  
 return mods;
}
// this function makes sure that any stuff sent withing XML to the
//  server is wrapped in the CDATA business, and also makes sure
//  there are no CDATA endings in the string
function xml_escape(s)
{

/* valid XML chars are:
#x    0 - #x     8 | INVALID
#x    9 - #x     a | OK
#x    B - #x     C | INVALID
#x    D            | OK
#x    E - #x    1F | INVALID
#x   20 - #x  D7FF | OK
#x D800 - #x  DFFF | INVALID
#x E000 - #x  FFFD | OK
#x FFFE - #x  FFFF | INVALID
#x10000 - #x10ffff | OK 
 */
   s = trim(s);
   s = s.replace(/([\u0000-\u0008]|[\u000B-\u000C]|[\u000E-\u001F]|[\uD800-\uDfff]|[\ufffe-\uffff])/g,'');
   return g_cdata_start + s + g_cdata_end;
}

function dBug(s)
{  if (typeof console != 'undefined' &&
       typeof console.log != 'undefined')
   {  console.log(s);
   }
}

function trim(s) {
   s += "";
   var l=0; var r=s.length -1;
   while(l < s.length && s[l] == ' ')
   {  l++; }
   while(r > l && s[r] == ' ')
   {  r-=1; }
   return s.substring(l, r+1);
}

function clone(myObj)
{
   if(typeof(myObj) != 'object') return myObj;
   if(myObj == null) return myObj;

   var myNewObj = new Object();

   for(var i in myObj)
      myNewObj[i] = clone(myObj[i]);

   return myNewObj;
}

function delete_cookie ( cookie_name )
{
  var cookie_date = new Date ( );  // current date & time
  cookie_date.setTime ( cookie_date.getTime() - 1 );
  document.cookie = cookie_name += "=; expires=" + cookie_date.toGMTString();
}

function urlencode( str ) {
    // http://kevin.vanzonneveld.net
    // +   original by: Philip Peterson
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +      input by: AJ
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: Brett Zamir (http://brettz9.blogspot.com)
    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +      input by: travc
    // +      input by: Brett Zamir (http://brettz9.blogspot.com)
    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: Lars Fischer
    // %          note 1: info on what encoding functions to use from: http://xkr.us/articles/javascript/encode-compare/
    // *     example 1: urlencode('Kevin van Zonneveld!');
    // *     returns 1: 'Kevin+van+Zonneveld%21'
    // *     example 2: urlencode('http://kevin.vanzonneveld.net/');
    // *     returns 2: 'http%3A%2F%2Fkevin.vanzonneveld.net%2F'
    // *     example 3: urlencode('http://www.google.nl/search?q=php.js&ie=utf-8&oe=utf-8&aq=t&rls=com.ubuntu:en-US:unofficial&client=firefox-a');
    // *     returns 3: 'http%3A%2F%2Fwww.google.nl%2Fsearch%3Fq%3Dphp.js%26ie%3Dutf-8%26oe%3Dutf-8%26aq%3Dt%26rls%3Dcom.ubuntu%3Aen-US%3Aunofficial%26client%3Dfirefox-a'
                             
    var histogram = {}, tmp_arr = [];
    var ret = (str+'').toString();
    
    var replacer = function(search, replace, str) {
        var tmp_arr = [];
        tmp_arr = str.split(search);
        return tmp_arr.join(replace);
    };
    
    // The histogram is identical to the one in urldecode.
    histogram["'"]   = '%27';
    histogram['(']   = '%28';
    histogram[')']   = '%29';
    histogram['*']   = '%2A';
    histogram['~']   = '%7E';
    histogram['!']   = '%21';
    histogram['%20'] = '+';
    histogram['\u00DC'] = '%DC';
    histogram['\u00FC'] = '%FC';
    histogram['\u00C4'] = '%D4';
    histogram['\u00E4'] = '%E4';
    histogram['\u00D6'] = '%D6';
    histogram['\u00F6'] = '%F6';
    histogram['\u00DF'] = '%DF';
    histogram['\u20AC'] = '%80';
    histogram['\u0081'] = '%81';
    histogram['\u201A'] = '%82';
    histogram['\u0192'] = '%83';
    histogram['\u201E'] = '%84';
    histogram['\u2026'] = '%85';
    histogram['\u2020'] = '%86';
    histogram['\u2021'] = '%87';
    histogram['\u02C6'] = '%88';
    histogram['\u2030'] = '%89';
    histogram['\u0160'] = '%8A';
    histogram['\u2039'] = '%8B';
    histogram['\u0152'] = '%8C';
    histogram['\u008D'] = '%8D';
    histogram['\u017D'] = '%8E';
    histogram['\u008F'] = '%8F';
    histogram['\u0090'] = '%90';
    histogram['\u2018'] = '%91';
    histogram['\u2019'] = '%92';
    histogram['\u201C'] = '%93';
    histogram['\u201D'] = '%94';
    histogram['\u2022'] = '%95';
    histogram['\u2013'] = '%96';
    histogram['\u2014'] = '%97';
    histogram['\u02DC'] = '%98';
    histogram['\u2122'] = '%99';
    histogram['\u0161'] = '%9A';
    histogram['\u203A'] = '%9B';
    histogram['\u0153'] = '%9C';
    histogram['\u009D'] = '%9D';
    histogram['\u017E'] = '%9E';
    histogram['\u0178'] = '%9F';
    
    // Begin with encodeURIComponent, which most resembles PHP's encoding functions
    ret = encodeURIComponent(ret);
    
    for (search in histogram) {
        replace = histogram[search];
        ret = replacer(search, replace, ret) // Custom replace. No regexing
    }
    
    // Uppercase for full PHP compatibility
    return ret.replace(/(\%([a-z0-9]{2}))/g, function(full, m1, m2) {
        return "%"+m2.toUpperCase();
    });
    
    return ret;
}

var keyStr = "ABCDEFGHIJKLMNOP" +
             "QRSTUVWXYZabcdef" +
             "ghijklmnopqrstuv" +
             "wxyz0123456789+/" +
             "=";

function encode64(input) {
   input = escape(input);
   var output = "";
   var chr1, chr2, chr3 = "";
   var enc1, enc2, enc3, enc4 = "";
   var i = 0;

   do {
      chr1 = input.charCodeAt(i++);
      chr2 = input.charCodeAt(i++);
      chr3 = input.charCodeAt(i++);

      enc1 = chr1 >> 2;
      enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
      enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
      enc4 = chr3 & 63;

      if (isNaN(chr2)) {
         enc3 = enc4 = 64;
      } else if (isNaN(chr3)) {
         enc4 = 64;
      }

      output = output +
         keyStr.charAt(enc1) +
         keyStr.charAt(enc2) +
         keyStr.charAt(enc3) +
         keyStr.charAt(enc4);
      chr1 = chr2 = chr3 = "";
      enc1 = enc2 = enc3 = enc4 = "";
   } while (i < input.length);

   return output;
}

function decode64(input) {
   var output = "";
   var chr1, chr2, chr3 = "";
   var enc1, enc2, enc3, enc4 = "";
   var i = 0;

   // remove all characters that are not A-Z, a-z, 0-9, +, /, or =
   var base64test = /[^A-Za-z0-9\+\/\=]/g;
   if (base64test.exec(input)) {
      alert("There were invalid base64 characters in the input text.\n" +
            "Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\n" +
            "Expect errors in decoding.");
   }
   input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

   do {
      enc1 = keyStr.indexOf(input.charAt(i++));
      enc2 = keyStr.indexOf(input.charAt(i++));
      enc3 = keyStr.indexOf(input.charAt(i++));
      enc4 = keyStr.indexOf(input.charAt(i++));

      chr1 = (enc1 << 2) | (enc2 >> 4);
      chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
      chr3 = ((enc3 & 3) << 6) | enc4;

      output = output + String.fromCharCode(chr1);

      if (enc3 != 64) {
         output = output + String.fromCharCode(chr2);
      }
      if (enc4 != 64) {
         output = output + String.fromCharCode(chr3);
      }

      chr1 = chr2 = chr3 = "";
      enc1 = enc2 = enc3 = enc4 = "";

   } while (i < input.length);

   return unescape(output);
}

function get_last_path(path)
{  
   var parts = path.split(DIR_SEP);
   var p = parts[parts.length - 1];
   for (var i = parts.length - 1; i >= 0; i--)
   {  p = parts[i];
      if (p) break;
   }
   if (!p)
   {  p = "(root)";
   }
   return p;
}

function browser()
{
   var b = navigator.userAgent;
   if (b.indexOf("Opera")!= -1)          b = "op";
   else if (b.indexOf("Firefox")!= -1)   b = "ff";
   else if (b.indexOf("MSIE")!= -1)      b = "ie";
   else if (b.indexOf("Netscape")!= -1)  b = "ns";
   else if (b.indexOf("Safari")!= -1)    b = "sa";
   else    ;  //  Not known, return userAgent string and ENDIF
   return b;
} 

function getInternetExplorerVersion()
// Returns the version of Internet Explorer or a -1
// (indicating the use of another browser).
{
  var rv = -1; // Return value assumes failure.
  if (navigator.appName == 'Microsoft Internet Explorer')
  {
    var ua = navigator.userAgent;
    var re  = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
    if (re.exec(ua) != null)
      rv = parseFloat( RegExp.$1 );
  }
  return rv;
}

