//json综述。此类主要处理以下两种情况的数据。
//1、后台返回的数据形如:{"id":"1","name":"zhangsan"}  称为json数据,在js中称为对象。
//  元素Elements,包括div,a,input等在前端的表现形式是:{"tagname":"input","className":""}
//                                                        {"tagname":"div","className":""}
//2、[
//     {"id":"1","name":"zhangsan"}
//     {"id":"2","name":"lisi"}
//  ]
//
//综上所述,前端元素,数据基本都是{}.所以本数据处理类是针对前端所有对象。

//#region 这里是json操作区域

Namespace.register("U.Json");


//兼容JSON
U.Json.init = function () {
    if (!window.JSON) {
        window.JSON = {
            stringify: U.Json.stringify,
            parse: U.Json.parse
        };
    }
}





//JSON类操作,如果不存在json类,则自己创建一个window.JSON。只有一个地方使用了此函数的parse方法

U.Json.stringify = function (json) {//转化成字符串
    return U.UF.C.jsonToStr(json);
}

U.Json.parse = function (str) {//转化成实体
    return str.parseJSON();
}

/**
* 判断数据是否符合条件
*
* @param  {object || array} 被添加的json对象或者数组
* 
* @param  {object} 比较的对象
* 
* @return  {object} 比较的对象
*/
U.Json.ifExists = function (key1, key2) {
    if (key2 === key1) {
        return true;
    }
    for (var i in key1) {
        if (key1[i] != key2[i]) {
            return false;
        }
    }
    return true;
}

//#region json对象处理类,处理类似下面的json数据
/*{
"_id" : ObjectId("532eab25aa01ee01e2297676"),
"UserID" : "83ddf636-7266-4d15-be11-a7ef89bcac55",
"TNode" : [{
"Name" : "根目录",
"CreateDate" : ISODate("2014-03-23T09:36:37.376Z"),
"Type" : "folder",
"ID" : "e6f3963e-6087-b772-8e54-561353832f7b",
"Deep" : 1.0,
"IsDelete" : false,
"TNode" : [{
"Name" : "Test",
"CreateDate" : ISODate("2014-03-23T09:36:43.526Z"),
"Type" : "folder",
"ID" : "0fb91d00-7c5b-dd79-4f3e-1c2d405611e2",
"IsDelete" : false,
"Deep" : 2.0,
"TNode" : [{
"Name" : "index.htm",
"CreateDate" : ISODate("2014-03-23T09:36:43.548Z"),
"Type" : "file",
"ID" : "929bb945-ca3b-dedd-7077-88d1ce0492e3",
"IsDelete" : false,
"Deep" : 3.0,
"Content" : ""
}],
"IsPublic" : true
}]
}]
}*/
/**
* 添加json对象
*
* @param  {object || array} 被添加的json对象或者数组
* 
* @param  {object} 需要添加的对象值
* 
* @return  {object} 返回添加后新的对象值
实例一
var a = [{username:"a"},{username:"b"},{username:"c"}];
var b = {test:'1'}
U.Json.add(a,b);
    
实例二
var a = {username:"cxs"}
var b = {id:'1'}
U.Json.add(a,b);
*/
U.Json.add = function (obj1, obj2) {
    var i; //循环初始值
    //判断参数obj1是否为对象或者数组,如果是对象,循环添加。
    if (!Array.isArray(obj1)) {//判断是否为数组
        for (i in obj2) {//循环参数obj2对象
            obj1[i] = obj2[i]; //对参数obj1赋值
        }
    }
    //如果参数obj1是数组,为数组中的每一个对象都添加赋值
    else {
        for (i = 0; i < obj1.length; i++) {//循环obj1数组
            U.UF.C.AddObj(obj1[i], obj2); //为数组中的每一个对象元素都添加对象obj2的值。
        }
    }
    //返回添加后新的对象值
    return obj1;
}

//少一个跨层搜索的方法。
//obj json格式 为类似mongodb中的数据,
//key 字符串 是关键字
//value 字符串 是值
U.Json.find = function (obj, key, value) {


}


//#endregion

//#region 处理jsonArray的数据,实质是数组

/**
* 根据条件,删除json数组中指定的json
*
* @param  {array} 被删除的json数组。
* 
* @param  {object} 删除json的数据。
* 
* @return  {object} 返回的删除数据。
            
实例一
var a = [{parentid:1, username:"a"},{parentid:1,username:"b"},{parentid:2,username:"c"}]
var b = {parentid:2,username:"c"}
U.Json.delete(a,b);
*/
U.Json.del = function (obj, key, data) { //删除 允许递归
    data = data || obj; //传递进来的json数据
    var i,
        _deldata,
        _delarray = []; //返回的删除数据。
    //数组删除指定obj条件的元素
    if (Array.isArray(data)) {//数组使用
        for (i = 0; i < data.length; i++) {
            //循环删除 获取移除的元素
            _deldata = U.Json.del(obj, key, data[i]);
            if (_deldata.length) { //判断是否移除了元素,length大于0相当于移除超过一个元素。
                data.splice(i, 1); //数组的系统移除方法
                _delarray = _delarray.concat(_deldata); //把移除的元素添加到变量中
                i--; //由于上面用了循环i++ 移除元素后 数组的下标减一了,所以这里用i--让i回到前面一个循环,这样即使数组删除了一个元素也不会直接跳过下一个元素的循环
            }
        }
    }
    else if (typeof data == "object") { //对象删除
        if (U.Json.ifExists(key, data)) {
            delete data;
            _delarray.push(data);
        }
        else if (key === true) { //递归删除
            for (i in data) {
                _deldata = U.Json.del(obj, key, data[i]); //递归删除该数据
                _delarray = _delarray.concat(_deldata); //把删除的数据追加到变量中
            }
        }
        else if (key && data[key]) { //根据指定的key进行递归删除
            _deldata = U.Json.del(obj, key, data[key]); //根据指定的key递归删除该数据
            _delarray = data.concat(_deldata);
        }
    }
    return _delarray;
}

/**
* 根据条件,查找json数组中指定的json
*
* @param  {array} 需要进行选择的json数组。
* 
* @param  {object} 选择的条件
*
* @param  {number} 选择的个数
* 
* @return  {array} 选择后的结果
实例一
var a = [{ parentid: 1, username: "a" }, { parentid: 1, username: "b" }, { parentid: 2, username: "c" }]
var b = { parentid: 1 }
U.Json.select(a,b,2);
*/
U.Json.select = function (arr, obj, num) {//条件获取
    var i, //判断初始化
        _bool, //用于参数判断
        _res = []; //用于存放选择后的结果
    //判断需要选择的对象是否为数组            
    if (Array.isArray(arr)) {
        //循环json数组
        for (i = 0; i < arr.length; i++) {
            //设置判断默认值
            _bool = true;
            //循环条件
            for (var j in obj) {
                //如果是其中有一个条件不符合要求,修改判断值。
                if (arr[i][j] != obj[j]) {
                    _bool = false;
                }
            }
            //如果所有的条件都成立,则记录数组
            if (_bool) {
                _res.push(arr[i]);
            }
            //判断程序选择的个数是否大于用户的选择个数,如果大于选择个数,跳出循环
            if (_res.length == num) {
                break;
            };
        }
    }
    //返回结果集
    return _res;
}

/**
* 根据条件,查找json数组中指定的json,只获取一个结果集
*
* @param  {array} 需要进行选择的json数组。
* 
* @param  {object} 选择的条件
* 
* @return  {array} 选择后的结果
            
实例一
var a = [{ parentid: 1, username: "a" }, { parentid: 1, username: "b" }, { parentid: 2, username: "c" }]
var b = { parentid: 1 }
U.Json.selectOne(a,b);
*/
U.Json.selectOne = function (arr, obj) {
    return (U.Json.select(arr, obj, 1))[0];
}


/**
* 根据条件,对json数组进行排序,此函数需要移动到数组中。
*
* @param  {array} 需要进行选择的json数组。 
* @param  {number} 排序方式 1正序 -1倒序
* @return  {string} 排序的条件,json数组中的键名  
实例一
var a = [{id:3},{id:1},{id:2}]; 
U.Json.sort(a,"id");
*/
U.Json.sort = function (arr, key, isreverse) { //排序

    isreverse = isreverse || 1;
    //采用数组本身的排序sort方法,此方法比较奇特。
    arr = arr.sort(function (obj1, obj2) {
        var _value,
            _type, //比较大小的类型
            _value1 = obj1[key],
            _value2 = obj2[key],
            _isobj = U.UF.C.isObject(obj1); //判断比较的大小是否为对象


        //对象的大小匹配
        if (_isobj) {
            _type = (typeof (obj1[key] || obj2[key])).capitalizeFirstLetter(); //由于类型的值有可能是null或者是undefined,判断两种比较安全
        }
        //非对象的处理方式 U.UF.Ut.compare+type 是一些列的对象比较大小的方法
        else {
            _type = (typeof obj1).capitalizeFirstLetter();
        }
        //数字大小比较  
        if (_type == "Number") {
            _value = _value1 > _value2;
        }
        //时间大小比较
        else if (_type == "Date") {
            _value = U.UF.D.SizeComparison(_value1, _value2);
        }
        //字符串大小比较
        else if (_type == "String") {
            _value = _value1.localeCompare(_value2) == 1;
        }
        //服务器的值可能是null,没有类型比较默认第一个比第二个大
        else {
            _value = true;
        }
        //isreverse 用于判断倒序还是正序,如果是-1就是倒序,如果是1就是正序,需要返回这个值给数组的sort函数,比较奇特
        _value = isreverse * (_value ? 1 : -1);
        return _value;
    });
    return arr;
}


/**
* 根据条件,对json数组进行排序,此函数注释有问题
*
* @param  {array} obj数组
* @param  {string} 关键字 
*/
U.Json.toKeyArray = function (arr, key) {
    var i,
        _returnarr = []; //数组存储数据
    //循环写入数据
    for (i = 0; i < arr.length; i++) {
        _returnarr.push(arr[i][key]);
    }
    //返回数组
    return _returnarr;
}

/**
* 根据条件,对json数组进行排序,此函数注释有问题
*
* @param  {array} obj数组
* @param  {object} key value的条件 
* @param  {number} 关键字 
*/
U.Json.like = function (arr, obj, num) {
    var i, //判断初始化
        _bool, //用于参数判断
        _res = []; //用于存放选择后的结果
    //判断需要选择的对象是否为数组            
    if (Array.isArray(arr)) {
        //循环json数组
        for (i = 0; i < arr.length; i++) {
            //设置判断默认值
            _bool = false;
            //循环条件
            for (var j in obj) {
                //如果是其中有一个条件不符合要求,修改判断值。
                if (arr[i][j] && (arr[i][j].indexOf(obj[j]) > -1 || obj[j].indexOf(arr[i][j]) > -1)) {
                    _bool = true;
                }
            }
            //如果所有的条件都成立,则记录数组
            if (_bool) {
                _res.push(arr[i]);
            }
            //判断程序选择的个数是否大于用户的选择个数,如果大于选择个数,跳出循环
            if (_res.length == num) {
                break;
            };
        }
        //返回结果集
        return _res;
    }
}
//#endregion