package com.idtronic.legic_hf;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.idtronic.legic_hf.crccalc.Crc16;
import com.idtronic.legic_hf.crccalc.CrcCalculator;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import cn.pda.serialport.SerialPort;
import cn.pda.serialport.Tools;

public class MainActivity extends Activity implements View.OnClickListener {

    private TextView tvRecv;
    private Button btnOpen;
    private Button btnStatus;
    private Button btn14443a;
    private Button btn14443b;
    private Button btnStandard;
    private Button btn15693;
    private Button btnSecure;
    private Button btnChipID;
    private Button btn15693UID;
    private Button btnClear;

    private boolean isOpen = false;
    private SerialPort serialPort;
    private InputStream inputStream;
    private OutputStream outputStream;

    private final String getStatus = "0400005A52";
    private final String getUid_RFstandard = "040100438A";
    private String getUid_15693 = "0401015203";
    private String getUid_14443A = "0401026098";
    private String getUid_14443B = "0401037111";
    private String getUid_Secure = "040104005A";
    private String getUidAndTag_15693 = "0417019342";
    private String getChipId = "03F31FC4";


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        initView();
    }

    private void initView() {
        tvRecv = (TextView) findViewById(R.id.tv_recv);
        btnOpen = (Button) findViewById(R.id.btn_open);
        btnStatus = (Button) findViewById(R.id.btn_get_status);
        btn14443a = (Button) findViewById(R.id.btn_get_iso14443a);
        btn14443b = (Button) findViewById(R.id.btn_get_iso14443b);
        btnStandard = (Button) findViewById(R.id.btn_get_legicrfstandard);
        btn15693 = (Button) findViewById(R.id.btn_get_iso15693);
        btnSecure = (Button) findViewById(R.id.btn_get_inside_secure);
        btnChipID = (Button) findViewById(R.id.btn_get_chip_id);
        btn15693UID = (Button) findViewById(R.id.btn_get_iso15693_uid_tag);
        btnClear = (Button) findViewById(R.id.btn_clear);

        btnOpen.setOnClickListener(this);
        btnStatus.setOnClickListener(this);
        btn14443a.setOnClickListener(this);
        btn14443b.setOnClickListener(this);
        btnStandard.setOnClickListener(this);
        btn15693.setOnClickListener(this);
        btnSecure.setOnClickListener(this);
        btnChipID.setOnClickListener(this);
        btn15693UID.setOnClickListener(this);
        btnClear.setOnClickListener(this);
    }

    private boolean closePort() {
        if (serialPort != null) {
            serialPort.rfid_poweroff();
            serialPort.close(13);
            return true;
        } else {
            return false;
        }
    }

    private boolean openPort() {
        try {
            serialPort = new SerialPort(13, 38400, 0);
        } catch (IOException e) {
            return false;
        }
        inputStream = serialPort.getInputStream();
        outputStream = serialPort.getOutputStream();
        serialPort.rfid_poweron();
        return true;
    }

    private byte[] check(byte[] data) {
        CrcCalculator calc = new CrcCalculator(Crc16.Params[12]);
        long result = calc.Calc(data, 0, data.length);
        byte[] bytes = Tools.HexString2Bytes(Long.toHexString(result).toUpperCase());
        return bytes;
    }

    private String getUID(String recv) {
        byte[] byte1 = check(Tools.HexString2Bytes(recv.substring(0, recv.length() -4)));
        byte[] byte2 = Tools.HexString2Bytes(recv.substring(recv.length()-4));
        if ((Tools.Bytes2HexString(byte1, byte1.length)).equals(Tools.Bytes2HexString(byte2, byte2.length))) {
            if (recv.length() > 12) {
                return recv.substring(10, recv.length() -4);
            }
            return "No card UID found";
        }
        return null;
    }

    private String sendCmd(String cmd) {
        if (outputStream != null) {
          try {
              inputStream.read(new byte[4960]);
              byte[] bytes = Tools.HexString2Bytes(cmd);
              outputStream.write(bytes);
              Thread.sleep(10);
              byte[] buf = new byte[128];
              byte[] recv;
              int lenTmp = 0;
              if (inputStream.available() >= 0 && lenTmp >= 0) {
                  Thread.sleep(50);
                  lenTmp = inputStream.read(buf);
                  recv = new byte[lenTmp];
                  System.arraycopy(buf, 0, recv, 0, lenTmp);
                  return Tools.Bytes2HexString(recv, lenTmp);
              }
          } catch (IOException e) {
              return null;
          } catch (InterruptedException e) {
              return null;
          }
        } else {
            return null;
        }
        return null;
    }

    @Override
    public void onClick(View view) {
        if (view.getId() == R.id.btn_open) {
            if (!isOpen) {
                openPort();
                btnOpen.setText("Close");
                isOpen = true;
                Toast.makeText(this, "Open com port success", Toast.LENGTH_SHORT).show();
            } else if (isOpen) {
                closePort();
                btnOpen.setText("Open");
                isOpen = false;
                Toast.makeText(this, "Close com port success", Toast.LENGTH_SHORT).show();
            }
        } else if (view.getId() == R.id.btn_get_status) {
            String recvStatus = sendCmd(getStatus);
            if (recvStatus != null) {
                tvRecv.append("Received: " + recvStatus + "\n");
                byte[] byte1 = check(Tools.HexString2Bytes(recvStatus.substring(0, recvStatus.length() -4)));
                byte[] byte2 = Tools.HexString2Bytes(recvStatus.substring(recvStatus.length()-4));
                if ((Tools.Bytes2HexString(byte1, byte1.length)).equals(Tools.Bytes2HexString(byte2, byte2.length))) {
                    if (recvStatus.substring(6, recvStatus.length() -4).equals("01"))
                        tvRecv.append("Application State is idle" + "\n");
                    else if (recvStatus.substring(6, recvStatus.length() -4).equals("02"))
                        tvRecv.append("Application State is on" + "\n");
                } else {
                    Toast.makeText(this, "Error", Toast.LENGTH_SHORT).show();
                }
            } else {
                Toast.makeText(this, "Please open the serial port and power supply first.", Toast.LENGTH_SHORT).show();
            }
        } else if (view.getId() == R.id.btn_get_iso14443a) {
            String recv = sendCmd(getUid_14443A);
            if (recv != null) {
                tvRecv.append("Received:" + recv + "\n");
                tvRecv.append("UID:" + getUID(recv) + "\n");
            } else {
                Toast.makeText(this, "Please open the serial port and power supply first.", Toast.LENGTH_SHORT).show();
            }
        } else if (view.getId() == R.id.btn_get_iso14443b) {
            String recv = sendCmd(getUid_14443B);
            if (recv != null) {
                tvRecv.append("Received:" + recv + "\n");
                tvRecv.append("UID:" + getUID(recv) + "\n");
            } else {
                Toast.makeText(this, "Please open the serial port and power supply first.", Toast.LENGTH_SHORT).show();
            }
        } else if (view.getId() == R.id.btn_get_legicrfstandard) {
            String recv = sendCmd(getUid_RFstandard);
            if (recv != null) {
                tvRecv.append("Received:" + recv + "\n");
                tvRecv.append("UID:" + getUID(recv) + "\n");
            } else {
                Toast.makeText(this, "Please open the serial port and power supply first.", Toast.LENGTH_SHORT).show();
            }
        } else if (view.getId() == R.id.btn_get_iso15693) {
            String recv = sendCmd(getUid_15693);
            if (recv != null) {
                tvRecv.append("Received:" + recv + "\n");
                tvRecv.append("UID:" + getUID(recv) + "\n");
            } else {
                Toast.makeText(this, "Please open the serial port and power supply first.", Toast.LENGTH_SHORT).show();
            }
        } else if (view.getId() == R.id.btn_get_inside_secure) {
            String recv = sendCmd(getUid_Secure);
            if (recv != null) {
                tvRecv.append("Received:" + recv + "\n");
                tvRecv.append("UID:" + getUID(recv) + "\n");
            } else {
                Toast.makeText(this, "Please open the serial port and power supply first.", Toast.LENGTH_SHORT).show();
            }
        } else if (view.getId() == R.id.btn_get_chip_id) {
            String recv = sendCmd(getChipId);
            if (recv != null) {
                tvRecv.append("Received:" + recv + "\n");
                byte[] byte1 = check(Tools.HexString2Bytes(recv.substring(0, recv.length() -4)));
                byte[] byte2 = Tools.HexString2Bytes(recv.substring(recv.length()-4));
                if ((Tools.Bytes2HexString(byte1, byte1.length)).equals(Tools.Bytes2HexString(byte2, byte2.length))) {
                    if (recv.substring(4, 6).equals("00") && recv.length() > 10) {
                        tvRecv.append("Status 00 = OK" + "\n");
                        tvRecv.append("ChipID: " + recv.substring(4, recv.length() -4) + "\n");
                    } else if (recv.substring(4, 6).equals("01") && recv.length() > 10) {
                        tvRecv.append("Status 01 = general error" + "\n");
                        tvRecv.append("ChipID: " + recv.substring(4, recv.length() - 4) + "\n");
                    } else if (recv.substring(4, 6).equals("02") && recv.length() > 10) {
                        tvRecv.append("Status 02 = wrong command length" + "\n");
                        tvRecv.append("ChipID: " + recv.substring(4, recv.length() - 4) + "\n");
                    }
                }
            } else {
                Toast.makeText(this, "Please open the serial port and power supply first.", Toast.LENGTH_SHORT).show();
            }
        } else if (view.getId() == R.id.btn_get_iso15693_uid_tag) {
            String recv = sendCmd(getUidAndTag_15693);
            if (recv != null) {
                tvRecv.append("Received:" + recv + "\n");
                tvRecv.append("UID:" + getUID(recv) + "\n");
            } else {
                Toast.makeText(this, "Please open the serial port and power supply first.", Toast.LENGTH_SHORT).show();
            }
        } else if (view.getId() == R.id.btn_clear) {
            tvRecv.setText("");
        }
    }
}