package fr.shortcircuit.tp9.service.dao.annotated.automation;

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

import org.apache.commons.collections.Predicate;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Repository;

import fr.shortcircuit.tp9.model.Product;
import fr.shortcircuit.tp9.service.dao.definition.IProductDAO;

/** @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
 */

@Repository("productDAO")
@Scope("session")
public class ProductAnnotatedAutomationDAO implements IProductDAO
{
	private static List<Product> list		= new ArrayList();
	private static List<String> listGenre	= Arrays.asList(new String[]{	"Aventure", "Policier", "Comedie", "Drame", "Comedie Dramatique", "Fantastique", "Film d'animation", "Action", "Guerre", "Documentaire", "Suspense"});
	private static List<String> listPrice	= Arrays.asList(new String[]{	"10", "15", "20", "25"});

	static 
	{
		//list.add(new Product(int id, String designation, int type, BigDecimal price, String genre, String realisateur, int annee, String musique, String scenario));
		
		list.add(new Product(1, "The Big Lebowsky", 1, new BigDecimal("15")));
		list.add(new Product(2, "L'enfer du dimanche", 1, new BigDecimal("10")));
		list.add(new Product(3, "American Beauty", 1, new BigDecimal("15")));
		list.add(new Product(4, "Braveheart", 1, new BigDecimal("15"), "Aventure", "Mel Gibson", 1995, "James Horner", "Randall Wallace"));
		list.add(new Product(5, "Vercingetorix", 1, new BigDecimal("15"), "Aventure", "Jack Dorfmann", 2001));
		list.add(new Product(6, "Animal Factory", 1, new BigDecimal("15"), "Policier", "Steve Buscemi", 2000));
		list.add(new Product(7, "La vie, l'amour, les vaches", 1, new BigDecimal("15"), "Comedie", "Ron Underwood", 1991));
		list.add(new Product(8, "Crossing Guard", 1, new BigDecimal("15"), "Drame", "Sean Penn", 1995));
		list.add(new Product(9, "Tigres et dragons", 1, new BigDecimal("15"), "Aventure", "Ang Lee", 2000));
		list.add(new Product(10, "Swimming with sharks", 1, new BigDecimal("25"), "Drame", "G. Huang", 1995));
		list.add(new Product(11, "Les grands ducs", 1, new BigDecimal("20"), "Comedie", "Patrice Leconte", 1995, "Jean-Claude Nachon, Angelique Nachon", "Patrice Leconte, S. Frydman"));
		list.add(new Product(12, "Sling Blade", 1, new BigDecimal("20"), "Drame", "Billy Bob Thornton", 1997));
		list.add(new Product(13, "Magnolia", 1, new BigDecimal("20"), "Drame", "Paul Thomas Anderson", 1999));
		list.add(new Product(14, "Exit", 1, new BigDecimal("20"), "Policier", "Olivier Megaton", 2000));
		list.add(new Product(15, "X-Men", 1, new BigDecimal("20"), "Fantastique", "Bryan Singer", 2000));
		list.add(new Product(16, "The Yards", 1, new BigDecimal("25"), "Policier", "James Gray", 2000));
		list.add(new Product(17, "O'Brother", 1, new BigDecimal("25"), "Comedie", "Joel Cohen, Ethan Cohen", 2000));
		list.add(new Product(18, "Les mutants de l'espace", 1, new BigDecimal("15"), "Film d'animation", "Bill Plympton", 2001));
		list.add(new Product(19, "High Fidelity", 1, new BigDecimal("10"), "Comedie", "Stephen Frears", 2000));
		list.add(new Product(20, "Trainspotting", 1, new BigDecimal("10"), "Drame", "Danny Boyle", 1996));
		list.add(new Product(21, "La ligne Verte", 1, new BigDecimal("10"), "Drame", "Frank Darambont", 1999, "Thomas Newman", "Frank Darambont"));
		list.add(new Product(22, "Predator 2", 1, new BigDecimal("10"), "Fantastique", "Stephen Hopkins", 1990));    
		list.add(new Product(23, "Fist of Legend", 1, new BigDecimal("15"), "Action", "Gordon Chan", 1994, "Joseph Koo", "Gordon Chan, Lan Kay Toa"));
		list.add(new Product(24, "En territoire ennemi", 1, new BigDecimal("20"), "Guerre", "John Moore", 2001, "Don Davis", "Jim Thomas, John  Thomas, David Veloz, Zak Penn"));
		list.add(new Product(25, "Monique", 1, new BigDecimal("25"), "Comedie", "Valerie Guignabodet", 2002, "Cedric Neveux", "Valerie Guignabodet"));
		list.add(new Product(26, "Une affaire de gožt", 1, new BigDecimal("15"), "Drame", "Bernard Rapp", 1999));
		list.add(new Product(27, "Cecil B. DeMented", 1, new BigDecimal("25"), "Comedie", "John Waters", 2000));
		list.add(new Product(28, "Abyss", 1, new BigDecimal("25"), "Fantastique", "James Cameron", 1989));
		list.add(new Product(29, "Ghost World", 1, new BigDecimal("15"), "Comedie", "Terry Zwigoff", 2001));
		list.add(new Product(30, "Les Autres", 1, new BigDecimal("20"), "Fantastique", "Alejandro Amenabar", 2001));
		list.add(new Product(31, "The Big One", 1, new BigDecimal("20"), "Documentaire", "Michael Moore", 1999));
		list.add(new Product(32, "Ocean's Eleven", 1, new BigDecimal("15"), "Suspense", "Steven Soderbergh", 2001));
		list.add(new Product(33, "La rançon", 1, new BigDecimal("15"), "Suspense", "Ron Howard", 1996));
		list.add(new Product(34, "La plage", 1, new BigDecimal("15"), "Aventure", "Danny Boyle", 1999));
		list.add(new Product(35, "Barton Fink", 1, new BigDecimal("15"), "Comedie Dramatique", "Joel et Ethan Cohen", 1991));
		list.add(new Product(36, "Little Buddha", 1, new BigDecimal("15"), "Comedie Dramatique", "Bernardo Bertolucci", 1993, "Ryuichi Sakamoto", "Bernardo Bertolucci, Mark Peploe"));             
	}


	public Product getProduct(Predicate predicate)
	{
        for (Product product : list)
        	if (predicate.evaluate(product))
        		return product;

		return null;
	}

	public List<Product> getAllProduct(Predicate predicate)
	{
		List<Product> l = new ArrayList<Product>();
		
        for (Product product : list)
        	if (predicate.evaluate(product))
        		l.add(product);

		return l;
	}
	
	public List<Product> getAllProduct(Comparator beanComparator)
	{
		Collections.sort(list, beanComparator);              
		
		return list;
	}

	/**
	 * Cette methode etend la precedente, elle permet de selectionner une portion de la liste en fonction de l'index et de la quantite passe en plus en parametre
	 * ces parametres peuvent etre delegues dans une requete SQL afin de remonter qu'un subset de donnees, et non la totalite d'une table :)
	 * 
	 * @param beanComparator
	 * @param rowIndex
	 * @param rowCount
	 * @return
	 */
	public List<Product> getAllProduct(Comparator beanComparator, int rowIndex, int rowCount)
	{//System.out.println("TP9: ProductAnnotatedAutomationDAO: getAllProduct(beanComparator, rowIndex, rowCount): enter");
		
		Collections.sort(list, beanComparator);
		
		int normalBound			= rowIndex + rowCount;
		int effectiveBound 		= (normalBound > list.size())? list.size() : normalBound;
		List<Product> lResult	= list.subList(rowIndex, effectiveBound);

		//System.out.println("TP9: ProductAnnotatedAutomationDAO: getAllProduct(beanComparator, rowIndex, rowCount): return lResult.size=" + lResult.size());

		return lResult;
	}

	public List<Product> getAllProduct(Comparator beanComparator, Predicate allPredicateFilters, int rowIndex, int rowCount)
	{//System.out.println("TP9: ProductAnnotatedAutomationDAO: getAllProduct: enter");
		
		List<Product> listFilteredResult	= getAllProduct(allPredicateFilters);

		Collections.sort(listFilteredResult, beanComparator);
		
		int normalBound						= rowIndex + rowCount;
		int effectiveBound 					= (normalBound > listFilteredResult.size())? listFilteredResult.size() : normalBound;
		List<Product> lResult				= listFilteredResult.subList(rowIndex, effectiveBound);

		//System.out.println("TP9: ProductAnnotatedAutomationDAO: getAllProduct: return lResult.size=" + lResult.size());

		return lResult;
	}

	public int count(Predicate allPredicateFilters)
	{
		return getAllProduct(allPredicateFilters).size();
	}

	public List<Product> getList()			{return list;}
	public List<String> getListGenre() 		{return listGenre;}
	public List<String> getListPrice() 		{return listPrice;}	
}
