/*
 * The MIT License
 * Copyright © 2023 Luis Andrés Lange <https://javacomm.net>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package org.nexuswob.gui;

import java.awt.Component;
import java.awt.EventQueue;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.swing.Action;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JTable;
import javax.swing.RowSorter;
import javax.swing.SortOrder;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.filechooser.FileFilter;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
import org.nexuswob.util.Util;



/**
 * Über den JavacommFileChooser können viele Dateien auf einmal ausgewählt
 * werden. Dieser FileChooser zeigt nach dem Aufruf eine sortierte Detailansicht
 * nach Datum an.
 */
public class JavacommFileChooser extends JFileChooser {

  private static final long serialVersionUID = -1231989618871457796L;

//  private final static Logger log = LogManager.getLogger(JavacommFileChooser.class);

  private int nameWidth;
  private int sizeWidth;
  private int typeWidth;
  private int modifiedWidth;
  private TableColumn name;
  private TableColumn size;
  private TableColumn modified;
  private TableColumn type;
  private JTable table = null;
  private TableColumnModel columnmodel;
  private JComboBox<?> box;
  private ItemListener comboboxAction = new ItemListener() {

    @Override
    public void itemStateChanged(ItemEvent event) {
      if (event.getStateChange() == ItemEvent.SELECTED) {
        sort();
      }
    }

  };

  public JavacommFileChooser() {
    this(null);
  }



  /**
   * 
   * @param file
   *             a <code>String</code> giving the path to a file or directory
   */
  public JavacommFileChooser(String file) {
    super(file);
    setNameWidth(700);
    setSizeWidth(100);
    setModifiedWidth(130);
    setTypeWidth(150);

    List<Component> components = Util.getAllComponents(this);

    for (Component comp : components) {
      if (comp instanceof JComboBox) {
        box = (JComboBox<?>) comp;
        if (box.getSelectedItem() instanceof FileFilter) {
          box.addItemListener(comboboxAction);
          break;
        }
      }
    }

  }



  /**
   * Adjust the column width along the X axis.
   */
  public void adjustColumnWidth() {

    List<Component> components = Util.getAllComponents(this);

    for (Component comp : components) {
      if (comp instanceof JTable) {
        table = (JTable) comp;
        break;
      }
    }
    if (table == null) return;
    table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);

    columnmodel = table.getColumnModel();
    name = columnmodel.getColumn(0);
    size = columnmodel.getColumn(1);
    type = columnmodel.getColumn(2);
    modified = columnmodel.getColumn(3);

    name.setPreferredWidth(getNameWidth());
    size.setPreferredWidth(getSizeWidth());
    type.setPreferredWidth(getTypeWidth());
    modified.setPreferredWidth(getModifiedWidth());
  }



  /**
   * COLUMN <b>Modified</b>
   * 
   * @return pixel
   */
  public int getModifiedWidth() {
    return modifiedWidth;
  }



  /**
   * COLUMN <b>Name</b>
   * 
   * @return pixel
   */
  public int getNameWidth() {
    return nameWidth;
  }



  /**
   * COLUMN Size
   * 
   * @return pixel
   */
  public int getSizeWidth() {
    return sizeWidth;
  }



  /**
   * COLUMN <b>Type</b>
   * 
   * @return pixel
   */
  public int getTypeWidth() {
    return typeWidth;
  }



  /**
   * Der Listener für den Dateifilter wird entfernt.
   * 
   */
  public void removeAllListener() {
    box.removeItemListener(comboboxAction);
  }



  @Override
  public void setCurrentDirectory(File dir) {
    try {
      super.setCurrentDirectory(dir);
    }
    catch (ArrayIndexOutOfBoundsException e) {}
    adjustColumnWidth();
    EventQueue.invokeLater(this::sort);
  }



  /**
   * The column width for <b>Modified</b>.
   * 
   * @param modifiedWidth
   */
  public void setModifiedWidth(int modifiedWidth) {
    this.modifiedWidth = modifiedWidth;
  }



  /**
   * The column width for <b>Name</b>.
   * 
   * @param nameWidth
   *                  pixel
   */
  public void setNameWidth(int nameWidth) {
    this.nameWidth = nameWidth;
  }



  /**
   * The column width for <b>Size</b>
   * 
   * @param sizeWidth
   *                  pixel
   */
  public void setSizeWidth(int sizeWidth) {
    this.sizeWidth = sizeWidth;
  }



  /**
   * The column width for <b>Type</b>.
   * 
   * @param typeWidth
   */
  public void setTypeWidth(int typeWidth) {
    this.typeWidth = typeWidth;
  }



  public void sort() {
    List<Component> components = Util.getAllComponents(this);

    for (Component comp : components) {
      if (comp instanceof JTable) {
        table = (JTable) comp;
        break;
      }
    }
    if (table == null) return;

    table.getModel().addTableModelListener(new TableModelListener() {

      @Override
      public void tableChanged(TableModelEvent event) {
        table.getModel().removeTableModelListener(this);
        EventQueue.invokeLater(() -> {
          TableRowSorter<? extends TableModel> sorter = (TableRowSorter<? extends TableModel>) table
              .getRowSorter();
          List<RowSorter.SortKey> sortkeys = new ArrayList<>();
          RowSorter.SortKey sortkey = new RowSorter.SortKey(3, SortOrder.ASCENDING);
          sortkeys.add(sortkey);
          sorter.setSortKeys(sortkeys);
          sorter.toggleSortOrder(3);
        });
      }
    });

  }



  /**
   * Directory structure is shown in detail.
   */
  public void viewTypeDetails() {
    Action details = getActionMap().get("viewTypeDetails");
    details.actionPerformed(null);
    adjustColumnWidth();
  }

}
