/*
 * Copyright 2009 Cedric Priscal
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.fusi24.rfid.util;

import android.app.AlertDialog;
import android.os.Bundle;

import androidx.appcompat.app.AppCompatActivity;

import com.fusi24.rfid.R;
import com.fusi24.rfid.config.Constant;

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

import android_serialport_api.SerialPort;
import android_serialport_api.SerialPortTool;

public abstract class LFSerialPortActivity extends AppCompatActivity {

  public static final String PATH = Constant.PATH;
  public static final int BAUTRATE = Constant.BAUTRATE;

  protected SerialPortTool serialPortTool;
  protected SerialPort mSerialPort;
  protected OutputStream mOutputStream;
  private InputStream mInputStream;
  private ReadThread mReadThread;

  private class ReadThread extends Thread {

    @Override
    public void run() {
      super.run();
      while (!isInterrupted()) {
        int size;
        try {
          byte[] buffer = new byte[64];
          if (mInputStream == null) {
            return;
          }
          size = mInputStream.read(buffer);
          if (size > 0) {
            onDataReceived(buffer, size);
          }
        } catch (IOException e) {
          e.printStackTrace();
          return;
        }
      }
    }
  }

  private void DisplayError(int resourceId) {
    AlertDialog.Builder b = new AlertDialog.Builder(this);
    b.setTitle("ERROR");
    b.setMessage(resourceId);
    b.setPositiveButton("OK", (dialog, which) -> LFSerialPortActivity.this.finish());
    b.show();
  }

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
  }

  protected abstract void onDataReceived(final byte[] buffer, final int size);

  @Override
  protected void onDestroy() {
    close();
    super.onDestroy();
  }

  public boolean open() {
    boolean bret = false;
    if (serialPortTool == null) {
      serialPortTool = new SerialPortTool();
    }

    try {

      mSerialPort = serialPortTool.getSerialPort(PATH, BAUTRATE);
      mOutputStream = mSerialPort.getOutputStream();
      mInputStream = mSerialPort.getInputStream();

      /* Create a receiving thread */
      if (mReadThread == null) {
        mReadThread = new ReadThread();
        mReadThread.start();
      }
      bret = true;
    } catch (SecurityException e) {
      DisplayError(R.string.error_security);
    } catch (IOException e) {
      DisplayError(R.string.error_unknown);
    } catch (InvalidParameterException e) {
      DisplayError(R.string.error_configuration);
    } catch (Exception e) {
      DisplayError(R.string.error_unknown);
    }

    return bret;
  }

  public void close() {
    if (mReadThread != null) {
      mReadThread.interrupt();
      mReadThread = null;
    }
    if (serialPortTool != null) {
      serialPortTool.closeSerialPort();
    }
    mSerialPort = null;
  }
}
