package h.com.newserialapp.activity.MIFAREUltralightActivity;

import android.graphics.Typeface;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import h.com.newserialapp.R;
import h.com.newserialapp.activity.BaseActivity;
import h.com.newserialapp.util.ToastUtil;
import h.com.newserialapp.util.Tools;
import h.com.newserialapp.views.FontEditText;
import h.com.newserialapp.views.FontTextView;
import h.com.serialportapi.comn.CommPacket;
import h.com.serialportapi.comn.Packet;
import h.com.serialportapi.comn.Reader;
import h.com.serialportapi.comn.SerialPortManager;
import h.com.serialportapi.comn.SerialReadThread;
import h.com.serialportapi.comn.message.ICMessage;
import h.com.serialportapi.comn.message.IMessage;

/**
 * Created by hxd on 2018/12/3.
 */

public class MifareUltralightActivity extends BaseActivity implements View.OnClickListener, AdapterView.OnItemSelectedListener {

    private FontTextView tvTagType, tvSAK, tvUIDNumber, tvBack, tvStatus, tvDataRead;
    private Button btActiveCard, btAuthenticate, btAPDUChannel, btChangeKey, btReadBlock, btWriteBlock;
    private FontEditText etAPDUChannel, etKey, etNewKey, etDataWrite;
    private Spinner spinnerPageAdd;
    private String[] addrArray;

    private Reader reader;

    private Handler handler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            switch (msg.what) {
                case 101:
                    tvTagType.setText(mICMessage.getTag_Type());
                    tvUIDNumber.setText(mICMessage.getUID_number());
                    tvSAK.setText(mICMessage.getSAK());
                    break;
                case 102:
                    if (!receiveCommand.substring(0, 2).equals("F0")) {
                        tvDataRead.setText(receiveCommand.substring(8, receiveCommand.length() - 2));
                    } else {
                        tvDataRead.setText("");
                    }
                    break;
            }
            return false;
        }
    });

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_mifare_ultralight);
        bindView();

        reader = SerialPortManager.instance().reader;
        if (reader == null) {
            Toast.makeText(this, "Please open the serial port first.", Toast.LENGTH_LONG).show();
        } else {
            reader.setLisenter(true);
        }
    }

    void bindView() {
        Typeface typeface = Typeface.createFromAsset(this.getAssets(), "fonts/Eurostile LT Demi.ttf");
        tvTagType = findViewById(R.id.tv_tag_type);
        tvSAK = findViewById(R.id.tv_sak);
        tvUIDNumber = findViewById(R.id.tv_uid_number);
        tvBack = findViewById(R.id.tv_back);
        tvStatus = findViewById(R.id.tv_status_bar);
        tvDataRead = findViewById(R.id.tv_data_read);
        btActiveCard = findViewById(R.id.bt_active_card);
        btAuthenticate = findViewById(R.id.bt_authenticate);
        btAPDUChannel = findViewById(R.id.bt_apdu_channel);
        btChangeKey = findViewById(R.id.bt_change_key);
        btReadBlock = findViewById(R.id.bt_read_block);
        btWriteBlock = findViewById(R.id.bt_write_block);
        etAPDUChannel = findViewById(R.id.et_apdu_channel);
        etKey = findViewById(R.id.et_key);
        etNewKey = findViewById(R.id.et_new_key);
        etDataWrite = findViewById(R.id.et_write_data);
        spinnerPageAdd = findViewById(R.id.spinner_addr);
        tvBack.setOnClickListener(this);
        btActiveCard.setOnClickListener(this);
        btAuthenticate.setOnClickListener(this);
        btAPDUChannel.setOnClickListener(this);
        btChangeKey.setOnClickListener(this);
        btReadBlock.setOnClickListener(this);
        btWriteBlock.setOnClickListener(this);
        btActiveCard.setTypeface(typeface);
        btAuthenticate.setTypeface(typeface);
        btAPDUChannel.setTypeface(typeface);
        btChangeKey.setTypeface(typeface);
        btReadBlock.setTypeface(typeface);
        btWriteBlock.setTypeface(typeface);
        addrArray = getResources().getStringArray(R.array.block_addr);
        spinnerPageAdd.setAdapter(new ArrayAdapter<>(this, R.layout.spinner_default_item, addrArray));
        spinnerPageAdd.setOnItemSelectedListener(this);
        spinnerPageAdd.setSelection(5);
    }

    private byte[] all = new byte[]{10, 52};
    private byte[] idle = new byte[]{10, 26};
    private ICMessage mICMessage;
    private String receiveCommand;

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.tv_back: {
                finish();
                break;
            }
            case R.id.bt_active_card: {
                byte[] pATQ = new byte[2];
                byte[] pSak = new byte[1];
                byte[] pUIDLen = new byte[1];
                byte[] pUID = new byte[16];

                tvStatus.setText("");
                if (reader == null) {
                    Tools.showToast(this, "Please open the serial port first.");
                    return;
                }
                int result = reader.PiccActivate((byte) 0x10, (byte) 0x26, pATQ, pSak, pUIDLen, pUID);
                if (result == 0) {
                    tvTagType.setText(Tools.toHexString(pATQ, pATQ.length));
                    tvSAK.setText(Tools.toHexString(pSak, 1));
                    tvUIDNumber.setText(Tools.toHexString(pUID, pUIDLen[0]));
                } else {
                    tvTagType.setText("-");
                    tvSAK.setText("-");
                    tvUIDNumber.setText("");
                }
                break;
            }
            case R.id.bt_authenticate: {
                tvStatus.setText("");
                if (reader == null) {
                    Tools.showToast(this, "Please open the serial port first.");
                    return;
                }
                byte[] pKey = Tools.toByteArray(etKey.getText().toString());
                if (pKey == null || pKey.length != 16) {
                    Tools.showToast(this, "Key must be 16 bytes");
                    return;
                }
                reader.PiccULAuth(pKey);
                break;
            }
            case R.id.bt_apdu_channel: {
                int [] pRcvLen = new int[1];
                byte[] pRcvBuf = new byte[1024];

                tvStatus.setText("");
                if (reader == null) {
                    Tools.showToast(this, "Please open the serial port first.");
                    return;
                }
                byte[] pSendBuf = Tools.toByteArray(etAPDUChannel.getText().toString());
                if (pSendBuf == null || pSendBuf.length == 0) {
                    Tools.showToast(this, "APDU Channel is not null");
                    return;
                }
                reader.PiccTransfer(pSendBuf.length, pSendBuf, pRcvLen, pRcvBuf);
                break;
            }
            case R.id.bt_change_key: {
                tvStatus.setText("");
                if (reader == null) {
                    Tools.showToast(this, "Please open the serial port first.");
                    return;
                }
                byte[] pKey = Tools.toByteArray(etNewKey.getText().toString());
                if (pKey == null || pKey.length != 16) {
                    Tools.showToast(this, "New Key must be 16 bytes");
                    return;
                }
                reader.PiccSetKey(pKey);
                break;
            }
            case R.id.bt_read_block: {
                byte[] pBuff = new byte[16];

                tvStatus.setText("");
                if (reader == null) {
                    Tools.showToast(this, "Please open the serial port first.");
                    return;
                }
                int result = reader.Picc_Read(Tools.toByte(addrValue), pBuff);
                if (result == 0) {
                    tvDataRead.setText(Tools.toHexString(pBuff, pBuff.length));
                } else {
                    tvDataRead.setText("");
                }
                break;
            }
            case R.id.bt_write_block: {
                tvStatus.setText("");
                if (reader == null) {
                    Tools.showToast(this, "Please open the serial port first.");
                    return;
                }
                byte[] pBuff = Tools.toByteArray(etDataWrite.getText().toString());
                if (pBuff == null || pBuff.length != 4) {
                    Tools.showToast(this, "Writing Data must be 4 bytes");
                    return;
                }
                reader.Picc_ULWrite(Tools.toByte(addrValue), pBuff);
                break;
            }
        }
    }

    private String addrValue;

    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
        switch (parent.getId()) {
            case R.id.spinner_addr:
                addrValue = addrArray[position];
                break;
        }
    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {

    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(IMessage message) {
        // 收到时间，刷新界面
        tvStatus.setText(message.getMessage());
    }

}
