package h.com.newserialapp.activity.ISO15693Activity;

import android.annotation.SuppressLint;
import android.graphics.Typeface;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
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 java.util.ArrayList;

import h.com.newserialapp.R;
import h.com.newserialapp.activity.BaseActivity;
import h.com.newserialapp.util.Tools;
import h.com.newserialapp.views.ScrollButton;
import h.com.serialportapi.comn.CommPacket;
import h.com.serialportapi.comn.Reader;
import h.com.serialportapi.comn.SerialPortManager;
import h.com.serialportapi.comn.SerialReadThread;
import h.com.serialportapi.comn.message.IMessage;


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

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

    private TextView tvUIDNumber, tvDataRead, tvBack, tvStatus;
    private EditText etAPDUChannel, etWriteData;
    private Spinner flag, blockAddr;
    private ScrollButton btInventory, btInventory16TimesSlot, btAPDUChannel, btSelectCard, btReadData, btWriteData;
    private String[] flagArray;
    private String[] addrArray;

    private ArrayList<String> adds;

    private Reader reader;

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

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_iso15693);
        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);
        }
    }

    @SuppressLint("ResourceType")
    void bindView() {
        Typeface typeface = Typeface.createFromAsset(this.getAssets(), "fonts/Eurostile LT Demi.ttf");
        tvUIDNumber = findViewById(R.id.tv_uid_number);
        tvDataRead = findViewById(R.id.tv_data_read);
        tvStatus = findViewById(R.id.tv_status_bar);
        etAPDUChannel = findViewById(R.id.et_apdu_channel);
        etWriteData = findViewById(R.id.et_write_data);
        flag = findViewById(R.id.spinner_flag);
        blockAddr = findViewById(R.id.spinner_block_addr);
        btInventory = findViewById(R.id.bt_inventory);
        btInventory16TimesSlot = findViewById(R.id.bt_inventory_16_times_slot);
        btAPDUChannel = findViewById(R.id.bt_apdu_channel);
        btSelectCard = findViewById(R.id.bt_select_card);
        btReadData = findViewById(R.id.bt_read_data);
        btWriteData = findViewById(R.id.bt_write_data);
        tvBack = findViewById(R.id.tv_back);
        btInventory.setOnClickListener(this);
        btInventory16TimesSlot.setOnClickListener(this);
        btAPDUChannel.setOnClickListener(this);
        btSelectCard.setOnClickListener(this);
        btReadData.setOnClickListener(this);
        btWriteData.setOnClickListener(this);
        tvBack.setOnClickListener(this);
        btInventory.setTypeface(typeface);
        btInventory16TimesSlot.setTypeface(typeface);
        btAPDUChannel.setTypeface(typeface);
        btSelectCard.setTypeface(typeface);
        btReadData.setTypeface(typeface);
        btWriteData.setTypeface(typeface);
        flagArray = getResources().getStringArray(R.array.flag);
        addrArray = getResources().getStringArray(R.array.block_addr);
        adds=new ArrayList<>();
        for(int i=0;i<255;i++){
            adds.add(String.valueOf(i));
        }
        flag.setAdapter(new ArrayAdapter<String>(this, R.layout.spinner_default_item, flagArray));
        blockAddr.setAdapter(new ArrayAdapter<String>(this, R.layout.spinner_default_item, addrArray));
        flag.setOnItemSelectedListener(this);
        blockAddr.setOnItemSelectedListener(this);
        blockAddr.setSelection(2);
    }

    private String receiveCommand;// serial port receive command

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.bt_inventory: {
                byte[] resplen = new byte[1];
                byte[] resp = new byte[16];

                tvStatus.setText("");
                if (reader == null) {
                    Tools.showToast(this, "Please open the serial port first.");
                    return;
                }
                int result = reader.ISO15693_Inventory((byte) 0x26, (byte) 0x00, (byte) 0x00, null, resplen, resp);
                if (result == 0) {
                    tvUIDNumber.setText(Tools.toHexString(resp, resplen[0]));
                } else {
                    tvUIDNumber.setText("");
                }
                break;
            }
            case R.id.bt_inventory_16_times_slot: {
                byte[] resplen = new byte[1];
                byte[] resp = new byte[16];

                tvStatus.setText("");
                if (reader == null) {
                    Tools.showToast(this, "Please open the serial port first.");
                    return;
                }
                int result = reader.ISO15693_Inventory((byte) 0x06, (byte) 0x00, (byte) 0x00, null, resplen, resp);
                if (result == 0) {
                    tvUIDNumber.setText(Tools.toHexString(resp, resplen[0]));
                } else {
                    tvUIDNumber.setText("");
                }
                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_select_card: {
                tvStatus.setText("");
                if (reader == null) {
                    Tools.showToast(this, "Please open the serial port first.");
                    return;
                }
                byte[] uid = Tools.toByteArray(tvUIDNumber.getText().toString());
                if (Tools.isNull(tvUIDNumber.getText().toString())) {
                    Tools.showToast(this, "UID Number is not null,Please first Inventory");
                    return;
                }
                reader.ISO15693_Select(Tools.toByte(flagValue), uid, null, null);
                break;
            }
            case R.id.bt_read_data: {
                int[] resplen = new int[1];
                byte[] resp = new byte[32];

                tvStatus.setText("");
                if (reader == null) {
                    Tools.showToast(this, "Please open the serial port first.");
                    return;
                }
                byte[] uid = Tools.toByteArray(tvUIDNumber.getText().toString());
                if (Tools.isNull(tvUIDNumber.getText().toString())) {
                    Tools.showToast(this, "UID Number is not null,Please first Inventory");
                    return;
                }
                int result = reader.ISO15693_Read_Block(Tools.toByte(flagValue), Tools.toByte(addrValue), (byte)0x01, uid, resplen, resp);
                if (result == 0) {
                    tvDataRead.setText(Tools.toHexString(resp, resplen[0]).substring((resplen[0] * 2) - 8));
                } else {
                    tvDataRead.setText("");
                }
                break;
            }
            case R.id.bt_write_data: {
                tvStatus.setText("");
                if (reader == null) {
                    Tools.showToast(this, "Please open the serial port first.");
                    return;
                }
                byte[] uid = Tools.toByteArray(tvUIDNumber.getText().toString());
                if (Tools.isNull(tvUIDNumber.getText().toString())) {
                    Tools.showToast(this, "UID Number is not null,Please first Inventory");
                    return;
                }
                byte[] WriteData = Tools.toByteArray(etWriteData.getText().toString());
                if (Tools.isNull(etWriteData.getText().toString())) {
                    Tools.showToast(this, "Write Data is not null");
                    return;
                }
                reader.ISO15693_Write_Block(Tools.toByte(flagValue), Tools.toByte(addrValue), (byte)0x01, uid, WriteData, null, null);
                break;
            }
            case R.id.tv_back: {
                finish();
                break;
            }
        }
    }

    private String flagValue;//this is temp flag value
    private String addrValue;//this is temporary Block Address value

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

    }

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


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

    }
}
