package Common.Visual.Tables;
import Common.CommonConstants;
import Common.Database.Objects.DBObject;
import Common.Database.Tables.DataSet;
import Common.Utils.Utils_;
import Common.Visual.DBObjectFilter_;
import Common.Visual.TextField.StyledTextField;

import javax.swing.*;
import javax.swing.border.MatteBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class HeaderTextFilter<D extends DBObject> implements DBObjectFilter_<D> {
    DataSet dataSet = null; //таблица к интерфейсу которой относится фильтр.
    int columnIndex = CommonConstants.Nan; //номер столбца к которому привязан фильтр.
    JTextField textField = null;
    JPopupMenu popup = null;
    boolean contains = true;
    private String filterValue = "";
    private int offset = 0;
    //при одиночном клике, показать поверх заголовка столбца выпавшее меню с полем фильтра.
    public HeaderTextFilter(DataSet dataSet_in, int columnIndex_in, int offset_in, boolean contains_in) {
        dataSet = dataSet_in;
        columnIndex = columnIndex_in;
        offset = offset_in;
        contains = contains_in;
    }
    public HeaderTextFilter(DataSet dataSet_in, int columnIndex_in, int offset_in) {
        this(dataSet_in, columnIndex_in, offset_in, true);
    }
    @Override
    public boolean Validate(D object) {
        Object field = dataSet.getUI().getColumnInfo(columnIndex).getFieldAt(object);
        if (field instanceof String) {
            String s = field.toString().toLowerCase();
            return contains ? s.contains(filterValue) :
                    (filterValue.isEmpty() || s.equals(filterValue)) || (filterValue.trim().isEmpty() && s.isEmpty());
        }
        return false;
    }
    //---
    public void Mount(DataTable control) {
        popup = new JPopupMenu() {
            {
                setBorder(new MatteBorder(0, 1, 1, 1, Color.DARK_GRAY));
            }
        };
        textField = new StyledTextField() {
            {
                setBorder(null);
                addActionListener(e -> {
                    popup.setVisible(false);
                    control.getTableHeader().repaint();
                });
                getDocument().addDocumentListener(new DocumentListener() {
                    @Override
                    public void insertUpdate(DocumentEvent e) {
                        setFilterValue(getText());
                        dataSet.getUI().Show();
                    }
                    @Override
                    public void removeUpdate(DocumentEvent e) {
                        setFilterValue(getText());
                        dataSet.getUI().Show();
                    }
                    @Override
                    public void changedUpdate(DocumentEvent e) {
                    }
                });
            }
        };
        popup.add(textField);
        /*
        Это лучше не использовать. убирание сортера по неведомым причинам урезает размер строк таблицы.
        control.setRowSorter(null);
        TableRowSorter<TableModel> sorter = new TableRowSorter<>(control.getModel());
        sorter.setSortable(columnIndex, false);
        control.setRowSorter(sorter);
         */
        control.getColumnModel().getColumn(columnIndex).setHeaderRenderer(
                (table, value, isSelected, hasFocus, row, column1) -> new JLabel() {
                    {
                        setIcon(Utils_.getIcon("/Common/icons/Filter.png"));
                        setForeground(control.getTableHeader().getForeground());
                        setBackground(control.getTableHeader().getBackground());
                        setFont(control.getTableHeader().getFont());
                        setBorder(new MatteBorder(0, 0, 1, 1, Color.DARK_GRAY));
                        setText(dataSet.getUI().getColumnInfo(columnIndex).getName() + " : " + getFilterValue());
                    }
                });
        //--
        control.getTableHeader().addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent event) {
                if (event.getClickCount() == 1) {
                    int clickedColumnIndex = control.getTableHeader().columnAtPoint(event.getPoint());
                    if (columnIndex == clickedColumnIndex) {
                        Rectangle columnRectangle = control.getTableHeader().getHeaderRect(columnIndex);
                        Dimension d = new Dimension(columnRectangle.width - offset, columnRectangle.height - 1);
                        //-
                        popup.setPreferredSize(d);
                        popup.setMaximumSize(d);
                        popup.show(control.getTableHeader(), columnRectangle.x + offset, 0);
                        //-
                        textField.setText(getFilterValue());
                        textField.requestFocusInWindow();
                        textField.selectAll();
                        //-
                    }
                }
            }
        });
    }
    public String getFilterValue() {
        return filterValue;
    }
    public void setFilterValue(String filterValue_in) {
        this.filterValue = filterValue_in.toLowerCase();
    }
}
