/**
 * 获取url参数
 * @param key
 */
window.location.getParam = function (key) {
    var reg = new RegExp("(^|&)" + key + "=([^&]*)(&|$)");
    var r = window.location.search.substr(1).match(reg);
    if (r != null) {
        return decodeURIComponent(r[2]);
    }
    return null;
}
/**
 * 打开新标签
 * @param url
 */
window.location.open = function (url) {
    $("body").append($("<a id='wb-open' href='" + url + "' target='_blank' style='display:none;'></a>"))
    document.getElementById("wb-open").click();
    $("#wb-open").remove();
}
/**
 * 日期格式化
 */
Date.prototype.format = function (format) {
    var o = {
        "M+": this.getMonth() + 1, //month
        "d+": this.getDate(),    //day
        "h+": this.getHours(),   //hour
        "m+": this.getMinutes(), //minute
        "s+": this.getSeconds(), //second
        "q+": Math.floor((this.getMonth() + 3) / 3),  //quarter
        "S": this.getMilliseconds() //millisecond
    }
    if (/(y+)/.test(format)) format = format.replace(RegExp.$1,
        (this.getFullYear() + "").substr(4 - RegExp.$1.length));
    for (var k in o)if (new RegExp("(" + k + ")").test(format))
        format = format.replace(RegExp.$1,
            RegExp.$1.length == 1 ? o[k] :
                ("00" + o[k]).substr(("" + o[k]).length));
    return format;
};
/**
 * 数组移除
 */
Array.prototype.remove = function (val) {
    var index = this.indexOf(val);
    if (index > -1) {
        this.splice(index, 1);
    }
};
/**
 * 数组替换
 */
Array.prototype.replace = function (val, obj) {
    var index = this.indexOf(val);
    if (index > -1) {
        this.splice(index, 1, obj);
    }
};
/**
 * 数组位置调整
 */
Array.prototype.exchange = function (val1, val2) {
    if (val1 < 0 || val2 < 0 || val2 >= this.length || val1 >= this.length) {
        return;
    }
    var o1 = this[val1];
    var o2 = this[val2];
    this.splice(val1, 1, o2);
    this.splice(val2, 1, o1);
};
/**
 * 数组异步循环
 * fun(item,next) 处理函数
 * finish()       处理完成函数
 */
Array.prototype.forAsync = function (callBack, finish) {
    var this_ = this;
    (function loop(index) {
        if (index < this_.length) {
            callBack(this_[index], function () {
                loop(++index)
            })
        } else if (typeof finish === 'function') {
            finish();
        }
    })(0)
};
/**
 * 自定义Map对象
 */
function Map() {
    this.keys = [];
    this.values = [];
    this.put = function (key, value) {
        var index = this.keys.indexOf(key);
        if (index > -1) {
            this.values.splice(index, 1, value)
        } else {
            this.keys.push(key);
            this.values.push(value);
        }
    }
    this.remove = function (key) {
        var index = this.keys.indexOf(key);
        if (index > -1) {
            this.keys.splice(index, 1);
            this.values.splice(index, 1);
        }
    }
    this.size = function () {
        return this.keys.length;
    }
    this.isEmpty = function () {
        return this.keys.length < 1;
    }
    this.clear = function () {
        this.keys = [];
        this.values = [];
    }
    this.get = function (key) {
        var index = this.keys.indexOf(key);
        if (index > -1) {
            return this.values[index];
        } else {
            return null;
        }
    }
    this.forEach = function (callBack) {
        for (var i = 0; i < this.keys.length; i++) {
            callBack(this.keys[i], this.values[i]);
        }
    }
    this.forAsync = function (callBack, finish) {
        var this_ = this;
        (function loop(index) {
            if (index < this_.keys.length) {
                callBack(this_.keys[index], this_.values[index], function () {
                    loop(++index)
                })
            } else if (typeof finish === 'function') {
                finish();
            }
        })(0)
    }
    this.containsKey = function (key) {
        return this.keys.indexOf(key) !== -1
    }
    this.containsValue = function (value) {
        return this.values.indexOf(value) !== -1
    }
    this.getKeys = function () {
        return this.keys.slice(0, this.keys.length);
    }
    this.getValues = function () {
        return this.values.slice(0, this.values.length);
    };
};
window.utils = {
    /**
     * 隐藏文件选择器
     *
     * @param cb 回调函数
     */
    selectFile: function (cb) {
        var input = document.createElement('input');
        input.style.display = 'none';
        input.type = "file";
        document.body.appendChild(input);
        input.dispatchEvent(new MouseEvent('click'));
        input.onchange = function (ev) {
            cb(ev.target.files);
            document.body.removeChild(input);
        }
    },
    /**
     * Blob二进制文件异步下载
     *
     * @param name 文件名
     * @param blob 二进制文件
     */
    blobtoDown: function (name, blob) {
        var url = window.URL.createObjectURL(blob);
        var link = document.createElement('a');
        link.style.display = 'none';
        link.href = url;
        link.setAttribute('download', name);
        document.body.appendChild(link);
        link.dispatchEvent(new MouseEvent('click'));
        document.body.removeChild(link);
    },
    /**
     * base64转为String
     *
     * @param base64 base64字符串
     * @returns {string} 字符串
     */
    base64toString: function (base64) {
        return window.atob(base64);
    },
    /**
     * String转为base64
     *
     * @param base64 base64字符串
     * @returns {string} 字符串
     */
    stringtoBase64: function (str) {
        return window.btoa(str);
    },
    /**
     * base64转为字节数组
     *
     * @param base64 base64字符串
     * @returns {string} 字节数组
     */
    base64toBytes: function (base64) {
        var str = window.atob(base64);
        var len = str.length;
        var bytes = new Int8Array(len);
        for (var i = 0; i < len; i++) {
            bytes[i] = str.charCodeAt(i);
        }
        return bytes;
    },
    /**
     *
     * @param base64
     * @returns {Int8Array}
     */
    base64toBlob: function (base64) {
        return new Blob(this.base64toBytes(base64));
    },
    isEmpty: function(val){
        return val === '' || typeof val === 'undefined' || val === null;
    },
    /**
     * 动态加载Js或css文件
     * @param url 文件http地址
     */
    loadJsCss: function(url){
        var node_;
        if (url.match(/\\.js$/i)) {
            node_ = document.createElement('script');
            node_.setAttribute("type", "text/javascript");
            node_.setAttribute("src", url);
        } else if (url.match(/\\.css$/i)) {
            node_ = document.createElement('link');
            node_.setAttribute("rel", "stylesheet");
            node_.setAttribute("type", "text/css");
            node_.setAttribute("href", url);
        }
        if (node_) {
            document.getElementsByTagName("head")[0].appendChild(node_);
        } else {
            console.error("load " + url + " method error!");
        }
    },
    /**
     * 深拷贝对象
     * @param obj
     */
    copy: function(obj){
        return JSON.parse(JSON.stringify(obj));
    }
}