//
//             Copyright (c) 2002, 2003 Smartlink Corp.
//                       All rights reserved.
//

var m_b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var m_f64 = null;

function utf8Encode (str) {
   var codes = new Array (str.length);
   for (var i = 0; i < str.length; i++) {
      var code = str.charCodeAt (i);
      if (code < 0x80) {
         code = String.fromCharCode (code);
      }
      else if (code < 0x800) {
         code = String.fromCharCode (0xc0 | (code >> 6))
              + String.fromCharCode (0x80 | (code & 0x3f));
      }
      else {
         code = String.fromCharCode (0xe0 | (code >> 12))
              + String.fromCharCode (0x80 | ((code & 0x0fc0) >> 6))
              + String.fromCharCode (0x80 | (code & 0x3f));
      }
      codes [i] = code;
   }
   return codes.join ("");
}

function utf8Decode (str) {
   var res = "", i = 0;
   while (i < str.length) {
      var code = str.charCodeAt (i);
      if (code < 0x80) {
         i++;
      }
      else if ((code & 0xe0) == 0xc0) {
         code = (code & 0x1f) << 6;
         code |= (str.charCodeAt (i + 1) & 0x3f);
         i += 2;
      }
      else if ((code & 0xf0) == 0xe0) {
         code = (code & 0x0f) << 12;
         code |= (str.charCodeAt (i + 1) & 0x3f) << 6;
         code |= (str.charCodeAt (i + 2) & 0x3f);
         i += 3;
      }
      else {
         code = 0x3f; // "?"
         i++;
      }
      res += String.fromCharCode (code);
   }
   return res;
}

function base64Encode (str) {
   var inbuf = new Array (3);
   var outbuf = new Array (4);
   var res = "";
   for (var i = 0; i < str.length; i += 3) {
      inbuf [0] = str.charCodeAt (i);
      inbuf [1] = (i + 1 < str.length ? str.charCodeAt (i + 1) : 0);
      inbuf [2] = (i + 2 < str.length ? str.charCodeAt (i + 2) : 0);

      outbuf [0] = ((inbuf [0] & 0xfc) >> 2);
      outbuf [1] = ((inbuf [0] & 0x03) << 4) | ((inbuf [1] & 0xf0) >> 4);
      outbuf [2] = ((inbuf [1] & 0x0f) << 2) | ((inbuf [2] & 0xc0) >> 6);
      outbuf [3] =  (inbuf [2] & 0x3f);

      var j, out = Math.min (str.length - i, 3) + 1;
      for (j = 0; j < out; j++)
         outbuf [j] = m_b64.charAt (outbuf [j]);
      for (; j < 4; j++)
         outbuf [j] = "=";
      res += outbuf.join ("");
   }
   return res;
}

function base64Decode (str) {
   if (!m_f64) {
      m_f64 = new Array (256);
      for (var i = 0; i < m_b64.length; i++)
         m_f64 [m_b64.charCodeAt (i)] = i;
      m_f64 [0] = 0;
   }

   str = str.replace (new RegExp ("[\r\n=]", "g"), "");
   var inbuf = new Array (4);
   var outbuf = new Array (3);
   var res = "";
   for (var i = 0; i < str.length; i += 4) {
      inbuf [0] = m_f64 [str.charCodeAt (i)];
      inbuf [1] = m_f64 [i + 1 < str.length ? str.charCodeAt (i + 1) : 0];
      inbuf [2] = m_f64 [i + 2 < str.length ? str.charCodeAt (i + 2) : 0];
      inbuf [3] = m_f64 [i + 3 < str.length ? str.charCodeAt (i + 3) : 0];

      outbuf [0] = (inbuf [0] << 2) | ((inbuf [1] & 0x30) >> 4);
      outbuf [1] = ((inbuf [1] & 0x0f) << 4) | ((inbuf [2] & 0x3c) >> 2);
      outbuf [2] = ((inbuf [2] & 0x03) << 6) | (inbuf [3] & 0x3f);

      for (var j = 0; j < 3; j++)
         outbuf [j] = String.fromCharCode (outbuf [j]);
      var out = Math.min (str.length - i, 4) - 1;
      if (out < 3)
         outbuf.length = out;
      res += outbuf.join ("");
   }
   return res;
}

function escEncode (str) {
   if (escape (String.fromCharCode (0xe7)) == "%C3%A7") {
      str = escape (str);
   }
   else {
      var escNode = [ 0x0000, 0x0000, 0xec00, 0x03ff,
                      0xffff, 0x87ff, 0xfffe, 0x07ff ];
      var arr = new Array (str.length);
      for (var i = 0; i < str.length; i++) {
         arr [i] = str.charAt (i);
         var code = str.charCodeAt (i);
         if (code < 0x80 && (escNode [code >> 4] & (1 << (code & 0x0f))))
            continue;
         var t = (code >= 0x80 ? "%u0000" : "%00");
         var s = code.toString (16).toUpperCase ();
         arr [i] = t.substr (0, t.length - s.length) + s;
      }
      str = arr.join ("");
   }
   str = str.replace (/\+/g, "%2B");
   return str;
}

function escDecode (str) {
   return unescape (str);
}
