/*!
 * jQuery Json Plugin (with Transition Definitions)
 * Examples and documentation at: http://json.cn/
 * Copyright (c) 2012-2013  China.Ren.
 * Version: 1.0.2 (19-OCT-2013)
 * Dual licensed under the MIT and GPL licenses.
 * http://jquery.malsup.com/license.html
 * Requires: jQuery v1.3.1 or later
 */
var JSONFormat = (function(){
    var _toString = Object.prototype.toString;
    var _bigNums = [];
    function hide(obj){
        var data_type = $(obj).parent().attr('data-type');
        var data_size = $(obj).parent().attr('data-size');

        $(obj).parent().hide();
        var span = document.createElement('span');
        span.className = 'custom-plus';
        if (data_type === 'array') {
            span.innerHTML = '<i  style="cursor:pointer;" class="ti ti-square-rounded-plus"></i>Array[<span class="json_number">' + data_size + '</span>]';
            $(obj).parent().before(span)
        }else{
            span.innerHTML = '<i  style="cursor:pointer;" class="ti ti-square-rounded-plus"></i>Object{...}';
            $(obj).parent().before(span)
        }

    }

    function show(obj){
        $(obj).parent().next().show();
        $(obj).parent().remove()
    }

    $('#json-target').on('click', '.ti-square-rounded-plus', function(e) {
        show(this)
    })

    $('#json-target').on('click', '.ti-square-rounded-minus', function(e) {
        hide(this)
    })

    function format(object, indent_count){
        var html_fragment = '';
        switch(_typeof(object)){
            case 'Null' :0
                html_fragment = _format_null(object);
                break;
            case 'Boolean' :
                html_fragment = _format_boolean(object);
                break;
            case 'Number' :
                html_fragment = _format_number(object);
                break;
            case 'String' :
                //replace blank to html blank to display in html.
                object  = object.replace(/ /g,"&nbsp;");
                html_fragment = _format_string(object);
                break;
            case 'Array' :
                html_fragment = _format_array(object, indent_count);
                break;
            case 'Object' :
                if(object instanceof BigNumber){
                    html_fragment = _format_number(object.toFixed());
                }else{
                    html_fragment = _format_object(object, indent_count);
                }
                break;
        }
        return html_fragment;
    };

    function _format_null(object){
        return '<span class="json_null" contenteditable="true">null</span>';
    }

    function _format_boolean(object){
        return '<span class="json_boolean" contenteditable="true">' + object + '</span>';
    }

    function _format_number(object){
        return '<span class="json_number" contenteditable="true">' + object + '</span>';
    }

    function _format_string(object){
        // 2023-2-20禁用
        object = object.replace(/\</g,"%yxplt;");
        object = object.replace(/\>/g,"%yxpgt;");
        // 2023-2-20禁用
        if(0 <= object.search(/^http/)){
            object = '<a href="' + object + '" target="_blank" class="json_link">' + object + '</a>'
        }
        return '<span class="json_string" contenteditable="true">"' + object + '"</span>';
    }

    function _format_array(object, indent_count){
        var tmp_array = [];
        for(var i = 0, size = object.length; i < size; ++i){
            tmp_array.push(indent_tab(indent_count) + format(object[i], indent_count + 1));
        }
        return '<span data-type="array" data-size="' + tmp_array.length + '"><i  style="cursor:pointer;" class="ti ti-square-rounded-minus"></i>[<br/>'
            + tmp_array.join(',<br/>')
            + '<br/>' + indent_tab(indent_count - 1) + ']</span>';
    }

    function _format_object(object, indent_count){
        var tmp_array = [];
        for(var key in object){
            var keyRe = key.replace('jsondotcnprefixyxp', '');
            tmp_array.push( indent_tab(indent_count) + '<span class="json_key" contenteditable="true">"' + keyRe + '"</span>:<span class="json_nbsp">&nbsp;</span>' +  format(object[key], indent_count + 1));
        }
        return '<span  data-type="object"><i  style="cursor:pointer;" class="ti ti-square-rounded-minus"></i>{<br/>'
            + tmp_array.join(',<br/>')
            + '<br/>' + indent_tab(indent_count - 1) + '}</span>';
    }

    function indent_tab(indent_count){
        return (new Array(indent_count + 1)).join('<span class="json_nbsp">&nbsp;&nbsp;&nbsp;&nbsp;</span>');
    }

    function _typeof(object){
        var tf = typeof object,
            ts = _toString.call(object);
        return null === object ? 'Null' :
            'undefined' == tf ? 'Undefined'   :
                'boolean' == tf ? 'Boolean'   :
                    'number' == tf ? 'Number'   :
                        'string' == tf ? 'String'   :
                            '[object Function]' == ts ? 'Function' :
                                '[object Array]' == ts ? 'Array' :
                                    '[object Date]' == ts ? 'Date' : 'Object';
    };

    function loadCssString(){
        var style = document.createElement('style');
        style.type = 'text/css';
        var code = Array.prototype.slice.apply(arguments).join('');
        try{
            style.appendChild(document.createTextNode(code));
        }catch(ex){
            style.styleSheet.cssText = code;
        }
        document.getElementsByTagName('head')[0].appendChild(style);
    }

    loadCssString(
        '.json_key{ color: #92278f;font-weight:bold;}',
        '.json_null{color: #f1592a;font-weight:bold;}',
        '.json_string{ color: #3ab54a;font-weight:bold;}',
        '.json_number{ color: #25aae2;font-weight:bold;}',
        '.json_boolean{ color: #f98280;font-weight:bold;}',
        '.json_link{ color: #61D2D6;font-weight:bold;}',
        '.json_nbsp{ letter-spacing: 4px; }',
        '.json_array_brackets{}');

    var _JSONFormat = function(origin_data){
        // this.data = origin_data ? origin_data :
        //     JSON && JSON.parse ? JSON.parse(origin_data) : eval('(' + origin_data + ')');
        // let stringedJSON = origin_data.replace(/:\s*\"(.*)?\[(.*)?\](.*)?\"\s*(,)?/g, ': "$1jsonbracketsdoctor$2jsonbracketsdoctor$3"$4');
        // 将s”: 78替换成s": jsondotcnprefix78 =======
        let stringedJSON = origin_data.replace(/([^\\]")\s*:\s*([-+Ee0-9.]+)\s*(,)?/g, function (match, p1, p2, p3) {
            return ((p1 || '') + ': ' + '"jsondotcnprefix' + (p2 || '') + '"' + (p3 || ''));
        });
        // 将字符串“1，2，3”中的数字添加前缀，以免在下面匹配时被替换
        stringedJSON = stringedJSON.replace(/("\s*)((\\"|[^"])*)\s*(")/g, function(match, p1, p2, p3, p4) {
            // console.log(p2)
            var replaceStr = p2.replace(/(,|^)(\s*)(\d+)(\s*)(?=,|$)/g, function(match, p1, p2, p3) {
                return ((p1 || '') + 'jsondotyxpprefixyxp' + (p2 || '') + (p3 || ''));
            });
            replaceStr = replaceStr.replace(/(\[)\s*(\d+)/g, function (match, p1, p2) {
                return ((p1 || '') + 'jsondotyxpprefixyxp' + (p2 || ''));
            });
            replaceStr = replaceStr.replace(/(\d+)(])/g, function (match, p1, p2){
                return ('jsondotyxpprefixyxp' + (p1 || '') + (p2 || ''));
            });
            return p1 + replaceStr + p4;
        });
        // 将,78,替换成,jsondotcnprefix78,
        stringedJSON = stringedJSON.replace(/(,|^)\s*(\d+)\s*(?=,|$)/g, function (match, p1, p2){
            return (p1 + '"jsondotcnprefix' + (p2 || '') + '"');
        });
        // 将s": [78替换成s" [jsondotcnprefix78
        stringedJSON = stringedJSON.replace(/([^\\]")\s*:\s*(\[)\s*([-+Ee0-9.]+)\s*(,)?\s*(])?/g, function(match, p1, p2, p3, p4, p5){
            return ((p1 || '') + ': ' + (p2 || '') + '"jsondotcnprefix' + (p3 || '') + '"' + (p4 || '') + (p5 || ''));
        });
        // 将,78],"替换成,jsondotcnprefix78],"
        stringedJSON = stringedJSON.replace(/(,)\s*([-+Ee0-9.]+)\s*(])\s*/g, function (match, p1, p2, p3){
            return ((p1 || '') + '"jsondotcnprefix' + (p2 || '') + '"' + (p3 || ''));
        });
        // stringedJSON = stringedJSON.replace(/(\[)\s*([-+Ee0-9.]+)\s*(,)?\s*(\])?/g, '$1"jsondotcnprefix$2"$3$4');
        // stringedJSON = stringedJSON.replace(/(,)\s*([-+Ee0-9.]+)\s*(\])?/g, '$1"jsondotcnprefix$2"$3');
        stringedJSON = stringedJSON.replace(/"([-+Ee0-9.]+)"\s*:\s*/g, function (match, p1) {
            return ('"jsondotcnprefixyxp' + (p1 || '') + '": ');
        });
        stringedJSON = stringedJSON.replace(/jsondotyxpprefixyxp/g, '');
        // console.log(stringedJSON)
        try {
            var temp = JSON.parse(stringedJSON, (key, value) => {
                // only changing strings
                if (typeof value !== 'string') return value;
                // only changing number strings
                if (!value.startsWith('jsondotcnprefix')) return value;
                // chop off the prefix
                value = value.slice('jsondotcnprefix'.length);
                // pick your favorite arbitrary-precision library
                return new BigNumber(value);
            });
            this.data = temp;
        } catch (e) {
            this.data = JSON.parse(origin_data);
            console.log(e);
        } finally {

        }
        //this.data = o;//JSON.parse(origin_data);
    };

    _JSONFormat.prototype = {
        constructor : JSONFormat,
        toString : function(){
            return format(this.data, 1);
        }
    }

    return _JSONFormat;

})();
