package fr.shortcircuit.tp9.web;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.faces.model.SelectItem;

import org.apache.commons.beanutils.BeanPredicate;
import org.apache.commons.collections.Predicate;
import org.apache.commons.collections.functors.AllPredicate;
import org.apache.commons.collections.functors.EqualPredicate;
import org.apache.commons.lang.StringUtils;

import fr.shortcircuit.tp9.business.definition.IProductBO;
import fr.shortcircuit.tp9.model.Product;
import fr.shortcircuit.tp9.web.definition.IProductSearchBean;
import fr.shortcircuit.tp9.web.util.StartsWithPredicate;
import fr.shortcircuit.tp9.web.util.WebHelper;

/** @author Dimitri Dean DARSEYNE (D3), 
 * Published by Short-Circuit under Creative Commons (CC) Licensing: 
 * Authorship/Paternity, NO Commercial Use, NO Derivative
 * Please check for more informations:
 * http://creativecommons.org/licenses/by-nc-nd/2.0/
 *
 * Auteur Dimitri Dean DARSEYNE (D3),
 * Publié par Short-Circuit sous license Creative Commons (CC):
 * Paternité, PAS d'Utilisation Commerciale, pas de Dérivés/Modifications
 * Pour plus d'informations, se rendre sur:
 * http://creativecommons.org/licenses/by-nc-nd/2.0/fr/ 
 * 
 * @since Short-Circuit 1999
 */

public class ProductSearchBean implements IProductSearchBean 
{
	//Injected references
	private IProductBO 				productBO;

	//Simple search criteria parameter
	private String 					id;
	private String 					idKey;
	
	//Multiple chained search criteria parameter
	private String 					selectedProperty 	= "genre";
	private String 					selectedPropertyItem;
	private List<SelectItem> 		properties;
	private List<SelectItem> 		itemsGenre;
	private List<SelectItem> 		itemsPrice;
	
	//Auto completion 
	private String 					strProduct; 
	
	private Product 				productResult;
	private Product 				productKeyResult;

	
	public ProductSearchBean() 
	{
		properties 			= WebHelper.wrapItemsWithLabel(Arrays.asList(new String[]{"genre", "price"}));
	}

	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//Search methods
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	public String search()
	{
		productResult = searchProduct(id);
		//System.out.println("ProductSearchBean: search: exit, productResult=" + productResult);
		return null;
	}	

	public void keySearch()
	{
		productKeyResult = searchProduct(idKey);
		//System.out.println("ProductSearchBean: search: exit, productKeyResult=" + productKeyResult);
	}
	
	private Product searchProduct(String idSearched)
	{//System.out.println("ProductSearchBean: searchProduct: enter, idSearched=" + idSearched);
		
		if (!StringUtils.isEmpty(idSearched))
			try
			{
				List<Predicate> listPredicate  = new ArrayList<Predicate>();
				
				listPredicate.add(new BeanPredicate("id", new EqualPredicate(Integer.parseInt(idSearched))));
				
				Predicate pAll                      =  new AllPredicate((Predicate[]) listPredicate.toArray(new Predicate[] {})); //AnyPredicate
				return productBO.getProduct(pAll);
			}
			catch (Exception e) {System.out.println("ProductSearchBean: searchProduct: catch " + e.toString());}
		
		return null;
	}	

	public List<Product> getMatchingProducts()
	{
		if ((StringUtils.isEmpty(selectedProperty)) || (StringUtils.isEmpty(selectedPropertyItem)))
				return new ArrayList<Product>();
				
		List<Predicate> listPredicate  = new ArrayList<Predicate>();
		
		listPredicate.add(new BeanPredicate(selectedProperty, new EqualPredicate(selectedProperty.equalsIgnoreCase("genre")? selectedPropertyItem : new BigDecimal(selectedPropertyItem))));
		
		Predicate pAll                 =  new AllPredicate((Predicate[]) listPredicate.toArray(new Predicate[] {})); //AnyPredicate
		
		return productBO.getAllProduct(pAll);		
	}
	
	public List<String> complete(String prefix)
	{
	    List<String> matches = new ArrayList<String>();

		if (StringUtils.isEmpty(prefix))
			return matches;
		
		List<Predicate> listPredicate  = new ArrayList<Predicate>();

		listPredicate.add(new BeanPredicate("designation", 	new StartsWithPredicate(prefix)));

		List<Product> matchesProduct = productBO.getAllProduct(new AllPredicate((Predicate[]) listPredicate.toArray(new Predicate[] {})));

		for (Product p : matchesProduct)
			matches.add(p.getDesignation());

	    return matches;
	}
	
	
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//Derivated property
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	public List<SelectItem> getPropertyItems()  						{return selectedProperty.equalsIgnoreCase("genre")? getItemsGenre() : getItemsPrice();}
	
	public List<SelectItem> getItemsGenre() 							
	{
		if (itemsGenre == null)
			itemsGenre 			= WebHelper.wrapItemsWithLabel(productBO.getListGenre());
			
		return itemsGenre;
	}
	
	public List<SelectItem> getItemsPrice() 							
	{
		if (itemsPrice == null)
			itemsPrice 			= WebHelper.wrapItemsWithLabel(productBO.getListPrice());

		return itemsPrice;
	}
	
	public void setIdKey(String idKey) 									
	{
		this.idKey 				= idKey;
		
		keySearch();
	}
	
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//Getters & Setters
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	public IProductBO getProductBO() 									{return productBO;}
	public String getId() 												{return id;}
	public Product getProductResult() 									{return productResult;}
	public String getSelectedProperty() 								{return selectedProperty;}
	public String getSelectedPropertyItem() 							{return selectedPropertyItem;}
	public List<SelectItem> getProperties() 							{return properties;}
	public String getIdKey() 											{return idKey;}
	public Product getProductKeyResult() 								{return productKeyResult;}
	public String getStrProduct() 										{return strProduct;}
	
	public void setProductBO(IProductBO productBO) 						{this.productBO 			= productBO;}
	public void setId(String id) 										{this.id 					= id;}
	public void setProductResult(Product productResult) 				{this.productResult 		= productResult;}
	public void setSelectedProperty(String selectedProperty) 			{this.selectedProperty 		= selectedProperty;}
	public void setSelectedPropertyItem(String selectedPropertyItem) 	{this.selectedPropertyItem 	= selectedPropertyItem;}
	public void setProperties(List<SelectItem> properties) 				{this.properties 			= properties;}
	public void setItemsGenre(List<SelectItem> itemsGenre) 				{this.itemsGenre 			= itemsGenre;}
	public void setItemsPrice(List<SelectItem> itemsPrice) 				{this.itemsPrice 			= itemsPrice;}
	public void setProductKeyResult(Product productKeyResult) 			{this.productKeyResult 		= productKeyResult;}
	public void setStrProduct(String strProduct) 						{this.strProduct 			= strProduct;}
	
}
