package one.jpro.hellojpro;

import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.cell.TreeItemPropertyValueFactory;
import javafx.scene.control.skin.VirtualFlow;
import javafx.scene.layout.*;
import javafx.stage.Stage;

public class TreeViewExpandTestApp extends Application {
    private TreeTableView<Entry> treeTableView = new TreeTableView<>();

    @Override
    public void start(Stage primaryStage) throws Exception {

        treeTableView.setRowFactory(treeTableView -> new TreeTableRow<>() {
            @Override
            protected void updateItem(Entry item, boolean empty) {
                super.updateItem(item, empty);
                if (item != null) {
                    setMinHeight(item.getHeight());
                    setPrefHeight(item.getHeight());
                    setMaxHeight(item.getHeight());
                } else {
                    setMinHeight(Region.USE_COMPUTED_SIZE);
                    setPrefHeight(Region.USE_COMPUTED_SIZE);
                    setMaxHeight(Region.USE_COMPUTED_SIZE);
                }
            }
        });

        TreeItem<Entry> root = createRows();

        treeTableView.getColumns().add(createTreeColumn());
        treeTableView.setRoot(root);
        treeTableView.setShowRoot(true);
        treeTableView.setPrefWidth(300);
        treeTableView.getStyleClass().add("gantt-tree-table-view");


        Scene scene = new Scene(treeTableView, 300, 300);
        primaryStage.setScene(scene);
        primaryStage.centerOnScreen();
        primaryStage.show();

        root.setExpanded(true);

        // org.scenicview.ScenicView.show(scene);
    }

    private VirtualFlow findVirtualFlow(Parent parent) {
        for (Node node : parent.getChildrenUnmodifiable()) {
            if (node instanceof VirtualFlow) {
                return (VirtualFlow) node;
            }

            if (node instanceof Parent) {
                VirtualFlow b = findVirtualFlow((Parent) node);
                if (b != null) {
                    return b;
                }
            }
        }

        return null;
    }


    private TreeItem<Entry> createRows() {
        TreeItem<Entry> root = new TreeItem<>(new Entry("Root", 25));
        for (int i = 0; i < 10; i++) {
            TreeItem<Entry> parent = new TreeItem<>(new Entry("Parent " + i, 25));
            parent.setExpanded(true);
            root.getChildren().add(parent);
            //parent.expandedProperty().addListener(it -> updateRows());
            for (int j = 0; j < 10 + i; j++) {
                TreeItem<Entry> treeItem = new TreeItem<>(new Entry("Child " + i + "/" + j));
                parent.getChildren().add(treeItem);
            }
        }
        //root.expandedProperty().addListener(it -> updateRows());
        return root;
    }

    public static class Entry {
        static int index = -1;
        private String name;
        private double height = 40;

        public Entry(String name, int height) {
            this.name = name + " h: " + height;
            this.height = height;
        }

        public Entry(String name) {

            switch (++index % 4) {
                case 0:
                    setHeight(50);
                    break;
                case 1:
                    setHeight(30);
                    break;
                case 2:
                    setHeight(70);
                    break;
                case 3:
                    setHeight(100);
                    break;
            }
            this.name = name + " h: " + getHeight();
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public double getHeight() {
            return height;
        }

        public void setHeight(double height) {
            this.height = height;
        }
    }

    TreeTableColumn<Entry, String> createTreeColumn() {
        TreeTableColumn<Entry, String> nameColumn = new TreeTableColumn<>("Name");
        nameColumn.setCellValueFactory(new TreeItemPropertyValueFactory<>("name"));
        nameColumn.setPrefWidth(170);
        nameColumn.setCellFactory(column -> new TreeTableCell<>() {
            {
                setAlignment(Pos.CENTER_LEFT);
            }

            @Override
            protected void updateItem(String item, boolean empty) {
                super.updateItem(item, empty);
                if (item != null) {
                    setText(item);
                } else {
                    setText("");
                }
            }
        });
        return nameColumn;
    }

    public static void main(String[] args) {
        System.out.println("v: " + System.getProperty("javafx.version") + ", position property binding");
        launch(args);
    }
}