package be.iminds.ilabt.jfed.ui.javafx.util;

import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ListProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleListProperty;
import javafx.collections.FXCollections;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;

import javax.inject.Inject;

/**
 * ExecuteServicesPanel
 */
public class EditableStringListPanel extends BorderPane {
    private final ListProperty<String> list = new SimpleListProperty<>(FXCollections.<String>observableArrayList());
    private final BooleanProperty editable = new SimpleBooleanProperty(true);
    @FXML
    protected Button addButton;
    @FXML
    protected Button deleteButton;
    @FXML
    protected ListView<String> listView;

    @Inject
    public EditableStringListPanel() {
    }

    public BooleanProperty editableProperty() {
        return editable;
    }

    public boolean getEditable() {
        return editable.get();
    }

    public void setEditable(boolean edit) {
        editable.set(edit);
    }

    @FXML
    private void initialize() {
        listView.setItems(list);
        listView.setEditable(true);
        listView.setCellFactory(stringListView -> new StringEditingCell());
        addButton.visibleProperty().bind(editable);
        deleteButton.visibleProperty().bind(editable);
    }

    public ListProperty<String> listProperty() {
        return list;
    }

    @FXML
    private void add() {
        String newItem = "new item";
        list.add(newItem);
        listView.edit(list.indexOf(newItem));
    }

    @FXML
    private void delete() {
        int selectedIndex = listView.getSelectionModel().getSelectedIndex();
        if (selectedIndex >= 0 && selectedIndex < list.size())
            list.remove(selectedIndex);
    }

    class StringEditingCell extends ListCell<String> {
        private TextField textField;

        public StringEditingCell() {
        }

        @Override
        public void startEdit() {
            if (!isEmpty()) {
                super.startEdit();
                createTextField();
                setText(null);
                setGraphic(textField);
                textField.selectAll();
            }
        }

        @Override
        public void cancelEdit() {
            super.cancelEdit();

            setText(getItem());
            setGraphic(null);
        }

        @Override
        public void updateItem(String item, boolean empty) {
            super.updateItem(item, empty);

            if (empty) {
                setText(null);
                setGraphic(null);
            } else {
                if (isEditing()) {
                    if (textField != null) {
                        textField.setText(getString());
                    }
                    setText(null);
                    setGraphic(textField);
                } else {
                    setText(getString());
                    setGraphic(null);
                }
            }
        }

        private void createTextField() {
            textField = new TextField(getString());
            textField.editableProperty().bind(editable);
            textField.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2);
            textField.focusedProperty().addListener((arg0, arg1, arg2) -> {
                if (!arg2) {
                    commitEdit(textField.getText());
                }
            });
        }

        private String getString() {
            return getItem() == null ? "" : getItem();
        }
    }
}
