/* 
 *  ComboDataGUI.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 javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.control.ComboBox;

public abstract class ComboDataGUI {

    private final Logger LOG;
    private final ObservableList<Data> items = FXCollections.observableArrayList();
    private final ComboBox<String> itemSelection = new ComboBox<>();
    private DetailsForm detailsForm;

    public ComboDataGUI(Logger LOG) {
        this.LOG = LOG;
        itemSelection.valueProperty().addListener(new ChangeListener<String>() {
            @Override
            public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
                String methodName = "itemSelectionChanged() ";
                LOG.trace(methodName + "+");
                redrawControls();
                LOG.trace(methodName + "-");
            }
        });
    }

    //Return the current user selection or a dummy value if there is none....
    protected Data getCurrentItemSelection() {
        String methodName = "getCurrentItemSelection() ";
        String currentSelection = getItemSelection().getValue();
        if (currentSelection != null) {
            LOG.trace(methodName + "current selection:" + currentSelection);
            return getItem(currentSelection);
        } else {
            LOG.trace(methodName + "current selection is NULL, returning null");
            return null;
        }
    }

    //This method is responsible for updating the gui with any new user related data
    public void update(ObservableList<Data> data) {
        String methodName = "update() ";
        LOG.info(methodName + " DataSize:" + data.size());
        items.clear();
        this.items.addAll(data);
        refreshListsAndRedraw();
    }

    //This version assumes only the new data object needs to be updated
    public void update(Data data) {
        String methodName = "update() ";
        LOG.trace(methodName + "DataID:" + data.getId());
        //Look in existing list of entry
        Data itemFound = null;
        for (Data item : this.items) {
            if (item.getId().equals(data.getId())) {
                // if there update it
                itemFound = item;
                break;
            }
        }
        if (itemFound != null) {
            LOG.trace(methodName + "existing entry found");
            this.items.remove(itemFound);
            if (data.isDeleted()) {
                LOG.trace(methodName + "update is a deletion update, not adding new data");
            } else {
                LOG.trace(methodName + "updating entry");
                this.items.add(data);
            }
        } else if (data.isDeleted()) {
            LOG.trace(methodName + "existing entry not found, but update is a delete so NOT adding");
        } else {
            LOG.trace(methodName + "existing entry not found, adding");
            this.items.add(data);
        }
        refreshListsAndRedraw();
    }

    public void clearData() {
        items.clear();
        refreshListsAndRedraw();
    }

    protected void refreshListsAndRedraw() {
        refreshList();
        if (this.getDetailsForm() != null) {
            this.getDetailsForm().refresh();
        }
        redrawControls();
    }

    protected void refreshList() {
        String methodName = "refreshList() ";
        //Check if the current selection is still in the list of users
        String currentSelection = getItemSelection().getValue();
        boolean stillExists = false;
        for (Data user : this.items) {
            if (user.getId().equals(currentSelection)) {
                stillExists = true;
            }
        }
        // If it is save this value to set it again
        getItemSelection().getItems().clear();
        for (Data user : this.items) {
            getItemSelection().getItems().add(user.getId());
        }
        if (stillExists) {
            LOG.trace(methodName + "existing selection still exists:" + currentSelection);
            getItemSelection().setValue(currentSelection);
        } else if (this.items.size() > 0) {
            LOG.trace(methodName + "existing selection does not exists, setting to first element");
            getItemSelection().getSelectionModel().selectFirst();
        } else {
            LOG.trace(methodName + "list is empty");
        }
    }

    public Data getItem(String id) {
        String methodName = "getItem() ";
        LOG.trace(methodName + "ID:" + id);
        for (Data item : this.items) {
            if (item.getId().equals(id)) {
                LOG.trace(methodName + "item found");
                return item;
            }
        }
        return null;
    }

    public ObservableList<Data> getItems() {
        return this.items;
    }

    //The implementing class implements this method which is responsible for redrawing the GUI elements
    protected abstract void redrawControls();

    public ComboBox<String> getItemSelection() {
        return itemSelection;
    }

    public DetailsForm getDetailsForm() {
        return detailsForm;
    }

    public void setDetailsForm(DetailsForm detailsForm) {
        this.detailsForm = detailsForm;
    }
}
