package com.gto.usb_sample_code;

import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.AssetManager;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

import com.gainscha.gtspl_sdk.GTSPLUsbActivity;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Iterator;

public class MainActivity extends AppCompatActivity {

    GTSPLUsbActivity mUSB = new GTSPLUsbActivity();
    EditText mDeviceName, mProductName, mSDKVersion, mPrinterStatus, mUhfMemoryET, mGJBDataET, mQueryUhfET;
    private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
    private static UsbManager mUsbManager;
    private static PendingIntent mPermissionIntent;
    private static boolean hasPermissionToCommunicate = false;
    private static UsbDevice mDevice;


    private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (ACTION_USB_PERMISSION.equals(action)) {
                synchronized (this) {
                    UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                    if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                        if (device != null) {
                            hasPermissionToCommunicate = true;
                        }
                    }
                }
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mDeviceName = findViewById(R.id.deviceName);
        mProductName = findViewById(R.id.productName);
        mSDKVersion = findViewById(R.id.sdk_version_txt);
        mPrinterStatus = findViewById(R.id.printer_status_txt);
        mUhfMemoryET = findViewById(R.id.ed_read_uhf_memory);
        mQueryUhfET = findViewById(R.id.et_query_uhf);
        mGJBDataET = findViewById(R.id.ed_read_gjb);

        //getUSBDevice();
        getAssetsFile();
        mUSB.GTSPL_setCmdSendMode("P");
    }

    //usb 裝置搜尋
    public void getUSBDevice() {
        mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
        mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
        IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
        registerReceiver(mUsbReceiver, filter);

        HashMap<String, UsbDevice> deviceList = mUsbManager.getDeviceList();
        Log.d("Detect ", deviceList.size() + " USB device(s) found");
        if (deviceList.size() > 0) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                mDeviceName.setTextColor(getResources().getColor(R.color.colorAccent, null));
                mProductName.setTextColor(getResources().getColor(R.color.colorAccent, null));
            }
            Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
            while (deviceIterator.hasNext()) {
                mDevice = deviceIterator.next();
                if (mDevice.getVendorId() == 1137 || mDevice.getVendorId() == 4611 || mDevice.getVendorId() == 2655 || mDevice.getVendorId() == 1298) {
                    mDeviceName.setText(mDevice.getDeviceName());
                    mProductName.setText(mDevice.getProductName());
                    break;
                } else {

                    mDeviceName.setText("No device found!");
                    mProductName.setText("");
                    break;
                }
            }
            try {
                mPermissionIntent = PendingIntent.getBroadcast(MainActivity.this, 0, new Intent(ACTION_USB_PERMISSION), PendingIntent.FLAG_ONE_SHOT);
                mUsbManager.requestPermission(mDevice, mPermissionIntent);
            } catch (Exception e) {
                Toast.makeText(this, "Device disconnected!", Toast.LENGTH_SHORT).show();
            }

        } else {
            mDeviceName.setText("No device found!");
            mProductName.setText("");
        }

    }

    //search usb device again
    public void refresh_btn_click(View view) {
        getUSBDevice();
    }

    //open port
    public void connect_btn_click(View view) {
        boolean isConnect = mUSB.GTSPL_openPort(mUsbManager, mDevice);
        if (isConnect) {
            Toast.makeText(this, "Connect to USB succesfully.", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(this, "Fail to connect to USB.", Toast.LENGTH_SHORT).show();
        }
    }

    //close port
    public void disconnect_btn_click(View view) {
        boolean isDisconnect = mUSB.GTSPL_closePort();
        if (isDisconnect) {
            Toast.makeText(this, "Disconnect successfully.", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(this, "Fail to disconnect.", Toast.LENGTH_SHORT).show();
        }
    }

    //set printer
    public void setup_btn_click(View view) {
        mUSB.GTSPL_setup(104, 76, 2, 3, 0, 3, 0, this);
        mUSB.GTSPL_sendCommand(this, "DIRECTION 1\r\n");
        Toast.makeText(this, "Setting Complete!", Toast.LENGTH_SHORT).show();

    }

    //print barcode
    public void print_barcode_btn_click(View view) {
        mUSB.GTSPL_clearBuffer(this);
        mUSB.GTSPL_barcode(30, 30, "128", 100, 1, 0, 2, 2, "barcode9463521", this);
        mUSB.GTSPL_printLabel(1, 1, this);
    }

    //print simplified chinese font 24*24
    public void print_cn_font_btn_click(View view) {
        String cnTest = "默认简体中文测试：海天米醋白米醋1瓶450ml";
        mUSB.GTSPL_clearBuffer(this);
        mUSB.GTSPL_printerFont(100, 50, "TSS24.BF2", 0, 1, 1, cnTest, this);
        mUSB.GTSPL_printLabel(1, 1, this);
    }

    //hide
    //print simplified chinese font
    public void print_tw_font_btn_click(View view) {
        String twTest = "默認繁體中文測試：海天米醋白米醋1瓶450ml";
        mUSB.GTSPL_clearBuffer(this);
        mUSB.GTSPL_printerFont(100, 10, "TST24.BF2", 0, 1, 1, twTest, this);
        mUSB.GTSPL_printLabel(1, 1, this);
    }

    //print bmp
    public void print_bmp_btn_click(View view) {
        mUSB.GTSPL_clearBuffer(this);
        mUSB.GTSPL_downloadBMP("CIRCLE.BMP", this);
        mUSB.GTSPL_sendCommand(this, "PUTBMP 10,10,\"CIRCLE.BMP\"\r\n");
        mUSB.GTSPL_printLabel(1, 1, this);
    }

    public void print_bmp_new_btn_click(View view) {
        mUSB.GTSPL_clearBuffer(this);
        mUSB.GTSPL_printBMP(-550,30,500,300,1,"good.jpg", this);
        mUSB.GTSPL_printLabel(1, 1, this);
    }

    public void print_bmp_compress_btn_click(View view) {
        mUSB.GTSPL_clearBuffer(this);
        mUSB.GTSPL_printBMP_Compression(-550,30,500,300,"good.jpg", this);
        mUSB.GTSPL_printLabel(1, 1, this);
    }

    //print monochrome bmp
    public void print_monochrome_btn_click(View view) {

        mUSB.GTSPL_clearBuffer(this);
        mUSB.GTSPL_download_Not1BitDepthBMP("penguin.jpg", this);
        mUSB.GTSPL_sendCommand(this, "PUTBMP 10,10,\"penguin.jpg\"\r\n");
        mUSB.GTSPL_printLabel(1, 1, this);
    }

    public void calibration_rfid_btn_click(View view) {

        mUSB.GTSPL_clearBuffer(this);
        mUSB.GTSPL_LabelCalibration(this);

    }

    //print qrcode
    public void print_qrcode_btn_click(View view) {

        mUSB.GTSPL_clearBuffer(this);
        mUSB.GTSPL_qrcode(300, 100, "H", 4, "A", 0, "ABCabc123", this);
        mUSB.GTSPL_printLabel(1, 1, this);
    }

    public void othersettings_btn_click(View view) {
        mUSB.GTSPL_clearBuffer(this);
        mUSB.GTSPL_genericDefault(this);
        mUSB.GTSPL_sensorDefault(this);
        mUSB.GTSPL_rfidSetupDefault(this);
        mUSB.GTSPL_setDirectionAndMirror(1, 1, this);
        mUSB.GTSPL_setShift(00, this);
        mUSB.GTSPL_printReverse(160, 160, 160, 160, this);
        mUSB.GTSPL_setOffset(20, this);
        mUSB.GTSPL_setCutMode(0, 2, this);
        mUSB.GTSPL_setAfterPrintAction(3, this);
        mUSB.GTSPL_printLabel(1, 1, this);
    }

    public void wifi_frequency_btn_click(View view) {
        mUSB.GTSPL_WifiFrequency("5G",this);
    }
    public void rfid_setup_btn_click(View view) {
        mUSB.GTSPL_Set_RFIDPorcedure(5,40,32,5,"N",5,5,"300",this);
        Toast.makeText(this, "Setting Complete!", Toast.LENGTH_SHORT).show();

    }
    //hide
    // print block
    public void print_block_btn_click(View view) {
        String sBlock = "block 測試 -- 默认简体中文测试：海天米醋白米醋1瓶450ml --";
        mUSB.GTSPL_clearBuffer(this);
        mUSB.GTSPL_printFontBlock("15", "15", "790", "90",
                "TSS24.BF2", "0", "1", "1",
                "1", "1", sBlock, this);
        mUSB.GTSPL_printLabel(1, 1, this);
    }

    //write epc data only
    public void write_rfid_click(View view) {
        mUSB.GTSPL_writeUHF("H", 2, 12, "E", "11223344556677889900AABB", this);
        mUSB.GTSPL_printLabel(1, 1, this);
        Toast.makeText(this, "Wrote Data：Hex format,block no.= 2, write 12 bytes, EPC Bank, data= 11223344556677889900AABB", Toast.LENGTH_LONG).show();
    }

    //hide
    //write epc data => write access pwd => lock access pwd => lock epc data
    public void write_and_lock_rfid_click(View view) {
        mUSB.GTSPL_writeUHF("H", 2, 12, "E", "11223344556677889900AABB", this);
        mUSB.GTSPL_AccessPWD_Action("S", "12345678", this);
        mUSB.GTSPL_AccessPWD_Action("L", "12345678", this);
        mUSB.GTSPL_EPCPWD_Action("L", "12345678", this);
        mUSB.GTSPL_printLabel(1, 1, this);
        Toast.makeText(this, "Wrote Data：as above cmd. Wrote Access PWD:12345678", Toast.LENGTH_LONG).show();

    }

    //read gen2 epc
    public void read_uhf_btn_click(View view) {
        mUhfMemoryET.setText("");
        final String ans = mUSB.GTSPL_readUHF("H", 2, 12, "E", MainActivity.this);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            mUhfMemoryET.setTextColor(getResources().getColor(
                    R.color.colorAccent, null));
        }
        mUhfMemoryET.setText("GEN2 EPC:" + ans);
    }

    public void bt_query_uhf_btn_click(View view) {
        mQueryUhfET.setText("");
        final String ans_query = mUSB.GTSPL_readUHFQ(
                "H", 0, 0, MainActivity.this);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            mQueryUhfET.setTextColor(getResources().getColor(
                    R.color.colorAccent, null));
        }
        mQueryUhfET.setText("GEN2 EPC:" + ans_query);
    }

    //SET GJB Status
    public void set_gjb_status(View view) {
        mUSB.GTSPL_Set_GJB_Pwd("S", "S", "11112222", "12345678", this);
        mUSB.GTSPL_Set_GJB_Status("E", "A", "11112222", this);
        mUSB.GTSPL_printLabel(1, 1, this);
        Toast.makeText(this, "Set EPC Status:R & W", Toast.LENGTH_LONG).show();

    }

    //Write gjb epc data
    public void write_gjb_rfid_click(View view) {
        mUSB.GTSPL_writeGJB("H", 2, 12, "E", "404041414242434344444545", "12345678", this);
        mUSB.GTSPL_Set_GJB_Pwd("W", "S", "87654321", "12345678", this);
        mUSB.GTSPL_printLabel(1, 1, this);
        Toast.makeText(this, "Wrote Data：404041414242434344444545", Toast.LENGTH_LONG).show();
    }

    //read gjb epc data
    public void read_gjb_btn_click(View view) {
        mGJBDataET.setText("");
        final String result = mUSB.GTSPL_readGJB(
                "H", 2, 12, "E", "00000000", MainActivity.this);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            mGJBDataET.setTextColor(getResources().getColor(
                    R.color.colorAccent, null));
        }
        mGJBDataET.setText("GJB EPC:" + result);
    }


    //get printer status
    public void get_status_btn_click(View view) {
        String status = mUSB.GTSPL_printersStatus(1000);
        setPrinterStatusToUI(status);
    }

    //get sdk version
    public void get_version_btn_click(View view) {
        String version = mUSB.GTSPL_getSDKVersion(0, this);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            mSDKVersion.setTextColor(getResources().getColor(R.color.colorAccent, null));
        }
        mSDKVersion.setText("SDK Version:" + version);
    }

    //將assets中檔案存入手機
    private void getAssetsFile() {
        AssetManager assetManager = getAssets();
        InputStream inputStream;
        BufferedInputStream bis;
        ByteArrayOutputStream bos = null;
        try {
            inputStream = assetManager.open("CIRCLE.BMP");
            int dataLength = inputStream.available();
            bis = new BufferedInputStream(inputStream);
            byte[] buffer = new byte[dataLength];
            int len = 0;
            bos = new ByteArrayOutputStream();
            while ((len = bis.read(buffer)) != -1) {
                bos.write(buffer, 0, len);
            }


            File dir = new File(String.valueOf(getExternalFilesDir("")));
            String pathName = dir.getAbsolutePath() + "/" + "CIRCLE" + ".BMP";
            File file = new File(pathName);
            if (!file.exists()) {
                FileOutputStream output = new FileOutputStream(file);
                output.write(bos.toByteArray());
                output.close();
            }
            bis.close();
            bos.close();
            inputStream.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //印表機狀態
    private void setPrinterStatusToUI(String status) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            mPrinterStatus.setTextColor(getResources().getColor(R.color.colorAccent, null));
        }
        switch (status) {
            case "00":
                mPrinterStatus.setText("Printer Status : Normal");
                break;
            case "01":
                mPrinterStatus.setText("Printer Status : Head opened");
                break;
            case "02":
                mPrinterStatus.setText("Printer Status : Paper Jam");
                break;
            case "03":
                mPrinterStatus.setText("Printer Status : Paper Jam and head opened");
                break;
            case "04":
                mPrinterStatus.setText("Printer Status : Out of paper");
                break;
            case "05":
                mPrinterStatus.setText("Printer Status : Out of paper and head opened");
                break;
            case "08":
                mPrinterStatus.setText("Printer Status : Out of ribbon");
                break;
            case "09":
                mPrinterStatus.setText("Printer Status : Out of ribbon and head opened");
                break;
            case "0A":
                mPrinterStatus.setText("Printer Status : Out of ribbon and paper jam");
                break;
            case "0B":
                mPrinterStatus.setText("Printer Status : Out of ribbon, paper jam and head opened");
                break;
            case "0C":
                mPrinterStatus.setText("Printer Status : Out of ribbon and out of paper");
                break;
            case "0D":
                mPrinterStatus.setText("Printer Status : Out of ribbon, out of paper and head opened");
                break;
            case "10":
                mPrinterStatus.setText("Printer Status : Pause");
                break;
            case "20":
                mPrinterStatus.setText("Printer Status : Printing");
                break;
            case "80":
                mPrinterStatus.setText("Printer Status : Other error");
                break;
            default:
                mPrinterStatus.setText("Printer Status : no status");
                break;
        }
    }
}