
(function (F) {

    /**
    * fetion.utils 名字空间<br/><br/>
    * 
    * @namespace
    * @name utils
    * @type Object
    * @description 引用方式 var utils=require('fetion/utils');
    */
    var utils = F.utils = F.utils || {};


    /**
    * 对一个字符串进行多次replace。
    * @memberOf utils
    * @private
    * @function multiReplace
    * @param {String} 需要处理的字符串
    * @param {Array} 数组，每一个元素都是由replace两个参数组成的数组
    * @returns {String} 返回处理后的字符串
    * @description from QWrap
    */

    function multiReplace(str, arr) {
        for (var i = 0; i < arr.length; i++) {
            str = str.replace(arr[i][0], arr[i][1]);
        }
        return str;
    }

    /**
    * 是飞信号吗。
    * @memberOf utils
    * @static
    * @function isFetionID
    * @param {String} obj 字符串
    * @returns {Boolean}
    */
    utils.isFetionID = function (str) {
        /// <summary>
        /// 是飞信号吗
        /// </summary>
        /// <param name="str">字符串</param>
        /// <returns type="boolean"></returns>
        return /^\d{1,10}$/.test(str);
    };

    /**
    * 是手机号吗。
    * @memberOf utils
    * @static
    * @function isMobileNO
    * @param {String} obj 字符串
    * @returns {Boolean}
    */
    utils.isMobileNO = function (str) {
        return /^1(30|31|32|33|34|35|36|37|38|39|47|50|51|52|53|55|56|57|58|59|82|83|87|88|85|86|80|89)[\d]{8}$/.test(str);
    };

    /**
    * 是中国移动手机号吗。
    * @memberOf utils
    * @static
    * @function isChinaMobileNO
    * @param {String} obj 字符串
    * @returns {Boolean}
    */
    utils.isChinaMobileNO = function (str) {
        return /^1(34|35|36|37|38|39|47|50|51|52|57|58|59|82|83|87|88)[\d]{8}$/.test(str);
    };

    /**
    * 是UT手机号吗。
    * @memberOf utils
    * @static
    * @function isUTMobileNO
    * @param {String} obj 字符串
    * @returns {Boolean}
    */
    utils.isUTMobileNO = function (str) {
        return /^1(30|31|32|33|53|55|56|80|85|86|89)[\d]{8}$/.test(str);
    };

    /**
    * 是中国联通手机号吗。
    * @memberOf utils
    * @static
    * @function isUnicomMobileNO
    * @param {String} obj 字符串
    * @returns {Boolean}
    */
    utils.isUnicomMobileNO = function (str) {
        return /^1(30|31|32|55|56|85|86|)[\d]{8}$/.test(str);
    };

    /**
    * 是中国电信手机号吗。
    * @memberOf utils
    * @static
    * @function isCHAMobileNO
    * @param {String} obj 字符串
    * @returns {Boolean}
    */
    utils.isCHAMobileNO = function (str) {
        return /^1(33|53|80|89)[\d]{8}$/.test(str);
    };

    /**
    * 是TXL手机号吗。
    * @memberOf utils
    * @static
    * @function isTXLMobileNO
    * @param {String} obj 字符串
    * @returns {Boolean}
    */
    utils.isTXLMobileNO = function (str) {
        return /^(\+86)?1(34|35|36|37|38|39|47|50|51|52|57|58|59|82|83|87|88|30|31|32|55|56|85|86|33|53|80|89)[\d]{8}$/.test(str);
    };

    /**
    * 是邮箱吗。
    * @memberOf utils
    * @static
    * @function isEmail
    * @param {String} obj 字符串
    * @returns {Boolean}
    */
    utils.isEmail = function (str) {
        return /^([\w]+[-|_|\_|\.]?)*[\w]+@([\w]+[-|_|\_|\.]?)*[\w]+\.[a-zA-Z]{2,3}$/.test(str);
    };

    /**
    * 是有效的飞信密码吗。
    * @memberOf utils
    * @static
    * @function isValidFetionPwd
    * @param {String} obj 字符串
    * @returns {Boolean}
    */
    utils.isValidFetionPwd = function (str) {
        return 6 <= str.length && str.length <= 16;
    };

    /**
    * 是短信在线吗。
    * @memberOf utils
    * @static
    * @function isSmsOnline
    * @param {String} obj 联系人的sms属性
    * @returns {Boolean}
    */
    utils.isSmsOnline = function (str) {
        return /^0+.0+:0+:0+$/.test(str);
    };

    /**
    * 为Html字符串转码。
    * @memberOf utils
    * @static
    * @function encode4Html
    * @param {String} obj 字符串
    * @returns {String} 转码后的字符串
    */
    utils.encode4Html = function (str) {
        var pre = document.createElement('pre'),
            text = document.createTextNode(str);

        pre.appendChild(text);

        return pre.innerHTML;
    };

    /**
    * 为Html转码后的字符串解码。
    * @memberOf utils
    * @static
    * @function decode4Html
    * @param {String} obj 字符串
    * @returns {String} 解码后的字符串
    */
    utils.decode4Html = function (str) {
        var div = document.createElement('div');

        div.innerHTML = str.replace(/<[^>]*>/gi, '');

        return div.childNodes[0] ?
            div.childNodes[0].nodeValue || '' :
            '';
    };

    /**
    * 根据 name 从 url的search 中获取参数值。
    * @memberOf utils
    * @static
    * @function queryString
    * @param {String} search url的search
    * @param {String} name 参数名
    * @returns {String} 参数值
    */
    utils.queryString = function (search, name) {
        var re = new RegExp("[\?\&]?" + name + "=([^\&]+)", "i"),
            result = search.match(re);

        if (result == null || result.length < 1) {
            return "";
        }
        return result[1];
    };

    /**
    * 将一个QueryString转化成一个key/value的Object。
    * @memberOf utils
    * @static
    * @function objects
    * @param {String} queryStr url的search
    * @returns {String} 参数值
    */
    utils.objects = function (queryStr) {
        var obj = new Object();
        var re = /[\?\&]?([^=^\&]+)=([^\&]+)/i;

        var querys = queryStr.split("&");
        for (var k = 0; k < querys.length; k++) {
            var result = querys[k].match(re);
            if (result == null) {
                continue;
            }

            var length = result.length;
            if (result != null) {
                for (var i = 1; i < length; i += 2) {
                    if (i + 1 < length) {
                        obj[result[i]] = result[i + 1];
                    } else {
                        obj[result[i]] = "";
                    }
                }
            }
        }

        return obj;
    };

    /**
    * 停止事件冒泡。
    * @memberOf utils
    * @static
    * @function stopPropagation
    * @param {Event} e 事件
    */
    utils.stopPropagation = function (e) {
        e = window.event || e;

        if (window.event) {
            e.cancelBubble = true;
        } else {
            e.stopPropagation();
        }
    };

    /**
    * 阻止默认浏览器动作。
    * @memberOf utils
    * @static
    * @function preventDefault
    * @param {Event} e 事件
    */
    utils.preventDefault = function (e) {
        // 如果提供了事件对象，则这是一个非IE浏览器 
        if (e && e.preventDefault) {
            e.preventDefault(); // 阻止默认浏览器动作(W3C)
        } else {
            // IE中阻止函数器默认动作的方式 
            window.event.returnValue = false;
        }
        return false;
    };


    /** 
    * 格式化字符串模版
    * @method contains
    * @param {String} template 字符串模版
    * @return {String} 处理后的字符串
    * @example String.format('hi, {0}, this is {1}.', 'jone', 'example')
    */
    String.format = function (template) {
        if (arguments.length > 0) {
            var args = Array.prototype.slice.call(arguments, 1);

            return template.replace(/\{(\d+)\}/g, function (m, i) {
                return args[i];
            });
        }
        return null;
    };

    /** 
    * 是否是非空字符串
    * @method contains
    * @param {String} str 字符串
    * @return {Boolean} 是否非空
    * @example String.nonempty('string')
    */
    String.nonempty = function (str) {
        return typeof str === 'string' && str.trim().length > 0;
    };

    /** 
    * 计算字节长度（中文和全角等字符算2个长度）
    * @method contains
    * @param {String} str 字符串
    * @return {Int} 字符串长度
    * @example String.nonempty('string')
    */
    String.byteLen = function (str) {
        return str.replace(/[^\x00-\xff]/g, "--").length;
    };

    /** 
    * 按字节长度取目标字符串的一部分
    * @method contains
    * @param {String} str 需要处理的字符串
    * @param {String} str 需要处理的字符串
    * @param {String} str 需要处理的字符串
    * @return {Boolean} 返回转化后的字符串
    * @example String.dbc2sbc("发票号是ＢＢＣ１２３４５６，发票金额是１２.３５元")
    */
    String.subByte = function (str, len, tail) {
        if (len < 0 || String.byteLen(str) <= len) {
            return str;
        }

        tail = tail || '';
        len -= String.byteLen(tail);

        return str.substr(0, len)
            .replace(/([^\x00-\xff])/g, "$1 ") // 双字节字符替换成两个
            .substr(0, len) // 截取长度
            .replace(/[^\x00-\xff]$/, "") // 去掉临界双字节字符
            .replace(/([^\x00-\xff]) /g, "$1") + tail; // 还原
    };

    /** 
    * 全角字符转半角字符
    * 全角空格为12288，转化成" "；
    * 全角句号为12290，转化成"."；
    * 其他字符半角(33-126)与全角(65281-65374)的对应关系是：均相差65248。
    * @method contains
    * @param {String} str 需要处理的字符串
    * @return {Boolean} 返回转化后的字符串
    * @example String.dbc2sbc("发票号是ＢＢＣ１２３４５６，发票金额是１２.３５元")
    */
    String.dbc2sbc = function (str) {
        return multiReplace(str, [
            [/[\uff01-\uff5e]/g, function (a) {
                return String.fromCharCode(a.charCodeAt(0) - 65248);
            } ],
            [/\u3000/g, ' '],
            [/\u3002/g, '.']
        ]);
    };

    /** 
    * 是否以 str 开头
    * @method contains
    * @param {String} str 开头字符串
    * @return {Boolean} 
    * @example 'equal'.startWith('al')
    */
    String.prototype.startWith = function (str) {
        return String.nonempty(str) &&
            (this.length > str.length) &&
            (this.substr(0, str.length) == str);
    };

    /** 
    * 是否以 str 结尾
    * @method contains
    * @param {String} str 结尾字符串
    * @return {Boolean} 
    * @example 'equal'.endWith('al')
    */
    String.prototype.endWith = function (str) {
        return String.nonempty(str) &&
            (this.length > str.length) &&
            (this.substr(this.length - str.length) == str);
    };

    /** 
    * 移除开头和结尾的 str
    * @method contains
    * @param {String} str 字符串
    * @return {String} 
    * @example 'equal'.trim('al')
    */
    String.prototype.trim = function (str) {
        var regExp;
        if (utils.isString(str)) {
            regExp = new RegExp("^[" + str + "]+|[" + str + "]+$", "g");
        } else {
            regExp = /^\s+|\s+$/g;
        }
        return this.replace(regExp, "");
    };

    /** 
    * 移除结尾的 str
    * @method contains
    * @param {String} str 结尾字符串
    * @return {String} 
    * @example 'equal'.trimEnd('al')
    */
    String.prototype.trimEnd = function (str) {
        var regExp;
        if (utils.isString(str)) {
            regExp = new RegExp("[" + c + "]+$", "g");
        } else {
            regExp = /\s+$/g;
        }
        return this.replace(regExp, "");
    };

    /** 
    * 转换为Unicode编码的数组
    * @method contains
    * @param {String} str Unicode编码的数组
    * @return {Array} 
    * @example var codeArr = 'equal'.toCodeArray()
    */
    String.prototype.toCodeArray = function () {
        var len = this.length,
            codeArray = new Array();

        for (var i = 0; i < len; i++) {
            codeArray.push(this.charCodeAt(i));
        }
        return codeArray;
    };

    /** 
    * 将Unicode编码的数组转换为当前字符串
    * @method contains
    * @param {String} str Unicode编码的数组
    * @return {String} 
    * @example 'equal'.fromCodeArray([115,34])
    */
    String.prototype.fromCodeArray = function (codeArray) {
        var i = 0,
            len = codeArray.length,
            str = "";

        for (; i < len; i++) {
            str += String.fromCharCode(codeArray[i]);
        }
        return str;
    };

    /** 
    * 判断当前字符串是否包含目标字符串
    * @method contains
    * @param {String} str 目标字符串
    * @return {Boolean} 
    * @example "abcdefg".contains("ab"))
    */
    String.prototype.contains = function (str) {
        return this.indexOf(str) != -1;
    };


})(this.fetion)