/* 
 *  PreviewDialForm.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 com.avaya.ccs.api.ContactNumberI;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
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 javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Callback;

public class PreviewDialForm {

    private final Stage previewDial = new Stage();
    private final InteractionExecutor interactionExe;
    private static final Logger LOG = Logger.getLogger(PreviewDialForm.class);

    public PreviewDialForm(InteractionExecutor interactionExe, String css) {
        this.interactionExe = interactionExe;
        BorderPane previewDialBorder = new BorderPane();
        Scene previewDialScene = new Scene(previewDialBorder, 300, 400);
        previewDialScene.getStylesheets().add(css);
        previewDial.setScene(previewDialScene);
        previewDial.titleProperty().set("Preview");
    }

    public void show() {
        previewDial.show();
    }

    public void updatePreviewDialForm(InteractionData interaction, CallbackForm callbackForm) {

        BorderPane bp = (BorderPane) previewDial.sceneProperty().get().getRoot();

        ListView<ContactNumberI> list = new ListView<>();
        ObservableList<ContactNumberI> items = FXCollections.observableArrayList(interaction.getContactNumbers());
        list.setItems(items);
        // We want the list to display the name and code only
        list.setCellFactory(new Callback<ListView<ContactNumberI>, ListCell<ContactNumberI>>() {
            @Override
            public ListCell<ContactNumberI> call(ListView<ContactNumberI> list) {
                return new PreviewDialForm.CodeCell();
            }
        });

        // Only enable the ok button when a selection is made....
        Button dialButton = new Button("Dial");
        dialButton.setDisable(true);

        list.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<ContactNumberI>() {
            @Override
            public void changed(ObservableValue<? extends ContactNumberI> observable, ContactNumberI oldValue,
                    ContactNumberI newValue) {
                if (newValue != null) {
                    dialButton.setDisable(false);
                }
            }
        });

        bp.setCenter(list);

        dialButton.getStyleClass().add("interactionButton");
        dialButton.setOnAction((ActionEvent t) -> {
            ContactNumberI toDial = list.getSelectionModel().getSelectedItem();
            String id = interaction.getId();
            LOG.info("DialButton() ID:" + id + " ContactNumber:" + toDial);
            this.interactionExe.previewDial(id, toDial);

            previewDial.close();
        });

        Button cancelButton = new Button("Cancel");
        cancelButton.getStyleClass().add("interactionButton");
        cancelButton.setOnAction((ActionEvent t) -> {
            String id = interaction.getId();
            LOG.info("CancelButton() ID:" + id);
            this.interactionExe.previewCancel(id);
            previewDial.close();
        });

        Button rescheduleButton = new Button("Callback");
        rescheduleButton.getStyleClass().add("interactionButton");
        rescheduleButton.setOnAction((ActionEvent t) -> {
            String id = interaction.getId();
            LOG.info("RescheduleButton() ID:" + id);
            callbackForm.initializeForm(interaction);
            interactionExe.getCallbackDestinations(id);
            callbackForm.show();
            previewDial.close();
        });

        HBox hbuttonbox = new HBox();
        hbuttonbox.getChildren().addAll(dialButton, cancelButton, rescheduleButton);

        // Free form number handling
        HBox freeFormBox = new HBox();
        TextField freeFormNumber = new TextField();
        Button freeFormDialButton = new Button("Dial");
        freeFormDialButton.getStyleClass().add("interactionButton");
        freeFormDialButton.setOnAction((ActionEvent t) -> {
            String id = interaction.getId();
            String number = freeFormNumber.getText();
            LOG.info("DialButton() ID:" + id + " Number:" + number);
            this.interactionExe.previewDialFreeForm(id, number);
            previewDial.close();
        });
        freeFormNumber.setDisable(!interaction.canPreviewDialFreeForm());
        freeFormDialButton.setDisable(true);
        // Disable the free dial button until there is a number entered
        // the dial button may be disabled based on the above capabilities
        // however
        freeFormNumber.textProperty().addListener(new ChangeListener<String>() {
            @Override
            public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
                freeFormDialButton.setDisable(!interaction.canPreviewDialFreeForm() && newValue.isEmpty());
            }
        });

        freeFormBox.getChildren().addAll(freeFormNumber, freeFormDialButton);

        // the ability to cancel a preview dial is capabiltiy driven
        cancelButton.setDisable(!interaction.canPreviewCancel());

        VBox v = new VBox();
        v.getChildren().addAll(freeFormBox, hbuttonbox);
        bp.setBottom(v);
    }

    private static class CodeCell extends ListCell<ContactNumberI> {

        @Override
        public void updateItem(ContactNumberI item, boolean empty) {
            super.updateItem(item, empty);
            if (item != null) {
                setText(item.getName() + ":" + item.getNumber());
            }
        }
    }
}
