package com.bpa.scalage.HBL.Communication;

import com.bpa.scalage.HBL.DataUtil.NotifyPropVar;
import com.bpa.scalage.HBL.Result.OperateResult;
import com.bpa.scalage.HBL.Result.OperateResultT;
import com.bpa.scalage.HBL.Thread.IThread;
import com.bpa.scalage.HBL.Thread.ThreadManager;
import com.bpa.scalage.HBL.Interface.IRun;
import com.bpa.scalage.HBL.Interface.IRunT;
import com.pc_rfid.api.PC_API;
import com.pc_rfid.api.PC_COMM;
import com.pc_rfid.api.RFdata;

import java.nio.charset.StandardCharsets;
import java.util.Arrays;

/**
 * RFID 操作类
 */
public class RFIDHelper {
    private static PC_API api=new PC_API();
    private static boolean mRunning = false;
    private static boolean mCartRunning = false;
    private static IRun CloseNotify;
    public static IRunT<String> DataUpdate;
    public static NotifyPropVar<String> ChipCode=new NotifyPropVar<>("");
    public static OperateResult Open(String comName, int baud, String format ){
        Close(null);
        try{
            if(api.PC_OpenCOM(comName,baud, format)){
                mCartRunning=true;
                getDataTask();
                return OperateResult.CreateSuccess();
            }
        }catch(Exception e){
            return OperateResult.CreateFailed("打开串口失败");
        }
        return OperateResult.CreateFailed("打开串口失败");
    }

    public static void Close(IRun closeNotify) {
        CloseNotify=closeNotify;
        ThreadManager.get().Stop("RFID卡数据获取");
    }


    /**
     * 设置无校验
     */
    public static void set8N1(){
        if(mCartRunning){
            RFdata rFRead=new RFdata();
            rFRead.SendData[0]=-86;
            rFRead.SendData[1]=15;
            rFRead.SendData[2]=-1;
            rFRead.SendData[3]=-91;
            rFRead.SendData[4]=1;
            rFRead.SendData[5]=0;
            rFRead.SendData[6]=1;
            rFRead.SendData[7]=56;
            rFRead.SendData[8]=0;
            rFRead.SendData[9]=0;
            rFRead.SendData[10]=0;
            rFRead.SendData[11]=0;
            rFRead.SendData[12]=0;
            rFRead.SendData[13]=0;
            rFRead.SendData[14]=24;
            rFRead.SendData[15]=91;
            int crc = PC_COMM.crc16(rFRead.SendData);
            rFRead.SendData[rFRead.SendData[1] - 1] = (byte)(crc % 256);
            rFRead.SendData[rFRead.SendData[1]] = (byte)(crc / 256);
            api.PC_Send(rFRead);
        }

    }

    public static void Close() {
        ThreadManager.get().Stop("RFID卡数据获取");
    }

    private static void getDataTask(){
        ThreadManager.get().StartLong("RFID卡数据获取", true, new IThread() {
            @Override
            public void Run() throws InterruptedException {
                getCardData().OnSource(s->{
                    if(DataUpdate!=null)DataUpdate.Run(s.Content);
                    ChipCode.setValue(s.Content);
                }).OnFailed(s->{
                    ChipCode.setValue("");
                });
                Thread.sleep(1);
            }
            @Override
            public void RunComplete() throws InterruptedException {
                api.PC_Close();
                mCartRunning=false;
                if(CloseNotify!=null)CloseNotify.Run();
            }
        });
    }

    private static OperateResultT<String> getCardData(){
        try{
            if(!mCartRunning){
                return OperateResultT.CreateFailedT("设备未连接");
            }
            RFdata rFRead=new RFdata();
            api.PC_InventoryTag(rFRead,(byte)4);//获取卡片UID
            if(rFRead.RecvData[16]!=0){
                byte[] result = Arrays.copyOfRange(rFRead.RecvData,7,15);
                RFdata r = new RFdata();
                Thread.sleep(500);
                api.PC_ReadCardOneBlock(r,result,(byte)1,(byte)0,(byte)0);//获取卡片数据
                if(r.RecvData[13]!=0){
                    String str = new String(Arrays.copyOfRange(r.RecvData,8,12), StandardCharsets.US_ASCII);
                    return OperateResultT.CreateSuccess(str);
                }
                else{return OperateResultT.CreateSuccess("无卡");}
            }else{
                return OperateResultT.CreateSuccess("无卡");
            }
        }catch (Exception e){
            return OperateResultT.CreateFailedT(e);
        }
    }

}
