/*
 * More info at: http://kevin.vanzonneveld.net/techblog/category/php2js
 *
 * php.js is copyright 2008 Kevin van Zonneveld.
 *
 * Portions copyright Ates Goral (http://magnetiq.com), Legaev Andrey,
 * _argos, Jonas Raoni Soares Silva (http://www.jsfromhell.com),
 * Webtoolkit.info (http://www.webtoolkit.info/), Carlos R. L. Rodrigues, Ash
 * Searle (http://hexmen.com/blog/), Tyler Akins (http://rumkin.com), mdsjack
 * (http://www.mdsjack.bo.it), Alexander Ermolaev
 * (http://snippets.dzone.com/user/AlexanderErmolaev), Andrea Giammarchi
 * (http://webreflection.blogspot.com), Bayron Guevara, Cord, David, Karol
 * Kowalski, Leslie Hoare, Lincoln Ramsay, Mick@el, Nick Callen, Peter-Paul
 * Koch (http://www.quirksmode.org/js/beat.html), Philippe Baumann, Steve
 * Clay, booeyOH
 *
 * Licensed under the MIT (MIT-LICENSE.txt) license.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL KEVIN VAN ZONNEVELD BE LIABLE FOR ANY CLAIM, DAMAGES
 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */



  function php_unserialize(data){
    // http://kevin.vanzonneveld.net
    // +     original by: Arpad Ray (mailto:arpad@php.net)
    // +     improved by: Pedro Tainha (http://www.pedrotainha.com)
    // +     bugfixed by: dptr1988
    // +      revised by: d3x
    // +     improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // %            note: Aiming for PHP-compatibility, we have to translate objects to arrays
    // *       example 1: unserialize('a:3:{i:0;s:5:"Kevin";i:1;s:3:"van";i:2;s:9:"Zonneveld";}');
    // *       returns 1: ['Kevin', 'van', 'Zonneveld']
    // *       example 2: unserialize('a:3:{s:9:"firstName";s:5:"Kevin";s:7:"midName";s:3:"van";s:7:"surName";s:9:"Zonneveld";}');
    // *       returns 2: {firstName: 'Kevin', midName: 'van', surName: 'Zonneveld'}



    var error = function (type, msg, filename, line){throw new window[type](msg, filename, line);};
      var read_until = function (data, offset, stopchr){
        var buf = [];
        var chr = data.slice(offset, offset + 1);
        var i = 2;
        while(chr != stopchr){
          if((i+offset) > data.length){
            error('Error', 'Invalid');
          }
          buf.push(chr);
          chr = data.slice(offset + (i - 1),offset + i);
          i += 1;
        }
        return [buf.length, buf.join('')];
    };

    var read_chrs = function (data, offset, length){
      buf = [];
      for(var i = 0;i < length;i++){
        var chr = data.slice(offset + (i - 1),offset + i);
        buf.push(chr);
      }
      return [buf.length, buf.join('')];
    };

    var _unserialize = function (data, offset){
      if(!offset) offset = 0;
      var buf = [];
      var dtype = (data.slice(offset, offset + 1)).toLowerCase();

      var dataoffset = offset + 2;
      var typeconvert = new Function('x', 'return x');
      var chrs = 0;
      var datalength = 0;

      switch(dtype){
        case "i":
          typeconvert = new Function('x', 'return parseInt(x)');
          var readData = read_until(data, dataoffset, ';');
          var chrs = readData[0];
          var readdata = readData[1];
          dataoffset += chrs + 1;
        break;
        case "b":
          typeconvert = new Function('x', 'return (parseInt(x) == 1)');
          var readData = read_until(data, dataoffset, ';');
          var chrs = readData[0];
          var readdata = readData[1];
          dataoffset += chrs + 1;
        break;
        case "d":
          typeconvert = new Function('x', 'return parseFloat(x)');
          var readData = read_until(data, dataoffset, ';');
          var chrs = readData[0];
          var readdata = readData[1];
          dataoffset += chrs + 1;
        break;
        case "n":
          readdata = null;
        break;
        case "s":
          var ccount = read_until(data, dataoffset, ':');
          var chrs = ccount[0];
          var stringlength = ccount[1];
          dataoffset += chrs + 2;

          var readData = read_chrs(data, dataoffset+1, parseInt(stringlength));
          var chrs = readData[0];
          var readdata = readData[1];
          dataoffset += chrs + 2;
          if(chrs != parseInt(stringlength) && chrs != readdata.length){
            error('SyntaxError', 'String length mismatch');
          }
        break;
        case "a":
          var readdata = {};

          var keyandchrs = read_until(data, dataoffset, ':');
          var chrs = keyandchrs[0];
          var keys = keyandchrs[1];
          dataoffset += chrs + 2;

          for(var i = 0;i < parseInt(keys);i++){
            var kprops = _unserialize(data, dataoffset);
            var kchrs = kprops[1];
            var key = kprops[2];
            dataoffset += kchrs;

            var vprops = _unserialize(data, dataoffset);
            var vchrs = vprops[1];
            var value = vprops[2];
            dataoffset += vchrs;

            readdata[key] = value;
          }

          dataoffset += 1;
        break;
        default:
          error('SyntaxError', 'Unknown / Unhandled data type(s): ' + dtype);
        break;
      }
      return [dtype, dataoffset - offset, typeconvert(readdata)];
    };

    return _unserialize(data, 0)[2];
  }

  function php_require( filename ) {
    // http://kevin.vanzonneveld.net
    // +   original by: Michael White (http://crestidg.com)
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // %        note 1: Force Javascript execution to pause until the file is loaded. Usually causes failure if the file never loads. ( Use sparingly! )
    // -    depends on: file_get_contents
    // *     example 1: require('http://www.phpjs.org/js/phpjs/_supporters/pj_test_supportfile_2.js');
    // *     returns 1: 2

    var js_code = file_get_contents(filename);
    var script_block = document.createElement('script');
    script_block.type = 'text/javascript';
    var client_pc = navigator.userAgent.toLowerCase();
    if((client_pc.indexOf("msie") != -1) && (client_pc.indexOf("opera") == -1)) {
      script_block.text = js_code;
    } else {
      script_block.appendChild(document.createTextNode(js_code));
    }

    if(typeof(script_block) != "undefined") {
      document.getElementsByTagName("head")[0].appendChild(script_block);

      // save include state for reference by include_once and require_once()
      var cur_file = {};
      cur_file[window.location.href] = 1;

      if (!window.php_js) window.php_js = {};
      if (!window.php_js.includes) window.php_js.includes = cur_file;

      if (!window.php_js.includes[filename]) {
        window.php_js.includes[filename] = 1;
      } else {
        // Use += 1 because ++ waits until AFTER the original value is returned to increment the value.
        return window.php_js.includes[filename] += 1;
      }
    }
  }