package serialporttest.utils;

import android.text.TextUtils;
import android.util.Log;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Timer;
import java.util.TimerTask;

import android_serialport_api.SerialPort;

/**
 * Created by Administrator on 2017/6/6.
 */

public class SerialPortUtil {
    private String TAG = "SerialPortUtil";

    public SerialPort serialPort = null;
    public InputStream inputStream = null;
    public OutputStream outputStream = null;

    ISerialPortBedOnclickEvent onDataReceiveListener = null;
    ISerialPortBedOnclickString onDataReceiveStringListener = null;
    public boolean isOpenSerialPortUtil = false;
    private static int length = 9;
    private static byte[] KeyValue = new byte[length];

    int DataIndex = 0;
    int DataValue = -1;

    public Thread receiveThread = null;

    public static SerialPortUtil instance = null;

    public Timer timer ;
    public TimerTask timerTask ;

    public SerialPortUtil() {
    }

    public static SerialPortUtil getInstance() {
        if (instance == null) {
            synchronized (SerialPortUtil.class) {
                if (instance == null) {
                    instance = new SerialPortUtil();
                }
            }
        }
        return instance;
    }

    /**
     * 打开串口的方法
     */
    public void openSerialPort() {
        Log.i(TAG, "打开串口");
        try {
            serialPort = new SerialPort(new File("/dev/" + getSystemPort()), getSystemBaudrate(), 0);
            //获取打开的串口中的输入输出流，以便于串口数据的收发
            inputStream = serialPort.getInputStream();
            outputStream = serialPort.getOutputStream();
            isOpenSerialPortUtil = true;
            receiveSerialPort();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 接收串口数据的方法
     */
    private byte[] buffer;
    private String data;

    public byte[] re_buffer = new byte[2048];
    String data1 = "";
    public int writeIndex = 0, readIndex = 0;
    public boolean finshFlag = false;

    /**
     * 请求设备维一序列号（设备 ID）
     */
    public static String KEY_ID = "";

    public void receiveSerialPort() {
        initKeyValue();
        Log.i(TAG, "接收串口数据");
        if (receiveThread != null)
            return;
        buffer = new byte[1024];
        receiveThread = new Thread() {
            @Override
            public void run() {
                while (isOpenSerialPortUtil) {
                    try {
                        if (inputStream == null) {
                            return;
                        }
                        int size = inputStream.read(buffer);
                        if (size > 0 && isOpenSerialPortUtil) {
                            data = new String(buffer, 0, size);
                            //Log.d("aaaa", "data==" + data);

                            if (systemVersionIsO()) {//安卓7.0.1 or 8.1.0 版用
                                //addByData(data);//my do
                                changeData(size);//吴总改了后的
                            } else {//安卓4.2.0 版用
                                sendData(data);
                            }

                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        //启动接收线程
        receiveThread.start();
    }

    String addData = "";

    public synchronized void addByData(String data) {
        addData = addData + data;
        if (StringUtils.vagueInquiry(data, "$") && StringUtils.vagueInquiry(data, "#")) {
            sendData(addData);
            addData = "";
        }
    }

    public void changeData(int size) {
        if (size > 0) {
            for (int i = 0; i < size; i++) {
                re_buffer[writeIndex] = buffer[i];
                writeIndex++;
                if (writeIndex > 2047) {
                    writeIndex = 0;
                }
            }
        }
        if (readIndex != writeIndex) {
            while (readIndex != writeIndex) {
                if (re_buffer[readIndex] == '$') {
                    data1 = "$";
                    readIndex++;
                    if (readIndex > 2047) {
                        readIndex = 0;
                    }
                } else if (re_buffer[readIndex] == '#') {
                    data1 = data1 + "#";
                    readIndex++;
                    if (readIndex > 2047) {
                        readIndex = 0;
                    }
                    finshFlag = true;
                    break;
                } else if (data1.length() > 0) {
                    data1 = data1 + new String(re_buffer, readIndex, 1);
                    readIndex++;
                    if (readIndex > 2047) {
                        readIndex = 0;
                    }
                } else {
                    readIndex++;
                    if (readIndex > 2047) {
                        readIndex = 0;
                    }
                }
            }
        }
        if (finshFlag) {
            sendData(data1);
            data1 = "";
            finshFlag = false;
        }
    }

    public void sendData(String data) {
        //Log.d("bbbb", "data==" + data);
        if (!StringUtils.notEmpty(data)) return;
        if (isOpenSerialPortUtil) {
            //reset data
            DataIndex = 0;
            DataValue = -1;
            if (data.contains("ID")) {
                String str = data.substring(data.indexOf(",") + 1, data.indexOf("1#"));
                int i = 0;
                while (i < 10) {
                    if (str.length() > 4) {
                        break;
                    } else {
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        getKeyId();
                        i++;
                    }
                }
                Log.e(TAG, str);
                KEY_ID = str;
            } else {
                if (data.contains("$") && data.contains("#")) {

                    if (null != onDataReceiveStringListener) {//add by waderson 20190708
                        onDataReceiveStringListener.serialPortBedOnclickString(data);
                    }

                    String str = data.substring(data.indexOf("$") + 1, data.indexOf("#"));
                    if (TextUtils.isDigitsOnly(str.substring(3, 4)) && TextUtils.isDigitsOnly(str.substring(5, 6))) {
                        DataIndex = Integer.parseInt(str.substring(3, 4));
                        DataValue = Integer.parseInt(str.substring(5, 6));
                    }
                    if (DataIndex < length && DataIndex >= 0) {
                        KeyValue[DataIndex] = (byte) DataValue;
                    }
                    if (null != onDataReceiveListener) {
                        onDataReceiveListener.serialPortBedOnclick(KeyValue);
                    }
                    //======================================
                    for (int i = 0; i < KeyValue.length; i++) {
                        if (KeyValue[i] > 0) KeyValue[i] = -1;
                    }
                    //======================================
                }
            }

        }
    }

    /**
     * 判断是否是7.1以上的系统版本
     *
     * @return
     */
    public static boolean systemVersionIsO() {
        if (android.os.Build.VERSION.SDK_INT >= 24) {//7.1以上的系统
            return true;
        } else {
            return false;
        }
    }

    /**
     * 关闭串口的方法
     * 关闭串口中的输入输出流
     * 然后将flag的值设为flag，终止接收数据线程
     */
    public void closeSerialPort() {
        Log.i(TAG, "关闭串口");
        try {
            if (inputStream != null) {
                inputStream.close();
            }
            if (outputStream != null) {
                outputStream.close();
            }
            if (receiveThread != null && receiveThread.isAlive()) {
                receiveThread.interrupt();
                receiveThread = null;
            }
            isOpenSerialPortUtil = false;
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    //初始化 key值
    public static void initKeyValue() {
        KeyValue[0] = -1;
        KeyValue[1] = -1;
        KeyValue[2] = -1;
        KeyValue[3] = -1;
        KeyValue[4] = -1;
        KeyValue[5] = -1;
        KeyValue[6] = -1;
        KeyValue[7] = -1;
        KeyValue[8] = -1;
    }

    public void startHeartBeat() {
        if (timer != null) timer.purge();
        if (timerTask != null) timerTask.cancel();
        timer = new Timer();
        timerTask = new TimerTask() {
            @Override
            public void run() {
                startHeart();
            }
        };
        timer.schedule(timerTask, 0, 5000);
    }

    /**
     * 心跳信号
     */
    public void startHeart() {
        send("$HEART,1F#");
    }

    /**
     * 关闭心跳<br>
     * 若MCU在10秒内没有收到信号，将自动重启Android.  随机数为“W”时将关闭心跳<br>
     */
    public void closeHeart() {
        send("$HEART,WE#");
    }

    /**
     * 系统重启
     */
    public void systemRestart() {
        send("$SYSRESET,2D#");
        Log.i(TAG, "系统重启发送");
    }

    /*
    * 进入系统ROM升级模式
    * */
    public void systemUpDate() {
        Log.i(TAG, "系统ROM升级模式串口数据");
        send("$SYSUPDATE,3C#");
        Log.i(TAG, "系统ROM升级模式发送");

    }


    /**
     * 发送串口数据的方法
     *
     * @param command 要发送的数据
     */
    private void send(String command) {
        try {
            if (isOpenSerialPortUtil) {
                byte[] sendData = command.getBytes();
                outputStream.write(sendData);
                Log.d("serialPort","==command==" + command);
            }
        } catch (IOException e) {
            e.printStackTrace();
            Log.d("serialPort","==command==" + command);
        }
    }

    public void setOnDataReceiveListener(ISerialPortBedOnclickEvent dataReceiveListener) {
        onDataReceiveListener = dataReceiveListener;
    }
    public void setOnDataReceiveStringListener(ISerialPortBedOnclickString dataReceiveStringListener) {
        onDataReceiveStringListener = dataReceiveStringListener;
    }

//    private void saveKeyValue() {
//        if (timer != null) {
//            timer.purge();
//        }
//        timer = new Timer();
//
//        if (timerTask != null) {
//            timerTask.cancel();
//        }
//        timerTask = new TimerTask() {
//            @Override
//            public void run() {
//                if (KeyValue[DataIndex] > 0) {
//                    initKeyValue();
//                }
//            }
//        };
//        timer.schedule(timerTask, 10, mTimeInterval);
//    }

    public static int getSystemVersion() {
        return android.os.Build.VERSION.SDK_INT;
    }

    public static String getSystemPort() {
        String port;
        if (getSystemVersion() >= 26) { //android8.0 = 26
            port = "ttyS4";// rk3368 android8.1
        } else if (getSystemVersion() >= 24) { //android7.0 = 24
            port = "ttyS1";//rk3128 android7.1
        } else {
            port = "ttyS2";// a33 android4.4
        }
        return port;
    }

    /**
     * 得到波特率
     *
     * @return String
     */
    public static int getSystemBaudrate() {
        int baudrate;
        if (getSystemVersion() >= 26) { //android8.0 = 26
            baudrate = 115200;// rk3368 android8.1
        } else if (getSystemVersion() >= 24) { //android7.0 = 24
            baudrate = 115200;//rk3128 android7.1
        } else {
            baudrate = 115200;// a20 android4.2
        }
        return baudrate;
    }


    public interface ISerialPortBedOnclickEvent {
        void serialPortBedOnclick(byte[] buffer);
    }

    public interface ISerialPortBedOnclickString {
        void serialPortBedOnclickString(String str);
    }

    //------------------------below things was add by Waderson 20171106  -----------------------------------

    public static final String C_HEARD = "$";//开头符
    public static final String C_END = "#";//结束符
    public static final String C_SEPARATE = ",";//分隔符

    /**
     * 手柄MIC切换<br>
     */
    public static final String MIC = "MIC";
    /**
     * 床头灯的切换<br> 0 关闭 1打开 2闪烁
     */
    public static final String BEDLIGHT = "RELAY";
    /**
     * 门灯控制开关
     */
    public static final String DOORLIGHT = "DOORLED";
    /**
     * 卫生间呼叫灯控制<br>
     */
    public static final String ULED = "ULED";
    /**
     * 护理灯光控制<br>
     */
    public static final String NURSELIGHT = "NLED";
    /**
     * 当前 SIP 协议状态<br>
     */
    public static final String SIP_STATUS = "SIP";
    /**
     * 呼叫状态<br>
     */
    public static final String CALL_STATUS = "CALL";
    /**
     * 网络状态<br>
     */
    public static final String NET_STATUS = "NETRESET";

    /**
     * 心跳控制<br>
     * 若MCU在10秒内没有收到信号，将自动重启Android.  随机数为“W”时将关闭心跳<br>
     * $ HEART ，1 E #  <br>
     */

    /**
     * 写入串口<br>
     * Waderson 20171103
     * command  命令 <br>
     * random   随机数<br>
     * check  校验符<br>
     */
    public void sendCommand(String command, String random, String check) {//$NLED3,beComeDoublF#
        String random_v = "1", check_v = "F";
        if (null == command || "".equals(command)) {// beComeDoubleStr(rr) + beComeDoubleStr(gg) + beComeDoubleStr(bb), "F"
            return;
        }
        if (null != random && !"".equals(random)) {
            random_v = random;
        }
        if (null != check && !"".equals(check)) {
            check_v = check;
        }
        send(C_HEARD + command + C_SEPARATE + random_v + check_v + C_END);
    }

    /**
     * 请求设备维一序列号（设备 ID）
     */
    public void getKeyId() {
        send("$ID,11#");
    }


}
