/*
 * Copyright (C) 2020 Andrew Gegg
 *
 *	This file is part of the Garden Notebook application
 *
 * The Garden Notebook application is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/gpl.html>.
 */

/*
	Change log
    2.8.0   first version - replaces ProductNameCombo<ProductBean>
 */

package uk.co.gardennotebook;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import uk.co.gardennotebook.fxbean.ProductBean;
import uk.co.gardennotebook.fxbean.ProductCategoryBean;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.message.EntryMessage;
import org.apache.logging.log4j.Level;
import uk.co.gardennotebook.fxbean.ProductBrandBean;
import uk.co.gardennotebook.spi.GNDBException;

/**
	*	Combo box for ProductName property on non-plantlike products.
	*
	*	Must be public to be loaded by FXML
	*
	*	@author	Andy Gegg
	*	@version	2.8.0
	*	@since	2.8.0
*/
final public class ProductNameCombo extends DiaryEntryCombo<String>
{
	private static final Logger LOGGER = LogManager.getLogger();

	private final SimpleObjectProperty<ProductCategoryBean> productCategory = new SimpleObjectProperty<>(this, "ParentProductCategory", null);

//	need a no-args constructor for FXML Loader
	public ProductNameCombo()
	{
		super();
		super.currentValue = null;
		productCategory.addListener((obs, oldVal, newVal) -> {
				if (newVal == null)
				{
					this.getItems().clear();
					this.setValue(null);
				}
				else if (oldVal != null && oldVal.getKey().equals(productCategoryProperty().getValue().getKey()))
				{// not actually changed - can happen during initialisation
					return;
				}
                else if (newVal.isPlantLike())
                {// this should not be used for PlantSpecies values, but may well need to respond to GUI changes to Category
					this.getItems().clear();
                }
				else
				{
                    ObservableList<ProductBean> prods = null;
					try {
						prods = ProductBean.fetchAll(newVal);
					} catch (GNDBException ex) {
						PanicHandler.panic(ex);
					}
                    List<String> justNames = prods.stream().map(ProductBean::getName).distinct().collect(Collectors.toList());
                    this.getItems().setAll(justNames);
                    
					this.setValue(null);
				}
		});
	}

	public ProductNameCombo(ProductCategoryBean parent)
	{
		this();
		productCategoryProperty().set(parent);
	}

	public ProductNameCombo(ProductCategoryBean parent, ProductBean initialVal)
	{
		this(parent);
		this.setValue(initialVal.getName());
		super.currentValue = initialVal.getName();
	}

	SimpleObjectProperty<ProductCategoryBean> productCategoryProperty()
	{
		return productCategory;
	}

	@Override
	String getName(String item)
	{
		EntryMessage log4jEntryMsg = LOGGER.traceEntry("getName({})", item);
		if (item == null)
		{
			return "";
		}
        return item;
	}	//	getName()

	@Override
	String newItem(String name)
	{
		EntryMessage log4jEntryMsg = LOGGER.traceEntry("newItem({})", name);
		if (name == null || name.isEmpty())
		{
			return "";
		}
		return LOGGER.traceExit(log4jEntryMsg, name);
	}	//	newItem()
}
