/* 
 *  DetailsForm.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.LinkedList;
import java.util.List;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.MenuItem;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx.util.Pair;

public abstract class DetailsForm {

    private final Stage stage = new Stage();
    private final ComboBox<String> detailsSelection = new ComboBox<>();
    private final MenuItem menuItem;
    private final Logger LOG;
    private boolean firstShown = false;

    public DetailsForm(Logger LOG, String title, String menu, String css) {
        this.LOG = LOG;
        stage.titleProperty().set(title);

        menuItem = new MenuItem(menu);
        BorderPane userDetailsborder = new BorderPane();
        Scene userDetailsScene = new Scene(userDetailsborder);
        userDetailsScene.getStylesheets().add(css);
        stage.setScene(userDetailsScene);

        detailsSelection.valueProperty().addListener(new ChangeListener<String>() {
            @Override
            public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
                String methodName = "detailsSelectionChanged() ";
                LOG.trace(methodName + "+");
                redrawDetailsForm();
                LOG.trace(methodName + "-");
            }
        });
        userDetailsborder.setTop(detailsSelection);

        menuItem.setOnAction((ActionEvent t) -> {
            stage.show();
            action();
        });
    }

    protected abstract void action();

    protected abstract ObservableList<Data> getItems();

    protected abstract Data getItem(String id);

    protected abstract Data getDefault();

    public MenuItem getMenuItem() {
        return this.menuItem;
    }

    public void refresh() {
        this.refreshDetailsDisplayList();
        this.redrawDetailsForm();
        this.stage.sizeToScene();
    }

    protected void redrawDetailsForm() {
        BorderPane bp = (BorderPane) stage.sceneProperty().get().getRoot();
        //Need to build up the props and caps lists for multiple users
        List<Pair<String, String>> props = new LinkedList<>();
        List<Pair<String, Boolean>> caps = new LinkedList<>();
        Data item = getCurrentDetailSelection();
        props.addAll(item.getProperties());
        caps.addAll(item.getCaps());
        bp.setLeft(GUIUtil.properties(props));
        bp.setCenter(GUIUtil.capabilities(caps));

        // Just the first time this is shown we place it centered for usability
        if (!firstShown) {
            firstShown = true;
            this.stage.sizeToScene();
            this.stage.centerOnScreen();
        }
    }

    protected void refreshDetailsDisplayList() {
        String methodName = "refreshDetailsDisplayList() ";
        LOG.trace(methodName + "+");
        //Check if the current selection is still in the list of users
        String currentSelection = detailsSelection.getValue();
        if (currentSelection != null) {
            LOG.trace(methodName + "Current Selection:" + currentSelection);
        } else {
            LOG.trace(methodName + "Current is null ");
        }
        List<Data> items = getItems();
        boolean stillExists = false;
        for (Data item : items) {
            if (item.getId().equals(currentSelection)) {
                stillExists = true;
            }
        }
        // If it is save this value to set it again
        LOG.trace(methodName + "clearing+");
        detailsSelection.getItems().clear();
        LOG.trace(methodName + "clearing-");
        for (Data item : items) {
            detailsSelection.getItems().add(item.getId());
        }
        if (stillExists) {
            LOG.trace(methodName + "existing selection still exists:" + currentSelection);
            detailsSelection.setValue(currentSelection);
        } else if (items.size() > 0) {
            LOG.trace(methodName + "existing selection does not exists, setting to first element");
            detailsSelection.setValue(items.get(0).getId());
        } else {
            LOG.trace(methodName + "list is empty");
        }
        LOG.trace(methodName + "-");
    }

    protected Data getCurrentDetailSelection() {
        String methodName = "getCurrentDetailSelection() ";
        String currentSelection = detailsSelection.getValue();
        if (currentSelection != null) {
            LOG.trace(methodName + "current detail selection = " + currentSelection);
            return getItem(currentSelection);
        } else {
            LOG.trace(methodName + "current detail selection is NULL, returning blank");
            return getDefault();
        }
    }
}
