/* 
 *  KVPTab.java
 * 
 *  Copyright 2016 Avaya Inc. All Rights Reserved.
 * 
 *  Usage of this source is bound to the terms described
 *  in AvayaLicenseSDK.rtf.
 * 
 *  Avaya - Confidential & Proprietary. Use pursuant to your signed agreement
 *  or Avaya Policy
 * 
 */
package com.avaya.ccs.javafxrefclient;

import java.util.Optional;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonBar;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Dialog;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.util.Pair;

public abstract class KVPTab extends KVPTabBase {

    private final Logger LOG;

    protected final InteractionExecutor interactionExe;
    protected final InteractionDataGUI gui;

    public KVPTab(Logger LOG, InteractionExecutor interactionExe, InteractionDataGUI gui, String title) {
        super(title);
        this.LOG = LOG;
        this.interactionExe = interactionExe;
        this.gui = gui;

        HBox buttons = new HBox();
        Button remove = new Button("Remove");
        remove.setDisable(true);
        remove.getStyleClass().add("kvpButton");
        remove.setOnAction((ActionEvent t) -> {
            LOG.info("RemoveButton()");
            KVPItem currentSelection = (KVPItem) getTable().getSelectionModel().getSelectedItem();
            removeDialog(currentSelection.getName(), currentSelection.getValue());
        });

        Button add = new Button("Add");
        add.getStyleClass().add("kvpButton");
        add.setOnAction((ActionEvent t) -> {
            LOG.info("AddButton()");
            addDialog();
        });

        Button edit = new Button("Edit");
        edit.setDisable(true);
        edit.getStyleClass().add("kvpButton");
        edit.setOnAction((ActionEvent t) -> {
            LOG.info("EditButton()");
            KVPItem currentSelection = (KVPItem) getTable().getSelectionModel().getSelectedItem();
            editDialog(currentSelection.getName(), currentSelection.getValue());
        });

        buttons.getChildren().addAll(remove, add, edit);
        getPane().setBottom(buttons);

        //disable the edit and remove buttons if no row is selected
        getTable().getSelectionModel().selectedItemProperty().addListener((obs, oldSelection, newSelection) -> {
            String methodName = "kvpSelectionChanged() ";
            if (newSelection != null) {
                LOG.trace(methodName + "selection is not null");                
                remove.setDisable(newSelection.isReadOnly());
                edit.setDisable(newSelection.isReadOnly());
            } else {
                LOG.trace(methodName + "selection is null");
                remove.setDisable(true);
                edit.setDisable(true);
            }
        });
    }


    protected void removeDialog(String key, String value) {
        Dialog<Pair<String, String>> dialog = new Dialog<>();
        dialog.setTitle("Remove " + getTitle());
        ButtonType removeButtonType = new ButtonType("Remove", ButtonBar.ButtonData.OK_DONE);
        dialog.getDialogPane().getButtonTypes().addAll(removeButtonType, ButtonType.CANCEL);
        GridPane grid = new GridPane();
        grid.getStyleClass().add("dialog");
        grid.add(new Label("Name:"), 0, 0);
        grid.add(new Label(key), 1, 0);
        grid.add(new Label("Value:"), 0, 1);
        grid.add(new Label(value), 1, 1);
        dialog.getDialogPane().setContent(grid);
        dialog.setResultConverter((ButtonType dialogButton) -> {
            if (dialogButton == removeButtonType) {
                return new Pair<>(key, value);
            }
            return null;
        });
        Optional<Pair<String, String>> result = dialog.showAndWait();
        result.ifPresent((Pair<String, String> keyValue) -> {
            String keyResult = keyValue.getKey();
            String methodName = "removeDialog() ";
            LOG.trace(methodName + "Key:" + keyResult + " Value: " + keyValue.getValue());
            remove(gui.getCurrentItemSelection().getId(), keyResult);
        });
    }

    protected void editDialog(String name, String value) {
        Dialog<Pair<String, String>> dialog = new Dialog<>();
        dialog.setTitle("Edit " + getTitle());
        ButtonType okButtonType = new ButtonType("Save", ButtonBar.ButtonData.OK_DONE);
        dialog.getDialogPane().getButtonTypes().addAll(okButtonType, ButtonType.CANCEL);
        GridPane grid = new GridPane();
        grid.getStyleClass().add("dialog");
        TextField nameTextField = new TextField();
        nameTextField.setText(name);
        
        nameTextField.setEditable(false);
        TextField valueTextField = new TextField();
        valueTextField.setText(value);
        grid.add(new Label("Name:"), 0, 0);
        grid.add(nameTextField, 1, 0);
        grid.add(new Label("Value:"), 0, 1);
        grid.add(valueTextField, 1, 1);
        dialog.getDialogPane().setContent(grid);
        Platform.runLater(() -> nameTextField.requestFocus());
        dialog.setResultConverter((ButtonType dialogButton) -> {
            if (dialogButton == okButtonType) {
                return new Pair<>(nameTextField.getText(), valueTextField.getText());
            }
            return null;
        });
        Optional<Pair<String, String>> result = dialog.showAndWait();
        result.ifPresent((Pair<String, String> resultNameValue) -> {
            String methodName = "editDialog() ";
            String resultKey = resultNameValue.getKey();
            String resultValue = resultNameValue.getValue();
            LOG.trace(methodName + "Key: " + resultKey + " Value: " + resultValue);
            edit(gui.getCurrentItemSelection().getId(), resultKey, resultValue);
        });
    }

    protected void addDialog() {
        Dialog<Pair<String, String>> dialog = new Dialog<>();
        dialog.setTitle("Add " + getTitle());

        ButtonType okButtonType = new ButtonType("Save", ButtonBar.ButtonData.OK_DONE);
        dialog.getDialogPane().getButtonTypes().addAll(okButtonType, ButtonType.CANCEL);

        GridPane grid = new GridPane();
        grid.getStyleClass().add("dialog");
        TextField nameTextField = new TextField();
        TextField valueTextField = new TextField();
        grid.add(new Label("Name:"), 0, 0);
        grid.add(nameTextField, 1, 0);
        grid.add(new Label("Value:"), 0, 1);
        grid.add(valueTextField, 1, 1);
        dialog.getDialogPane().setContent(grid);

        Platform.runLater(() -> nameTextField.requestFocus());

        dialog.setResultConverter((ButtonType dialogButton) -> {
            if (dialogButton == okButtonType) {
                return new Pair<>(nameTextField.getText(), valueTextField.getText());
            }
            return null;
        });
        Optional<Pair<String, String>> result = dialog.showAndWait();
        result.ifPresent((Pair<String, String> resultNameValue) -> {
            String methodName = "addDialog() ";
            String resultName = resultNameValue.getKey();
            String resultValue = resultNameValue.getValue();
            LOG.trace(methodName + "Add called on name: " + resultName + " with value: " + resultValue);
            add(gui.getCurrentItemSelection().getId(), resultName, resultValue);
        });
    }

    abstract void add(String interactionID, String name, String newValue);

    abstract void edit(String interactionID, String name, String newValue);

    abstract void remove(String interactionID, String name);
    
}
