package com.holtek.a4050nfctest;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.IntentFilter;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.MifareClassic;
import android.nfc.tech.MifareUltralight;
import android.nfc.tech.Ndef;
import android.nfc.tech.NfcA;
import android.util.Log;

import java.util.Arrays;
import java.util.List;

/**
 * Created by cheetah on 2017/4/7.
 */
public class NFCManager    {
    //
    public static final int TAGTYPE_MifareUltralight = 0x01;
    public static final int TAGTYPE_NfcA = 0x02;
    public static final int TAGTYPE_Ndef = 0x03;

    public String tagId;

    //单例私有静态变量
    private static NFCManager instance;
    NfcAdapter nfcAdapter;
    public Activity activity;
    OnDiscoverListener discoverListener;
    boolean fNFCSupport = false;
    boolean fNFCEnable = false;
    //boolean fDiscoverTag = false;
    // 传达意图
    MifareUltralight tagMul;
    NfcA tagNfcA;
    Ndef tagNdef;
    //PendingIntent pendingIntent = null;
    IntentFilter[] intentFiltersArray;
    String[][] techListsArray;


    public NFCManager(Activity activity){
        this.activity = activity;
    }

    //单例
    public static synchronized NFCManager getInstance(Activity activity){
        if (instance == null){
            instance = new NFCManager(activity);
        }
        return instance;
    }

    public boolean isNFCSupport(){

        return fNFCSupport;
    }

    public boolean isNFCEnable(){
        if(!fNFCSupport){
            return false;
        }
        fNFCEnable = nfcAdapter.isEnabled();
        return fNFCEnable;
    }

    public void setOnDiscoverListener(OnDiscoverListener discoverListener){
        this.discoverListener = discoverListener;
    }

    public void OnPause(Activity activity){
        if(fNFCEnable) {
            //this.activity = activity;
            //关闭前台调度，使能APP退出后可自动检测打开
            nfcAdapter.disableForegroundDispatch(activity);


        }
    }

    public void OnResume(Activity activity){
        if(fNFCEnable) {
            //this.activity = activity;
            //使能前台调度，屏蔽系统检测到NFC时自动弹出选APP的界面
            //用于前台调度：初始化PendingIntent，当有NFC设备连接上的时候，就交给当前Activity处理
            PendingIntent pendingIntent = PendingIntent.getActivity(activity, 0, new Intent(activity, activity.getClass())
                    .addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
            nfcAdapter.enableForegroundDispatch(activity, pendingIntent, intentFiltersArray, techListsArray);
        }else{
            //從後台回來時，判斷NFC是否已打開
            if(fNFCSupport){
                initNFCModule();
            }
        }
    }

    /**
     * 往指定地址讀數據
     * @param addr  page地址
     * @return  读到的数据
     */
    public byte[] ReadPage(int addr){
        byte[] readBuff;
        //优先考虑通过MifareUltralight协议
        if(tagMul != null) {
            try {
                readBuff = tagMul.readPages(addr);
                return readBuff;
            } catch (Exception e) {
                //fDiscoverTag = false;
                Log.e("NFCManager", "读取NFC异常 by MifareUltralight", e);
                return null;
            }
        }
        //使用NfcA协议
        if(tagNfcA != null){
            try{
                byte[] addrBuff = {0x30, (byte)(addr & 0x0ff)};
                readBuff = tagNfcA.transceive(addrBuff);
                return readBuff;
            }catch (Exception e){
                Log.e("NFCManager", "读取NFC异常 by NfcA", e);
                return null;
            }
        }
        //使用Ndef协议
        if(tagNdef != null){

        }
        return null;
    }

    /**
     * 往指定地址寫數據
     * @param addr          指定的地址
     * @param writeData     要发送的数据buff
     * @return  是否写成功
     */
    public boolean WritePage(int addr, byte[] writeData){
        //优先考虑通过MifareUltralight协议
        if(tagMul != null) {
            try {
                tagMul.writePage(addr, writeData);
            } catch (Exception e) {
                Log.e("NFCManager", "寫NFC异常", e);
                if (addr == 24 || addr == 25) {
                    return true;
                }
                //fDiscoverTag = false;
                return false;
            }
            return true;
        }
        //使用NfcA协议
        if(tagNfcA != null) {
            try {
                byte[] writeBuff = {(byte) 0xA2, (byte)(addr & 0x0ff), writeData[0], writeData[1], writeData[2], writeData[3]};
                tagNfcA.transceive(writeBuff);
            } catch (Exception e) {
                Log.e("NFCManager", "寫NFC异常", e);
                if (addr == 24 || addr == 25) {
                    return true;
                }
                //fDiscoverTag = false;
                return false;
            }
            return true;
        }
        return false;
    }

    /**
     * 初始化NFC模块,获取是否支持,是否打开等信息
     * @return  描述
     */
    public String initNFCModule() {
        // 初始化设备支持NFC功能
        fNFCSupport = false;
        fNFCEnable = false;
        // 得到默认nfc适配器
        nfcAdapter = NfcAdapter.getDefaultAdapter(activity);
        // 判定设备是否支持NFC或启动NFC
        if (nfcAdapter == null) {
            return activity.getString(R.string.info_nfc_not_support);
        }
        fNFCSupport = true;
        if (!nfcAdapter.isEnabled()) {
            return activity.getString(R.string.info_nfc_not_open);
        }
        fNFCEnable = true;
        //用于前台调度：初始化PendingIntent，当有NFC设备连接上的时候，就交给当前Activity处理
        //pendingIntent = PendingIntent.getActivity(activity, 0, new Intent(activity, activity.getClass())
        //            .addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
        // 新建IntentFilter，使用的是第二种的过滤机制
        IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED);
        tagDetected.addCategory(Intent.CATEGORY_DEFAULT);
        intentFiltersArray = new IntentFilter[] {tagDetected};
        //支持的NFC类型: MifareUltralight、NfcA、NdeF
        techListsArray = new String[][] {
                new String[] { MifareClassic.class.getName() } ,
                new String[] { NfcA.class.getName() }
        };
        return activity.getString(R.string.info_nfc_already_open);
    }

    /**
     *
     * @param intent
     * @return
     */
    public boolean ProcessIntent(Intent intent){
        // 当前app正在前端界面运行，这个时候有intent发送过来，那么系统就会调用onNewIntent回调方法，将intent传送过来
        // 我们只需要在这里检验这个intent是否是NFC相关的intent，如果是，就调用处理方法
        if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction())) {
            //取出封装在intent中的TAG
            Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
            //获取Tag Id
            byte[] tagIDByte = tagFromIntent.getId();
            tagId = bytesToHexString(tagIDByte);
            //轮询是否有支持的tag协议
            boolean fCheckTag = false;
            //释放之前数据
            closeTag();
            List techList = Arrays.asList(tagFromIntent.getTechList());
            //先搜索MifareUltralight,再搜索NfcA
            if(techList.contains(MifareUltralight.class.getName())){
                //支持MifareUltralight协议
                getMifareUltralightTag(tagFromIntent);
                fCheckTag = true;
            }else if(techList.contains(NfcA.class.getName())){
                //支持NfcA协议
                getNfcATag(tagFromIntent);
                fCheckTag = true;
            }
            /*
            //测试版先搜索NfcA,再搜索MifareUltralight
            if(techList.contains(NfcA.class.getName())){
                //支持NfcA协议
                getNfcATag(tagFromIntent);
                fCheckTag = true;
            }else if(techList.contains(MifareUltralight.class.getName())){
                //支持MifareUltralight协议
                getMifareUltralightTag(tagFromIntent);
                fCheckTag = true;
            }
            */
            return fCheckTag;
        }
        //不支持的Intent Action
        return false;
    }

    /**
     * 检测tag是否有支持MifareUltralight协议
     * @param tagFromIntent
     * @return
     */
    private boolean getMifareUltralightTag(Tag tagFromIntent){
        //读取TAG
        tagMul = MifareUltralight.get(tagFromIntent);
        if(tagMul == null){
            return false;
        }
        try {
            //Enable I/O operations to the tag from this TagTechnology object.
            tagMul.connect();
            int type = tagMul.getType();//获取TAG的类型
            String typeS = "";
            switch (type) {
                case MifareUltralight.TYPE_ULTRALIGHT_C:
                    typeS = "TYPE_ULTRALIGHT_C";
                    break;
                case MifareUltralight.TYPE_ULTRALIGHT:
                    typeS = "TYPE_ULTRALIGHT";
                    break;
                case MifareUltralight.TYPE_UNKNOWN:
                    typeS = "TYPE_UNKNOWN";
                    break;
            }
            Log.d("NFC Info","NfcA Tag, 类型：" + typeS);
            //檢測到NFC，回調狀態
            if(discoverListener != null) {
                discoverListener.onDiscoverNFC(TAGTYPE_MifareUltralight,
                        "卡片类型: "+typeS+"\r\n"+
                        "ID: 0x"+bytesToHexString(tagFromIntent.getId()) +"\r\n"+
                        "最大传输尺寸: "+tagMul.getMaxTransceiveLength()
                );
            }
        } catch (Exception e) {
            Log.e("NFCManager Mul", "Connect error");
            return false;
        }
        return true;
    }

    /**
     * 检测tag是否有支持NfcA协议
     * @param tagFromIntent
     * @return
     */
    private boolean getNfcATag(Tag tagFromIntent){
        //读取TAG
        tagNfcA = NfcA.get(tagFromIntent);
        if(tagNfcA == null){
            return false;
        }
        //
        try {
            tagNfcA.connect();
        }catch (Exception e){
            Log.e("NFCManager NfcA", "Connect error");
            return false;
        }
        //檢測到NFC，回調狀態
        if(discoverListener != null) {
            discoverListener.onDiscoverNFC(TAGTYPE_NfcA,
                    "卡片类型: NfcA \r\n"+
                    "ID: 0x"+bytesToHexString(tagFromIntent.getId()) +"\r\n"+
                    "ATQA: 0x" +bytesToHexString(tagNfcA.getAtqa())+"\r\n"+
                    "SAK: " +tagNfcA.getSak() + "\r\n"+
                    "最大传输尺寸: "+tagNfcA.getMaxTransceiveLength()
            );
        }
        return true;
    }

    public void closeTag(){
        try {
            if (tagMul != null) {
                tagMul.close();
                tagMul = null;
            }
            if (tagNfcA != null) {
                tagNfcA.close();
                tagNfcA = null;
            }
        }catch (Exception e){
            Log.e("NFCManager Close", "close tag error");
        }
    }

    /**
     * 字符序列转换为16进制字符串
     * @param src
     * @return
     */
    private String bytesToHexString(byte[] src) {
        if (src == null || src.length <= 0) {
            return null;
        }
        StringBuilder stringBuilder = new StringBuilder();
        char[] buffer = new char[2];
        for (int i = 0; i < src.length; i++) {
            buffer[0] = Character.toUpperCase(Character.forDigit(
                    (src[i] >>> 4) & 0x0F, 16));
            buffer[1] = Character.toUpperCase(Character.forDigit(src[i] & 0x0F,
                    16));
            System.out.println(buffer);
            stringBuilder.append(buffer);
        }
        return stringBuilder.toString();
    }


    /**
     * 发现NFC Tag回调接口
     */
    public interface OnDiscoverListener{
        /**
         * 扫描到NFC后回调
         * @param tag       tag协议,暂定两种
         * @param tagInfo      tag信息
         */
        void onDiscoverNFC(int tag, String tagInfo);
    }
}


