package com.algobase.share.activity;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Stack;

/*
import android.app.Activity;
*/
import android.app.AlertDialog;
import android.app.AlertDialog;
import android.app.Dialog;

import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;

import android.database.Cursor;

import android.provider.OpenableColumns;
import android.provider.DocumentsContract;

import android.text.InputType;

import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;

import android.net.Uri;

import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.util.Log;

import android.view.Window;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;

import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.BaseAdapter;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.EditText;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.Toast;

import android.webkit.MimeTypeMap;

import androidx.core.content.FileProvider;


import com.algobase.share.system.*;
import com.algobase.share.activity.*;
import com.algobase.share.dialog.*;
import com.algobase.share.network.*;
import com.algobase.share.compat.*;

import com.algobase.share.compat.Activity;


public class FileExplorerActivity extends Activity 
{

  final static int REQUEST_SELECT_FILE = 888;
  final static int REQUEST_EXPORT_FILE = 999;

  //final static int FILE_MENU_VIEW   = 0;
  final static int FILE_MENU_OPEN   = 0;
  final static int FILE_MENU_SHARE  = 1;
  final static int FILE_MENU_EXPORT = 2;
  final static int FILE_MENU_SELECT1 = 3;
  final static int FILE_MENU_SELECT2 = 4;
  final static int FILE_MENU_RENAME = 5;
  final static int FILE_MENU_DELETE = 6;

  static final int BLUE     = 0xff003d8f;
  static final int DARKBLUE = 0xff00285e;
  //static final int GREY     = 0xff777777;
  //static final int GREY     = 0xff888888;
  static final int GREY     = 0xff999999;
  static final int YELLOW   = 0xffeeee77;

        
  public final static String EXTRA_FILE_PATH = "file_path";
  public final static String EXTRA_DIR_PATH = "dir_path";
  public final static String EXTRA_SELECT_MODE = "select_mode";

  public final static String EXTRA_FILE_MODE = "file_mode";

  public final static String EXTRA_SD_EXTERNAL_PATH = "sd_external_path";
  public final static String EXTRA_SHOW_HIDDEN_FILES = "show_hidden_files";
  public final static String EXTRA_FILE_EXTENSIONS = "file_extensions";

  public final static String EXTRA_SELECT_NAME1 = "select_name1";
  public final static String EXTRA_SELECT_NAME2 = "select_name2";
        
  File root_dir;
  File tmp_dir;
  File current_dir;

  ArrayList<File> file_list;
  FileListAdapter list_adapter;
  boolean show_hidden_files = false;
  String select_op_name1 = "Select";
  String select_op_name2 = "Select-D";
  String[] accepted_ext;

  Context context;

  TextView title_text;
  ListView list_view;
  ImageButton menu_button;


  MyPopupMenu popup_menu;

  Handler handler;

  String pkg_name;

  File sd_internal;
  File sd_external;
  String sd_external_path;

  boolean developer_mode = false;

  int dp = 1;

  //int dialog_style = MyDialog.STYLE_HOLO_LIGHT;
  int dialog_style = MyDialog.getStyle();

  int title_bg_clr = GREY;

  int button_hi_clr = YELLOW;
  int button_bg_clr = 0xffeeeeee;
  int button_fg_clr = 0xff222222;

  protected int getFileImageRes() { return -1; }
  protected int getFolderImageRes() { return -1; }
  protected int getMenuImageRes() { return -1; }

  protected boolean openFileHandler(File file) { return false; }

  class MyButton extends Button {

     public void touch_action() {}

     MyButton(Context ctxt, String label) 
     { super(ctxt);
       super.setBackgroundColor(button_bg_clr);
       super.setTextColor(button_fg_clr);
       super.setText(label);
       super.setTextSize(19);

       super.setOnTouchListener(new OnTouchListener() {
               public boolean onTouch(View v, MotionEvent event) {
                   Button b = (Button)v;

                   if (event.getAction() == MotionEvent.ACTION_DOWN)
                   { //b.setBackgroundColor(0xff000066);
                     b.setBackgroundColor(button_hi_clr);
                     //touch_action();
                    }

                   if (event.getAction() == MotionEvent.ACTION_UP)
                   { b.setBackgroundColor(button_bg_clr);
                     touch_action();
                    }

                   return true;
               }
       });

     }

  }

  int DipToPixels(float dp)
  { float dpi = getResources().getDisplayMetrics().densityDpi;
    return (int)(0.5 + dp * (dpi/160f));
   }




  void showToast(final String txt) {
     final Context ctxt = this;
     handler.post(new Runnable() {
        public void run() {
           Toast.makeText(ctxt,txt, Toast.LENGTH_SHORT).show();
        }
     });
   }


  String getMimeType(File file)
  {
    String ext = MimeTypeMap.getFileExtensionFromUrl(file.getPath());

    if (ext == null || ext.equals(""))
    { String name = file.getName();
      int p = name.lastIndexOf(".");
      if (p != -1) ext = name.substring(p+1); 
    }

    String type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(ext);

    if (type == null) {
      type = "*/*";
      if (ext.equals("fit")) type = "application/vnd.dsi.fit";
      if (ext.equals("gpx")) type = "application/gpx+xml";
      if (ext.equals("log")) type = "text/plain";
      if (ext.equals("gps")) type = "text/plain";
      if (ext.equals("trk")) type = "text/plain";
      if (ext.equals("txt")) type = "text/plain";
    }

    return type;
  }


  void openFileUri(Uri uri)
  { 
    String mime = getContentResolver().getType(uri);
    String name = "";

    Cursor cursor = getContentResolver().query(uri,null,null,null,null);
    if (cursor != null && cursor.moveToFirst())
    { int index = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
      name = cursor.getString(index);
    }

    showToast(name + "\n" + mime);

    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setDataAndType(uri,mime);
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    try { startActivity(intent);
    } catch(Exception ex) { showToast("Cannot open this type of file."); }
  }


  void exportFile(File file) 
  { 
    String mime = getMimeType(file); 

/*
    File dl_folder = Environment.getExternalStoragePublicDirectory(
                                             Environment.DIRECTORY_DOWNLOADS);
    Uri download_uri = FileProvider.getUriForFile(context,pkg_name,dl_folder);
*/


    Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    intent.setType(mime);
    intent.putExtra(Intent.EXTRA_TITLE,file.getName());

/*
    intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI,
                     Environment.DIRECTORY_DOWNLOADS);
*/

/*
    Uri download_uri = FileProvider.getUriForFile(context,pkg_name,
                   new File(Environment.DIRECTORY_DOWNLOADS));
    showToast(download_uri.toString());
    intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI,download_uri);
*/

    intent.putExtra("android.content.extra.SHOW_ADVANCED",true);

    try {
      startActivityForResult(intent, REQUEST_EXPORT_FILE);
    } catch (Exception ex) { 
         showToast("No Activity (ACTION_CREATE_DOCUMENT)");
     }
  }


  void shareFile(File file, String mime_type) 
  { Intent intent = new Intent(Intent.ACTION_SEND);
    Uri uri = FileProvider.getUriForFile(context,pkg_name,file);
    //intent.setType("text/plain");
    intent.setType(mime_type);
    intent.putExtra(Intent.EXTRA_STREAM, uri);
    startActivity(Intent.createChooser(intent, "Share File"));
  }



 void init_menu() 
 {
   popup_menu = new MyPopupMenu(this) {
        @Override
        public void callMenuAction(View view, int p, int i) { 
          switch(i) {
           case 0: {
                   Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
                   intent.addCategory(Intent.CATEGORY_OPENABLE);
                   intent.setType("*/*");
                   intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI,
                                   Environment.DIRECTORY_DOWNLOADS);
                   intent.putExtra("android.content.extra.SHOW_ADVANCED",true);
                   startActivityForResult(intent,REQUEST_SELECT_FILE);
                   break;
                   }
           case 1: change_dir(root_dir.getParentFile());
                   break;
           case 2: create_file_dialog(); 
                   break;
           case 3: FileExplorerActivity.this.finish();
                   break;
          }
        }

        @Override
        public void dismissHandler() {}
   };

   popup_menu.setAnchorView(menu_button);
   popup_menu.setAutoDismiss(true);
   popup_menu.setTextSize(19);

   popup_menu.setWidth(175);

   popup_menu.add("Downloads",   0,0);
   popup_menu.add("Root Folder", 0,1);
   if (developer_mode) {
     popup_menu.add("New File",  0, 0xffff0000, 2);
   }
   popup_menu.add("Exit",        0,3);
 }

 void init_layout()
 {
   LinearLayout layout = new LinearLayout(this);
   layout.setOrientation(LinearLayout.VERTICAL);

   if (Build.VERSION.SDK_INT >= 35) {
     adjustLayout(layout,0xff222222);
   }


   LinearLayout title_layout = new LinearLayout(this);
   title_layout.setOrientation(LinearLayout.HORIZONTAL);

   title_text = new TextView(this);
   title_text.setTextSize(19);
   title_text.setTextColor(0xffffffff);
   title_text.setBackgroundColor(title_bg_clr);
   title_text.setPadding(6*dp,4*dp,0*dp,4*dp);
   title_text.setPadding(6*dp,4*dp,0*dp,4*dp);
   title_text.setGravity(Gravity.CENTER_VERTICAL);
   title_text.setClickable(true);

   title_text.setOnClickListener(new OnClickListener() {
      @Override
      public void onClick(View v) { 
        File parent = current_dir.getParentFile();
        if (parent != null && !current_dir.getName().equals(pkg_name))
          change_dir(parent);
      }
   });

   title_layout.addView(title_text);
   ((LayoutParams)title_text.getLayoutParams()).width = -1;
   ((LayoutParams)title_text.getLayoutParams()).height= -1;
   ((LayoutParams)title_text.getLayoutParams()).weight = 1;


   int res = getMenuImageRes();

   if (res != -1) {
      menu_button = new ImageButton(this); 
      menu_button.setPadding(10*dp,7*dp,10*dp,10*dp);
      //menu_button.setBackgroundColor(button_bg_clr);
      menu_button.setBackgroundColor(title_bg_clr);
      menu_button.setImageResource(res);

      menu_button.setOnTouchListener(new OnTouchListener() {
               public boolean onTouch(View v, MotionEvent event) {
                   if (event.getAction() == MotionEvent.ACTION_DOWN)
                     v.setBackgroundColor(button_hi_clr);
                   else
                   if (event.getAction() == MotionEvent.ACTION_UP)
                     v.setBackgroundColor(title_bg_clr);
                   return false;
               }
       });

      menu_button.setOnClickListener(new OnClickListener() {
         @Override
         public void onClick(View v) { 
           //popup_menu.show(+1,0);
           popup_menu.show(+1,-10);
         }
      });

      title_layout.addView(menu_button);
      ((LayoutParams)menu_button.getLayoutParams()).leftMargin=dp;
      ((LayoutParams)menu_button.getLayoutParams()).height=40*dp;
   }


    list_view = new ListView(this);
    list_view.setId(android.R.id.list);

    LinearLayout button_line = new LinearLayout(this);


    Button but_left, but_middle, but_right;



    but_left = new MyButton(this," .. ") {
       public void touch_action() { change_dir(current_dir.getParentFile()); }
   };

    but_middle = new MyButton(this,"/" + root_dir.getName()) {
       public void touch_action() { change_dir(root_dir); }
     };


     but_right= new MyButton(this,"exit") {
       public void touch_action() { 
         // finish and return current directory
         Intent extra = new Intent();
         extra.putExtra(EXTRA_DIR_PATH,current_dir.getPath());
         setResult(RESULT_OK, extra);
         finish();
       }
    };


    layout.addView(title_layout);
    ((LayoutParams)title_layout.getLayoutParams()).height=40*dp;


    layout.addView(list_view);
    ((LayoutParams)list_view.getLayoutParams()).weight=1;
    ((LayoutParams)list_view.getLayoutParams()).leftMargin=1;
    ((LayoutParams)list_view.getLayoutParams()).rightMargin=1;


    LayoutParams params = new LayoutParams(0,(int)(42*dp));
    params.weight = 1;
    params.leftMargin = 1;
    params.rightMargin = 1;

    button_line.addView(but_left,params);
    button_line.addView(but_middle,params);
    button_line.addView(but_right,params);

/*
    layout.addView(button_line);
*/

        
    list_view.setOnItemClickListener(new OnItemClickListener() {
      @Override
      public void onItemClick(AdapterView<?> adapter, View v, int pos, long id) 
      {  File file = (File)list_view.getItemAtPosition(pos);
         if (file.isDirectory()) 
           change_dir(file);
         else
         { open_text_file(file);
/*
             if (check_file_extension(file))
             { //if (openFileHandler(file)) return;
               Intent extra = new Intent();
               extra.putExtra(EXTRA_DIR_PATH,current_dir.getPath());
               extra.putExtra(EXTRA_FILE_PATH, file.getAbsolutePath());
               setResult(RESULT_OK, extra);
               finish();
              }
             else {
                //openFileHandler(file);
                open_text_file(file);
              }
*/
          }
       }
    });

   list_view.setOnItemLongClickListener(new OnItemLongClickListener() {
      @Override
      public boolean onItemLongClick(AdapterView<?> a, View v, int pos, long x)
      { File file = (File)list_view.getItemAtPosition(pos);
        if (file.isDirectory()) 
          folder_context_menu(file);
        else
          file_context_menu(file);

        return true;
       }
     });



  
    file_list = new ArrayList<File>();
    list_adapter = new FileListAdapter(this, file_list);
    list_view.setAdapter(list_adapter);

    setContentView(layout);
  }

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

    context = this;

/*
    int style = MyDialog.STYLE_HOLO_LIGHT;
    MyDialog.setStyle(style);
*/

    //requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);

    dp = (int)(0.5f + getResources().getDisplayMetrics().densityDpi/160f);

    handler = new Handler();

    sd_internal = Environment.getExternalStorageDirectory();

    // searching for external sd cards
    sd_external = null;

     try {
       File[] dirs = getExternalFilesDirs(null);
       for(int i=0; i<dirs.length; i++)
       { String path  = dirs[i].getPath();
         int p = path.indexOf("/Android");
         if (p != -1)
         { File f = new File(path.substring(0,p));
           if (!f.getCanonicalPath().equals(sd_internal.getCanonicalPath()))
              //sd_external = f;
              sd_external = dirs[i];
              sd_external_path = sd_external.getPath();
          }
       }
     } catch(Exception ex) {}


  //root_dir = new File("/");
    root_dir = getFilesDir();

    tmp_dir = new File(root_dir,"tmp");
    if (!tmp_dir.exists()) tmp_dir.mkdir(); 
                
    accepted_ext = new String[]{};


    Intent intent = getIntent();

    if (intent.hasExtra(EXTRA_SD_EXTERNAL_PATH)) {
        sd_external_path = intent.getStringExtra(EXTRA_SD_EXTERNAL_PATH);
        sd_external = new File(sd_external_path);
    }
                
    if (intent.hasExtra(EXTRA_FILE_PATH)) {
        root_dir = new File(intent.getStringExtra(EXTRA_FILE_PATH));
    }

    pkg_name = getPackageName();
    developer_mode = pkg_name.endsWith("devel");

    File sn_file = new File(root_dir,"stefan.naeher");
    if (sn_file.exists()) {
       developer_mode = true;
       showToast("developer");
    }

    current_dir = root_dir;

    if (intent.hasExtra(EXTRA_SELECT_NAME1)) {
      select_op_name1 = intent.getStringExtra(EXTRA_SELECT_NAME1);
    }

    if (intent.hasExtra(EXTRA_SELECT_NAME2)) {
      select_op_name2 = intent.getStringExtra(EXTRA_SELECT_NAME2);
    }

    if (intent.hasExtra(EXTRA_SHOW_HIDDEN_FILES)) {
      show_hidden_files = intent.getBooleanExtra(EXTRA_SHOW_HIDDEN_FILES,false);
    }

    if (intent.hasExtra(EXTRA_FILE_EXTENSIONS)) {
      ArrayList<String> collection = 
                          intent.getStringArrayListExtra(EXTRA_FILE_EXTENSIONS);
      accepted_ext= (String[])collection.toArray(new String[collection.size()]);
      Log.v("FileExplorer","extensions n = " + accepted_ext.length);
      Log.v("FileExplorer","ext = " + accepted_ext[0]);
    }

    init_layout();

    init_menu();
  }

        
  @Override
  protected void onResume() {
      refresh_list();
      super.onResume();
  }


  @Override
  public void onActivityResult(int requestCode,int resultCode,Intent resultData)
  {
    if (resultCode != Activity.RESULT_OK) return;

    if (requestCode == REQUEST_SELECT_FILE && resultData != null) 
    { Uri uri = resultData.getData();
      //openFileUri(uri);

      File file = new File(uri.getPath());
      //showToast(file.getName());

      Intent extra = new Intent();
      //extra.putExtra(EXTRA_DIR_PATH,current_dir.getPath());
      extra.putExtra(EXTRA_FILE_PATH, file.getAbsolutePath());
      extra.putExtra(EXTRA_SELECT_MODE,select_op_name1);
      extra.putExtra(EXTRA_FILE_MODE,"uri");
      extra.setData(uri);
      setResult(RESULT_OK, extra);
      finish();
    }
  }



  private boolean check_file_extension(File file)
  {
     if (file.isDirectory()) return true;

     boolean matched = false;
     String fname = file.getName();
     for(String ext:accepted_ext)
            if (fname.endsWith(ext)) matched = true;

     return matched;
  }

        

  protected void refresh_list() 
  { 
    String path = current_dir.getPath();

    path = path.replace("/data/user/0/"+pkg_name,"");

    if (path.equals("")) path = "/";

/*
    if (path.endsWith(pkg_name)) 
      path = path.replace("/data/user/0/","");
    else
      path = path.replace("/data/user/0/"+pkg_name,"");
*/

    title_text.setText(path);

    file_list.clear();

    File[] files = current_dir.listFiles();

    if (files != null) 
    { for(File f : files) 
      { if (f.isHidden() && !show_hidden_files) continue;
        file_list.add(f);
       }
      Collections.sort(file_list, new FileComparator());
    }
    list_adapter.notifyDataSetChanged();
  }


  void change_dir(File dir)
  { if (dir == null) return;
    current_dir = dir;
    refresh_list();
   }

        
  @Override
  public void onBackPressed() 
  { 
/*
    // return current directory
    Intent extra = new Intent();
    extra.putExtra(EXTRA_DIR_PATH,current_dir.getPath());
    setResult(RESULT_OK, extra);
    finish();
*/
    File parent = current_dir.getParentFile();

    if (parent == null || current_dir.getPath().equals(root_dir.getPath())
                       || current_dir.getName().equals(pkg_name))
      finish();
    else
      change_dir(parent);


    //super.onBackPressed();
  }
        



   void file_context_menu(final File file)
   {
     final MyDialog dialog = new MyDialog(this,file.getName());
     dialog.setTitleTextSize(22);

     String mime = getMimeType(file); 
     long bytes = file.length();
     String size_str = String.format("%,d\u00A0\u00A0bytes",bytes);

     TextView tv = dialog.newTextView();
     tv.setPadding(7*dp,5*dp,5*dp,5*dp);
     if (mime == null)
       tv.setText(size_str);
     else
       tv.setText("type:  " + mime + "\nsize:  " + size_str);
     tv.setTextSize(19);
     //tv.setTextColor(0xff777777);

     dialog.addView(tv);
     dialog.addSeparator(0xff777777);


     BaseAdapter adapter = new BaseAdapter() { 

           String items[] = { "Open", 
                              "Share", 
                              "Export", 
                              select_op_name1,
                              // developer
                              select_op_name2,
                              "Rename",
                              "Delete" };

            @Override
            public int getCount() { return developer_mode ? items.length : 4; }

            @Override
            public String getItem(int pos) { return items[pos]; }

            @Override
            public long getItemId(int pos) { return pos; }

            @Override
            public View getView(int pos, View view, ViewGroup parent)
            { TextView tv = (TextView)view;

              if (tv == null)
              { tv = new TextView(context);
                tv.setTextSize(19);
                tv.setPadding(7*dp,7*dp,7*dp,7*dp);

                if (dialog_style == MyDialog.STYLE_HOLO_LIGHT ||
                    dialog_style == MyDialog.STYLE_MATERIAL_LIGHT)
                  tv.setTextColor(0xff333333);
                else
                  tv.setTextColor(0xffcccccc);
/*

                if (pos == 3 && !items[pos].equals("Select")) {
                    tv.setTextColor(0xff0000ff);
                }
*/
                if (pos >= 4) tv.setTextColor(0xffff0000);
             }

             tv.setText(items[pos]);

             return tv;
           }
      };


     dialog.addListView(adapter, new DialogInterface.OnClickListener() {
       public void onClick(DialogInterface d, int i) {

         switch (i) {
    
/*
         case FILE_MENU_VIEW:
                open_text_file(file);
                break;
*/
    
         case FILE_MENU_OPEN:
              { String mime = getMimeType(file); 
                if (mime == null)
                  open_as_text_dialog(file);
                else
                { Uri uri = FileProvider.getUriForFile(context,pkg_name,file);
                  openFileUri(uri);
                }
    
                break;
              }
    
         case FILE_MENU_EXPORT:
              exportFile(file);
              break;
    
         case FILE_MENU_SHARE:
               //shareFile(file,"text/plain");
               shareFile(file,"application/octet-stream");
               break;

    
         case FILE_MENU_SELECT1:
              { Intent extra = new Intent();
                extra.putExtra(EXTRA_DIR_PATH,current_dir.getPath());
                extra.putExtra(EXTRA_FILE_PATH, file.getAbsolutePath());
                extra.putExtra(EXTRA_FILE_MODE, "file");
                extra.putExtra(EXTRA_SELECT_MODE,select_op_name1);
                setResult(RESULT_OK, extra);
                finish();
                break;
               }

         case FILE_MENU_SELECT2:
              { Intent extra = new Intent();
                extra.putExtra(EXTRA_DIR_PATH,current_dir.getPath());
                extra.putExtra(EXTRA_FILE_PATH, file.getAbsolutePath());
                extra.putExtra(EXTRA_FILE_MODE, "file");
                extra.putExtra(EXTRA_SELECT_MODE,select_op_name2);
                setResult(RESULT_OK, extra);
                finish();
                break;
              }

    
         case FILE_MENU_RENAME:
              if (developer_mode)
                rename_file_dialog(file);
              else
                showToast("Read Only");
              break;
    
         case FILE_MENU_DELETE:
              if (developer_mode || file.getPath().indexOf("/maps/") != -1)
                delete_file_dialog(file);
              else
                showToast("Read Only");
              break;
    
         }
    
         dialog.dismiss();
        }
      });

     dialog.show();
   }


   void folder_context_menu(final File file)
   {
     File[] lst = file.listFiles();

     final MyDialog dialog = new MyDialog(this,file.getName());
     dialog.setTitleTextSize(22);

     TextView tv = dialog.newTextView();
     tv.setPadding(7*dp,5*dp,5*dp,5*dp);

     int file_num = (lst == null) ? 0 : lst.length;

     tv.setText(String.format("Folder  (Files: %d)",file_num));
     tv.setTextSize(19);
     //tv.setTextColor(0xff777777);

     dialog.addView(tv);
     dialog.addSeparator(0xff777777);


     BaseAdapter adapter = new BaseAdapter() { 

           String items[] = { "Open", 
                              "Export (zip)",
                              // developer
                              "Rename",
                              "Delete" };

            @Override
            public int getCount() { return developer_mode ? items.length : 2; }

            @Override
            public String getItem(int pos) { return items[pos]; }

            @Override
            public long getItemId(int pos) { return pos; }

            @Override
            public View getView(int pos, View view, ViewGroup parent)
            { TextView tv = (TextView)view;

              if (tv == null)
              { tv = new TextView(context);
                tv.setTextSize(19);
                tv.setPadding(7*dp,7*dp,7*dp,7*dp);

                if (dialog_style == MyDialog.STYLE_HOLO_LIGHT ||
                    dialog_style == MyDialog.STYLE_MATERIAL_LIGHT)
                  tv.setTextColor(0xff333333);
                else
                  tv.setTextColor(0xffcccccc);

                if (pos >= 2) tv.setTextColor(0xffff0000);
             }


             tv.setText(items[pos]);

             return tv;
           }
      };



     dialog.addListView(adapter, new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface d, int i) {

         switch (i) {
    
         case 0: change_dir(file);
                 break;

         case 1: zipFolder(file,true);
                 break;
    
         case 2: rename_file_dialog(file);
                 break;
    
         case 3: delete_file_dialog(file);
                 break;
    
         }
    
         dialog.dismiss();
        }
      });

     dialog.show();
   }




  void deleteRecursive(File file)
  { 
    if (file.isDirectory())
    { File[] lst = file.listFiles();
      for (File f: lst) deleteRecursive(f);
     }
    file.delete();
  }

  void deleteFolder(final File file)
  {
    final MyProgressDialog spinner = new MyProgressDialog(this);
    spinner.setProgressStyle(MyProgressDialog.PROGRESS_STYLE_SPINNER);
    spinner.setMessage("Deleting Folder");
    spinner.show();
    new MyThread() {
        public void run() { 
           deleteRecursive(file);
           sleep(1500);
           spinner.dismiss();
           handler.post(new Runnable() {
              public void run() { refresh_list(); }
           });
       }
    }.start();
  }


  void zipFolder(final File file, final boolean export)
  {
    final String name = file.getName();

    final MyProgressDialog spinner = new MyProgressDialog(this);
    spinner.setProgressStyle(MyProgressDialog.PROGRESS_STYLE_SPINNER);
    spinner.setMessage(name + " ---> /tmp/" + name + ".zip");
    spinner.show();

    new MyThread() {
        public void run() { 
            MyZipFile zipFile = new MyZipFile();
            File parent = file.getParentFile();
            File zip_file = new File(tmp_dir,name + ".zip");
            zipFile.zip(file,zip_file);
            sleep(1500);
            spinner.dismiss();
            handler.post(new Runnable() {
                public void run() { refresh_list(); }
            });
            if (export) shareFile(zip_file,"application/zip");
        }
    }.start();
  }



   public void delete_file_dialog(final File file)
   { 
     MyDialog diag = new MyDialog(this);
     diag.setTitleTextSize(20);
     if (file.isDirectory())
       diag.setTitle("Delete Folder");
     else
       diag.setTitle("Delete File");

     diag.setMessage(file.getName());

     diag.setPositiveButton("OK", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface d, int which) {
                        if (file.isDirectory())
                          deleteFolder(file);
                        else
                        { file.delete();
                          refresh_list();
                         }
                }
     });

     diag.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface d, int which) {
                         refresh_list();
                }
     });

    diag.show();
  }

   public void rename_file_dialog(final File file)
   { 
     MyDialog diag = new MyDialog(this);
     diag.setTitleTextSize(20);

     diag.setTitle("Rename File");
     diag.setMessage(file.getName());

     final EditText edit = diag.newEditText();
     edit.setText("");
     edit.setTextSize(20);
     edit.requestFocus();

     LinearLayout layout = new LinearLayout(this);
     layout.setOrientation(LinearLayout.VERTICAL);
     layout.addView(edit);
     ((LayoutParams)edit.getLayoutParams()).bottomMargin = 20;
     diag.addView(layout);

     diag.setPositiveButton("OK", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface d, int which) {
                        String fname = edit.getText().toString();
                        File f = new File(current_dir,fname);
                        file.renameTo(f);
                        refresh_list();
                }
     });

     diag.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface d, int which) {
                         refresh_list();
                }
     });

    diag.show();
  }

  void writeStringToFile(File file, String txt)
    { try {
        FileOutputStream out = new FileOutputStream(file);
        byte[] bytes = txt.getBytes();
        out.write(bytes, 0, bytes.length);
        out.close();
      } catch(IOException e) {}
    }



   public void create_file_dialog()
   { 
     MyDialog diag = new MyDialog(this);
     diag.setTitleTextSize(20);
     diag.setTitle("New File");

     LinearLayout layout = new LinearLayout(this);
     layout.setOrientation(LinearLayout.VERTICAL);
     layout.setPadding(5*dp,5*dp,5*dp,5*dp);

     TextView title_name = diag.newTextView(); 
     title_name.setText("Name");
     title_name.setTextSize(19);
     layout.addView(title_name);

     final EditText edit_name = diag.newEditText();
     edit_name.setText("");
     edit_name.setTextSize(20);
     //edit_name.setInputType(InputType.TYPE_CLASS_TEXT);
     edit_name.setInputType(InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS);
     layout.addView(edit_name);

     TextView title_text = diag.newTextView(); 
     title_text.setText("Text");
     //title_text.setTextSize(19);
     title_text.setTextSize(18);
     layout.addView(title_text);

     final EditText edit_text = diag.newEditText();
     edit_text.setText("");
     edit_text.setTextSize(20);
     layout.addView(edit_text);

     diag.addView(layout);


     diag.setPositiveButton("OK", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface d, int which) {
                        String fname = edit_name.getText().toString();
                        String text = edit_text.getText().toString();
                        File f = new File(current_dir,fname);
                        writeStringToFile(f,text);
                        refresh_list();
                }
     });

     diag.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface d, int which) {
                         refresh_list();
                }
     });

    diag.show();
  }



  void open_text_file(File file)
  { Bundle bundle = new Bundle();
    bundle.putString("file_name",file.getPath());
    bundle.putInt("menu_image",getMenuImageRes());
    Intent intent = new Intent(this, FileViewerActivity.class);
    intent.putExtras(bundle);
    startActivity(intent);
  }


   public void open_as_text_dialog(final File file)
   { 
     MyDialog diag = new MyDialog(this);
     diag.setTitleTextSize(20);
     diag.setTitle(file.getName());
     diag.setMessage("Unknown Type of File");

     diag.setPositiveButton("Open as Text", 
         new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface d, int which) {
                open_text_file(file);
                refresh_list();
            }
     });

     diag.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface d, int which) {
                         refresh_list();
                }
     });

    diag.show();
  }



        
  private class FileListAdapter extends ArrayAdapter<File> 
  { 
     private Context context;

     private List<File> files;
                
     public FileListAdapter(Context ctxt, List<File> objects) 
     { super(ctxt,android.R.layout.simple_list_item_1,objects);
       context = ctxt;
       files = objects;
      }

/*
     @Override
     public boolean areAllItemsEnabled() { return false; }

     @Override
     public boolean isEnabled(int position) 
     { File file = files.get(position);
       return check_file_extension(file);
      }
*/
     @Override
     public View getView(int position, View convertView, ViewGroup parent) 
     {
       File file = files.get(position);
       String fname = file.getName();
       boolean is_file = file.isFile();
       
       LinearLayout line;
       ImageView iv;
       TextView tv;

       if (convertView != null) 
       { line = (LinearLayout)convertView;
         iv = (ImageView)line.getChildAt(0);
         tv = (TextView)line.getChildAt(1);
        }
       else
       { int d = (int)(5*dp);

         line = new LinearLayout(context);
         //line.setPadding(0,d,0,d);

         iv = new ImageView(context);
         iv.setScaleType(ImageView.ScaleType.CENTER_CROP);
         iv.setPadding(d,d,d,d);

         tv = new TextView(context);
         tv.setSingleLine(true);
         tv.setTextSize(18);
         tv.setTextColor(Color.WHITE);

         tv.setGravity(Gravity.CENTER_VERTICAL);
         tv.setPadding(2*d,0,0,0);

         //tv.setPadding(3*d,d,d,d);

         LayoutParams params1 = new LayoutParams(9*d,9*d);
         line.addView(iv,params1);

         LayoutParams params2 = new LayoutParams(0,LayoutParams.WRAP_CONTENT);
         params2.weight = 1;
         params2.gravity = Gravity.CENTER_VERTICAL;
         line.addView(tv,params2);
        }

       tv.setText(fname);
    
       if (is_file) 
       { int res = getFileImageRes();
         if (res > 0) iv.setImageResource(res);
         if (accepted_ext.length == 0 || check_file_extension(file)) 
           tv.setTextColor(0xffffffff); 
         else
           tv.setTextColor(0xff777777);
        }
       else
       { int res = getFolderImageRes();
         if (res > 0) iv.setImageResource(res);
         tv.setTextColor(0xffffffb0); // light yellow
        }

       return line;
     }

   }
        
    private class FileComparator implements Comparator<File> 
    { //@Override
      public int compare(File f1, File f2) 
      { if (f1 == f2) return 0;
        if (f1.isDirectory() && f2.isFile()) return -1;
        if(f1.isFile() && f2.isDirectory()) return 1;
        return f1.getName().compareToIgnoreCase(f2.getName());
      }
    }
    
    
}
