package nxm.ucl.prim;

import java.awt.Button;
import java.awt.Choice;
import java.awt.Dialog;
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Label;
import java.awt.List;
import java.awt.Panel;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;

import nxm.sys.lib.CoreIO;
import nxm.sys.lib.Parser;
import nxm.sys.libg.GPrimitive;

/**
  Displays a list of files and allows users to select one or
  more, which are then returned to the caller.

  @author  Chuck Winings
*/
public class selectfile extends GPrimitive {
  private String name,ext,aux, res, theChoice, mul, res_path, res_file;
  private int ifMultiple;
  private boolean exit;
  private Frame f = new Frame();

  TextField nameText = new TextField(20);
  TextField extText = new TextField(20);
  TextField dirText = new TextField(40);

  List theList = new List(10, true);

  /** default constructor */
  public selectfile () {}

  public int open () {
    M.deprecate("Deprecated since NeXtMidas 2.5.0. Use GCONTROL FILES or POPUP");
    exit = false;
    createFiler();
    if (!res.equals("")) {
      MR.put(res_file, "");
      MR.put(res_path, "");
    }
    getMoreFiles();
    return NORMAL;
  }

  public int process () {
    if (exit==true) {
      return FINISH;
    } else {
      return NOOP;
    }
  }

  public int close () {
    f.dispose();
    return NORMAL;
  }

/**
** Creates frame and dialog box to obtain file selection.
*/
  public void createFiler () {
    Dialog d = new Dialog(f);
    Choice pick = new Choice();

    Panel p = new Panel();
    Panel p2 = new Panel();

    GridBagConstraints gbc;
    Insets i = new Insets(0,0,0,0);

    Button okButton = new Button("OK");
    Button cancelButton = new Button("Cancel");

    Label auxLabel = new Label("Aux");
    Label fnLabel = new Label("Filename");
    Label extLabel = new Label("Extension");

    res = MA.getU("RESLABEL");
    if (!res.equals("")) {
      res_file = res + ".FILENAME";
      res_path = res + ".PATHNAME";
    }
    name  = MA.getU("NAME");
    ext   = MA.getU("EXT");
    aux   = MA.getU("AUX");
    mul	  = MA.getU("MULTIPLE");

    String raux = MR.getString("AUX.READ");
    Parser auxes = new Parser(raux);
    auxes.setDelimiter('|');

    nameText.setText(name);
    extText.setText(ext);
    if (mul.equals("")) mul = "0";
    ifMultiple = Integer.parseInt(mul);
    if (aux=="") {
      theChoice = auxes.get(1);
      dirText.setText(getPATH());
    }
    else {
      theChoice=aux;
      if (getPATH()==null) {
        M.warning(theChoice+" is not found");
        theChoice = auxes.get(1);
      }
    }
    for (int j=1; auxes.more(); j++) {
      aux = auxes.get(j);
      pick.add(aux);
      pick.select(theChoice);
    }

    pick.addItemListener(new pickHandler());
    theList.addItemListener(new listHandler());
    theList.addMouseListener(new mouseHandler());
    okButton.addActionListener(new buttonHandler());
    okButton.addMouseListener(new mouseHandler());
    cancelButton.addActionListener(new buttonHandler());
    cancelButton.addMouseListener(new mouseHandler());
    nameText.addKeyListener(new keyHandler());
    nameText.addMouseListener(new mouseHandler());
    extText.addKeyListener(new keyHandler());
    extText.addMouseListener(new mouseHandler());
    p.addMouseListener(new mouseHandler());

    GridBagLayout auxLayout = new GridBagLayout();
    p.setLayout(auxLayout);
    gbc = new GridBagConstraints(0,0,1,1,0.0,0.0,
                                 GridBagConstraints.EAST,
                                 GridBagConstraints.NONE,i,0,0);
    auxLayout.setConstraints(auxLabel, gbc);

    gbc = new GridBagConstraints(1,0,1,1,0.0,0.0,
                                 GridBagConstraints.WEST,
                                 GridBagConstraints.NONE,i,0,0);
    auxLayout.setConstraints(pick, gbc);

    gbc = new GridBagConstraints(0,1,1,1,0.0,0.0,
                                 GridBagConstraints.EAST,
                                 GridBagConstraints.NONE,i,0,0);
    auxLayout.setConstraints(fnLabel, gbc);

    gbc = new GridBagConstraints(1,1,1,1,0.0,0.0,
                                 GridBagConstraints.WEST,
                                 GridBagConstraints.HORIZONTAL,i,0,0);
    auxLayout.setConstraints(nameText, gbc);

    gbc = new GridBagConstraints(0,2,1,1,0.0,0.0,
                                 GridBagConstraints.EAST,
                                 GridBagConstraints.NONE,i,0,0);
    auxLayout.setConstraints(extLabel, gbc);

    gbc = new GridBagConstraints(1,2,1,1,0.0,0.0,
                                 GridBagConstraints.WEST,
                                 GridBagConstraints.HORIZONTAL,i,0,0);
    auxLayout.setConstraints(extText, gbc);

    gbc = new GridBagConstraints(0,3,3,1,0.0,0.0,
                                 GridBagConstraints.WEST,
                                 GridBagConstraints.HORIZONTAL,i,0,0);
    auxLayout.setConstraints(dirText, gbc);

    gbc = new GridBagConstraints(0,4,3,1,0.0,1.0,
                                 GridBagConstraints.WEST,
                                 GridBagConstraints.BOTH,i,0,0);
    auxLayout.setConstraints(theList, gbc);

    gbc = new GridBagConstraints(1,5,1,1,1.0,0.0,
                                 GridBagConstraints.CENTER,
                                 GridBagConstraints.HORIZONTAL,i,0,0);
    auxLayout.setConstraints(p2, gbc);

    p.add(auxLabel);  p.add(pick);
    p.add(fnLabel);   p.add(nameText);
    p.add(extLabel);  p.add(extText);
    p.add(dirText);   p.add(theList);

    p2.add(okButton); p2.add(cancelButton);

    if (ifMultiple>0) {
      p.add(p2);
    }

    d.add(p);
    d.setResizable(true);
    d.setSize(350, 350);
    //d.show(); //<-- JC4: This is deprecated
    d.setVisible(true);
    dirText.setEditable(false);
  }

  /** Get the Auxillary path upon the users menu choice
   *  @return the Auxillary path upon the users menu choice. */
  public String getPATH() {
    CoreIO io = new CoreIO(M);
    String path = io.getAuxPath(theChoice);
    return path;
  }

  /** Get matchname to compare filename to
   *  @return matchname to compare filename to. */
  public String getFN() {
    String matchname = new String();
    matchname = nameText.getText();
    return matchname;
  }

  /** Get matchext to compare file extension to
   *  @return matchext to compare file extension to. */
  public String getEXT() {
    String matchext = new String();
    matchext = extText.getText();
    return matchext;
  }

  /** getMoreFiles() appends passing list of files onto list display on the frame. */
  public void getMoreFiles() {
    CoreIO io = new CoreIO(M);
    String[] files = io.listFiles(getPATH(), getFN(), getEXT());
    ArrayList<String> al = new ArrayList<>();

    theList.removeAll();
    if (files!=null) {
      dirText.setText(getPATH());
      for (int k=0; k<files.length; k++) {
        al.add(files[k]);
        java.util.Collections.sort(al);
      }
      for (int j=0; j<al.size(); j++) {
        theList.add(al.get(j).toString());
      }
    }
  }

/**
** pickHandler() implements action taken upon the user's choice of
** Auxilary directory to be searched.
*/
  class pickHandler implements ItemListener {
    public void itemStateChanged(ItemEvent ie) {
      Choice choice = (Choice) ie.getItemSelectable();
      theChoice = choice.getSelectedItem();
      dirText.setText(getPATH());
      getMoreFiles();
    }
  }

  class listHandler implements ItemListener {
    public void itemStateChanged(ItemEvent ie) {
      if (ifMultiple<=0) {
        List l = (List) ie.getItemSelectable();
        String longList = l.getSelectedItem();
        if (!res.equals("")) {
          MR.put(res_file, longList);
          MR.put(res_path, getPATH());
        }
        else M.info("Selected file: "+longList);
        exit = true;
      }
    }
  }

/**
** keyHandler() implements action taken upon the pressing of
** Return after input text in either the name or ext textfield.
*/
  class keyHandler implements KeyListener {
    public void keyPressed(KeyEvent evt) {
      int keyCode = evt.getKeyCode();
      if (keyCode==KeyEvent.VK_ENTER){
        getMoreFiles();
      }
    }
    public void keyReleased(KeyEvent evt) {}
    public void keyTyped(KeyEvent evt) {}
  }

/**
** mouseHandler() implements action taken upon the pressing of
** the right mousebutton within the panel, list, textfields, and
** buttons.
*/
  class mouseHandler implements MouseListener {
    public void mouseClicked(MouseEvent me) {
      // Changed in 3.9.3 due to deprecation and better use of api
      if (me.isMetaDown()) {
        exit = true;
      }
    }
    public void mousePressed(MouseEvent me) {}
    public void mouseReleased(MouseEvent me) {}
    public void mouseEntered(MouseEvent me) {}
    public void mouseExited(MouseEvent me) {}
  }

/**
** buttonHandler() implements action taken upon the pressing of the
** OK or Cancel button.
*/
  class buttonHandler implements ActionListener {
      public void actionPerformed(ActionEvent evt) {
      String arg = evt.getActionCommand();
      String[] longList = theList.getSelectedItems();
      String listArray = new String("");

      if (arg.equals("OK")) {
        for (int k=0; k<longList.length; k++) {
          if (k==0) {
            listArray = longList[0];
          } else {
            listArray = listArray+"|"+longList[k];
          }
        }

        if (res=="") {
          M.info("Selected files: "+listArray);
        } else {
          MR.put(res_file, listArray);
          MR.put(res_path, getPATH());
        }
        exit = true;
      }
      else exit = true;
    }
  }
}
