package com.unitech.utility.btscanner;


import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import com.google.android.material.snackbar.Snackbar;
import com.unitech.scanner.utility.service.IMyAidlInterface_IsMainActiviyRunning;

import org.tinylog.Logger;

import java.util.Arrays;
import java.util.Hashtable;

public class MainActivity extends AppCompatActivity {
    //==============================================================================================
    //region Variable

    //----------------------------------------------------------------------------------------------
    private util_usu_api Util_API;
    //----------------------------------------------------------------------------------------------
    private TextView txt_TriggerStatus;
    private TextView txt_Battery;
    private TextView txt_FirmwareVersion;
    private TextView txt_SerialNumber;
    private TextView txt_BluetoothName;
    private TextView txt_BluetoothMAC;
    private TextView txt_ACKStatus;
    private TextView txt_AutoConnStatus;
    private TextView txt_Data;
    private TextView txt_CodeType;
    private TextView txt_DataLength;
    private TextView txt_DataByte;
    private TextView txt_DataByteLength;
    private TextView txt_DataAll;
    private TextView txt_SetConfigName;
    private TextView txt_SetConfigValue;
    private TextView txt_GetConfigValue;
    private TextView txt_SignalCheckingLevel;
    private TextView txt_targetScanner_sn_callback;
    private TextView txt_targetScanner_connection_status_callback;
    private TextView txt_targetScanner_sn;
    private TextView txt_targetScanner_connection_status;
    private TextView txt_dataTerminator;
    private TextView txt_actionName;
    private TextView txt_dataKey;
    private TextView txt_dataTypeKey;
    private TextView txt_dataLengthKey;
    private TextView txt_dataByteKey;
    private TextView txt_enable_byte;
    private TextView txt_enable_length;
    private TextView txt_enable_type;
    private TextView txt_scan2key;
    private TextView txt_clipboard;
    private TextView txt_output_method;
    private TextView txt_format;
    private TextView txt_buffer_action;
    private TextView txt_intent_cost;
    private TextView txt_encoding;
    private TextView txt_formatting_status;
    private TextView txt_removeNonPrintableChar;
    private TextView txt_formatting;
    private TextView txt_floatingButton;
    private TextView txt_sound;
    private TextView txt_sound_freq;
    private TextView txt_sound_duration;
    private TextView txt_vibration;
    private TextView txt_startup;
    private TextView txt_autoEnforce;
    private EditText edt_set_inter_char_delay;
    private EditText edt_prefix;
    private EditText edt_suffix;
    private EditText edt_find;
    private EditText edt_replacement;
    private EditText edt_formatting;
    private EditText edt_formatting_type;
    private Spinner spinner_DataACK;
    private Spinner spinner_BeetTimes;
    private Spinner spinner_Vibrate;
    private Spinner spinner_LEDColor;
    private Spinner spinner_ConfigName;
    private AlertDialog mDialog = null;
    //----------------------------------------------------------------------------------------------
    private final Hashtable <String, Integer> ConfigTable = new Hashtable <>();
    private IMyAidlInterface_IsMainActiviyRunning myAidlInterface_isMainActivityRunning;
    private ServiceConnection mConnection = null;
    private String bufferAction = "";
    private long startTime = 0;
    private String usuDataAction = "USU_INTENT_DATA_ACTION";
    private String usuDataKey = "data";
    private String usuDataTypeKey = "datatype";
    private String usuDataLengthKey = "datalength";
    private String usuDataByteKey = "databyte";
    private final String usuPackage = "com.unitech.scanner.utility";
    //----------------------------------------------------------------------------------------------
    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent mIntent) {
            String action = mIntent.getAction();
            Bundle bundle = mIntent.getExtras();
            logWriter("mReceiver action=" + action);
            if (bundle != null) {
                logWriter("mReceiver bundle = " + bundle.keySet());
            }

            if (action == null) return;
            if (bundle == null) return;

            if (action.equals(bufferAction + "_reply")) {
                bufferAction = "";
                String cost = nowTime() - startTime + " ms";
                txt_intent_cost.setText(cost);
            }
            if (action.equals(usuDataAction)) {
                if (bundle.get(usuDataKey) != null) {
                    String data = bundle.getString(usuDataKey);
                    txt_Data.setText(data);
                }
                if (bundle.get(usuDataTypeKey) != null) {
                    int type = bundle.getInt(usuDataTypeKey);
                    txt_CodeType.setText(String.valueOf(type));
                }
                if (bundle.get(usuDataLengthKey) != null) {
                    int length = bundle.getInt(usuDataLengthKey);
                    txt_DataLength.setText(String.valueOf(length));
                }
                if (bundle.get(usuDataByteKey) != null) {
                    byte[] array = bundle.getByteArray(usuDataByteKey);
                    txt_DataByte.setText(Arrays.toString(array));
                }
            }
            switch (action) {
                case AllUsageAction.apiGetBatteryReply: {//Battery Status
                    int data = bundle.getInt("battery", -1);
                    String battery = "Unknown";
                    switch (data) {
                        case 0:
                            battery = "Charging";
                            break;
                        case 1:
                            battery = "Very Low";
                            break;
                        case 2:
                            battery = "Low";
                            break;
                        case 3:
                            battery = "OK";
                            break;
                        case 4:
                            battery = "Full";
                            break;
                    }
                    txt_Battery.setText(battery);
                    logWriter("Get Battery = " + battery);
                    break;
                }
                case AllUsageAction.apiGetTriggerReply: { //Trigger Key Status
                    boolean trig = bundle.getBoolean("trig", true);
                    txt_TriggerStatus.setText(String.valueOf(trig));
//                    showSnack("Trigger Key Status : " + trig);
                    logWriter("Trigger Key Status : " + trig);
                    break;
                }
                case AllUsageAction.apiGetAutoConnectionReply: {//Auto Connection Status
                    boolean status = bundle.getBoolean("autoConn", true);
                    txt_AutoConnStatus.setText(String.valueOf(status));
//                    showSnack("Auto Connection : " + status);
                    logWriter("Auto Connection : " + status);
                    break;
                }
                case AllUsageAction.apiGetPairingBarcodeReply: {
                    String pairingBarcode = bundle.getString("PairingBarcodeContent");
                    logWriter("PairingBarcodeContent : " + pairingBarcode);
                    if (pairingBarcode != null) {
                        SharedPreferences sharedPreferences = getSharedPreferences(getString(R.string.LocalInfo), Context.MODE_PRIVATE);
                        sharedPreferences.edit().putString("PairingBarcodeContent", pairingBarcode).apply();
                        getSupportFragmentManager().beginTransaction().replace(R.id.settingFrag, new BtImageFragment()).commit();
                    }
                    break;
                }
                case AllUsageAction.apiGetTargetScannerStatusReply:// Get Target Scanner Status
                {
                    boolean isConnected = bundle.getBoolean("IsConnected", false);
                    String sn = mIntent.getStringExtra("serialNo");
                    logWriter("target scanner is connected : " + isConnected + " , SN : " + sn);
                    if (sn != null) {
                        //sn has value
                        txt_targetScanner_sn.setText(sn);
                    }
                    txt_targetScanner_connection_status.setText(
                            isConnected ? getString(R.string.connected) : getString(R.string.disconnected)
                    );
                    break;
                }
                case AllUsageAction.apiTargetScanner:// Get Target Scanner
                {
                    boolean isConnected = bundle.getBoolean("IsConnected", false);
                    String sn = mIntent.getStringExtra("serialNo");
                    logWriter("target scanner is connected : " + isConnected + " , SN : " + sn);
                    if (sn != null) {
                        //sn has value
                        txt_targetScanner_sn_callback.setText(sn);
                    }
                    txt_targetScanner_connection_status_callback.setText(
                            isConnected ? getString(R.string.connected) : getString(R.string.disconnected)
                    );
                    break;
                }
                case AllUsageAction.apiGetSNReply: {//Serial Number
                    String sn = bundle.getString("sn");
                    txt_SerialNumber.setText(sn);
                    logWriter("get SN : " + sn);
                    break;
                }
                case AllUsageAction.apiGetFWReply: {//Firmware Version
                    String fw = bundle.getString("fw");
                    txt_FirmwareVersion.setText(fw);
                    logWriter("get FW : " + fw);
                    break;
                }
                case AllUsageAction.apiGetNameReply: {//Bluetooth Name
                    String name = bundle.getString("name");
                    txt_BluetoothName.setText(name);
                    logWriter("get bt name : " + name);
                    break;
                }
                case AllUsageAction.apiGetAddressReply: {//Bluetooth MAC Address
                    String btMAC = bundle.getString("address");
                    txt_BluetoothMAC.setText(btMAC);
                    logWriter("get address : " + btMAC);
                    break;
                }
                case AllUsageAction.apiGetAckReply: {//ACK Status
                    boolean status = bundle.getBoolean("ack", true);
                    txt_ACKStatus.setText(String.valueOf(status));
                    logWriter("get ack : " + status);
                    break;
                }
                case AllUsageAction.apiDataCodeType: {//SSI code type and data
                    byte codeType = bundle.getByte("codeType", (byte) 0xff);
                    txt_CodeType.setText(codeType != (byte) 0xff ? byteToHex(codeType) : "");
                    logWriter("code type : " + codeType);
                    break;
                }
                case AllUsageAction.apiGetFormatReply: {  //Get Format
                    int format = bundle.getInt("format", -1);
                    txt_format.setText(format == 0 ? "RAW" : "SSI");
                    break;
                }
                case AllUsageAction.apiGetDataTerminatorReply: {//Get Data Terminator
                    int dataTerminator = bundle.getInt("DataTerminator", 2);
                    String terminator = "";
                    switch (dataTerminator) {
                        case 0:
                            terminator = "None";
                            break;
                        case 1:
                            terminator = "CR";
                            break;
                        case 2:
                            terminator = "LF";
                            break;
                        case 3:
                            terminator = "CRLF";
                            break;
                        case 4:
                            terminator = "TAB";
                            break;
                    }
                    if (!terminator.equals("")) {
                        logWriter("Terminator is " + terminator);
                        txt_dataTerminator.setText(terminator);
                    }
                    break;
                }
                case AllUsageAction.apiGetIntentActionReply: {
                    String actionName = bundle.getString("actionName");
                    String dataKey = bundle.getString("dataKey");
                    String dataTypeKey = bundle.getString("dataTypeKey");
                    String dataLengthKey = bundle.getString("dataLengthKey");
                    String dataByteKey = bundle.getString("dataByteKey");
                    boolean enableByte = bundle.getBoolean("enableByte");
                    boolean enableType = bundle.getBoolean("enableType");
                    boolean enableLength = bundle.getBoolean("enableLength");
                    logWriter("Get Intent Action = " + actionName + ", dataKey = " + dataKey + ", dataTypeKey = " + dataTypeKey + ", dataLengthKey = " + dataLengthKey + ", dataByteKey = " + dataByteKey);
                    logWriter("Get Intent enableByte = " + enableByte + ", enableType = " + enableType + ", enableLength = " + enableLength);
                    txt_actionName.setText(actionName);
                    txt_dataKey.setText(dataKey);
                    txt_dataTypeKey.setText(dataTypeKey);
                    txt_dataLengthKey.setText(dataLengthKey);
                    txt_dataByteKey.setText(dataByteKey);
                    txt_enable_byte.setText(String.valueOf(enableByte));
                    txt_enable_length.setText(String.valueOf(enableLength));
                    txt_enable_type.setText(String.valueOf(enableType));

                    usuDataAction = actionName;
                    usuDataKey = dataKey;
                    usuDataTypeKey = dataTypeKey;
                    usuDataLengthKey = dataLengthKey;
                    usuDataByteKey = dataByteKey;

                    setReceiverEnable(false);
                    setReceiverEnable(true, actionName);
                    break;
                }
//                case AllUsageAction.apiData: {//Data
//                    String data = bundle.getString("text");
//                    txt_Data.setText(data);
//                    logWriter("Get Data = " + data);
////                    showSnack("Get data :" + data);
//                    break;
//                }
//                case AllUsageAction.apiDataLength: {//Data Length
//                    int length = bundle.getInt("text", 0);
//                    txt_DataLength.setText(String.valueOf(length));
//                    logWriter("Get Data length = " + length);
//                    break;
//                }
//                case AllUsageAction.apiDataByte: { //Data Byte
//                    byte[] dataByte = bundle.getByteArray("text");
//                    txt_DataByte.setText(Arrays.toString(dataByte));
//                    logWriter("Get Data byte = " + Arrays.toString(dataByte));
//                    break;
//                }
//                case AllUsageAction.apiDataByteLength: {//Data Byte Length
//                    int dataByteLength = bundle.getInt("text", 0);
//                    txt_DataByteLength.setText(String.valueOf(dataByteLength));
//                    logWriter("Get Data byte length = " + dataByteLength);
//                    break;
//                }
//                case AllUsageAction.apiDataAll: {//Data All
//                    int dataByteLength = bundle.getInt("databytelength", 0);
//                    byte[] dataByte = bundle.getByteArray("databyte");
//                    logWriter("Get Data byte length = " + dataByteLength);
//                    logWriter("Get Data byte = " + Arrays.toString(dataByte));
//                    String str = "Data : " + Arrays.toString(dataByte) + " Len : " + dataByteLength;
//                    txt_DataAll.setText(str);
//                    break;
//                }
                case AllUsageAction.apiGetConfigReply: {//Get Configuration Reply
                    ConfigTable.clear();
                    spinner_ConfigName.setAdapter(null);
                    String[] configNameList = new String[bundle.keySet().size()];

                    int i = 0;
                    for (String key : bundle.keySet()) {
                        try {
                            Object value = bundle.get(key);
                            if (value == null) {
                                continue;
                            }
                            configNameList[i++] = key;
                            ConfigTable.put(key, (Integer) bundle.get(key));
                            logWriter(String.format("%s %s (%s)", key, value.toString(), value.getClass().getName()));
                        } catch (Exception e) {
                            Logger.error("Get config error = " + key + " message = " + e.getMessage());
                            e.printStackTrace();
                        }

                    }

                    if (configNameList.length > 0) {
                        ArrayAdapter <String> adapter = new ArrayAdapter <>(MainActivity.this, android.R.layout.simple_spinner_dropdown_item, configNameList);
                        spinner_ConfigName.setAdapter(adapter);
                    }

                    break;
                }
                case AllUsageAction.apiGetBtSignalCheckingLevelReply: {//Get Bluetooth Signal Check Status
                    int level = bundle.getInt("btSignalCheckingLevel", 0);
                    txt_SignalCheckingLevel.setText(level == 0 ? "Normal" : "Higher");
                    logWriter("BT signal level = " + (level == 0 ? "Normal" : "Higher"));
                    break;
                }
                case AllUsageAction.apiGetScan2keyReply: { //Get Scan2Key
                    boolean scan2Key = bundle.getBoolean("scan2key", true);
                    txt_scan2key.setText(scan2Key ? "Enable" : "Disable");
                    logWriter("Scan to Key = " + (scan2Key ? "Enable" : "Disable"));
                    break;
                }
                case AllUsageAction.apiGetOutputReply: { //Get Output
                    boolean enableClipboard = bundle.getBoolean("enableClipboard", false);
                    int method = bundle.getInt("method", 0);
                    int interCharDelay = bundle.getInt("interCharDelay", 0);
                    txt_clipboard.setText(enableClipboard ? "Enable" : "Disable");
                    txt_output_method.setText(method == 0 ? "Copy/Paste" : "KeyEmulator");
                    edt_set_inter_char_delay.setText(String.valueOf(interCharDelay));
                    logWriter("Output enableClipboard= " + (enableClipboard ? "Enable" : "Disable") + " , method = " + (method == 0 ? "Copy/Paste" : "KeyEmulator") + " , interCharDelay = " + interCharDelay);
                    break;
                }
                case AllUsageAction.apiGetEncodingReply: { //Get Encoding
                    int encoding = bundle.getInt("encoding", 0);
                    String sEncoding = "UTF-8";
                    switch (encoding) {
                        case 1:
                            sEncoding = "GBK";
                            break;
                        case 2:
                            sEncoding = "BIG5";
                            break;
                        case 3:
                            sEncoding = "ShiftJIS";
                            break;
                    }
                    txt_encoding.setText(sEncoding);

                    logWriter("Encoding = " + sEncoding);
                    break;
                }
                case AllUsageAction.apiGetFormattingStatusReply: { //Get FormattingStatus
                    boolean enable = bundle.getBoolean("enable", false);
                    txt_formatting_status.setText(enable ? "Enable" : "Disable");
                    logWriter("FormattingStatus = " + (enable ? "Enable" : "Disable"));
                    break;
                }
                case AllUsageAction.apiGetAppendReply: { //Get Append
                    String prefix = bundle.getString("prefix", "");
                    String suffix = bundle.getString("suffix", "");
                    edt_prefix.setText(prefix);
                    edt_suffix.setText(suffix);
                    logWriter("Append prefix= " + prefix + " , suffix = " + suffix);
                    break;
                }
                case AllUsageAction.apiGetReplaceReply: { //Get Replace
                    String find = bundle.getString("find", "");
                    String replacement = bundle.getString("replacement", "");
                    edt_find.setText(find);
                    edt_replacement.setText(replacement);
                    logWriter("Replace find= " + find + " , replacement = " + replacement);
                    break;
                }
                case AllUsageAction.apiGetRemoveNonPrintableCharReply: { //Get RemoveNonPrintableCharReply
                    boolean enable = bundle.getBoolean("enable", false);
                    txt_removeNonPrintableChar.setText(enable ? "Enable" : "Disable");
                    logWriter("removeNonPrintableChar = " + (enable ? "Enable" : "Disable"));
                    break;
                }
                case AllUsageAction.apiGetFormattingReply: { //Get FormattingReply
                    String formatting = bundle.getString("formatting", "{}");
                    txt_formatting.setText(formatting);
                    logWriter("Formatting = " + formatting);
                    break;
                }
                case AllUsageAction.apiGetFloatingButtonReply: { //Get FloatingButtonReply
                    boolean enable = bundle.getBoolean("enable", false);
                    txt_floatingButton.setText(enable ? "Enable" : "Disable");
                    logWriter("FloatingButton = " + (enable ? "Enable" : "Disable"));
                    break;
                }
                case AllUsageAction.apiGetSoundReply: { //Get SoundReply
                    boolean enable = bundle.getBoolean("enable", true);
                    int freq = bundle.getInt("freq", 1);
                    int duration = bundle.getInt("duration", 1);
                    String sFreq = "";
                    switch (freq) {
                        case 0:
                            sFreq = "Base";
                            break;
                        case 1:
                            sFreq = "Normal";
                            break;
                        case 2:
                            sFreq = "Sharp";
                            break;
                    }
                    txt_sound_freq.setText(sFreq);
                    String sDuration = "";
                    switch (duration) {
                        case 0:
                            sDuration = "Short";
                            break;
                        case 1:
                            sDuration = "Medium";
                            break;
                        case 2:
                            sDuration = "Long";
                            break;
                    }
                    txt_sound_duration.setText(sDuration);

                    txt_sound.setText(enable ? "Enable" : "Disable");
                    logWriter("Sound enable = " + (enable ? "Enable" : "Disable")+" , freq = "+sFreq+" , duration = "+sDuration);
                    break;
                }
                case AllUsageAction.apiGetVibrationReply: { //Get VibrationReply
                    boolean enable = bundle.getBoolean("enable", false);
                    txt_vibration.setText(enable ? "Enable" : "Disable");
                    logWriter("Vibration = " + (enable ? "Enable" : "Disable"));
                    break;
                }
                case AllUsageAction.apiGetStartupReply: { //Get StartupReply
                    boolean enable = bundle.getBoolean("enable", false);
                    txt_startup.setText(enable ? "Enable" : "Disable");
                    logWriter("Startup = " + (enable ? "Enable" : "Disable"));
                    break;
                }
                case AllUsageAction.apiGetAutoEnforceSettingsReply: { //Get AutoEnforceSettingsReply
                    boolean enable = bundle.getBoolean("enable", false);
                    txt_autoEnforce.setText(enable ? "Enable" : "Disable");
                    logWriter("AutoEnforceSettings = " + (enable ? "Enable" : "Disable"));
                    break;
                }
            }
        }
    };
    //endregion
    //==============================================================================================
    //region LifeCycle

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        WindowManager.LayoutParams params = getWindow().getAttributes();
        params.screenBrightness = 0.75f;
        getWindow().setAttributes(params);
        //------------------------------------------------------------------------------------------

        checkPermission();
        findViewId();
        setViewEvent();
        //------------------------------------------------------------------------------------------
        Util_API = new util_usu_api(this, getPackageName());
        mConnection = new ServiceConnection() {
            // Called when the connection with the service is established
            public void onServiceConnected(ComponentName className, IBinder service) {
                // Following the example above for an AIDL interface,
                // this gets an instance of the IRemoteInterface, which we can use to call on the service
                myAidlInterface_isMainActivityRunning = IMyAidlInterface_IsMainActiviyRunning.Stub.asInterface(service);
                // We want to monitor the service for as long as we are
                // connected to it.
                Logger.tag("ServiceConnection").debug("onServiceConnected");
            }

            // Called when the connection with the service disconnects unexpectedly
            public void onServiceDisconnected(ComponentName className) {
                Logger.tag("ServiceConnection").error("Service has unexpectedly disconnected");
                myAidlInterface_isMainActivityRunning = null;
            }
        };

        bindService(new Intent(AllUsageAction.apiUSURunning).setPackage(usuPackage), mConnection, Context.BIND_AUTO_CREATE);
        new Handler().postDelayed(() -> startUSU(getWindow().getDecorView()), 100);
        //------------------------------------------------------------------------------------------
        Intent intent = getPackageManager().getLaunchIntentForPackage(usuPackage);
        if (intent == null) return;
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK)
                .putExtra("ismoveTaskToBack", true);
        startActivity(intent);
        //------------------------------------------------------------------------------------------

    }

    private boolean destroyFlag = false;
    @Override
    protected void onDestroy() {
        Logger.debug("onDestroy");
        while (!destroyFlag) {
            try {
                if (mConnection != null) {
                    unbindService(mConnection);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            Intent intent = getPackageManager().getLaunchIntentForPackage(usuPackage);
            if (intent == null) return;
            intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK)
                    .putExtra("ismoveTaskToBack", false);
            startActivity(intent);
            sendBroadcast(new Intent(AllUsageAction.usuExit));
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            destroyFlag = true;
        }
        super.onDestroy();

    }

    @Override
    public void onResume() {
        super.onResume();
        setReceiverEnable(true, usuDataAction);

    }

    @Override
    public void onPause() {
        super.onPause();
        setReceiverEnable(false);

    }

    private void setReceiverEnable(boolean enable, String... action) {
        if (enable) {
            IntentFilter filter = new IntentFilter();
            filter.addAction(AllUsageAction.apiGetPairingBarcodeReply);//2.1
            filter.addAction(AllUsageAction.apiGetTargetScannerStatusReply);//2.2
            filter.addAction(AllUsageAction.apiTargetScanner);//2.3
            filter.addAction(AllUsageAction.apiUnpairedReply);//2.4
            filter.addAction(AllUsageAction.apiGetSNReply);//2.5
            filter.addAction(AllUsageAction.apiGetNameReply);//2.6
            filter.addAction(AllUsageAction.apiGetAddressReply);//2.7
            filter.addAction(AllUsageAction.apiGetFWReply);//2.8
            filter.addAction(AllUsageAction.apiGetBatteryReply);//2.9

            filter.addAction(AllUsageAction.apiSetTriggerReply);//3.1
            filter.addAction(AllUsageAction.apiGetTriggerReply);//3.1
            filter.addAction(AllUsageAction.apiStartDecodeReply);//3.2
            filter.addAction(AllUsageAction.apiStopDecodeReply);//3.3
            filter.addAction(AllUsageAction.apiSetAckReply);//3.4
            filter.addAction(AllUsageAction.apiGetAckReply);//3.4
            filter.addAction(AllUsageAction.apiSetAutoConnectionReply);//3.5
            filter.addAction(AllUsageAction.apiGetAutoConnectionReply);//3.5
            filter.addAction(AllUsageAction.apiSetConfigReply);//3.6
            filter.addAction(AllUsageAction.apiGetConfigReply);//3.6
            filter.addAction(AllUsageAction.apiSetBtSignalCheckingLevelReply);//3.7
            filter.addAction(AllUsageAction.apiGetBtSignalCheckingLevelReply);//3.7
            filter.addAction(AllUsageAction.apiSetDataTerminatorReply);//3.8
            filter.addAction(AllUsageAction.apiGetDataTerminatorReply);//3.8

            filter.addAction(AllUsageAction.apiChangeToFormatSsiReply);//4.1
            filter.addAction(AllUsageAction.apiChangeToFormatRawReply);//4.1
//            filter.addAction(AllUsageAction.apiData);//4.1
//            filter.addAction(AllUsageAction.apiDataLength);//4.1
//            filter.addAction(AllUsageAction.apiDataByte);//4.1
//            filter.addAction(AllUsageAction.apiDataByteLength);//4.1
//            filter.addAction(AllUsageAction.apiDataAll);//4.1
//            filter.addAction(AllUsageAction.apiDataCodeType);//4.1
            filter.addAction(AllUsageAction.apiGetFormatReply);//4.1
            filter.addAction(AllUsageAction.apiSetIntentActionReply);//4.1
            filter.addAction(AllUsageAction.apiGetIntentActionReply);//4.1
            filter.addAction(AllUsageAction.apiSetIndicatorReply);//4.2

            filter.addAction(AllUsageAction.apiExportSettingsReply);//5.1
            filter.addAction(AllUsageAction.apiImportSettingsReply);//5.2
            filter.addAction(AllUsageAction.apiUploadSettingsReply);//5.3
            filter.addAction(AllUsageAction.apiResetSettingsReply);//5.4
            filter.addAction(AllUsageAction.apiGetScan2keyReply);//5.5
            filter.addAction(AllUsageAction.apiSetScan2keyReply);//5.5
            filter.addAction(AllUsageAction.apiGetOutputReply);//5.6
            filter.addAction(AllUsageAction.apiSetOutputReply);//5.6
            filter.addAction(AllUsageAction.apiGetEncodingReply);//5.7
            filter.addAction(AllUsageAction.apiSetEncodingReply);//5.7
            filter.addAction(AllUsageAction.apiGetFormattingStatusReply);//5.8
            filter.addAction(AllUsageAction.apiSetFormattingStatusReply);//5.8
            filter.addAction(AllUsageAction.apiGetAppendReply);//5.9
            filter.addAction(AllUsageAction.apiSetAppendReply);//5.9
            filter.addAction(AllUsageAction.apiGetReplaceReply);//5.10
            filter.addAction(AllUsageAction.apiSetReplaceReply);//5.10
            filter.addAction(AllUsageAction.apiGetRemoveNonPrintableCharReply);//5.11
            filter.addAction(AllUsageAction.apiSetRemoveNonPrintableCharReply);//5.11
            filter.addAction(AllUsageAction.apiGetFormattingReply);//5.12
            filter.addAction(AllUsageAction.apiSetFormattingReply);//5.12
            filter.addAction(AllUsageAction.apiDeleteFormattingReply);//5.12
            filter.addAction(AllUsageAction.apiGetFloatingButtonReply);//5.13
            filter.addAction(AllUsageAction.apiSetFloatingButtonReply);//5.13
            filter.addAction(AllUsageAction.apiGetSoundReply);//5.14
            filter.addAction(AllUsageAction.apiSetSoundReply);//5.14
            filter.addAction(AllUsageAction.apiGetVibrationReply);//5.15
            filter.addAction(AllUsageAction.apiSetVibrationReply);//5.15
            filter.addAction(AllUsageAction.apiGetStartupReply);//5.16
            filter.addAction(AllUsageAction.apiSetStartupReply);//5.16
            filter.addAction(AllUsageAction.apiGetAutoEnforceSettingsReply);//5.17
            filter.addAction(AllUsageAction.apiSetAutoEnforceSettingsReply);//5.17

            if (action != null) {
                for (String s : action) {
                    filter.addAction(s);
                }
            }

            registerReceiver(mReceiver, filter);
        } else {
            unregisterReceiver(mReceiver);
        }
    }

    //endregion
    //==============================================================================================
    //region Menu

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // 設置要用哪個menu檔做為選單
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle item selection
        int itemID = item.getItemId();

        if (itemID == R.id.action_about) {
            aboutSettings();
        } else if (itemID == R.id.action_detail) {
            detailSettings();
        }
        return super.onOptionsItemSelected(item);
    }

    //endregion
    //==============================================================================================
    //region ViewSupport

    private void findViewId() {
        txt_TriggerStatus = findViewById(R.id.txt_triggerStatus);
        txt_Battery = findViewById(R.id.txt_BatteryStatus);
        txt_SerialNumber = findViewById(R.id.txt_ScannerSerialNumber);
        txt_FirmwareVersion = findViewById(R.id.txt_ScannerFirmwareVersion);
        txt_BluetoothName = findViewById(R.id.txt_ScannerBluetoothName);
        txt_BluetoothMAC = findViewById(R.id.txt_ScannerBluetoothAddress);
        txt_ACKStatus = findViewById(R.id.txt_ack_status);
        txt_AutoConnStatus = findViewById(R.id.txt_auto_conn_status);
        txt_CodeType = findViewById(R.id.CodeType_data);
        txt_Data = findViewById(R.id.txt_data);
        txt_DataLength = findViewById(R.id.txt_data_length);
        txt_DataByte = findViewById(R.id.txt_data_byte);
        txt_DataByteLength = findViewById(R.id.txt_data_byte_length);
        txt_DataAll = findViewById(R.id.txt_data_all);
        txt_SetConfigName = findViewById(R.id.txt_set_config_name);
        txt_SetConfigValue = findViewById(R.id.txt_set_config_value);
        txt_GetConfigValue = findViewById(R.id.txt_config_value);
        txt_SignalCheckingLevel = findViewById(R.id.txt_signalLevelStatus);
        txt_targetScanner_sn_callback = findViewById(R.id.targetScanner_sn_callback);
        txt_targetScanner_connection_status_callback = findViewById(R.id.targetScanner_connection_status_callback);
        txt_targetScanner_sn = findViewById(R.id.targetScanner_sn);
        txt_targetScanner_connection_status = findViewById(R.id.targetScanner_connection_status);
        txt_dataTerminator = findViewById(R.id.txt_dataTerminator);
        txt_actionName = findViewById(R.id.txt_actionName);
        txt_dataKey = findViewById(R.id.txt_dataKey);
        txt_dataTypeKey = findViewById(R.id.txt_dataTypeKey);
        txt_dataLengthKey = findViewById(R.id.txt_dataLengthKey);
        txt_dataByteKey = findViewById(R.id.txt_dataByteKey);
        txt_enable_byte = findViewById(R.id.txt_enable_byte);
        txt_enable_length = findViewById(R.id.txt_enable_length);
        txt_enable_type = findViewById(R.id.txt_enable_type);
        txt_scan2key = findViewById(R.id.txt_scan2key);
        txt_clipboard = findViewById(R.id.txt_clipboard);
        txt_output_method = findViewById(R.id.txt_output_method);
        txt_format = findViewById(R.id.txt_format);
        txt_buffer_action = findViewById(R.id.txt_buffer_action);
        txt_intent_cost = findViewById(R.id.txt_intent_cost);
        txt_encoding = findViewById(R.id.txt_encoding);
        txt_formatting_status = findViewById(R.id.txt_formatting_status);
        txt_removeNonPrintableChar = findViewById(R.id.txt_removeNonPrintableChar);
        txt_formatting = findViewById(R.id.txt_formatting);
        txt_floatingButton = findViewById(R.id.txt_floatingButton);
        txt_sound = findViewById(R.id.txt_sound);
        txt_sound_freq = findViewById(R.id.txt_sound_freq);
        txt_sound_duration = findViewById(R.id.txt_sound_duration);
        txt_vibration = findViewById(R.id.txt_vibration);
        txt_startup = findViewById(R.id.txt_startup);
        txt_autoEnforce = findViewById(R.id.txt_autoEnforce);
        edt_set_inter_char_delay = findViewById(R.id.edt_set_inter_char_delay);
        edt_prefix = findViewById(R.id.edt_prefix);
        edt_suffix = findViewById(R.id.edt_suffix);
        edt_find = findViewById(R.id.edt_find);
        edt_replacement = findViewById(R.id.edt_replacement);
        edt_formatting = findViewById(R.id.edt_formatting);
        edt_formatting_type = findViewById(R.id.edt_formatting_type);
        spinner_DataACK = findViewById(R.id.spinner_data_ack);
        spinner_BeetTimes = findViewById(R.id.spinner_beep_times);
        spinner_Vibrate = findViewById(R.id.spinner_vibrate);
        spinner_LEDColor = findViewById(R.id.spinner_led_color);
        spinner_ConfigName = findViewById(R.id.spinner_configs);
    }

    private void setViewEvent() {
        spinner_ConfigName.setOnItemSelectedListener(new Spinner.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView <?> adapterView, View view, int i, long l) {
                try {
                    txt_GetConfigValue.setText(String.valueOf(ConfigTable.get(spinner_ConfigName.getSelectedItem().toString())));
                    txt_SetConfigName.setText(spinner_ConfigName.getSelectedItem().toString());
                } catch (Exception e) {
                    txt_GetConfigValue.setText("");
                }
            }

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

            }
        });

        int layout = android.R.layout.simple_spinner_dropdown_item;
        spinner_BeetTimes.setAdapter(new ArrayAdapter <>(getApplicationContext(), layout, parseIntArray(getResources().getIntArray(R.array.beep_times))));
        spinner_DataACK.setAdapter(new ArrayAdapter <>(getApplicationContext(), layout, getResources().getStringArray(R.array.status)));
        spinner_Vibrate.setAdapter(new ArrayAdapter <>(getApplicationContext(), layout, getResources().getStringArray(R.array.status)));
        spinner_LEDColor.setAdapter(new ArrayAdapter <>(getApplicationContext(), layout, getResources().getStringArray(R.array.led)));
    }

    private void checkPermission() {
        String PERMISSION_WRITE_STORAGE = "android.permission.WRITE_EXTERNAL_STORAGE";
        String PERMISSION_READ_STORAGE = "android.permission.READ_EXTERNAL_STORAGE";
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if ((ActivityCompat.checkSelfPermission(this, PERMISSION_WRITE_STORAGE) != PackageManager.PERMISSION_GRANTED) ||
                    (ActivityCompat.checkSelfPermission(this, PERMISSION_READ_STORAGE) != PackageManager.PERMISSION_GRANTED)
            ) {
                String[] perms = {PERMISSION_WRITE_STORAGE, PERMISSION_READ_STORAGE};
                int permsRequestCode = 1;
                requestPermissions(perms, permsRequestCode);
            }
        }
    }
    //endregion
    //==============================================================================================
    //region Util

    public void startUSU(View view) {
        if (myAidlInterface_isMainActivityRunning != null) {
            Logger.tag("ServiceConnection").debug("myAidlInterface_isMainActivityRunning!=null");
            boolean isRunning = false;
            if (myAidlInterface_isMainActivityRunning.asBinder().isBinderAlive()) {
                try {
                    isRunning = myAidlInterface_isMainActivityRunning.isRunning();
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
            Logger.tag("ServiceConnection").debug("isRunning = " + isRunning);
        } else {
            Logger.tag("ServiceConnection").debug("myAidlInterface_isMainActivityRunning==null");
        }
    }

    private Integer[] parseIntArray(int[] intArray) {
        Integer[] returnArray = new Integer[intArray.length];
        int i = 0;
        for (int value : intArray) {
            returnArray[i++] = value;
        }
        return returnArray;
    }

    public String byteToHex(byte num) {
        char[] hexDigits = new char[2];
        hexDigits[0] = Character.forDigit((num >> 4) & 0xF, 16);
        hexDigits[1] = Character.forDigit((num & 0xF), 16);
        return new String(hexDigits);
    }

    private void logWriter(String logText) {
        Logger.debug(logText);
    }

    /**
     * Show app's version
     */
    private void aboutSettings() {
        if (mDialog != null && mDialog.isShowing()) {
            mDialog.dismiss();
            mDialog = null;
        }
        String mMessage = getString(R.string.version) + getVersionName(this) + "\n"
                + getString(R.string.copyright);
        mDialog = new androidx.appcompat.app.AlertDialog.Builder(MainActivity.this)
                .setTitle(getString(R.string.about))
                .setMessage(mMessage)
                .create();
        mDialog.show();
    }

    /**
     * Explain the intent of the application
     */
    private void detailSettings() {
        if (mDialog != null && mDialog.isShowing()) {
            mDialog.dismiss();
            mDialog = null;
        }
        mDialog = new androidx.appcompat.app.AlertDialog.Builder(MainActivity.this)
                .setTitle(getString(R.string.detail))
                .setMessage(getString(R.string.detailMessage))
                .create();
        mDialog.show();
    }


    /**
     * get App versionName
     *
     * @param context input the app's context
     * @return version name
     */
    public String getVersionName(Context context) {
        PackageManager packageManager = context.getPackageManager();
        PackageInfo packageInfo;
        String versionName = "";
        try {
            packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
            versionName = packageInfo.versionName;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return versionName;
    }

    private void showSnack(String msg) {
        Snackbar.make(getWindow().getDecorView(), msg, Snackbar.LENGTH_SHORT)
                .setAction("Action", null).show();
    }

    private long nowTime() {
        return System.currentTimeMillis();
    }

    private void setBufferIntent(String action) {
        bufferAction = action;
        startTime = nowTime();
        String str = action.replaceAll("unitech.scanservice.bluetooth.", "")
                .replace("com.unitech.bluetooth.", "")
                .replace("unitech.scanservice.", "");
        txt_buffer_action.setText(str);
        txt_intent_cost.setText("0");
    }

    //endregion
    //==============================================================================================
    //region APIEvent

    //----------------------------------------------------------------------------------------------
    //region chapter2

    //2.1
    public void getPairingBarcode(View view) {
        logWriter("getPairingBarcode");
        setBufferIntent(AllUsageAction.apiGetPairingBarcode);
        Util_API.GetPairingBarcode();
    }

    //2.2
    public void getTargetScannerStatus(View view) {
        logWriter("getTargetScannerStatus");
        txt_targetScanner_sn.setText(getString(R.string.serial_number));
        txt_targetScanner_connection_status.setText(getString(R.string.connection_status));
        setBufferIntent(AllUsageAction.apiGetTargetScannerStatus);
        Util_API.GetTargetScannerStatus();
    }

    //2.4
    public void setDisconnect(View view) {
        logWriter("setDisconnect");
        setBufferIntent(AllUsageAction.apiUnpaired);
        Util_API.SetDisconnect();
    }

    //2.5
    public void getScannerSN(View view) {
        logWriter("getSerialNumber");
        txt_SerialNumber.setText(R.string.unknown);
        setBufferIntent(AllUsageAction.apiGetSN);
        Util_API.GetSerialNumber();
    }

    //2.6
    public void getScannerName(View view) {
        logWriter("getRemoteBTName");
        txt_BluetoothName.setText(R.string.unknown);
        setBufferIntent(AllUsageAction.apiGetName);
        Util_API.GetRemoteBTName();
    }

    //2.7
    public void getScannerMAC(View view) {
        logWriter("getRemoteBTAddress");
        txt_BluetoothMAC.setText(R.string.unknown);
        setBufferIntent(AllUsageAction.apiGetAddress);
        Util_API.GetRemoteBTAddress();
    }

    //2.8
    public void getScannerFW(View view) {
        logWriter("getFirmwareVersion");
        txt_FirmwareVersion.setText(R.string.unknown);
        setBufferIntent(AllUsageAction.apiGetFW);
        Util_API.GetFirmwareVersion();
    }

    //2.9
    public void getScannerBattery(View view) {
        logWriter("getBattery");
        txt_Battery.setText(R.string.unknown);
        setBufferIntent(AllUsageAction.apiGetBattery);
        Util_API.GetBattery();
    }


    //endregion
    //----------------------------------------------------------------------------------------------
    //region chapter3

    //3.1
    public void getTrigger(View view) {
        logWriter("Get trigger");
        txt_TriggerStatus.setText(R.string.unknown);
        setBufferIntent(AllUsageAction.apiGetTrigger);
        Util_API.GetTrigger();
    }

    public void enableTrigger(View view) {
        logWriter("Enable Trigger");
        setTrigger(true);
    }

    public void disableTrigger(View view) {
        logWriter("Disable Trigger");
        setTrigger(false);
    }

    private void setTrigger(boolean status) {
        logWriter("setTrigger to " + status);
        txt_TriggerStatus.setText("");
        setBufferIntent(AllUsageAction.apiSetTrigger);
        Util_API.SetTrigger(status);
    }

    //3.2
    public void startDecode(View view) {
        logWriter("Start Decode");
        //Reset UI
        txt_CodeType.setText("");
        txt_Data.setText("");
        txt_DataLength.setText("");
        txt_DataByte.setText("");
        txt_DataByteLength.setText("");
        txt_DataAll.setText("");
        setBufferIntent(AllUsageAction.aipStartDecode);
        Util_API.StartDecode();
    }

    //3.3
    public void stopDecode(View view) {
        logWriter("stopDecode");
        setBufferIntent(AllUsageAction.apiStopDecode);
        Util_API.StopDecode();
    }

    //3.4
    public void getACK(View view) {
        logWriter("getACK");
        txt_ACKStatus.setText(R.string.unknown);
        setBufferIntent(AllUsageAction.apiGetAck);
        Util_API.GetACK();
    }

    public void enableACK(View view) {
        logWriter("Enable ACK");
        setACK(true);
    }

    public void disableACK(View view) {
        logWriter("Disable ACK");
        setACK(false);
    }

    public void setACK(boolean ack) {
        logWriter("setACK");
        txt_ACKStatus.setText("");
        setBufferIntent(AllUsageAction.apiSetAck);
        Util_API.SetACK(ack);
    }

    //3.5
    public void getAutoConnect(View view) {
        logWriter("getAutoConnect");
        txt_AutoConnStatus.setText(R.string.unknown);
        setBufferIntent(AllUsageAction.apiGetAutoConnection);
        Util_API.GetAutoConnect();
    }

    public void enableAutoConnect(View view) {
        logWriter("Enable Auto Connection");
        setAutoConnect(true);
    }

    public void disableAutoConnect(View view) {
        logWriter("Disable Auto Connection");
        setAutoConnect(false);
    }

    private void setAutoConnect(boolean autoConn) {
        logWriter("setAutoConnect to " + autoConn);
        txt_AutoConnStatus.setText("");
        setBufferIntent(AllUsageAction.apiSetAutoConnection);
        Util_API.SetAutoConnect(autoConn);
    }

    //3.6
    public void getConfiguration(View view) {
        logWriter("getConfiguration");
        setBufferIntent(AllUsageAction.apiGetConfig);
        Util_API.GetConfiguration();
    }

    public void setConfiguration(View view) {
        String configName = txt_SetConfigName.getText().toString();
        try {
            int configValue = Integer.parseInt(txt_SetConfigValue.getText().toString());
            logWriter("Set Configuration of " + configName + " to " + configValue);
            setBufferIntent(AllUsageAction.apiSetConfig);
            Util_API.SetConfiguration(configName, configValue);
        } catch (Exception e) {
            logWriter("setConfig error!");
            txt_SetConfigValue.setText("");
        }
    }


    //3.7
    public void getBTSignalCheckingLevel(View view) {
        logWriter("getBTSignalCheckingLevel");
        txt_SignalCheckingLevel.setText(R.string.unknown);
        setBufferIntent(AllUsageAction.apiGetBtSignalCheckingLevel);
        Util_API.GetBTSignalCheckingLevel();
    }

    public void setNormalLevel(View view) {
        logWriter("Set Normal Signal Checking Level");
        setBTSignalCheckingLevel(0);
    }

    public void setHighLevel(View view) {
        logWriter("Set Higher Signal Checking Level");
        setBTSignalCheckingLevel(1);
    }

    private void setBTSignalCheckingLevel(int level) {
        logWriter("setBTSignalCheckingLevel to " + level);
        txt_SignalCheckingLevel.setText("");
        setBufferIntent(AllUsageAction.apiSetBtSignalCheckingLevel);
        Util_API.SetBTSignalCheckingLevel(level);
    }

    //3.8
    public void getDataTerminator(View view) {
        logWriter("getDataTerminator");
        txt_dataTerminator.setText(R.string.unknown);
        setBufferIntent(AllUsageAction.apiGetDataTerminator);
        Util_API.GetDataTerminator();
    }

    public void toNone(View view) {
        logWriter("Set Data Terminator to NONE");
        setDataTerminator(0);
    }

    public void toCR(View view) {
        logWriter("Set Data Terminator to CR");
        setDataTerminator(1);
    }

    public void toLF(View view) {
        logWriter("Set Data Terminator to LF");
        setDataTerminator(2);
    }

    public void toCRLF(View view) {
        logWriter("Set Data Terminator to CRLF");
        setDataTerminator(3);
    }

    public void toTAB(View view) {
        logWriter("Set Data Terminator to TAB");
        setDataTerminator(4);
    }

    private void setDataTerminator(int parseInt) {
        logWriter("setDataTerminator to " + parseInt);
        txt_dataTerminator.setText("");
        setBufferIntent(AllUsageAction.apiSetDataTerminator);
        Util_API.SetDataTerminator(parseInt);
    }


    //endregion
    //----------------------------------------------------------------------------------------------
    //region chapter4

    //4.1
    public void getFormat(View view) {
        logWriter("getFormat");
        txt_format.setText(R.string.unknown);
        setBufferIntent(AllUsageAction.apiGetFormat);
        Util_API.GetFormat();
    }

    public void changeToSSI(View view) {
        logWriter("changeToSSI");
        txt_format.setText("");
        setBufferIntent(AllUsageAction.apiChangeToFormatSsi);
        Util_API.SetSSIMode();
    }

    public void changeToRAW(View view) {
        logWriter("changeToRAW");
        txt_format.setText("");
        setBufferIntent(AllUsageAction.apiChangeToFormatRaw);
        Util_API.SetRAWMode();
    }

    public void getIntentAction(View view) {
        logWriter("getIntentAction");
        setBufferIntent(AllUsageAction.apiGetIntentAction);
        Util_API.getIntentAction();
    }

    public void setIntentAction(View view) {
        logWriter("setIntentAction");
        setBufferIntent(AllUsageAction.apiSetIntentAction);
        Util_API.setIntentAction("unitech.scanservice.data", "testdata","testdataType","testdataLength","testdataByte", true, true, true);
        txt_actionName.setText("");
        txt_dataKey.setText("");
        txt_dataTypeKey.setText("");
        txt_dataLengthKey.setText("");
        txt_dataByteKey.setText("");
        txt_enable_byte.setText("");
        txt_enable_length.setText("");
        txt_enable_type.setText("");
    }

    //4.2
    public void setIndicator(View view) {
        Bundle bundle = new Bundle();
        bundle.putBoolean("dataAck", spinner_DataACK.getSelectedItem().toString().toLowerCase().equals("true"));
        bundle.putInt("beepTime", Integer.parseInt(spinner_BeetTimes.getSelectedItem().toString()));
        bundle.putBoolean("vibrate", spinner_Vibrate.getSelectedItem().toString().toLowerCase().equals("true"));

        if (spinner_LEDColor.getSelectedItem().toString().toLowerCase().equals("no led")) {
            bundle.putString("ledColor", "none");
        } else {
            bundle.putString("ledColor", spinner_LEDColor.getSelectedItem().toString().toLowerCase());
        }
        StringBuilder str = new StringBuilder();
        for (String key : bundle.keySet()) {
            str.append(key).append(" => ").append(bundle.get(key)).append("\n");
        }
        logWriter("setIndicator " + str);
        setBufferIntent(AllUsageAction.apiSetIndicator);
        Util_API.SetIndicator(bundle);
    }
    //endregion
    //----------------------------------------------------------------------------------------------
    //region chapter5

    //5.1
    public void exportSettings(View view) {
        logWriter("exportSettings");
        setBufferIntent(AllUsageAction.apiExportSettings);
        Util_API.ExportSettings(null);
    }

    //5.2
    public void importSettings(View view) {
        logWriter("importSettings");
        setBufferIntent(AllUsageAction.apiImportSettings);
        Util_API.ImportSettings(null, null);
    }

    //5.3
    public void uploadAllSettings(View view) {
        logWriter("uploadAllSettings");
        setBufferIntent(AllUsageAction.apiUploadSettings);
        Util_API.UploadAllSettings();
    }

    //5.4
    public void resetAllSettings(View view) {
        logWriter("resetAllSettings");
        setBufferIntent(AllUsageAction.apiResetSettings);
        Util_API.resetAllSettings();

        txt_TriggerStatus.setText("");
        txt_Battery.setText("");
        txt_FirmwareVersion.setText("");
        txt_SerialNumber.setText("");
        txt_BluetoothName.setText("");
        txt_BluetoothMAC.setText("");
        txt_ACKStatus.setText("");
        txt_AutoConnStatus.setText("");
        txt_Data.setText("");
        txt_CodeType.setText("");
        txt_DataLength.setText("");
        txt_DataByte.setText("");
        txt_DataByteLength.setText("");
        txt_DataAll.setText("");
        txt_SetConfigName.setText("");
        txt_SetConfigValue.setText("");
        txt_GetConfigValue.setText("");
        txt_SignalCheckingLevel.setText("");
        txt_dataTerminator.setText("");
        txt_actionName.setText("");
        txt_dataKey.setText("");
        txt_dataTypeKey.setText("");
        txt_dataLengthKey.setText("");
        txt_dataByteKey.setText("");
        txt_enable_byte.setText("");
        txt_enable_length.setText("");
        txt_enable_type.setText("");
        txt_format.setText("");
        txt_scan2key.setText("");
        edt_set_inter_char_delay.setText("");
        txt_clipboard.setText("");
        txt_output_method.setText("");
        txt_encoding.setText("");
        txt_formatting_status.setText("");
        edt_prefix.setText("");
        edt_suffix.setText("");
        edt_find.setText("");
        edt_replacement.setText("");
        txt_removeNonPrintableChar.setText("");
        txt_formatting.setText("");
        edt_formatting.setText("");
        edt_formatting_type.setText("");
        txt_floatingButton.setText("");
        txt_sound.setText("");
        txt_sound_freq.setText("");
        txt_sound_duration.setText("");
        txt_vibration.setText("");
        txt_startup.setText("");
        txt_autoEnforce.setText("");
    }

    //5.5
    public void getScan2Key(View view) {
        logWriter("getScan2Key");
        setBufferIntent(AllUsageAction.apiGetScan2key);
        txt_scan2key.setText(R.string.unknown);
        Util_API.getScanToKey();
    }

    public void enableScan2Key(View view) {
        logWriter("enableScan2Key");
        setBufferIntent(AllUsageAction.apiSetScan2key);
        Util_API.setScanToKey(true);
        txt_scan2key.setText("");
    }

    public void disableScan2Key(View view) {
        logWriter("disableScan2Key");
        setBufferIntent(AllUsageAction.apiSetScan2key);
        Util_API.setScanToKey(false);
        txt_scan2key.setText("");
    }

    //5.6
    public void getOutput(View view) {
        logWriter("getOutput");
        setBufferIntent(AllUsageAction.apiGetOutput);
        edt_set_inter_char_delay.setText(R.string.unknown);
        txt_clipboard.setText(R.string.unknown);
        txt_output_method.setText(R.string.unknown);
        Util_API.apiGetOutput();
    }

    public void changeToCopyPaste(View view) {
        logWriter("changeToCopyPaste");
        setBufferIntent(AllUsageAction.apiSetOutput);
        Bundle bundle = new Bundle();
        bundle.putInt("method", 0);
        Util_API.apiSetOutput(bundle);
        txt_output_method.setText("");

    }

    public void changeToEmulator(View view) {
        logWriter("changeToEmulator");
        setBufferIntent(AllUsageAction.apiSetOutput);
        Bundle bundle = new Bundle();
        bundle.putInt("method", 1);
        Util_API.apiSetOutput(bundle);
        txt_output_method.setText("");
    }

    public void enableClipboard(View view) {
        logWriter("enableClipboard");
        setBufferIntent(AllUsageAction.apiSetOutput);
        Bundle bundle = new Bundle();
        bundle.putBoolean("enableClipboard", true);
        Util_API.apiSetOutput(bundle);
        txt_clipboard.setText("");
    }

    public void disableClipboard(View view) {
        logWriter("disableClipboard");
        setBufferIntent(AllUsageAction.apiSetOutput);
        Bundle bundle = new Bundle();
        bundle.putBoolean("enableClipboard", false);
        Util_API.apiSetOutput(bundle);
        txt_clipboard.setText("");
    }

    public void setInterCharDelay(View view) {
        logWriter("setInterCharDelay");
        setBufferIntent(AllUsageAction.apiSetOutput);
        String str = edt_set_inter_char_delay.getText().toString();
        int delay = 0;
        try {
            delay = Integer.parseInt(str);
        } catch (Exception ignored) {
        }
        Bundle bundle = new Bundle();
        bundle.putInt("interCharDelay", delay);
        Util_API.apiSetOutput(bundle);
        edt_set_inter_char_delay.setText("");
    }


    //5.7
    public void getEncoding(View view) {
        logWriter("getEncoding");
        setBufferIntent(AllUsageAction.apiGetEncoding);
        txt_encoding.setText(R.string.unknown);
        Util_API.apiGetEncoding();
    }

    public void toUTF8(View view) {
        logWriter("apiSetEncoding toUTF8");
        setBufferIntent(AllUsageAction.apiSetEncoding);
        Util_API.apiSetEncoding(0);
        txt_encoding.setText("");
    }

    public void toGBK(View view) {
        logWriter("apiSetEncoding toGBK");
        setBufferIntent(AllUsageAction.apiSetEncoding);
        Util_API.apiSetEncoding(1);
        txt_encoding.setText("");
    }

    public void toBIG5(View view) {
        logWriter("apiSetEncoding toBIG5");
        setBufferIntent(AllUsageAction.apiSetEncoding);
        Util_API.apiSetEncoding(2);
        txt_encoding.setText("");
    }

    public void toShiftJIS(View view) {
        logWriter("apiSetEncoding toShiftJIS");
        setBufferIntent(AllUsageAction.apiSetEncoding);
        Util_API.apiSetEncoding(3);
        txt_encoding.setText("");
    }

    //5.8
    public void getFormattingStatus(View view) {
        logWriter("getFormattingStatus");
        setBufferIntent(AllUsageAction.apiGetFormattingStatus);
        txt_formatting_status.setText(R.string.unknown);
        Util_API.apiGetFormattingStatus();
    }

    public void enableFormatting(View view) {
        logWriter("enableFormatting");
        setBufferIntent(AllUsageAction.apiSetFormattingStatus);
        Util_API.apiSetFormattingStatus(true);
        txt_formatting_status.setText("");
    }

    public void disableFormatting(View view) {
        logWriter("disableFormatting");
        setBufferIntent(AllUsageAction.apiSetFormattingStatus);
        Util_API.apiSetFormattingStatus(false);
        txt_formatting_status.setText("");
    }

    //5.9
    public void getAppend(View view) {
        logWriter("getAppend");
        setBufferIntent(AllUsageAction.apiGetAppend);
        edt_prefix.setText(R.string.unknown);
        edt_suffix.setText(R.string.unknown);
        Util_API.apiGetAppend();
    }

    public void setPrefix(View view) {
        logWriter("setPrefix");
        setBufferIntent(AllUsageAction.apiSetAppend);
        Bundle bundle = new Bundle();
        bundle.putString("prefix", edt_prefix.getText().toString());
        Util_API.apiSetAppend(bundle);
        edt_prefix.setText("");
    }

    public void setSuffix(View view) {
        logWriter("setSuffix");
        setBufferIntent(AllUsageAction.apiSetAppend);
        Bundle bundle = new Bundle();
        bundle.putString("suffix", edt_suffix.getText().toString());
        Util_API.apiSetAppend(bundle);
        edt_suffix.setText("");
    }

    //5.10
    public void getReplace(View view) {
        logWriter("getReplace");
        setBufferIntent(AllUsageAction.apiGetReplace);
        edt_find.setText(R.string.unknown);
        edt_replacement.setText(R.string.unknown);
        Util_API.apiGetReplace();
    }

    public void setReplace(View view) {
        logWriter("setReplace");
        setBufferIntent(AllUsageAction.apiSetReplace);
        Bundle bundle = new Bundle();
        bundle.putString("find", edt_find.getText().toString());
        bundle.putString("replacement", edt_replacement.getText().toString());
        Util_API.apiSetReplace(bundle);
        edt_find.setText("");
        edt_replacement.setText("");
    }

    //5.11
    public void getRemoveNonPrintableChar(View view) {
        logWriter("getNonPrintableChar");
        setBufferIntent(AllUsageAction.apiGetRemoveNonPrintableChar);
        txt_removeNonPrintableChar.setText(R.string.unknown);
        Util_API.apiGetRemoveNonPrintableChar();
    }

    public void enableRemoveNonPrintableChar(View view) {
        logWriter("enableNonPrintableChar");
        setBufferIntent(AllUsageAction.apiSetRemoveNonPrintableChar);
        Util_API.apiSetRemoveNonPrintableChar(true);
        txt_removeNonPrintableChar.setText("");
    }

    public void disableRemoveNonPrintableChar(View view) {
        logWriter("enableNonPrintableChar");
        setBufferIntent(AllUsageAction.apiSetRemoveNonPrintableChar);
        Util_API.apiSetRemoveNonPrintableChar(false);
        txt_removeNonPrintableChar.setText("");
    }

    //5.12
    public void getFormatting(View view) {
        logWriter("getFormatting");
        setBufferIntent(AllUsageAction.apiGetFormatting);
        Util_API.apiGetFormatting();
        txt_formatting.setText(getString(R.string.unknown));
    }

    public void setFormatting(View view) {
        logWriter("setFormatting");
        setBufferIntent(AllUsageAction.apiSetFormatting);
        Util_API.apiSetFormatting(edt_formatting.getText().toString());
        edt_formatting.setText("");
        txt_formatting.setText("");
    }

    public void deleteFormatting(View view) {
        logWriter("deleteFormatting");
        setBufferIntent(AllUsageAction.apiDeleteFormatting);
        int type = 0;
        try {
            type = Integer.parseInt(edt_formatting_type.getText().toString());
        } catch (Exception ignore) {

        }
        Util_API.apiDeleteFormatting(type);
        edt_formatting_type.setText("");
        txt_formatting.setText("");
    }

    //5.13
    public void getFloatingButton(View view) {
        logWriter("getFloatingButton");
        setBufferIntent(AllUsageAction.apiGetFloatingButton);
        Util_API.apiGetFloatingButton();
        txt_floatingButton.setText(getString(R.string.unknown));
    }

    public void enableFloatingButton(View view) {
        logWriter("enableFloatingButton");
        setBufferIntent(AllUsageAction.apiSetFloatingButton);
        Util_API.apiSetFloatingButton(true);
        txt_floatingButton.setText("");
    }

    public void disableFloatingButton(View view) {
        logWriter("enableFloatingButton");
        setBufferIntent(AllUsageAction.apiSetFloatingButton);
        Util_API.apiSetFloatingButton(false);
        txt_floatingButton.setText("");
    }

    //5.14
    public void getSound(View view) {
        logWriter("getSound");
        setBufferIntent(AllUsageAction.apiGetSound);
        Util_API.apiGetSound();
        txt_sound.setText(getString(R.string.unknown));
        txt_sound_freq.setText(getString(R.string.unknown));
        txt_sound_duration.setText(getString(R.string.unknown));
    }

    public void enableSound(View view) {
        logWriter("apiSetSound enableSound");
        setBufferIntent(AllUsageAction.apiSetSound);
        Bundle bundle = new Bundle();
        bundle.putBoolean("enable", true);
        Util_API.apiSetSound(bundle);
        txt_sound.setText("");
    }

    public void disableSound(View view) {
        logWriter("apiSetSound disableSound");
        setBufferIntent(AllUsageAction.apiSetSound);
        Bundle bundle = new Bundle();
        bundle.putBoolean("enable", false);
        Util_API.apiSetSound(bundle);
        txt_sound.setText("");
    }

    public void toBaseFreq(View view) {
        logWriter("apiSetSound toBaseFreq");
        setBufferIntent(AllUsageAction.apiSetSound);
        Bundle bundle = new Bundle();
        bundle.putInt("freq", 0);
        Util_API.apiSetSound(bundle);
        txt_sound_freq.setText("");
    }

    public void toNormalFreq(View view) {
        logWriter("apiSetSound toNormalFreq");
        setBufferIntent(AllUsageAction.apiSetSound);
        Bundle bundle = new Bundle();
        bundle.putInt("freq", 1);
        Util_API.apiSetSound(bundle);
        txt_sound_freq.setText("");
    }

    public void toSharpFreq(View view) {
        logWriter("apiSetSound toSharpFreq");
        setBufferIntent(AllUsageAction.apiSetSound);
        Bundle bundle = new Bundle();
        bundle.putInt("freq", 2);
        Util_API.apiSetSound(bundle);
        txt_sound_freq.setText("");
    }

    public void toShortTime(View view) {
        logWriter("apiSetSound toShortTime");
        setBufferIntent(AllUsageAction.apiSetSound);
        Bundle bundle = new Bundle();
        bundle.putInt("duration", 0);
        Util_API.apiSetSound(bundle);
        txt_sound_duration.setText("");
    }

    public void toMediumTime(View view) {
        logWriter("apiSetSound toMediumTime");
        setBufferIntent(AllUsageAction.apiSetSound);
        Bundle bundle = new Bundle();
        bundle.putInt("duration", 1);
        Util_API.apiSetSound(bundle);
        txt_sound_duration.setText("");
    }

    public void toLongTime(View view) {
        logWriter("apiSetSound toLongTime");
        setBufferIntent(AllUsageAction.apiSetSound);
        Bundle bundle = new Bundle();
        bundle.putInt("duration", 2);
        Util_API.apiSetSound(bundle);
        txt_sound_duration.setText("");
    }

    //5.15
    public void getVibration(View view) {
        logWriter("getVibration");
        setBufferIntent(AllUsageAction.apiGetVibration);
        Util_API.apiGetVibration();
        txt_vibration.setText(getString(R.string.unknown));
    }

    public void enableVibration(View view) {
        logWriter("enableVibration");
        setBufferIntent(AllUsageAction.apiSetVibration);
        Util_API.apiSetVibration(true);
        txt_vibration.setText("");
    }

    public void disableVibration(View view) {
        logWriter("disableVibration");
        setBufferIntent(AllUsageAction.apiSetVibration);
        Util_API.apiSetVibration(false);
        txt_vibration.setText("");
    }

    //5.16
    public void getStartup(View view) {
        logWriter("getStartup");
        setBufferIntent(AllUsageAction.apiGetStartup);
        Util_API.apiGetStartup();
        txt_startup.setText(getString(R.string.unknown));
    }

    public void enableStartup(View view) {
        logWriter("enableStartup");
        setBufferIntent(AllUsageAction.apiSetStartup);
        Util_API.apiSetStartup(true);
        txt_startup.setText("");
    }

    public void disableStartup(View view) {
        logWriter("enableStartup");
        setBufferIntent(AllUsageAction.apiSetStartup);
        Util_API.apiSetStartup(false);
        txt_startup.setText("");
    }

    //5.17
    public void getAutoEnforce(View view) {
        logWriter("getAutoEnforce");
        setBufferIntent(AllUsageAction.apiGetAutoEnforceSettings);
        Util_API.apiGetAutoEnforceSettings();
        txt_autoEnforce.setText(getString(R.string.unknown));
    }

    public void enableAutoEnforce(View view) {
        logWriter("enableAutoEnforce");
        setBufferIntent(AllUsageAction.apiSetAutoEnforceSettings);
        Util_API.apiSetAutoEnforceSettings(true);
        txt_autoEnforce.setText("");
    }

    public void disableAutoEnforce(View view) {
        logWriter("enableAutoEnforce");
        setBufferIntent(AllUsageAction.apiSetAutoEnforceSettings);
        Util_API.apiSetAutoEnforceSettings(false);
        txt_autoEnforce.setText("");
    }

    //endregion

    //endregion
    //==============================================================================================
}
