package com.fingerprint.reader.test;

import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

import com.fpreader.fpdevice.Constants;
import com.fpreader.fpdevice.UsbReader;

import java.util.Timer;
import java.util.TimerTask;

public class UsbTest3Activity extends AppCompatActivity {

    private static final int WORK_TYPE_ENROL = 1;
    private static final int WORK_TYPE_MATCH = 2;

    private UsbReader  fpModule;
    private volatile boolean isopening=false;
    private boolean isautocap=false;
    private TextView tvStatus=null;
    private TextView tvResult=null;
    private ImageView ivImage=null;
    private Button buttonOpenDevice,buttonCloseDevice,buttonEnrol,buttonMatch;

    private  volatile int workType=0;
    private int enrolCount=0;
    private  int pageid=0;

    private byte[][] tplist=new byte[100][UsbReader.TP_SIZE_REF];
    private int tpcount=0;

    private Timer timer =null;
    private TimerTask task=null;

    private byte[] fpimage=new byte[UsbReader.FAP10_RAW_SIZE];
    private byte[] fpbitmap=new byte[UsbReader.FAP10_BMP_SIZE];
    private int[] fpsize=new int[1];
    private int[] refsize=new int[1];
    private int[] matsize=new int[1];
    private byte refdata[]=new byte[512];
    private byte matdata[]=new byte[512];

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_usb_test3);

        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.test3), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });

        fpModule=new UsbReader();
        fpModule.InitMatch();
        fpModule.SetContextHandler(this,mHandler);

        buttonOpenDevice=(Button)findViewById(R.id.buttonOpenDevice);
        buttonCloseDevice=(Button)findViewById(R.id.buttonCloseDevice);
        buttonEnrol=(Button)findViewById(R.id.buttonEnrol);
        buttonMatch=(Button)findViewById(R.id.buttonMatch);
        tvStatus=(TextView)findViewById(R.id.textView1);
        tvResult=(TextView)findViewById(R.id.textView2);
        ivImage=(ImageView)findViewById(R.id.imageView1);


        buttonOpenDevice.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                if(fpModule.OpenDevice()==0){
                    tvStatus.setText(getString(R.string.txt_opendeviceok));
                    isopening=true;
                }else{
                    tvStatus.setText(getString(R.string.txt_opendevicefail));
                }
            }
        });

        buttonCloseDevice.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                isautocap=false;
                isopening=false;
                workType = 0;
                SetButtonsStatus(true);
                fpModule.CloseDevice();
                tvStatus.setText(getString(R.string.txt_closedevice));
            }
        });

        buttonEnrol.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(workType>0) return;
                if(isopening) {
                    workType = WORK_TYPE_ENROL;   //Enrol
                    enrolCount = 0;
                    tvStatus.setText(getString(R.string.txt_placfinger));
                }
            }
        });

        buttonMatch.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if(isopening) {
                    if(isautocap){
                        isautocap=false;
                        workType = 0;
                        SetButtonsStatus(true);
                        tvStatus.setText(R.string.txt_status);
                    }else {
                        if(workType>0)
                            return;
                        isautocap=true;
                        SetButtonsStatus(false);
                        workType = WORK_TYPE_MATCH; //Match
                        tvStatus.setText(getString(R.string.txt_placfinger));
                    }
                }
            }
        });

        fpModule.ResumeRegister();
        fpModule.requestPermission();
        TimerStart();
        workType = 0;
    }

    private void SetButtonsStatus(boolean enable){
        if(enable){
            buttonOpenDevice.setEnabled(true);
            buttonCloseDevice.setEnabled(true);
            buttonEnrol.setEnabled(true);
            buttonMatch.setEnabled(true);
            buttonMatch.setText(R.string.txt_MatchTemplate);
        }
        else{
            buttonOpenDevice.setEnabled(false);
            buttonCloseDevice.setEnabled(false);
            buttonEnrol.setEnabled(false);
            buttonMatch.setEnabled(true);
            buttonMatch.setText(R.string.txt_StopCapture);
        }
    }

    @SuppressLint("HandlerLeak")
    private Handler mHandler = new Handler(){
        public void handleMessage(Message msg){
            switch(msg.what){
                case Constants.FPM_DEVICE:{
                    switch(msg.arg1){
                        case Constants.DEV_ATTACHED:
                            break;
                        case Constants.DEV_DETACHED:
                            isopening=false;
                            isautocap=false;
                            workType = 0;
                            SetButtonsStatus(true);
                            fpModule.CloseDevice();
                            tvStatus.setText(getString(R.string.txt_closedevice));
                            break;
                        case Constants.DEV_OK:
                            isopening=true;
                            tvStatus.setText(getString(R.string.txt_opendeviceok));
                            break;
                        default:
                            tvStatus.setText(getString(R.string.txt_opendevicefail));
                            break;
                    }
                }
                break;
                case Constants.FPM_PLACE:
                    tvStatus.setText(getString(R.string.txt_placfinger));
                    break;
                case Constants.FPM_LIFT:
                    tvStatus.setText(getString(R.string.txt_liftfinger));
                    break;
                case Constants.FPM_NEWIMAGE:{
                    fpModule.FPImageToBitmap(fpimage,fpbitmap);
                    Bitmap bm1= BitmapFactory.decodeByteArray(fpbitmap, 0, fpsize[0]+1078);
                    ivImage.setImageBitmap(bm1);
                }
                break;
                case Constants.FPM_ENRFPT:
                    tvStatus.setText(getString(R.string.txt_enroltemplateok)+" "+String.valueOf(tpcount));
                    System.arraycopy(refdata,0,tplist[tpcount],0,256);
                    tpcount++;
                    if(tpcount>=100)
                        tpcount=0;
                    break;
                case Constants.FPM_GENCHAR:
                    tvStatus.setText(R.string.txt_generatetemplateok);
                    if(tpcount>0) {
                        boolean bfind=false;
                        for(int i=0;i<tpcount;i++){
                            if(fpModule.MatchTemplate(matdata,tplist[i])>=60){
                                bfind=true;
                                tvResult.setText(String.format(getString(R.string.txt_matchok), i));
                                break;
                            }
                        }
                        if(!bfind)
                            tvResult.setText(R.string.txt_matchfail);
                    }
                    break;
            }
        }
    };

    void TimerStart(){

        Timer timer = new Timer();
        TimerTask task = new TimerTask() {
            @Override
            public void run() {
                if(!isopening)
                    return;
                switch (workType){
                    case WORK_TYPE_ENROL:{ //Enrol
                            if(fpModule.FPGetImage(0xFFFFFFFF)==0){
                                if(fpModule.FPUpImage(0xFFFFFFFF,fpModule.ImageWidth,fpModule.ImageHeight,fpimage,fpsize)==0){
                                    mHandler.obtainMessage(Constants.FPM_NEWIMAGE, 1, -1).sendToTarget();
                                    if(fpModule.FPGenChar(0xFFFFFFFF,1)==0){
                                        if(fpModule.FPUpChar(0xFFFFFFFF,1,refdata,refsize)==0){
                                            mHandler.obtainMessage(Constants.FPM_ENRFPT, 1, -1).sendToTarget();
                                            workType=0;
                                        }
                                    }
                                }
                            }
                        }
                        break;
                    case WORK_TYPE_MATCH: {//Match
                            mHandler.obtainMessage(Constants.FPM_PLACE, 0, -1).sendToTarget();
                            if(fpModule.FPGetImage(0xFFFFFFFF)==0){
                                if(fpModule.FPUpImage(0xFFFFFFFF,fpModule.ImageWidth,fpModule.ImageHeight,fpimage,fpsize)==0){

                                    mHandler.obtainMessage(Constants.FPM_NEWIMAGE, 1, -1).sendToTarget();

                                    if(fpModule.FPGenChar(0xFFFFFFFF,1)==0){
                                        if(fpModule.FPUpChar(0xFFFFFFFF,1,matdata,matsize)==0){
                                            mHandler.obtainMessage(Constants.FPM_GENCHAR, 1, -1).sendToTarget();
                                            if(!isautocap)
                                                workType=0;
                                        }
                                    }
                                }
                            }
                        }
                        break;
                }
            }
        };
        timer.schedule(task,0,100);
    }

    void TimerStop(){
        if(timer!=null) {
            timer.cancel();
            task.cancel();
        }
    }

    @Override
    protected void onDestroy(){
        super.onDestroy();
        TimerStop();
        if(isopening)
            fpModule.CloseDevice();
        fpModule.PauseUnRegister();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        switch(id){
            case android.R.id.home:
                this.setResult(1);
                this.finish();
                return true;
        }
        return super.onOptionsItemSelected(item);
    }
}
