//package com.yiako.bluetoothprinter.bt;
//
//import android.bluetooth.BluetoothAdapter;
//import android.bluetooth.BluetoothDevice;
//import android.bluetooth.BluetoothServerSocket;
//import android.bluetooth.BluetoothSocket;
//import android.content.Context;
//import android.util.Log;
//
//
//
//import java.io.IOException;
//import java.io.InputStream;
//import java.io.OutputStream;
//import java.util.UUID;
//
//
///**
// * Created by liuguirong on 8/1/17.
// * This class does all the work for setting up and managing Bluetooth
// * connections with other devices. It has a thread that listens for incoming
// * connections, a thread for connecting with a device, and a thread for
// * performing data transmissions when connected.
// * 这个类完成所有的设置和管理蓝牙的工作
//   *与其他设备的连接。 它有一个线程来侦听来电
//   *连接，用于与设备连接的线程和线程
//   *连接时执行数据传输。
// */
//public class BtService {
//
//    // Constants that indicate the current connection state
//    public static final int STATE_NONE = 0; // we're doing nothing
//    public static final int STATE_LISTEN = 1; // now listening for incoming connections
//    public static final int STATE_CONNECTING = 2; // now initiating an outgoing connection
//
//    // INSECURE "8ce255c0-200a-11e0-ac64-0800200c9a66"
//    // SECURE "fa87c0d0-afac-11de-8a39-0800200c9a66"
//    // SPP "0001101-0000-1000-8000-00805F9B34FB"
//    public static final int STATE_CONNECTED = 3; // now connected to a remote device
//    // Debugging
//    private static final String TAG = "BtService";
//    // Name for the SDP record when creating server socket
//    private static final String NAME = "BtService";
//    // Unique UUID for this application
//    private static final UUID MY_UUID = UUID.fromString("0001101-0000-1000-8000-00805F9B34FB");
//    // Member fields
//    private final BluetoothAdapter mAdapter;
//    private AcceptThread mAcceptThread;
//    private ConnectThread mConnectThread;
//    private ConnectedThread mConnectedThread;
//    private int mState;
//    // context
//    private Context mContext;
//
//    /**
//     * Constructor. Prepares a new BluetoothChat session.
//     */
//    public BtService(Context context) {
//        mAdapter = BluetoothAdapter.getDefaultAdapter();
//        mState = STATE_NONE;
//        this.mContext = context;
//    }
//
//    /**
//     * Return the current connection state.
//     */
//    public synchronized int getState() {
//        return mState;
//    }
//
//    /**
//     * Set the current state of the chat connection
//     *
//     * @param state An integer defining the current connection state
//     */
//    private synchronized void setState(int state) {
//        Log.d(TAG, "setState() " + mState + " -> " + state);
//        mState = state;
//
//        // if need to show bt status, use the code below
//        // Give the new state to the Handler so the UI Activity can update
//        switch (mState) {
//            case STATE_LISTEN:
//                EventBus.getDefault().post(new PrintMsgEvent(PrinterMsgType.MESSAGE_STATE_CHANGE, "等待连接"));
//                break;
//            case STATE_CONNECTING:
//                EventBus.getDefault().post(new PrintMsgEvent(PrinterMsgType.MESSAGE_STATE_CHANGE, "正在连接"));
//                break;
//            case STATE_CONNECTED:
//                EventBus.getDefault().post(new PrintMsgEvent(PrinterMsgType.MESSAGE_STATE_CHANGE, "已连接"));
//                break;
//            default:
//                EventBus.getDefault().post(new PrintMsgEvent(PrinterMsgType.MESSAGE_STATE_CHANGE, "未连接"));
//                break;
//        }
//
//
//    }
//
//    /**
//     * Start the ConnectThread to initiate a connection to a remote device.
//     *
//     * @param device The BluetoothDevice to connect
//     */
//    public synchronized void connect(BluetoothDevice device) {
//        Log.d(TAG, "connect to: " + device);
//        EventBus.getDefault().post(new PrintMsgEvent(PrinterMsgType.MESSAGE_TOAST, "正在连接蓝牙设备"));
//        // Cancel any thread attempting to make a connection
//        if (mState == STATE_CONNECTING) {
//            if (mConnectThread != null) {
//                mConnectThread.cancel();
//                mConnectThread = null;
//            }
//        }
//
//        // Cancel any thread currently running a connection
//        if (mConnectedThread != null) {
//            mConnectedThread.cancel();
//            mConnectedThread = null;
//        }
//
//        // Start the thread to connect with the given device
//        mConnectThread = new ConnectThread(device);
//        mConnectThread.start();
//        setState(STATE_CONNECTING);
//    }
//
//    /**
//     * Start the ConnectedThread to begin managing a Bluetooth connection
//     *
//     * @param socket The BluetoothSocket on which the connection was made
//     * @param device The BluetoothDevice that has been connected
//     */
//    public synchronized void connected(BluetoothSocket socket,
//                                       BluetoothDevice device, final String socketType) {
//        Log.d(TAG, "connected, Socket Type:" + socketType);
//
//        // Cancel the thread that completed the connection
//        if (mConnectThread != null) {
//            mConnectThread.cancel();
//            mConnectThread = null;
//        }
//
//        // Cancel any thread currently running a connection
//        if (mConnectedThread != null) {
//            mConnectedThread.cancel();
//            mConnectedThread = null;
//        }
//
//        // Cancel the accept thread because we only want to connect to one
//        // device
//        if (mAcceptThread != null) {
//            mAcceptThread.cancel();
//            mAcceptThread = null;
//        }
//        // Start the thread to manage the connection and perform transmissions
//        mConnectedThread = new ConnectedThread(socket, socketType);
//        mConnectedThread.start();
//
//        // Send the name of the connected device back to the UI Activity
//        EventBus.getDefault().post(new PrintMsgEvent(PrinterMsgType.MESSAGE_TOAST, "蓝牙设备连接成功"));
//
//        setState(STATE_CONNECTED);
//
//        // call print queue to print
//        PrintQueue.getQueue(mContext).print();
//
//    }
//
//    /**
//     * Stop all threads
//     */
//    public synchronized void stop() {
//        Log.d(TAG, "stop");
//
//        if (mConnectThread != null) {
//            mConnectThread.cancel();
//            mConnectThread = null;
//        }
//
//        if (mConnectedThread != null) {
//            mConnectedThread.cancel();
//            mConnectedThread = null;
//        }
//
//        if (mAcceptThread != null) {
//            mAcceptThread.cancel();
//            mAcceptThread = null;
//        }
//        setState(STATE_NONE);
//    }
//
//    /**
//     * Write to the ConnectedThread in an unsynchronized manner
//     *
//     * @param out The bytes to write
//     */
//    public void write(byte[] out) {
//        // Create temporary object
//        ConnectedThread r;
//        // Synchronize a copy of the ConnectedThread
//        synchronized (this) {
//            if (mState != STATE_CONNECTED)
//                return;
//            r = mConnectedThread;
//        }
//        // Perform the write unsynchronized
//        r.write(out);
//        EventBus.getDefault().post(new PrintMsgEvent(PrinterMsgType.MESSAGE_PRINTER_SUCCESS, "打印成功!"));
//
//    }
//
//    /**
//     * Write to the ConnectedThread in an unsynchronized manner after sleepTime
//     *
//     * @param out       The bytes to write
//     * @param sleepTime sleep time
//     */
//    public void write(byte[] out, long sleepTime) {
//        // Create temporary object
//        ConnectedThread r;
//        // Synchronize a copy of the ConnectedThread
//        synchronized (this) {
//            if (mState != STATE_CONNECTED)
//                return;
//            r = mConnectedThread;
//        }
//        // Perform the write unsynchronized
//        r.write(out, sleepTime);
//    }
//
//    /**
//     * Indicate that the connection attempt failed and notify the UI Activity.
//     */
//    private void connectionFailed() {
////         Send a failure message back to the Activity
//        EventBus.getDefault().post(new PrintMsgEvent(PrinterMsgType.MESSAGE_TOAST, "蓝牙连接失败,请重启打印机再试"));
//        EventBus.getDefault().post(new PrintMsgEvent(PrinterMsgType.MESSAGE_PRINTER_FAIL, "蓝牙连接失败,请重启打印机再试"));
//        setState(STATE_NONE);
//        // Start the service over to restart listening mode
//        BtService.this.start();
//    }
//
//    /**
//     * Start the chat service. Specifically start AcceptThread to begin a
//     * session in listening (server) mode. Called by the Activity onResume()
//     * 开始聊天服务。 具体启动AcceptThread开始一个
//      会话在监听（服务器）模式。 由Activity onResume（）调用
//     */
//    public synchronized void start() {
//        Log.d(TAG, "start");
//
//        // Cancel any thread attempting to make a connection
//        if (mConnectThread != null) {
//            mConnectThread.cancel();
//            mConnectThread = null;
//        }
//
//        // Cancel any thread currently running a connection
//        if (mConnectedThread != null) {
//            mConnectedThread.cancel();
//            mConnectedThread = null;
//        }
//
//        setState(STATE_LISTEN);
//
//        // Start the thread to listen on a BluetoothServerSocket
//        if (mAcceptThread == null) {
//            mAcceptThread = new AcceptThread();
//            mAcceptThread.start();
//        }
//    }
//
//    /**
//     * Indicate that the connection was lost and notify the UI Activity.
//     */
//    private void connectionLost() {
////         Send a failure message back to the Activity
//        EventBus.getDefault().post(new PrintMsgEvent(PrinterMsgType.MESSAGE_TOAST, "蓝牙连接断开"));
//        setState(STATE_NONE);
//        // Start the service over to restart listening mode
//        BtService.this.start();
//    }
//
//    /**
//     * This thread runs while listening for incoming connections. It behaves
//     * like a server-side client. It runs until a connection is accepted (or
//     * until cancelled).
//     */
//    private class AcceptThread extends Thread {
//        // The local server socket
//        private final BluetoothServerSocket mmServerSocket;
//        private String mSocketType;
//
//        public AcceptThread() {
//            BluetoothServerSocket tmp = null;
//
//            // Create a new listening server socket
//            try {
//                tmp = mAdapter
//                        .listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
//            } catch (Exception e) {
//                Log.e(TAG, "Socket Type: " + mSocketType + "listen() failed", e);
//            }
//            mmServerSocket = tmp;
//        }
//
//        public void run() {
//            try {
//                Log.d(TAG, "Socket Type: " + mSocketType
//                        + "BEGIN mAcceptThread" + this);
//                setName("AcceptThread" + mSocketType);
//
//                BluetoothSocket socket = null;
//
//                // Listen to the server socket if we're not connected
//                while (mState != STATE_CONNECTED) {
//                    try {
//                        // This is a blocking call and will only return on a
//                        // successful connection or an exception
//                        socket = mmServerSocket.accept();
//                    } catch (Exception e) {
//                        Log.e(TAG, "Socket Type: " + mSocketType
//                                + "accept() failed", e);
//                        break;
//                    }
//
//                    // If a connection was accepted
//                    if (socket != null) {
//                        synchronized (BtService.this) {
//                            switch (mState) {
//                                case STATE_LISTEN:
//                                case STATE_CONNECTING:
//                                    // Situation normal. Start the connected thread.
//                                    connected(socket, socket.getRemoteDevice(),
//                                            mSocketType);
//                                    break;
//                                case STATE_NONE:
//                                case STATE_CONNECTED:
//                                    // Either not ready or already connected. Terminate
//                                    // new socket.
//                                    try {
//                                        socket.close();
//                                    } catch (IOException e) {
//                                        Log.e(TAG, "Could not close unwanted socket", e);
//                                    }
//                                    break;
//                            }
//                        }
//                    }
//                }
//                Log.i(TAG, "END mAcceptThread, socket Type: " + mSocketType);
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
//
//        }
//
//        public void cancel() {
//            Log.d(TAG, "Socket Type" + mSocketType + "cancel " + this);
//            try {
//                mmServerSocket.close();
//            } catch (Exception e) {
//                Log.e(TAG, "Socket Type" + mSocketType
//                        + "close() of server failed", e);
//            }
//        }
//    }
//
//    /**
//     * This thread runs while attempting to make an outgoing connection with a
//     * device. It runs straight through; the connection either succeeds or
//     * fails.
//     */
//    private class ConnectThread extends Thread {
//        private final BluetoothSocket mmSocket;
//        private final BluetoothDevice mmDevice;
//        private String mSocketType;
//
//        public ConnectThread(BluetoothDevice device) {
//            mmDevice = device;
//            BluetoothSocket tmp = null;
//
//            // Get a BluetoothSocket for a connection with the
//            // given BluetoothDevice
//            try {
//                tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
//            } catch (Exception e) {
//                Log.e(TAG, "Socket Type: " + mSocketType + "create() failed", e);
//            }
//            mmSocket = tmp;
//        }
//
//        public void run() {
//            try {
//                Log.i(TAG, "BEGIN mConnectThread SocketType:" + mSocketType);
//                setName("ConnectThread" + mSocketType);
//
//                // Always cancel discovery because it will slow down a connection
//                mAdapter.cancelDiscovery();
//
//                // Make a connection to the BluetoothSocket
//                try {
//                    // This is a blocking call and will only return on a
//                    // successful connection or an exception
//                    mmSocket.connect();
//                } catch (Exception e) {
//                    // Close the socket
//                    try {
//                        mmSocket.close();
//                    } catch (IOException e2) {
//                        Log.e(TAG, "unable to close() " + mSocketType
//                                + " socket during connection failure", e2);
//                    }
//                    connectionFailed();
//                    return;
//                }
//
//                // Reset the ConnectThread because we're done
//                synchronized (BtService.this) {
//                    mConnectThread = null;
//                }
//
//                // Start the connected thread
//                connected(mmSocket, mmDevice, mSocketType);
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
//        }
//
//        public void cancel() {
//            try {
//                mmSocket.close();
//            } catch (Exception e) {
//                Log.e(TAG, "close() of connect " + mSocketType
//                        + " socket failed", e);
//            }
//        }
//    }
//
//    /**
//     * This thread runs during a connection with a remote device. It handles all
//     * incoming and outgoing transmissions.
//     */
//    private class ConnectedThread extends Thread {
//        private final BluetoothSocket mmSocket;
//        private final InputStream mmInStream;
//        private final OutputStream mmOutStream;
//
//        public ConnectedThread(BluetoothSocket socket, String socketType) {
//            Log.d(TAG, "create ConnectedThread: " + socketType);
//            mmSocket = socket;
//            InputStream tmpIn = null;
//            OutputStream tmpOut = null;
//
//            // Get the BluetoothSocket input and output streams
//            try {
//                tmpIn = socket.getInputStream();
//                tmpOut = socket.getOutputStream();
//            } catch (Exception e) {
//                Log.e(TAG, "temp sockets not created", e);
//            }
//
//            mmInStream = tmpIn;
//            mmOutStream = tmpOut;
//        }
//
//        public void run() {
//            Log.i(TAG, "BEGIN mConnectedThread");
//            byte[] buffer = new byte[1024];
//            int bytes;
//
//            // Keep listening to the InputStream while connected
//            while (true) {
//                try {
//                    // Read from the InputStream
//                    bytes = mmInStream.read(buffer);
//                    // send data
//                    EventBus.getDefault().post(new BtMsgReadEvent(bytes, buffer));
//                } catch (IOException e) {
//                    Log.e(TAG, "disconnected", e);
//                    connectionLost();
//                    // Start the service over to restart listening mode
//                    BtService.this.start();
//                    break;
//                } catch (Exception e) {
//                    connectionLost();
//                    BtService.this.start();
//                    break;
//                }
//            }
//        }
//
//        /**
//         * Write to the connected OutStream.
//         *
//         * @param buffer The bytes to write
//         */
//        public void write(byte[] buffer) {
//            try {
//                mmOutStream.write(buffer);
//            } catch (Exception e) {
//                Log.e(TAG, "Exception during write", e);
//            }
//        }
//
//        /**
//         * Write to the connected OutStream after sleep
//         *
//         * @param buffer The bytes to write
//         */
//        public void write(byte[] buffer, long sleepTime) {
//            try {
//                Thread.sleep(sleepTime);
//                mmOutStream.write(buffer);
//            } catch (Exception e) {
//                Log.e(TAG, "Exception during write", e);
//            }
//        }
//
//
//        public void cancel() {
//            try {
//                mmSocket.close();
//            } catch (Exception e) {
//                Log.e(TAG, "close() of connect socket failed", e);
//            }
//        }
//    }
//
//}
