/**
 * @author 何秀刚
 * @description wechat 工具类,依赖JQuery，如果引入此文件，自动绑定分享事件。
 * @version V.1.1
 */
// 获取绑定微信JSSDK的配置参数 
var getConfigUrl = "http://w.iamberry.com/watero/config/get";
var jssdkSuccess = true;
var isInitialize = false;

// 为字符串对象添加属性
if (typeof String.prototype.startsWith != 'function') {
    String.prototype.startsWith = function (prefix){
        return this.slice(0, prefix.length) === prefix;
    };
}

if (window.hiddenAllWechatMenu == null) {
    window.hiddenAllWechatMenu = false;
}
window.wxFriend = null;
if (window.repleFlag) {
    window.wxFriend = window.repleWxData;
} else {
    window.wxFriend = {
        "appId": "",
        "imgUrl":'http://m.iamberry.com/common/goods/images/indexShare.jpg',
        "link":"http://www.iamberry.com/ratfw/index",
        "desc":"这里是分享描述",
        "title":"这里是分享标题",
        "netError":"您的网络异常，请刷新重试!如多次刷新无效，请向我们反应 ~",
        "shareTimeSuccess":"这里是分享朋友圈后调用的文字",
        "shareTimeCancel":"这里是取消分享给朋友圈后调用的文字",
        "shareAppSuccess":"这里是分享好友后调用的文字",
        "shareAppCancel":"这里是取消分享给好友后调用的文字"
    };
}
// 微信共享地址数据
window.wechatAddr = {
    "status":false, // 是否调用成功，true成功，false失败
    "statusMsg":"失败时信息",
    "detailInfo":"详细地址",
    "postalCode":"邮编",
    "userName":"收货人",
    "userTel":"收货人电话",
    "nationalCode":"收货地址国家码"
};
incoldeJSFile("http://res.wx.qq.com/open/js/jweixin-1.1.0.js");
getConfig();

/** 获取服务器JSSDK参数配置 */
function getConfig(){
    $.ajax({
        type: 'get', url: getConfigUrl, data: {appid: "", url: location.href,"date":new Date().getTime()}, dataType: 'json', timeout: 10000, context: $('body'),
        success: function(data){setConfig(data);},
        error: function(xhr, type){getConfig();}
    });
}

/**配置JS-SDK*/
function setConfig(config){
    // 调用微信硬件平台JSSDK，需要传入beta字段
    wx.config({
        debug: false,
        beta:true,
        appId: config.appId,
        timestamp: config.timestamp,
        nonceStr: config.nonceStr,
        signature: config.signature,
        jsApiList: [
            'checkJsApi',
            'scanQRCode',
            'onMenuShareTimeline',
            'onMenuShareAppMessage',
            'hideMenuItems',
            'showMenuItems',
            "openWXDeviceLib",
            "closeWXDeviceLib",
            "getWXDeviceInfos",
            "sendDataToWXDevice",
            "startScanWXDevice",
            "stopScanWXDevice",
            "connectWXDevice",
            "disconnectWXDevice",
            "getWXDeviceTicket",
            "onWXDeviceBindStateChange",
            "onWXDeviceStateChange",
            "onReceiveDataFromWXDevice",
            "onScanWXDeviceResult",
            "onWXDeviceBluetoothStateChange"
        ]
    });
    wx.ready(function(){
        //JSSDK绑定成功
        wxReadySuccess();
    });
    wx.error(function(res){
        // JSSDK绑定失败的方法
        wxReadyError();
    });
}

function wxReadySuccess() {
    window.jssdkSuccess = true;
    shareMessage();
    wx.getNetworkType({success: function (res) {}});
    // 初始化微信硬件的库
    wx.invoke('openWXDeviceLib', {'brandUserName':'gh_2674097b2442','connType':'blue'}, function(res) {
        isInitialize = true;
        if (res.bluetoothState != "on") {
            mui.alert("请打开蓝牙或者授予微信访问蓝牙的权限!");
            isInitialize = false;
        } else {
            if (res.err_msg != "openWXDeviceLib:ok") {
                mui.alert("初始化蓝牙失败，请刷新重试!!");
                isInitialize = false;
            }
        }
        console.log('openWXDeviceLib',res);
    });
    // 右上角菜单
    if (window.hiddenAllWechatMenu) {
        wx.showMenuItems({
            menuList: []
        });
        wx.hideMenuItems({
            menuList: [
                "menuItem:copyUrl",
                "menuItem:openWithSafari",
                "menuItem:originPage",
                "menuItem:share:email",
                "menuItem:dayMode",
                "menuItem:setFont",
                "menuItem:nightMode",
                "menuItem:share:qq",
                "menuItem:dayMode",
                "menuItem:exposeArticle",
                "menuItem:nightMode",
                "menuItem:openWithQQBrowser",
                "menuItem:share:QZone",
                "menuItem:favorite",
                "menuItem:share:facebook",
                "menuItem:share:appMessage",
                "menuItem:share:timeline"
            ]
        });
    } else {
        wx.showMenuItems({
            menuList: [
                "menuItem:share:appMessage",
                "menuItem:share:timeline"
            ]
        });
        wx.hideMenuItems({
            menuList: [
                "menuItem:copyUrl",
                "menuItem:openWithSafari",
                "menuItem:originPage",
                "menuItem:share:email",
                "menuItem:dayMode",
                "menuItem:setFont",
                "menuItem:nightMode",
                "menuItem:share:qq",
                "menuItem:dayMode",
                "menuItem:exposeArticle",
                "menuItem:nightMode",
                "menuItem:openWithQQBrowser",
                "menuItem:share:QZone",
                "menuItem:favorite",
                "menuItem:share:facebook"
            ]
        });
    }
};
function wxReadyError() {};

/** 分享时、分享后调用方法 */
function shareMessage(title, message) {
    title = title || wxFriend.title;
    message = message || wxFriend.desc;
    wx.onMenuShareTimeline({ //分享到朋友圈,只有标题、图标，没有内容简介
        title: title, link: wxFriend.link, imgUrl: wxFriend.imgUrl,
        success: function () {
            if (wxFriend.shareAppSuccess != null && wxFriend.shareAppSuccess != "") {}
        },
        cancel: function () {
            if (wxFriend.shareTimeCancel != null && wxFriend.shareTimeCancel != "") {}
        }
    });
    wx.onMenuShareAppMessage({ // 分享给好友，有标题、内容简介、图标
        title: title, desc: message, link: wxFriend.link, imgUrl: wxFriend.imgUrl,
        success: function () {
            if (wxFriend.shareAppSuccess != null && wxFriend.shareAppSuccess != "") {}
        },
        cancel: function () {
            if (wxFriend.shareTimeCancel != null && wxFriend.shareTimeCancel != "") {}
        }
    });
}

function wechatPay(str, paySuccessCallBack, payCancelCallBack) {
    if (typeof WeixinJSBridge == "undefined"){
        mui.alert("非微信浏览器！无法发起微信支付请求!");
        return;
    }
    var obj = JSON.parse("{" + str + "}");
    WeixinJSBridge.invoke('getBrandWCPayRequest', obj, function(res) {
        if(res.err_msg=='get_brand_wcpay_request:ok'){
            paySuccessCallBack;
        }else{
            payCancelCallBack;
        }
    });
}
if (typeof WeixinJSBridge == "undefined"){
    if( document.addEventListener ){
        document.addEventListener('WeixinJSBridgeReady', wechatPay, false);
    }else if (document.attachEvent){
        document.attachEvent('WeixinJSBridgeReady', wechatPay);
        document.attachEvent('onWeixinJSBridgeReady', wechatPay);
    }
}

function editAddrV1(successCallback, errorCallback) {
    if (!window.jssdkSuccess) {
        mui.alert("错误啦 ~~ 请刷新重试!");
        return;
    }
    wx.openAddress({
        success: successCallback,
        cancel: errorCallback
    });
}
function incoldeJSFile(jsUrl) {
    var typeHand = document.getElementsByTagName('head').item(0);
    var typeScript= document.createElement("script");
    typeScript.type = "text/javascript";
    typeScript.src=jsUrl;
    typeHand.appendChild(typeScript);
}

// ----------------------------------------------------------微信硬件相关方法
/**
 * 连接设备
 * @param deviceId		机器的id
 * @param connCallback	当连接成功时回调此方法,并传入deviceId
 * @returns
 */
function connectDevice(deviceId, connCallback) {

    if (!window.jssdkSuccess) {
        mui.alert("错误啦 ~~ 请刷新重试!");
        return;
    }
    wx.invoke('connectWXDevice', {'deviceId':deviceId, 'connType':'blue'}, function(res) {
        mui.alert("connect:" + JSON.stringify(res));
        if (res.err_msg != "connectWXDevice:ok") {
            mui.alert("连接失败，请刷新重试!");
            return;
        } else {
            // 如果连接成功，那么注册监听事件
            WeixinJSBridge.on('onWXDeviceStateChange', function(argv) {
                console.log("onWXDeviceStateChange", argv);
                connCallback(argv);
            });
        }
    });
}

/**
 * 获取设备状态
 * @param deviceId
 * @param callback	回调方法，传入为1表示机器在线，否则不在线
 * @returns
 */
function deviceState(deviceId, callback) {
    WeixinJSBridge.invoke('getWXDeviceInfos', {}, function(res){
        var len=res.deviceInfos.length;  //绑定设备总数量
        if (len <= 0) {
            // 没有机器
            callback(0);
            return;
        }
        for(i = 0; i < len; i ++) {
            if(res.deviceInfos[i].state==="connected" && res.deviceInfos[i].deviceId == deviceId) {
                callback(1);
                return;
            }
        }
        callback(0);
    });
}

/**
 * 发送信息给设备
 * @param deviceId	设置id
 * @param msg		base64转码后的数据
 * @param callbackFun	回调方法，如果发送成功，返回1，失败则返回2
 * @returns
 */
function sendMsgToDevice(deviceId, msg, callbackFun) {
    wx.invoke('sendDataToWXDevice', {'deviceId':deviceId, 'connType':'blue', 'base64Data':msg}, function(res) {
        mui.alert("返回:" + JSON.stringify(res));
        if (res.err_msg == "sendDataToWXDevice:ok") {
            callbackFun(1);
        } else {
            callbackFun(2);
        }
    });
};

/**
 * 扫描二维码
 * @returns
 */
function scanQrcode() {
    wx.scanQRCode({
        needResult: 0, // 默认为0，扫描结果由微信处理，1则直接返回扫描结果，
        scanType: ["qrCode"],
        success: function (res) {}
    });
}

/**
 * 发送信息给设备，并且等待接收设备消息, 注意：调用此方法时，需要自己过滤返回信息
 * @param deviceId
 * @param msg
 * @param callback
 * @returns
 */
function sendMsgAndReceiveData(deviceId, msg, callback) {
    // 第一条数据，均是设置数据方向：HTML
    var defaultCommand = "*setDir2#";
    // 改变数据方向
    wx.invoke('sendDataToWXDevice', {'deviceId':deviceId, 'connType':'blue', 'base64Data':base64encode(defaultCommand)}, function(res) {
    	if (res.err_msg != "sendDataToWXDevice:ok") {
            callback(500, null);
            return;
        }
        // 发送真实数据
        wx.invoke('sendDataToWXDevice', {'deviceId':deviceId, 'connType':'blue', 'base64Data':base64encode(msg)}, function(res) {
            if (res.err_msg == "sendDataToWXDevice:ok") {
                // 注册监听
                wx.on('onReceiveDataFromWXDevice',function(res){
                    // 回调
                    var r = base64decode(res.base64Data);
                    if (r.startsWith("getData")) {
                        callback(200, r.replace("getData", ""));
                    } else if (r.startsWith("err")) {
                        callback(501, r.replace("err", ""));
                    } else if (r.startsWith("isUse")) {
                            // 获取数据成功
                            callback(200, r.replace("isUse", ""));
                        } else {
                            // 机器故障,501回传故障码
                            callback(501, arr[2]);
                        }
                });
                // 改变数据方向 ： 设置为服务器
                wx.invoke('sendDataToWXDevice',
                    {'deviceId':deviceId, 'connType':'blue', 'base64Data':base64encode("*setDir0#")}, function(u) {});
            } else {
                // 发送失败,可能是蓝牙未打开、或者机器不在线
                callback(500, null);
            }
        });
    });
}

//!!!!!!需要确认测试的是，H5接受以后，后台是否还能接受到？
/**
 * 接受数据的方法，等待回调
 */
function receiveData(callbackFun) {
    //接收到设备传来的数据
    wx.on('onReceiveDataFromWXDevice',function(res){
        callbackFun(res);
    });
}

//!!!!!!需要确认测试的，当H5发起绑定关系以后，后台是否能够接受到本次的事件？
var startScan = 1;// 1:已经开始扫描；2：为开始
function scanDevice() {
    // 如果方法已经启动，那么调用无效
    if (startScan != 2) {
        return;
    }
    // 开始扫描15秒
    timeId = setInterval(function(){
        if (time == 15) {
            // 注销定时器
            window.clearInterval(timeId);

            // 停止扫描
            wx.invoke("stopScanWXDevice",{},function(res){});
        } else {
            time = time + 1;
        }
    },1000);

    // 开始扫描
    wx.invoke("startScanWXDevice", {"connType":"blue"}, function(res) {
        console.log("startScanWXDevice",res);
    });

    // 注册接受扫描到的设备
    wx.on('onScanWXDevicesResult',function(res){
        console.log("onScanWXDevicesResult",res);
        // 扫描到设备以后，获取ticket
        wx.invoke('getWXDeviceTicket', {'deviceId':deviceId,'type':'1', 'connType':'blue'}, function(res) {
            console.log('getWXDeviceTicket',res);
        });
    });
}
var time = 1;
var timeId = null;
// --------------------------------------------------- 以下为Base64
var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var base64DecodeChars = new Array(
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
    52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
    -1,　0,　1,　2,　3,  4,　5,　6,　7,　8,　9, 10, 11, 12, 13, 14,
    15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
    -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
    41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1);
/**
 * 将字符串编码为base64位格式
 * @param str
 * @returns
 */
function base64encode(str) {
    var out, i, len;
    var c1, c2, c3;
    len = str.length;
    i = 0;
    out = "";
    while(i < len) {
        c1 = str.charCodeAt(i++) & 0xff;
        if(i == len) {
            out += base64EncodeChars.charAt(c1 >> 2);
            out += base64EncodeChars.charAt((c1 & 0x3) << 4);
            out += "==";
            break;
        }
        c2 = str.charCodeAt(i++);
        if(i == len) {
            out += base64EncodeChars.charAt(c1 >> 2);
            out += base64EncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));
            out += base64EncodeChars.charAt((c2 & 0xF) << 2);
            out += "=";
            break;
        }
        c3 = str.charCodeAt(i++);
        out += base64EncodeChars.charAt(c1 >> 2);
        out += base64EncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));
        out += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6));
        out += base64EncodeChars.charAt(c3 & 0x3F);
    }
    return out;
}
/**
 * 将base64位反译为字符串
 * @param str
 * @returns
 */
function base64decode(str) {
    var c1, c2, c3, c4;
    var i, len, out;
    len = str.length;
    i = 0;
    out = "";
    while(i < len) {
		/* c1 */
        do {
            c1 = base64DecodeChars[str.charCodeAt(i++) & 0xff];
        } while(i < len && c1 == -1);
        if(c1 == -1)
            break;
		/* c2 */
        do {
            c2 = base64DecodeChars[str.charCodeAt(i++) & 0xff];
        } while(i < len && c2 == -1);
        if(c2 == -1)
            break;
        out += String.fromCharCode((c1 << 2) | ((c2 & 0x30) >> 4));
		/* c3 */
        do {
            c3 = str.charCodeAt(i++) & 0xff;
            if(c3 == 61)
                return out;
            c3 = base64DecodeChars[c3];
        } while(i < len && c3 == -1);
        if(c3 == -1)
            break;
        out += String.fromCharCode(((c2 & 0XF) << 4) | ((c3 & 0x3C) >> 2));
		/* c4 */
        do {
            c4 = str.charCodeAt(i++) & 0xff;
            if(c4 == 61)
                return out;
            c4 = base64DecodeChars[c4];
        } while(i < len && c4 == -1);
        if(c4 == -1)
            break;
        out += String.fromCharCode(((c3 & 0x03) << 6) | c4);
    }
    return out;
}
function utf16to8(str) {
    var out, i, len, c;
    out = "";
    len = str.length;
    for(i = 0; i < len; i++) {
        c = str.charCodeAt(i);
        if ((c >= 0x0001) && (c <= 0x007F)) {
            out += str.charAt(i);
        } else if (c > 0x07FF) {
            out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));
            out += String.fromCharCode(0x80 | ((c >>　6) & 0x3F));
            out += String.fromCharCode(0x80 | ((c >>　0) & 0x3F));
        } else {
            out += String.fromCharCode(0xC0 | ((c >>　6) & 0x1F));
            out += String.fromCharCode(0x80 | ((c >>　0) & 0x3F));
        }
    }
    return out;
}

function utf8to16(str) {
    var out, i, len, c;
    var char2, char3;
    out = "";
    len = str.length;
    i = 0;
    while(i < len) {
        c = str.charCodeAt(i++);
        switch(c >> 4) {
            case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
            // 0xxxxxxx
            out += str.charAt(i-1);
            break;
            case 12: case 13:
            // 110x xxxx　 10xx xxxx
            char2 = str.charCodeAt(i++);
            out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
            break;
            case 14:
                // 1110 xxxx　10xx xxxx　10xx xxxx
                char2 = str.charCodeAt(i++);
                char3 = str.charCodeAt(i++);
                out += String.fromCharCode(((c & 0x0F) << 12) |
                    ((char2 & 0x3F) << 6) |
                    ((char3 & 0x3F) << 0));
                break;
        }
    }
    return out;
}