/*
 * Copyright (c) 2020. Lemon Healthcare
 * Kangsh
 *
 * NFC를 스캔하는 클래스이다.
 */

package com.lemonhc.mplus.mcare_plus.activity;

import android.annotation.SuppressLint;
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.IsoDep;
import android.nfc.tech.NfcA;
import android.os.Bundle;

import com.lemonhc.mplus.app.MPlusApplication;

import static android.nfc.NfcAdapter.EXTRA_TAG;

final class NfcManager {
    private final static String KEY_DISCOVERYDELAY = "opt_discovery_delay";
    private final static int DEF_DISCOVERYDELAY = 3000;

    interface TagListener {
        void onNewTagIntent(Intent intent);
    }

    NfcManager(Activity activity) {
        this.activity = activity;

        nfcAdapter = NfcAdapter.getDefaultAdapter(activity);

        Intent intent = new Intent(activity, activity.getClass());
        intent.setAction(NfcAdapter.ACTION_NDEF_DISCOVERED);
        intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

        pendingIntent = PendingIntent.getActivity(activity, 0, intent, 0);

    }

    void onPause() {
        if (nfcAdapter != null) {
            setReaderMode(false, 0);
        }
    }

    void onResume(TagListener listener) {
        this.tagListener = listener;

        if (nfcAdapter != null) {
            setReaderMode(true, getDiscoveryDelay());

        }
    }

    int getDiscoveryDelay() {
        return MPlusApplication.getPreference(KEY_DISCOVERYDELAY, DEF_DISCOVERYDELAY);
    }

    void setDiscoveryDelay(int delay) {
        MPlusApplication.setPreference(KEY_DISCOVERYDELAY, delay);
        setReaderMode(true, delay);
    }

    @SuppressLint("NewApi")
    private void setReaderMode(boolean enable, int delay) {
        if (nfcAdapter == null)
            return;

        if (!enable) {
            nfcAdapter.disableReaderMode(activity);
            return;
        }

        Bundle opts = new Bundle();
        opts.putInt(NfcAdapter.EXTRA_READER_PRESENCE_CHECK_DELAY, 5000);

        int flags = NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK;
        flags |= NfcAdapter.FLAG_READER_NFC_A;

        // For the 'READ BINARY' problem of Braodcom's NFC stack.
        // Only works on Android 4.4+
        nfcAdapter.enableReaderMode(activity, new NfcAdapter.ReaderCallback() {

            @Override
            public void onTagDiscovered(Tag tag) {
                Intent i = new Intent().putExtra(EXTRA_TAG, tag);
                tagListener.onNewTagIntent(i);
            }
        }, flags, opts);
    }

    public NfcA attachCard(Intent intent) {
        Tag tag = (Tag) intent.getParcelableExtra(EXTRA_TAG);
        return (tag != null) ? NfcA.get(tag) : null;
    }

    public String getCardId(NfcA nfcA) {
        if (nfcA != null) {
            byte[] id = nfcA.getTag().getId();
            if (id != null && id.length > 0)
                return toHexString(id, 0, id.length);
        }

        return "UNKNOWN";
    }

    static String toHexString(byte[] d, int s, int n) {
        final char[] ret = new char[n * 2];
        final int e = s + n;

        int x = 0;
        for (int i = s; i < e; ++i) {
            final byte v = d[i];
            ret[x++] = HEX[0x0F & (v >> 4)];
            ret[x++] = HEX[0x0F & v];
        }
        return new String(ret);
    }
    private final static char[] HEX = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };

    private final Activity activity;
    private NfcAdapter nfcAdapter;
    private PendingIntent pendingIntent;
    private TagListener tagListener;

    private static String[][] TECHLISTS;
    private static IntentFilter[] TAGFILTERS;

    static {
        try {
            TECHLISTS = new String[][] { { IsoDep.class.getName() } };

            TAGFILTERS = new IntentFilter[] { new IntentFilter(
                    NfcAdapter.ACTION_TECH_DISCOVERED, "*/*") };
        } catch (Exception e) {
        }
    }
}