package com.youchain.rfid;

import com.alibaba.druid.sql.visitor.functions.Length;
import com.uhf.api.cls.BackReadOption;
import com.uhf.api.cls.ReadExceptionListener;
import com.uhf.api.cls.ReadListener;
import com.uhf.api.cls.Reader;
import com.uhf.api.cls.Reader.READER_ERR;
import com.youchain.basicdata.domain.LampLog;
import com.youchain.utils.BaseStatus;

import javax.swing.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Vector;

public class RfidDocJava {
    public static String ip="192.168.0.224";
    public static int POWER=3300;
    public static Reader rdr = null;
    private static HashSet vt;
//    Vector<String> vt=new Vector<String>();

    public static void main(String[] args) {
        HashSet rfids = RfidDocJava.readRfid();
        System.out.println(rfids);
    }
    public static String linkOpen(){
        RfidDocJava rfidDocJava=new RfidDocJava();
        return rfidDocJava.OpenReader().toString();// 初始化
    }
    public static HashSet<String> readRfid(){
        RfidDocJava rfidDocJava=new RfidDocJava();
        /*try {
            Thread.sleep(3000);
        }catch (Exception e){

        }*/
        rfidDocJava.stopRead();
        return vt;
    }
    public static void startRfid(){
        RfidDocJava rfidDocJava=new RfidDocJava();
        rfidDocJava.startRead();
    }
    public void startRead(){
        vt=new HashSet();
        StartReadTags();
    }
    public void stopRead(){
        rdr.StopReading();
    }
    READER_ERR StartReadTags()
    {
        //初始化结BackReadOption
        BackReadOption m_BROption=new BackReadOption();
        //本例只使用天线1进行盘存，如果要使用多个天线则只需要将使用的天线编
        //号赋值到数组ants中，例如同时使用天线1和2，则代码应该改为ants[0] = 1;
        //ants[1] = 2;antcnt = 2;
        int antcnt=4;
        int[] ants=new int[]{1,2,3,4};
        /*是否采用高速模式（目前只有slr11xx和slr12xx系列读写器才支持）,对于
         *一般标签数量不大，速度不快的应用没有必要使用高速模式,本例没有设置
         *使用高速模式
         * */
        m_BROption.IsFastRead = true;//采用非高速模式盘存标签


        ///非高速盘存模式下必须要设置的参数*******************************************
        //盘存周期,单位为ms，可根据实际使用的天线个数按照每个天线需要200ms
        //的方式计算得出,如果启用高速模式则此选项没有任何意义，可以设置为
        //任意值，或者干脆不设置
        m_BROption.ReadDuration = (short)(200 * antcnt);
        //盘存周期间的设备不工作时间,单位为ms,一般可设置为0，增加设备不工作
        //时间有利于节电和减少设备发热（针对某些使用电池供电或空间结构不利
        //于散热的情况会有帮助）
        m_BROption.ReadInterval = 0;
        //****************************************************************************


        //高速盘存模式参数设置********************************************************
        //以下为选择使用高速模式才起作用的选项参,照如下设置即可,如果使能高速
        //模式，即把IsFastRead设置为true则,只需取消以下被注释的代码即可
        //*
        //高速模式下为取得最佳效果设置为0即可
        m_BROption.FastReadDutyRation = 0;
        //标签信息是否携带识别天线的编号
        m_BROption.TMFlags.IsAntennaID = true;
        //标签信息是否携带标签识别次数
        m_BROption.TMFlags.IsReadCnt = false;
        //标签信息是否携带识别标签时的信号强度
        m_BROption.TMFlags.IsRSSI = false;
        //标签信息是否携带时间戳
        m_BROption.TMFlags.IsTimestamp = false;
        //标签信息是否携带识别标签时的工作频点
        m_BROption.TMFlags.IsFrequency = false;
        //标签信息是否携带识别标签时同时读取的其它bank数据信息,如果要获取在
        //盘存时同时读取其它bank的信息还必须设置MTR_PARAM_TAG_EMBEDEDDATA参数,
        //（目前只有slr11xx和slr12xx系列读写器才支持）
        m_BROption.TMFlags.IsEmdData = false;
        //保留字段，可始终设置为0
        m_BROption.TMFlags.IsRFU = false;
        return rdr.StartReading(ants, antcnt, m_BROption);
    }
    READER_ERR OpenReader()
    {
        READER_ERR err = READER_ERR.MT_OK_ERR;
        if (rdr != null)
        {
            rdr.CloseReader();
            rdr=null;
        }
        //初始化读写器实例************************************************************
        //当使用设备的串口进行连接的时候，InitReader_Notype函数的第一个参数也可
        //能是串口号（例如com1）当设备仅有一个天线端口时（例如一体机或者发卡器），
        //InitReader_Notype函数的第二个参数也可能为1
        //读写器出厂默认IP为192.168.1.100   com4
        int portnum = 4;  //注意是读写器天线端口数，不是已连接数量
        rdr=new Reader();
        err =rdr.InitReader_Notype(ip, portnum);
        System.out.println("connect:"+err.toString());
        if (err != READER_ERR.MT_OK_ERR)
            return err;
        //****************************************************************************

        //以下为必须要设置的参数和事件回调处理函数************************************
        //设置读写器发射功率,本例设置为最大发射功率，可根据实际情况调整,
        //一般来说，功率越大则识别距离越远

        //获取读写器最大发射功率
        int[] maxpower=new int[1];
        maxpower[0]=POWER;
        /*err=rdr.ParamGet(Reader.Mtr_Param.MTR_PARAM_RF_MAXPOWER, maxpower);
        //*
        if (err != READER_ERR.MT_OK_ERR)
            return err;*/

        Reader.AntPowerConf apcf=rdr.new AntPowerConf();
        apcf.antcnt=portnum;
        for(int i=0;i<apcf.antcnt;i++)
        {
            Reader.AntPower jaap=rdr.new AntPower();
            jaap.antid=i+1;
            jaap.readPower=(short)maxpower[0];
            jaap.writePower=(short)maxpower[0];
            apcf.Powers[i]=jaap;
        }
        err=rdr.ParamSet( Reader.Mtr_Param.MTR_PARAM_RF_ANTPOWER, apcf);
        //*
        if (err != READER_ERR.MT_OK_ERR)
            return err;

        //设置读写器执行GEN2空中接口协议
        Reader.Inv_Potls_ST ipst=rdr.new Inv_Potls_ST();
        ipst.potlcnt=1;
        ipst.potls=new Reader.Inv_Potl[1];
        for(int i=0;i<ipst.potlcnt;i++)
        {
            Reader.Inv_Potl ipl=rdr.new Inv_Potl();
            ipl.weight=30;
            ipl.potl= Reader.SL_TagProtocol.SL_TAG_PROTOCOL_GEN2;
            ipst.potls[0]=ipl;
        }
        //不用检查返回值，不会失败
        err= rdr.ParamSet(Reader.Mtr_Param.MTR_PARAM_TAG_INVPOTL, ipst);


        //设置盘存到标签时的回调处理函数
        rdr.addReadListener(RL);
        //*
        //设置读写器发生错误时的回调处理函数
        rdr.addReadExceptionListener(REL);
        //****************************************************************************

        //以下为根据应用需求可能要设置的参数******************************************
        //*
        //标签数量比较大，且移动速度缓慢或静止不动,设置为Session1可取得更
        //好效果,反之标签数量较少移动速度较快应设置为Session0,读写器默认
        //为Session0

        int[] gen2session=new int[]{1};
        err =rdr.ParamSet(Reader.Mtr_Param.MTR_PARAM_POTL_GEN2_SESSION, gen2session);
        if (err != READER_ERR.MT_OK_ERR)
            return err;
        return READER_ERR.MT_OK_ERR;
    }
    ReadListener RL=new ReadListener()
    {

        @Override
        public void tagRead(Reader r, final Reader.TAGINFO[] tag) {
            // TODO Auto-generated method stub
            SwingUtilities.invokeLater(new Runnable(){
                @Override
                public void run() {
                    for(int i=0;i<tag.length;i++){
                        String v=Reader.bytes_Hexstr(tag[i].EpcId);
                        // RFID长度验证
                        boolean flag = BaseStatus.lengthVerifyList.contains(Long.valueOf(v.length()));
                        if (flag) {
                            vt.add(Reader.bytes_Hexstr(tag[i].EpcId));
                        }
                    }
                }
            });
        }

    };
    ReadExceptionListener REL=new ReadExceptionListener()
    {

        @Override
        public void tagReadException(Reader reader, READER_ERR readerErr) {
            System.out.println("读写器错误");
        }
    };
}
