/*
此函数区域用于常用的通用函数 如位置 大小 计时器等
*/
Namespace.register("U.UF.C");
//#region 通用函数区域

/**
* 浏览器全屏
*
*/
U.UF.C.fullScreen = function () {
    var _funcname = U.UF.C.getFullSreeenName("requestFullScreen"); //全屏函数名
    if (_funcname != null) {
        document[_funcname] ? document[_funcname]() : document.documentElement[_funcname]();   //执行全屏函数
    }
}

/**
* 退出浏览器全屏
*
*/
U.UF.C.cancelfullScreen = function () {
    var _funcname = U.UF.C.getFullSreeenName("cancelFullScreen") || U.UF.C.getFullSreeenName("exitFullScreen"); //全屏函数名
    if (_funcname != null) {
        document[_funcname] ? document[_funcname]() : document.documentElement[_funcname]();   //执行退出全屏函数
    }
}

/**
* 根据函数名获取浏览器兼容名字
** @return  {string} 全屏功能的函数名 
*/
U.UF.C.getFullSreeenName = function (funcname) {
    var i, _functionname;
    //各个浏览器的全屏函数名称是不一样的,用数组把各个全屏函数包装起来。
    //注:各个浏览器全屏函数名如数组: _full = ["requestFullscreen", "mozRequestFullScreen", "webkitRequestFullscreen", "msRequestFullscreen", "oRequestFullscreen"];
    //各个浏览器还有不同的取消全屏,退出全屏功能"cancelFullScreen","exitFullScreenU.UF.C.getBriefText" 
    var _full = ["", "webkit", "moz", "ms", "o"]; //所有浏览器的兼容字符串集
    for (i = 0; i < _full.length; i++) {
        if (_full[i]) {
            _functionname = _full[i] + funcname.capitalizeFirstLetter();
        }
        else {
            _functionname = funcname;
        }
        //判断拼接的浏览器兼容函数名在文档中是否存在。存在则返回函数,不存在返回null。
        if (_functionname in document.documentElement || _functionname in document) {
            return _functionname;
        }
    }
    return null;
}

/**
* 对象转化成数组
*
* @param  {object} 需要转换成数组的对象
* @return  {string} 指定事件是否在捕获或冒泡阶段执行
*/
U.UF.C.toArray = function (obj) {
    try {
        return Array.prototype.slice.call(obj);
    }
    catch (e) {
        var i = 0,
            _arr = []; //循环创建
        for (; obj[i]; i++) {
            _arr.push(obj[i]);
        }
        return _arr;
    }
}

/**
* 统一处理函数,解决闭包添加事件的问题
* 使用apply,把事件与属性添加到对象上,而不是添加到window顶级对象。使用apply而不是call,是因为apply第二个参数可以传递参数数组,代码更少。
* 调用方法 U.UF.C.apply(this,'执行函数的事件')  例如 U.UF.C.apply(this,'this.style.display="none"');
*
* @param  {object} 将要绑定事件与属性的对象,如没有,可以传递null或者this,此处还需要优化,很多地方都会调用此函数,会导致速度降低。
* @param  {object} 函数与参数组成的数组。

案例:U.FC.C.apply(this,function(){});  //this用dialog做案例.
案例: U.FC.C.apply(element,function(){});
案例:U.FC.C.apply(element,function(){
//执行其他函数
});
*/
U.UF.C.apply = function (scope, fun) {
    //返回一个在指定域下执行的函数
    return function () {
        fun.call(scope || this);
    }
}


/*
解决给元素循环赋予事件及闭包的问题函数名称为:U.FC.C.closure
案例:U.FC.C.apply(element,function(){
//执行其他函数
});

//不用闭包的解决方法。
//当给元素循环赋予事件时,为了解决事件始终聚焦在最后一个元素的问题,可以采用闭包的写法,但毕竟复杂。
for(var i = 0;i<100;i++){
//使用闭包的写法
div[i].onclick=clickfun(i,div[i]);
}
function clickfun(j,el){
return function(){
el.style.backgroudcolor = '#000';
}  
}


//当给元素循环赋予事件时,为了解决事件始终聚焦在最后一个元素的问题,可以采用闭包的写法,但毕竟复杂。
for(var i = 0;i<100;i++){
//使用闭包的写法
div[i].onclick=function(j,el){
return function(){
div[j].style.backgroudcolor = '#000';
}  
}(i,div[i]);
}


//为了解决此问题,优化方案如下:
for(var i = 0;i<100;i++){
div[i].onclick =  U.FC.C.apply(i,div[i],clickfun);
}
function clickfun(j,el){
el.style.backgroudcolor = '#000';
}
*/
U.UF.C.closure = function (fun, parms) {
    //创建一个函数返回
    return function () {
        return fun.apply(this, parms)
    }
}


/**
* 获取 rgb颜色值
*
* @param  {array} 进行操作的对象 
* @return  {string} 确定循环范围 
*/
U.UF.C.getColorByRGB = function (style) {
    var i, //循环初始化
        _color = "#", //rgb颜色前缀
        _grbarr = style.match(U.UF.S.rgb); //判断颜色是不是rgb值
    //如果是rgb那么转化成#nnnnnn的值
    if (_grbarr) {
        for (i = 1; i < _grbarr.length; i++) {
            _color += ("0" + _grbarr[i].toInt().toString(16)).slice(-2); //转换的方式
        }
        return _color;
    }
    return style;
}

/**
* 获取url参数
*
* @param  {string}  QueryString key
* @param  {string}  QueryString 默认为window.document.location.search ,可以自己选择字符串进行拆分
* @return  {string}  获取key对应的值
*/
U.UF.C.queryString = function (key, search) {
    var _search = (search || window.document.location.search).substr(1);
    var i, j,
        _return = "",
        _valuearr, //网页传参 key和value组成的数组
        _arr = _search.split("&"); //生成传参数组
    for (i = 0; i < _arr.length; i++) { //循环传参数组获取值
        _valuearr = _arr[i].split("="); //把网页传参拆分
        if (_valuearr[0].toUpperCase() == key.toUpperCase()) { //判断key是否相等
            for (j = 1; j < _valuearr.length; j++) { //返回值
                _return += _valuearr[j] + (j == _valuearr.length - 1 ? "" : "="); //拼接返回值
            }
            break;
        }
    }
    return _return;
}

/**
* 获取地址hash
*
*/
U.UF.C.getUrlHash = function () {
    var _hash = document.location.hash; //地址传参
    return _hash.split("/");
}

/**
* 判断Url是否合法
*
* @param  {string} url值
* @return  {boolean} 是否盒饭的url
*/
U.UF.C.isUrl = function (str) {
    //获取参数
    var _str = str;
    //正则表达式字符串
    var _String = /http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/;
    //new 一个正则表达式
    var _objExp = new RegExp(_String);
    //正则表达式判断是否有http等合法标识
    if (_objExp.test(str) == true) {
        return true;
    } else {
        return false;
    }
}


/**
* 设置iframe同一个域,创建空iframe,在iframe中设置域名,等待iframe加载完回调。
*
* @param  {element} iframe
* @param  {string} 写入iframe的值
* @param  {function} 成功的回调函数
* @return  {element} 返回iframe
*/
U.UF.C.iframeSameDomain = function (iframe, htmlstr, cb) {
    //iframe设置onload事件的回调
    U.UF.DL.iframeLoad(iframe, function () {
        if (htmlstr) {
            iframe.contentWindow.document.body.innerHTML = htmlstr;
        }
        if (cb) {
            cb();
        }
    });
    //设置iframe的链接,这里设置的是空链接(空连接分为两种,一种是带domain有域名的,这种创建需要创建一个带域名的,第二种是没有域名的比如localhost或者f://1.html打开的页面)
    iframe.src = document.domain ? "javascript:void((function(){document.open();document.domain='" + document.domain + "';document.close()})())" : "about:blank"; //添加链接 "about:blank";
    return iframe;
}

/**
* url中文加密,用于ajax
*
* @param  {array} 需要加密的字符串数组 这个为url加密
* @return  {array} 返回加密成功的url数组
*/
U.UF.C.urlEncode = function (arr) {
    var i; //循环初始化
    for (i = 0; i < arr.length; i++) {
        arr[i] = encodeURIComponent(encodeURIComponent(arr[i]));
    }
    return arr.join(",");
}

/**
* 文字复制
*
*/
U.UF.C.copy = function () {
    if (window.clipboardData) { //ie
        window.clipboardData.setData("text", copystr);
    }
    else if (event && event.clipboardData) {//html5兼容
        event.clipboardData.setData("text/HTML", copystr);
    }
    else if (event && event.originalEvent && event.originalEvent.clipboardData) { //firfox兼容
        event.originalEvent.clipboardData("Text", copystr);
    }
    else if (document.execCommand) { //基本全兼容除了手机端的safari
        document.execCommand("copy");
        return document.execCommand("copy");
    }
    else {
        U.alert("请手动选择复制");
    }
}

/**
* 文字粘贴剪贴板
*
*/
U.UF.C.pasteText = function () {
    if (window.clipboardData) { //ie
        return window.clipboardData.getData("text");
    }
    else if (event.clipboardData) { //html5
        var _str = event.clipboardData.getData("text/HTML"); //获取带html的文本
        if (!_str) { //如果文本不存在,则通过纯文本获取
            _str = event.clipboardData.getData("text/plain").replaceAngleBrackets(); //从文本处理
        }
        return _str;
    }
    else if (event && event.originalEvent && event.originalEvent.clipboardData) { //firfox兼容
        return event.originalEvent.clipboardData("Text")
    }
    else if (document.execCommand) { //基本全兼容除了手机端的safari
        if (document.execCommand("paste") == true) {
            document.execCommand("paste");
            return document.execCommand("paste");
        } else {
            U.alert && U.alert("无法粘贴");
            return false;
        }
    }
    else {
        U.alert && U.alert("无法粘贴");
    }
}

/*
**作用:对元素在点击右键或者左键的时候,制定的菜单元素定位到鼠标点击的附近。
**@param {element} el     需要定位的右键菜单元素
*/
U.UF.C.rightClickMenuLocation = function (el) {
    //获取鼠标当前位置
    var _e = event || window.event, //获取事件源
        _elementposition = U.UF.EL.getElementPosition(el), //获取元素的位置
	    _getmousex = _e.clientX - _elementposition[1], //获取鼠标的X坐标
	    _getmousey = _e.clientY - _elementposition[0], //获取鼠标的Y坐标
        _eloffsetp = U.selectEl(el).Parent(), //获取需要定位的右键菜单元素的offsetParent
	    _ellocationw = el.offsetWidth, //获取定位的右键菜单元素的offsetWidth属性
	    _ellocationh = el.offsetHeight, //获取定位的右键菜单元素的offsetHeight属性
	    _eloffsetpw = _eloffsetp.offsetWidth, //获取元素offsetParent的offsetWidth属性
	    _eloffsetph = _eloffsetp.offsetHeight; //获取元素offsetparent的offsetHeight属性
    //判断top的最大范围
    if ((_ellocationw + _getmousex) > _eloffsetpw) {//如果定位元素的offsetWidth和鼠标X坐标的和大于元素offsetParent的offsetWidth
        _getmousex = _getmousex; // -_ellocationw; //则鼠标的X坐标为原先的鼠标X坐标减去定位元素的offsetWidth
    }
    else {
        _getmousex = _getmousex; //否则,鼠标的X坐标还是为原先的鼠标X坐标
    }
    //判断left的最大范围
    if ((_ellocationh + _getmousey) > _eloffsetph) {//如果定位元素的offsetHeight和鼠标X坐标的和大于元素offsetParent的offsetHeight
        _getmousey = _getmousey; // - _ellocationh; //则鼠标的Y坐标为原先的鼠标Y坐标减去定位元素的offsetHeight
    }
    else {
        _getmousey = _getmousey; //否则,鼠标的X坐标还是为原先的鼠标Y坐标
    }
    U.selectEl(el)[0].style.top = _getmousey + "px"; //添加右键菜单的top坐标
    U.selectEl(el)[0].style.left = _getmousex + "px"; //添加右键菜单的left坐标
    console.log('xzda');
}


/**
* 序列化json为字符串
*
* @param  {object 、 array} 需要序列化对象
* @returns {string} json为字符串 
注释:在写api时需要获取数据库返回值并转化为可识别字符串时经常用到。可精简名字,写成好的api
*/
U.UF.C.jsonToStr = function (o) {
    var r = [];
    if (typeof o == "string") {
        return "\"" + o.replace(/([\'\"\\])/g, "\\$1").replace(/(\n)/g, "\\n").replace(/(\r)/g, "\\r").replace(/(\t)/g, "\\t") + "\"";
    }
    if (typeof o == "object") {
        if (!o.sort) {
            for (var i in o) {
                r.push(i + ":" + U.UF.C.jsonToStr(o[i]));
            }
            if (!!document.all && !/^\n?function\s*toString\(\)\s*\{\n?\s*\[native code\]\n?\s*\}\n?\s*$/.test(o.toString)) {
                r.push("toString:" + o.toString.toString());
            }
            r = "{" + r.join() + "}";
        }
        else {
            for (var i = 0; i < o.length; i++) {
                r.push(U.UF.C.jsonToStr(o[i]));
            }
            r = "[" + r.join() + "]";
        }
        return r;
    }
    if (o == null) {
        return "null";
    }
    else { return o.toString(); }
}

/**
* 返回制定的对象类型名
*
* @param  {object} 需要判断的对象
* @return  {string} 返回object转化后的的
*/
U.UF.C.objectToString = function (obj) {
    return Object.prototype.toString.call(obj);
}

/**
* 监听用户是否断网
*
* @param  {function} 需要判断的对象
* @return  {boolean} 是否联网
*/
//U.UF.C.monitorInternet = function (fun) {
//    window.addEventListener("online", fun);
//    window.addEventListener("offline", fun);
//}

/**
* 错误函数控制台处理,,,解决ie的问题
*
* @param  {string} 输入控制台的类型 默认log
* @return  {object} 输出控制台的值
*/
U.UF.C.console = function (err) {
    try {
        //        console.log(err);
        return;
    }
    catch (e) { }
}

/**
* html加载,存储一篇文章,javascritp可以放在任何地方,当把文章追加到div等元素中时,由于没有刷新,导致javascript不能执行。需要把javascript重新移动到head头部才会加载。
*
* @param  {element} 任何html元素 
* @param  {string} 文章内容 
@return  返回文章内容
*/
U.UF.C.loadJs = function (el, htmlstr) {
    if (htmlstr != null) {
        el.innerHTML = htmlstr;
    }
    var i, //循环初始化
        _head = U.selectEl("head"),
        _scripts = U.selectEl("script", el); //获取script标签
    //循环把js的标签写入
    for (i = 0; i < _scripts.length; i++) {
        //uform.js就不重新加载了,因为可以调用到该函数说明uform.js还能正常使用
        if (_scripts[i].src) {
            U.UF.DL.asynLoadJs({ "src": _scripts[i].src });
        } else {
            //追加元素
            $$("script", { "type": _scripts[i].type || 'text/javascript' }, _head[0]).text = _scripts[i].text;
        }
    }
    return htmlstr;
}


/**
* 
*
* @param  {element} 任何html元素 
* @param  {string} 文章内容 
*/
U.UF.C.toJson = function (str) {
    var i,
        _json = str; //转化成字符串
    //如果传进来的值是字符串那么就转化成json
    if (U.UF.C.isString(str)) {
        _json = str.parseJSON();
    }
    if (Array.isArray(_json)) {
        //如果转成的json是arrayjson那么循环,看看有没有需要转化成json值得
        for (i = 0; i < _json.length; i++) {
            if (U.UF.C.isString(_json[i])) { //如果下标还是字符串的话,需要继续转化
                _json[i] = _json[i].parseJSON(); //字符串转化成json处理
            }
            else if (Array.isArray(_json[i])) { //如果是数组的处理
                U.UF.C.toJson(_json[i]);
            }
        }
    }
    //返回数据
    return _json;
}


/**
* 获取文字简写
*
* @param  {element、 string} 传入的对象或者文字
* @param  {number} 截图的长度
* @param  {string} 后缀的添加
*/
U.UF.C.getBriefText = function (el, length, str) {
    if (el.length > length) {
        var _el = U.UF.C.isString(el) ? $$("div", { "innerHTML": el }) : el; //截取的对象
        var _length = length || 200; //截取的长度
        var _str = str || ""; //省略号
        var _biretext = _el.innerText.substring(0, _length) + (_el.innerText._length > 200 ? _str : "") + str; //得到缩写加省略号
        return _biretext;
    }
    return el;
}

/**
* 禁止元素选择文字
*
*/
U.UF.C.shieldedSelect = function () {
    var _editel = U.UF.EL.getAncestorEditElement(event.srcElement); //获取一个可编辑元素
    //如果是可编辑元素,那么不禁止元素可选择
    if (_editel && (_editel.nodeType == 3 || _editel.contentEditable == "true" ||
                    "textarea,input".indexOf(_editel.tagName.toLocaleLowerCase()))) {
        return true;
    }
    U.UF.EV.stopBubble(); //取消冒泡
    U.UF.EV.stopDefault(); //取消浏览器默认行为
    return false; //禁止右键菜单
}

/**
* 禁止页面点击backspace键的时候整个网页回退
*
*/
U.UF.C.shieldedBackspace = function () {
    if (event.keyCode == 8) { //不允许按下后台键
        //如果按下回车键的区域不在可编辑区内,那么可能会发生网页回退,这里判断如果非可编辑区域,直接阻止出发backspace
        if (U.UF.EL.getAncestorEditElement((event.srcElement)) == document.body && !document.body.isContentEditable) {
            U.UF.EV.stopDefault();
        }
    }
}

/**
* 判断是否为对象
*
* @param   {object} 判断对象是否为object对象
* @return  {boolean} 是否为FormData
*/
U.UF.C.isObject = function (obj) {
    return (typeof obj == "object" && obj !== null);
}

/**
* 判断是否为数字
*
* @param  {array} 判断数组是否有值
* @return  {boolean} 是否为number
*/
U.UF.C.isNumber = function (obj) {
    return typeof obj == "number";
}

/**
* 判断是否为字符串
*
* @param  {string} 判断的字符串
* @return  {boolean} 是否为字符串
*/
U.UF.C.isString = function (str) {
    return typeof str == "string"
}

/**
* 判断是否为函数类型
*
* @param  {function} 函数值
* @return  {boolean} 函数对象值
*/
U.UF.C.isFunction = function (fun) {
    var _isfun = typeof fun == "function"; //直接通过类型判断是否为函数
    var _isobjfun = U.UF.C.objectToString(fun) == "[object Function]";   //通过对象名判断是否为函数
    return _isfun || _isobjfun;  //只要二者符合其一即为函数  且返回判断结果
}

/**
* 判断是否为元素,用于在窗体中判断用户传入的是字符串还是元素
*
* @param  {element} 元素
* @return  {boolean} 返回是否为元素 同时不为文本元素
*/
U.UF.C.isElement = function (el) {
    return el != null && el.nodeType != null;
}

/**   
* 该函数存在问题 但由于多处使用暂不删除
* 函数的作用是给已有的集合添加新的属性。
*说明:此函数代替U.Json中的Add方法,以避免调试难调,速度降低的问题
* @param  {object} U.UF.CD的自定义变量或者Array,Object等系统变量
* @param  {object} 属性的集合,形如:{ "domain": "1473.cn", "SystemId": 0}
*/
U.UF.C.AddObj = function (obj1, obj2) {
    for (var i in obj2) {
        if (obj2.hasOwnProperty(i)) {
            obj1[i] = obj2[i];
        }
    }
    return obj2;
}

//计算文件大小,小于1024用B,大于1024用KB,大于1024*1024用MB,大于1024*1024*1024用GB
//参数一:  整形,文件大小.
//返回值:字符串,小于1024用B,大于1024用KB,大于1024*1024用MB,大于1024*1024*1024用GB
U.UF.C.computeFileSize = function (size) {
    var _s; //返回的文件大小
    if (size > 1024) {
        if (size / 1024 > 1024) {
            if (size / (1024 * 1024) > 1024) {
                _s = (size / (1024 * 1024 * 1024)).toFixed(2) + 'GB'; //返回GB
            }
            else {
                _s = (size / (1024 * 1024)).toFixed(2) + 'MB'; //返回MB
            }
        }
        else {
            _s = (size / 1024).toFixed(2) + 'KB'; //返回KB
        }
    }
    else {
        _s = size.toFixed(2) + 'B'; //返回B
    }
    return _s;
}

/*移除危险标签*/
U.UF.C.filterTag = function () {

}