package leigh.elements.javafx.type1;

import javafx.collections.ObservableList;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.TableRow;
import javafx.scene.input.MouseEvent;
import javafx.util.Callback;
import leigh.elements.sdk.AppDataFrame;
import leigh.eo.sort.EOSortPolicy;
import leigh.mecha.log.MechaLogger;
import leigh.mecha.log.MechaLoggerFactory;
import leigh.mecha.sort.FieldSort;
import leigh.mecha.sort.SortCardinality;

import java.util.Locale;

/**
 * Implementation of the {@link javafx.scene.control.TableView} class with an overridden <code>sort()</code> mechanic suitable for use with
 * Elements applications. Additionally this implementation provides a native de-selection mechanic on the rows, so
 * that the end-user can second-click a row to de-select it.
 *
 * @author Alex Leigh
 */
public class TableView extends javafx.scene.control.TableView {
    private static final MechaLogger logger = MechaLoggerFactory.getLogger(TableView.class);
    private final AppDataFrame frame;

    public TableView(AppDataFrame frame) {
        this.frame = frame;

        getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);

        setRowFactory((Callback<javafx.scene.control.TableView, TableRow>) param -> {
            TableRow row = new TableRow();
            row.addEventFilter(MouseEvent.MOUSE_PRESSED, event -> {
                // Do Nothing
            });
            return row;
        });
    }

    /**
     * This implementation of the sort() method works by using the sort functionality present in the
     * {@link leigh.conflux.DataFrame} instead of that which {@link javafx.scene.control.TableView} provides.
     * This method requires that the {@link javafx.scene.control.TableColumn} objects previously setup in the
     * {@link javafx.scene.control.TableView} are {@link VisionTableColumn}
     * instances.
     */
    @Override
    public void sort() {
        // getSortOrder list will be empty if we're expected to have the natural order.

        // TODO: Copy rather than retain the sortPolicy
        ObservableList<javafx.scene.control.TableColumn> sortOrder = this.getSortOrder();

        // FIXME Get the Locale properly
        EOSortPolicy policy = new EOSortPolicy(Locale.US);
        for (javafx.scene.control.TableColumn gridCol : sortOrder) {
            VisionTableColumn col = (VisionTableColumn) gridCol;
            javafx.scene.control.TableColumn.SortType type = gridCol.getSortType();
            SortCardinality card = (type == javafx.scene.control.TableColumn.SortType.ASCENDING
                    ? SortCardinality.ASCENDING : SortCardinality.DESCENDING);
            policy.addField(new FieldSort(col.getName(), card));
        }

        try {
            frame.sort(policy);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
