package org.imaginer.scol;


import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LifecycleRegistry;

import android.Manifest;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.ParcelFileDescriptor;
import android.provider.DocumentsContract;
import android.provider.OpenableColumns;
import android.util.Log;
import android.app.NativeActivity;
import android.content.Intent;
import android.os.Bundle;
import android.content.pm.PackageManager;
import android.view.KeyEvent;
import android.bluetooth.*;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.app.AlertDialog; // Make sure to import the native AlertDialog
import android.content.DialogInterface;
import android.provider.Settings;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.text.Normalizer;
import java.util.regex.Pattern;


public class NativeWrap extends NativeActivity implements ActivityCompat.OnRequestPermissionsResultCallback, LifecycleOwner
{
  static {
    System.loadLibrary("kernel");
  }
  String[] PERMISSIONS = {Manifest.permission.INTERNET,
                          Manifest.permission.WAKE_LOCK,
                          Manifest.permission.VIBRATE}; // List of permissions required

  String[] BTPERMISSIONS = {Manifest.permission.BLUETOOTH,
                            Manifest.permission.BLUETOOTH_CONNECT,
                            Manifest.permission.BLUETOOTH_ADMIN,
                            Manifest.permission.ACCESS_COARSE_LOCATION};

  String[] FILEPERMISSIONS = {Manifest.permission.READ_EXTERNAL_STORAGE,
                              Manifest.permission.WRITE_EXTERNAL_STORAGE};

  private static final int REQUEST_PERM_USB = 0;
  private static final int REQUEST_PERM_MIN = 1;
  private static final int REQUEST_PERM_ENABLE_BT = 2;
  private static final int REQUEST_PERM_CAMERA = 3;
  private static final int REQUEST_PERM_FINE_LOCATION = 4;
  private static final int REQUEST_PERM_FILES = 5;

  private static final int REQUEST_PERM_RECORD_AUDIO = 6;
  private static final int REQUEST_OPEN_FOLDER = 10;
  private static final int REQUEST_OPEN_FILE = 11;

  private String mCallFilePath;
  private String mLastcallFilePath;
  private String mLastOpenedFile;
  private String mLastOpenedFolder;
  public boolean mDlgOpenFile = false;
  public boolean mDlgOpenFolder = false;
  private LifecycleRegistry lifecycleRegistry;
  public boolean mMinAuthPassed = false;
  public boolean mCameraAuthPassed = false;
  public boolean mRecordAudioAuthPassed = false;
  public boolean mLocationAuthPassed = false;
  public boolean mBtAuthPassed = false;
  public boolean mFilesAuthPassed = false;
  public boolean mUsbAuthPassed = false;
  public CameraBackend mCameraBackend;
  public ScolExternal mScolExternal;
  public static native void nativeSurfaceCreated(Surface surface);
  public static native void nativeSurfaceChanged(Surface surface, int left, int top, int width, int height);
  public static native void nativeSurfaceDestroyed(Surface surface);
  private SurfaceView surfaceView;
  private Surface lastSurface;

  @NonNull
  @Override
  public Lifecycle getLifecycle() {
    return lifecycleRegistry;
  }

  @Override
  protected void onCreate(Bundle savedInstanceState)
  {
    requestWindowFeature(Window.FEATURE_NO_TITLE);

    Window window = getWindow();

    //window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); //show the activity in full screen
    //window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
    //window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
    window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
    if ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) && (Build.VERSION.SDK_INT <= Build.VERSION_CODES.UPSIDE_DOWN_CAKE))
        window.getAttributes().layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;

    super.onCreate(savedInstanceState);

    SurfaceView view = new SurfaceView(this);
    SurfaceHolder holder = view.getHolder();
    surfaceView = view;

    holder.addCallback(new SurfaceHolder.Callback()
    {
      public void surfaceCreated(SurfaceHolder holder)
      {
        if (holder.getSurface() != null && holder.getSurface().isValid())
        {
          lastSurface = holder.getSurface();
          nativeSurfaceCreated(lastSurface);
        }
      }

      public void surfaceDestroyed(SurfaceHolder holder)
      {
        if (lastSurface != null)
        {
          nativeSurfaceDestroyed(lastSurface);
          lastSurface = null; // Clear reference to avoid reusing an invalid surface
        }
      }

      public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
      {
        if (holder.getSurface() != null && holder.getSurface().isValid())
        {
          lastSurface = holder.getSurface(); // Update reference

          int[] viewLocation = new int[2];
          surfaceView.getLocationInWindow(viewLocation);

          nativeSurfaceChanged(holder.getSurface(), viewLocation[0], viewLocation[1], width, height);
        }
      }
    });

    getWindow().takeSurface( null );
    setContentView(surfaceView);

    onNewIntent(getIntent());
    // Settings the intent to some dummy data after processing to prevent getting the same data
    // when the task is brought back again from background does not work:
    setIntent(new Intent());

    lifecycleRegistry = new LifecycleRegistry(this);
    lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);

    mCameraBackend = new CameraBackend();
    mCameraBackend.setup(this);

    mScolExternal = new ScolExternal();
    mScolExternal.setup(this);

    /*
    PackageManager mgr = getPackageManager();
    boolean hasVrTracking = mgr.hasSystemFeature(PackageManager.FEATURE_VR_HEADTRACKING);

    if (!hasVrTracking)
    {
      setContentView(R.layout.main);
      SurfaceView surfaceView = (SurfaceView) findViewById(R.id.surfaceview);
      surfaceView.getHolder().addCallback(mScolExternal);
    }
    */

    getDefaultPermissions();
  }

  @Override
  public void onStart()
  {
    super.onStart();
    lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
  }

  @Override
  protected void onPause()
  {
    lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
    super.onPause();
  }

  @Override
  protected void onResume()
  {
    super.onResume();
    lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);

    // Check if surface is still there
    SurfaceHolder holder = surfaceView.getHolder();
    if ((lastSurface == null) && (holder.getSurface() != null) && holder.getSurface().isValid())
    {
      // Manually trigger nativeSurfaceCreated if needed
      lastSurface = holder.getSurface();
      nativeSurfaceCreated(lastSurface);
    }

    // Re-add SurfaceView if it was removed
    ViewGroup parent = (ViewGroup) surfaceView.getParent();
    if (parent == null)
      setContentView(surfaceView);
  }

  @Override
  protected void onStop()
  {
    lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
    super.onStop();
  }

  @Override
  protected void onDestroy()
  {
    Log.i("ScolApp", "Finish it!");
    lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
    super.onDestroy();
    android.os.Process.killProcess(android.os.Process.myPid());
  }

  @Override
  public void onNewIntent(Intent intent)
  {
    super.onNewIntent(intent);

    if (((getIntent().getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY)) == 0)
    {
      // process intent data here using intent.getData();
      if (intent != null)
      {
        android.net.Uri idata = intent.getData();

        if (idata != null)
        {
          FileMetaData fdata = getFileMetaData(getApplicationContext(), idata);
          if (fdata != null)
          {
            String path = idata.toString() + ":" + fdata.displayName;

            if ((mLastcallFilePath == null) || !mLastcallFilePath.equals(path))
            {
              mCallFilePath = path;
              mLastcallFilePath = path;

              Log.i("ScolApp", "Load file :" + path + " : " + path);
            }
          }
        }
      }
    }
  }

  public static class FileMetaData
  {
    public String displayName;
    public long size;
    public String mimeType;
    public String path;

    @Override
    public String toString()
    {
      return "name : " + displayName + " ; size : " + size + " ; path : " + path + " ; mime : " + mimeType;
    }
  }

  private static final int COPYSTREAM_BUFFER_SIZE = 2 * 1024;

  public int fopen(String path, String mode)
  {
    try
    {
      //remove real filename at string end
      int endIndex = path.lastIndexOf(":");
      if (endIndex != -1)
        path = path.substring(0, endIndex);

      Uri contentUri = Uri.parse(path);
      ContentResolver resolver = getApplicationContext().getContentResolver();

      ParcelFileDescriptor parcelFd = resolver.openFileDescriptor(contentUri, mode);

      if (parcelFd != null)
      {
        int fd = parcelFd.detachFd();
        return fd;
      }
    }
    catch (java.io.FileNotFoundException e)
    {
      Log.i("ScolApp", "fopen Error: " + e.getMessage());
    }
    return 0;
  }

  public void fclose(int fd)
  {
    if (fd > 0)
    {
      try
      {
        ParcelFileDescriptor parcelFd = ParcelFileDescriptor.adoptFd(fd);
        parcelFd.close();
      }
      catch (java.io.IOException e)
      {
        Log.i("ScolApp", "fclose Error: " + e.getMessage());
      }
    }
  }

  public static boolean copyStream(InputStream src, OutputStream dest)
  {
    byte[] buffer = new byte[COPYSTREAM_BUFFER_SIZE];

    try {/*w  ww .j a v a 2  s  .  com*/
      int size;

      while ((size = src.read(buffer)) != -1) {
        dest.write(buffer, 0, size);
      }
    } catch (IOException e) {
      return false;
    }

    return true;
  }

  public static String GetRealPath(Uri treeUri)
  {
    if (treeUri == null)
      return "";

    Uri guri = DocumentsContract.buildDocumentUriUsingTree(treeUri, DocumentsContract.getTreeDocumentId(treeUri));

    CharSequence dbdots = ":";
    String path1 = guri.getPath();
    if (path1.startsWith("/tree/"))
    {
      String path2 = path1.substring(6);
      if (path2.startsWith("primary:"))
      {
        String primary = path2.substring(8);
        String[] bdot = path2.split(":");

        String storeName = Environment.getExternalStorageDirectory().getAbsolutePath();
        String realPath = storeName + (bdot.length > 1 ? File.separator + bdot[1] : "");;
        return realPath;
      }
      else
      {
        String[] bdot = path2.split(":");
        if (bdot.length > 1)
        {
          String storeName = bdot[0];
          String last = bdot[bdot.length -1];
          String realPath = "/" + storeName + "/" + last;
          return realPath;
        }
      }
    }
    return path1;
  }

  public static FileMetaData getFileMetaData(Context context, Uri uri)
  {
    FileMetaData fileMetaData = new FileMetaData();

    if ("file".equalsIgnoreCase(uri.getScheme()))
    {
      File file = new File(uri.getPath());
      fileMetaData.displayName = file.getName();
      fileMetaData.size = file.length();
      fileMetaData.path = file.getPath();

      return fileMetaData;
    }
    else
    {
      ContentResolver contentResolver = context.getContentResolver();
      Cursor cursor = contentResolver.query(uri, null, null, null, null);
      fileMetaData.mimeType = contentResolver.getType(uri);

      try
      {
        if (cursor != null && cursor.moveToFirst())
        {
          int sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE);
          fileMetaData.displayName = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));

          if (!cursor.isNull(sizeIndex))
            fileMetaData.size = cursor.getLong(sizeIndex);
          else
            fileMetaData.size = -1;

          try
          {
            fileMetaData.path = cursor.getString(cursor.getColumnIndexOrThrow("_data"));
          }
          catch (Exception e)
          {
            // DO NOTHING, _data does not exist
          }

          return fileMetaData;
        }
      }
      catch (Exception e)
      {
        Log.e("ScolApp", e.getMessage());
      }
      finally
      {
        if (cursor != null)
          cursor.close();
      }

      return null;
    }
  }

  public void openDirectory(String path)
  {
    mDlgOpenFolder = true;
    Uri uri = Uri.parse(path);
    // Choose a directory using the system's file picker.
    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);

    // Optionally, specify a URI for the directory that should be opened in
    // the system file picker when it loads.
    intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, uri);
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION|Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION|Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
    startActivityForResult(intent, REQUEST_OPEN_FOLDER);
  }

  public void openFile(String path, String fileType) // "*/*"
  {
    mDlgOpenFile = true;
    Uri uri = Uri.parse(path);
    Intent intent = new Intent(Intent.ACTION_PICK);
    intent.setDataAndType(uri, fileType);

    // special intent for Samsung file manager
    Intent sIntent = new Intent("com.sec.android.app.myfiles.PICK_DATA");
    // if you want any file type, you can skip next line
    sIntent.putExtra("CONTENT_TYPE", fileType);
    sIntent.addCategory(Intent.CATEGORY_DEFAULT);

    Intent chooserIntent;
    if (getPackageManager().resolveActivity(sIntent, 0) != null)
    {
      // it is device with Samsung file manager
      chooserIntent = Intent.createChooser(sIntent, "Open file");
      chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] {intent});
    }
    else
    {
      chooserIntent = Intent.createChooser(intent, "Open file");
    }

    try
    {
      startActivityForResult(chooserIntent, REQUEST_OPEN_FILE);
    }
    catch (android.content.ActivityNotFoundException ex)
    {
      Log.i("ScolApp", "openFile: No suitable File Manager was found.");
    }
  }

  public String getCallFilePath()
  {
    String ret = mCallFilePath;
    mCallFilePath = "";
    return ret;
  }

  public String getLastOpenFile()
  {
    String ret = mLastOpenedFile;
    mLastOpenedFile = "";
    return ret;
  }

  public String getLastOpenFolder()
  {
    String ret = mLastOpenedFolder;
    mLastOpenedFolder = "";
    return ret;
  }

  public String stringFromKeyCode(long downTime, long eventTime,
            int eventAction, int keyCode, int repeatCount, int metaState,
            int deviceId, int scanCode, int flags, int source)
  {
    KeyEvent keyEvent = new KeyEvent(downTime, eventTime, eventAction, keyCode, repeatCount, metaState, deviceId, scanCode, flags, source);
    String strConv = "";
    int uniChar = keyEvent.getUnicodeChar(metaState);
    // Handle Unicode character
    if (uniChar == 0)
    {
      uniChar = keyEvent.getUnicodeChar();

      if (eventAction == KeyEvent.ACTION_MULTIPLE && keyCode == KeyEvent.KEYCODE_UNKNOWN && keyEvent.getCharacters() != null)
      {
        strConv = keyEvent.getCharacters();
      }
      else if (uniChar != 0 && strConv.isEmpty())
      {
        strConv = Character.toString((char) uniChar);
      }
      else if (strConv.isEmpty() && keyEvent.getDisplayLabel() != 0)
      {
        strConv += keyEvent.getDisplayLabel();
      }
    }
    else
      strConv = Character.toString((char) uniChar);

    String strNorm = Normalizer.normalize(strConv, Normalizer.Form.NFKD);
    String cleanedStr = strNorm.replaceAll("\\p{InCombiningDiacriticalMarks}+", "");
    return new String(cleanedStr.getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8);
  }

  public void getDefaultPermissions()
  {
    boolean needPerm = false;
    for (String permission : PERMISSIONS)
    {
      if (ActivityCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED)
      {
        needPerm = true;
      }
    }

    if (needPerm)
    {
      mMinAuthPassed = false;
      try
      {
        ActivityCompat.requestPermissions(this, PERMISSIONS, REQUEST_PERM_MIN);
      }
      catch (Exception e)
      {
        showPermissionExplanationDialog("This app requires access to minimum permissions. Please grant this permissions in settings.", REQUEST_PERM_MIN);
      }
    }
    else
    {
      mMinAuthPassed = true;
    }
  }

  public boolean CheckFilesPermissions()
  {
    for (String permission : FILEPERMISSIONS)
    {
      if (ActivityCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED)
      {
        return false;
      }
    }

    return true;
  }
  public void RequestFilesPermissions()
  {
    boolean needPerm = CheckFilesPermissions();
    if (needPerm)
    {
      mFilesAuthPassed = false;
      try
      {
        ActivityCompat.requestPermissions(this, FILEPERMISSIONS, REQUEST_PERM_FILES);
      }
      catch (Exception e)
      {
        showPermissionExplanationDialog("This app requires access to files permissions. Please grant this permissions in settings.", REQUEST_PERM_FILES);
      }
    }
    else
    {
      mFilesAuthPassed = true;
    }
  }

  public boolean CheckCameraPermission()
  {
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED)
      return false;
    else
      return mCameraAuthPassed = true;
  }

  public void RequestCameraPermission()
  {
    if (!CheckCameraPermission())
    {
      mCameraAuthPassed = false;
      try
      {
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, REQUEST_PERM_CAMERA);
      }
      catch (Exception e)
      {
        showPermissionExplanationDialog("This app requires access to camera permission. Please grant this permissions in settings.", REQUEST_PERM_CAMERA);
      }
    }
    else
    {
      mCameraAuthPassed = true;
    }
  }

  public boolean CheckRecordAudioPermission()
  {
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED)
      return false;
    else
      return mRecordAudioAuthPassed = true;
  }

  public void RequestRecordAudioPermission()
  {
    if (!CheckRecordAudioPermission())
    {
      mRecordAudioAuthPassed = false;
      try
      {
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, REQUEST_PERM_RECORD_AUDIO);
      }
      catch (Exception e)
      {
        showPermissionExplanationDialog("This app requires access to microphone permission. Please grant this permissions in settings.", REQUEST_PERM_RECORD_AUDIO);
      }
    }
    else
    {
      mRecordAudioAuthPassed = true;
    }
  }

  public void RequestBluetoothPermission()
  {
    boolean needPerm = false;

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
    {
      if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) == PackageManager.PERMISSION_DENIED)
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.BLUETOOTH_CONNECT}, REQUEST_PERM_ENABLE_BT);
    }
    else
    {
      for (String permission : BTPERMISSIONS)
      {
        if (ActivityCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_DENIED)
          needPerm = true;
      }

      if (needPerm)
      {
        mBtAuthPassed = false;
        try
        {
          ActivityCompat.requestPermissions(this, BTPERMISSIONS, REQUEST_PERM_ENABLE_BT);
        }
        catch (Exception e)
        {
          showPermissionExplanationDialog("This app requires access to bluetooth permission. Please grant this permissions in settings.", REQUEST_PERM_ENABLE_BT);
        }
      }
      else
      {
        mBtAuthPassed = true;
        Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        startActivityForResult(enableBtIntent, REQUEST_PERM_ENABLE_BT);
      }
    }
  }

  public boolean CheckLocationPermission()
  {
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)
      return false;
    else
      return mLocationAuthPassed = true;
  }

  public void RequestLocationPermission()
  {
    if (!CheckLocationPermission())
    {
      mLocationAuthPassed = false;

      try
      {
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_PERM_FINE_LOCATION);
      }
      catch (Exception e)
      {
        showPermissionExplanationDialog("This app requires access to fine location permission. Please grant this permissions in settings.", REQUEST_PERM_FINE_LOCATION);
      }
    }
  }

  protected void onActivityResult(int requestCode, int resultCode, Intent data)
  {
    super.onActivityResult(requestCode, resultCode, data);
    Context context = getApplicationContext();

    // Handle the case where the user returned from settings screen after granting/rejecting the permission
    if (requestCode == REQUEST_PERM_MIN)
    {
      mMinAuthPassed = true;
    }
    else if (requestCode == REQUEST_PERM_ENABLE_BT)
    {
      mBtAuthPassed = true;
    }
    else if (requestCode == REQUEST_PERM_CAMERA)
    {
      mCameraAuthPassed = true;
    }
    else if (requestCode == REQUEST_PERM_RECORD_AUDIO)
    {
      mRecordAudioAuthPassed = true;
    }
    else if (requestCode == REQUEST_PERM_FINE_LOCATION)
    {
      mLocationAuthPassed = true;
    }
    else if (requestCode == REQUEST_PERM_FILES)
    {
      mFilesAuthPassed = true;
    }
    else if (requestCode == REQUEST_PERM_USB)
    {
      mUsbAuthPassed = true;
    }

    if (data != null)
    {
      android.net.Uri idata = data.getData();
      if (requestCode == REQUEST_OPEN_FILE)
      {
        FileMetaData fdata = getFileMetaData(context, idata);
        if (fdata != null)
        {
          String path = idata.toString() + ":" + fdata.displayName;
          mLastOpenedFile = path;
          mDlgOpenFile = false;
          Log.i("ScolApp", "Load file :" + path + " : " + path);

          /*
          // get private download dir for Android 10
          File downloadDir = context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS);
          String dstPath = downloadDir + "/" + fdata.displayName;

          if ((mLastcallFilePath == null) || !mLastcallFilePath.equals(dstPath))
          {
            ContentResolver contentResolver = context.getContentResolver();
            try
            {
              InputStream inputStream = contentResolver.openInputStream(idata);
              File f = new File(dstPath);

              FileOutputStream out = new FileOutputStream(f);
              copyStream(inputStream, out);

              mLastOpenedFile = dstPath;
            }
            catch (java.io.FileNotFoundException e)
            {
              Log.i("ScolApp", "Load file error :" + path + " : " + fdata.displayName);
              mDlgOpenFile = false;
              return;
            }

            mDlgOpenFile = false;
            Log.i("ScolApp", "Load file :" + path + " : " + dstPath);
          }
        */
        }
      }
      else if (requestCode == REQUEST_OPEN_FOLDER)
      {
        if (idata.getPath() != null)
        {
          ContentResolver contentResolver = context.getContentResolver();
          int takeFlags = data.getFlags();
          takeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
          contentResolver.takePersistableUriPermission(idata, takeFlags);

          String rpath = GetRealPath(idata);
          mLastOpenedFolder = rpath;
          mDlgOpenFolder = false;
          Log.i("ScolApp", "Open folder :" + idata.getPath() + " : " + rpath);
        }
      }
    }
  }

  @Override
  public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, int[] grantResults)
  {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    Log.i("ScolApp", "Received permission response for: " + requestCode);

    if (requestCode == REQUEST_PERM_MIN)
    {
      Log.i("ScolApp", "Received response for Default permission request.");
      mMinAuthPassed = true;
    }
    else if (requestCode == REQUEST_PERM_ENABLE_BT)
    {
      Log.i("ScolApp", "Received response for Bluetooth permission request.");
      mBtAuthPassed = true;

      //Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
      //startActivityForResult(enableBtIntent, REQUEST_PERM_ENABLE_BT);
    }
    else if (requestCode == REQUEST_PERM_CAMERA)
    {
      // Received permission result for camera permission.
      Log.i("ScolApp", "Received response for Camera permission request.");
      
      // Check if the only required permission has been granted
      if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
      {
        // Camera permission has been granted, preview can be displayed
        Log.i("ScolApp", "CAMERA permission has now been granted.");
      }
      else
      {
        Log.i("ScolApp", "CAMERA permission was NOT granted.");
      }
      mCameraAuthPassed = true;
    }
    else if (requestCode == REQUEST_PERM_RECORD_AUDIO)
    {
      // Received permission result for camera permission.
      Log.i("ScolApp", "Received response for Record audio permission request.");

      // Check if the only required permission has been granted
      if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
      {
        // Record audio permission has been granted
        Log.i("ScolApp", "Record audio permission has now been granted.");
      }
      else
      {
        Log.i("ScolApp", "Record audio permission was NOT granted.");
      }
      mRecordAudioAuthPassed = true;
    }
    else if (requestCode == REQUEST_PERM_FINE_LOCATION)
    {
      // Received permission result for location permission.
      Log.i("ScolApp", "Received response for Fine Location permission request.");

      // Check if the only required permission has been granted
      if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
      {
        Log.i("ScolApp", "Fine Location permission has now been granted.");
      }
      else
      {
        Log.i("ScolApp", "Fine Location permission was NOT granted.");
      }
      mLocationAuthPassed = true;
    }
    else if (requestCode == REQUEST_PERM_FILES)
    {
      // Received permission result for location permission.
      Log.i("ScolApp", "Received response for files permission request.");

      // Check if the only required permission has been granted
      if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
      {
        Log.i("ScolApp", "Files permission has now been granted.");
      }
      else
      {
        Log.i("ScolApp", "Files Location permission was NOT granted.");
      }
      mFilesAuthPassed = true;
    }
    else if (requestCode == REQUEST_PERM_USB)
    {
      // Received permission result for camera permission.
      Log.i("ScolApp", "Received response for USB permission request.");

      // Check if the only required permission has been granted
      if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
      {
        Log.i("ScolApp", "USB permission has now been granted.");
      }
      else
      {
        Log.i("ScolApp", "USB permission was NOT granted.");
      }
      mUsbAuthPassed = true;
    }
    /*else
    {
      super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }*/
  }

  // Method to show the explanation dialog
  private void showPermissionExplanationDialog(String message, final int permissionRequestCode)
  {
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle("Permission Needed")
            .setMessage(message) // Use the passed message here
            .setPositiveButton("Go to Settings", new DialogInterface.OnClickListener() {
              @Override
              public void onClick(DialogInterface dialog, int which) {
                // Open the app's settings so the user can manually grant the permission
                Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                Uri uri = Uri.fromParts("package", getPackageName(), null);
                intent.setData(uri);
                startActivityForResult(intent, permissionRequestCode);
              }
            })
            .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
              @Override
              public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
              }
            })
            .setOnDismissListener(new DialogInterface.OnDismissListener() {
              @Override
              public void onDismiss(DialogInterface dialog) {
                // This is called when the dialog is dismissed
                Log.i("ScolApp", "Permission dialog dismissed without going to settings.");
                handlePermissionDismissed(permissionRequestCode);
              }
            })
            .create()
            .show();
  }

  // Handle the case when the user dismisses the dialog without granting the permission
  private void handlePermissionDismissed(int requestCode)
  {
    // Handle the case where the user returned from settings screen after granting/rejecting the permission
    if (requestCode == REQUEST_PERM_MIN)
    {
      mMinAuthPassed = true;
    }
    else if (requestCode == REQUEST_PERM_ENABLE_BT)
    {
      mBtAuthPassed = true;
    }
    else if (requestCode == REQUEST_PERM_CAMERA)
    {
      mCameraAuthPassed = true;
    }
    else if (requestCode == REQUEST_PERM_RECORD_AUDIO)
    {
      mRecordAudioAuthPassed = true;
    }
    else if (requestCode == REQUEST_PERM_FINE_LOCATION)
    {
      mLocationAuthPassed = true;
    }
    else if (requestCode == REQUEST_PERM_FILES)
    {
      mFilesAuthPassed = true;
    }
    else if (requestCode == REQUEST_PERM_USB)
    {
      mUsbAuthPassed = true;
    }
  }

}
