package edu.chl.proton.control;

import javafx.scene.control.*;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;

import java.io.File;
import java.io.IOException;

/**
 * @author Stina werme
 * Created by stinawerme on 20/05/17.
 *
 * Extends java class TreeCell to make the tree editable for the user.
 * The Treecell wraps around a treeItem and has methods to get the treeItem.
 */
public class EditableTreeCell extends TreeCell<File> {

    private TextField textField;
    private ContextMenu contextMenu;


    public EditableTreeCell() {

    }

    /**
     * Start edit
     */
    @Override
    public void startEdit() {
        super.startEdit();

        if (textField == null) {
            createTextField();
        }
        setText(null);
        setGraphic(textField);
        textField.selectAll();
    }

    /**
     * Cancel edit
     */
    @Override
    public void cancelEdit() {
        super.cancelEdit();
        File item = getItem();

        item.getName();
        setText(item.getName());
        setGraphic(getTreeItem().getGraphic());
    }

    /**
     * Update item
     * @param item
     * @param empty
     */
    @Override
    public void updateItem(File item, boolean empty) {
        super.updateItem(item, empty);

        if (empty) {
            setText(null);
            setGraphic(null);
            return;
        }

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

            setText(null);
            setGraphic(textField);
            return;
        }

        setText(getString());
        setGraphic(getTreeItem().getGraphic());
        createContextMenu();
    }

    /**
     * Create a contextMenu with varying items depending on the type of treeItem.
     */
    private void createContextMenu() {
        TreeItem<File> treeItem = getTreeItem();
        contextMenu = new ContextMenu();

        if (!treeItem.isLeaf() && treeItem.getParent() != null) {
            createAddMenuItem();
        }

        createDeleteMenuItem();
        setContextMenu(contextMenu);
    }

    /**
     * Create a context menu item for adding files.
     */
    private void createAddMenuItem() {
        MenuItem addMenuItem = new MenuItem("Add new");
        contextMenu.getItems().add(addMenuItem);
        addMenuItem.setOnAction(t -> {

            TreeItem<File> currentTreeItem = getTreeItem();
            File currentFile = currentTreeItem.getValue();

            String path = null;
            try {
                path = currentFile.getCanonicalPath();
            } catch (IOException e) {
                e.printStackTrace();
            }

            File f = new File(path, "untitled.md");

            f.getParentFile().mkdirs();
            int number = 2;

            try {
                while (f.exists()) {
                    f = new File(path, "untitled" + number + ".md");
                    number++;
                }
                f.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }

            TreeItem newTreeItem = new TreeItem<File>();
            newTreeItem.setValue(f);
            currentTreeItem.getChildren().add(newTreeItem);

            if (!currentTreeItem.isExpanded()) {
                currentTreeItem.setExpanded(true);
            }
        });
    }

    /**
     * Create a context menu item for deleting files.
     */
    private void createDeleteMenuItem() {
        MenuItem deleteMenuItem = new MenuItem("Delete");
        contextMenu.getItems().add(deleteMenuItem);
        deleteMenuItem.setOnAction(t -> {
            TreeItem<File> currentTreeItem = getTreeItem();
            File currentFile = currentTreeItem.getValue();

            Alert alert = new Alert(Alert.AlertType.CONFIRMATION,
                    "Delete " + currentFile.getName() + " ?",
                    ButtonType.YES, ButtonType.CANCEL);
            alert.showAndWait();

            if (alert.getResult() == ButtonType.CANCEL) {
                return;
            }

            currentTreeItem.getParent().getChildren().remove(currentTreeItem);
            currentFile.delete();
        });
    }

    /**
     * Create a text field to change name
     * If user clicks enter, update name
     */
    private void createTextField() {
        textField = new TextField(getString());
        textField.setOnKeyReleased(keyReleaseEventObject -> {
            if (keyReleaseEventObject.getCode() == KeyCode.ENTER) {
                String name = textField.getText();
                File newFileName = new File(getItem().getParentFile(), name);
                getItem().renameTo(newFileName);
                commitEdit(newFileName);

            } else if (keyReleaseEventObject.getCode() == KeyCode.ESCAPE) {
                cancelEdit();
            }
        });
    }

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

@@ -1998,17 +1998,16 @@
     if (
-!
 treeItem
@@ -2011,51 +2011,104 @@
 tem.
-isLeaf() && treeItem.getParent() != null) %7B
+getParent() != null && treeItem.getValue().isDirectory()) %7B%0A            createAddFileMenuItem();
 %0A   
@@ -2117,32 +2117,38 @@
        createAdd
+Folder
 MenuItem();%0A    
@@ -2324,16 +2324,20 @@
 reateAdd
+File
 MenuItem
@@ -2390,15 +2390,16 @@
 em(%22
-Add new
+New file
 %22);%0A
@@ -3198,32 +3198,32 @@
 ntStackTrace();%0A
-
             %7D%0A%0A 
@@ -3501,32 +3501,1183 @@
      %7D);%0A    %7D%0A%0A
+    /**%0A     * Create a context menu item for adding folders.%0A     */%0A    private void createAddFolderMenuItem() %7B%0A        MenuItem addMenuItem = new MenuItem(%22New folder%22);%0A        contextMenu.getItems().add(addMenuItem);%0A        addMenuItem.setOnAction(t -%3E %7B%0A%0A            TreeItem%3CFile%3E currentTreeItem = getTreeItem();%0A            File currentFile = currentTreeItem.getValue();%0A%0A            String path = null;%0A            try %7B%0A                path = currentFile.getCanonicalPath();%0A            %7D catch (IOException e) %7B%0A                e.printStackTrace();%0A            %7D%0A%0A            File f = new File(path, %22untitledFolder%22);%0A%0A            f.getParentFile().mkdirs();%0A            int number = 2;%0A%0A            while (f.exists()) %7B%0A                f = new File(path, %22untitledFolder%22 + number);%0A                number++;%0A            %7D%0A            f.mkdir();%0A%0A            TreeItem newTreeItem = new TreeItem%3CFile%3E();%0A            newTreeItem.setValue(f);%0A            currentTreeItem.getChildren().add(newTreeItem);%0A%0A            if (!currentTreeItem.isExpanded()) %7B%0A                currentTreeItem.setExpanded(true);%0A            %7D%0A        %7D);%0A    %7D%0A%0A
     /**%0A     * C

Make it possible to add folders in tree