/**
 * 
 */
package bargainingchips.utilityfunctions;

import bargainingchips.Bundle;
import bargainingchips.BundleBuilder;
import bargainingchips.Chip;
import bargainingchips.ChipIssueValue;
import bargainingchips.ChipIssueValueBuilder;
import bargainingchips.wishlist.WishList;
import bargainingchips.wishlist.WishListBuilder;

/**
 * 
 * If total price of the offered bundle is higher that the total price of the Wishlist, returns 0.0.
 * Otherwise, it evaluates the offered bundle based on its price ratio (with respect to the Wishlist).
 *  
 * As specific cases, when the unit prices are equal but the total price regarding the quantities, 
 * it evaluates the offer as 0.0. Moreover, in case of chip unit prices where the total price regarding 
 * the offered quantities is equal or less than the total desired price, it returns 1.0. 
 * 
 * For other cases, this ignoring quantity utility function returns a value between 0.0 and 1.0. 
 *  
 * 
 * @author Faria Nassiri-Mofakham
 *
 */
public class UF_LessPrice implements UtilityFunction {

	private WishList wishlist;
	private ChipIssueValue<Double> breakEvenPrices;

	public UF_LessPrice(WishList w, ChipIssueValue<Double> bEP)
	{
		this.wishlist = w;
		this.breakEvenPrices = bEP;
	}

	
	@Override
	public Double getUtility(Bundle b) 
	{
		double desired=0.0;
		for (Chip c : wishlist)
			desired += ((c!=null) ? ((breakEvenPrices.getUnitValue(c)>0.0) ? breakEvenPrices.getUnitValue(c) : 0.0): 0.0);
		double offered = (b!=null ? b.getTotalPrice() : 0.0);
//		System.out.println("offered " + offered + " desired " + desired);
		return ((offered > desired) ? 0.0 : 1.0 - offered/desired);
	}

	@Override
	public String toString()
	{
		return this.getClass().getSimpleName() + ": WishList " + wishlist.toString() + ": BreakEvenPrices "+ breakEvenPrices.toString();
	}
	
	public static void main(String[] args) 
	{
		WishList wishlist1 = new WishListBuilder().addWish("Red", 7).addWish("Green", 5).build();
		ChipIssueValue<Double> prices1 = new ChipIssueValueBuilder<Double>().addIssue("Red", 100.0).addIssue("Green", 200.0).addIssue("Blue", 700.0).build();
				
		UF_LessPrice u1 = new UF_LessPrice(wishlist1, prices1);
		
		
		
		WishList wishlist2 = new WishListBuilder().addWish("Red", 7).addWish("Green", 5).build();
		ChipIssueValue<Double> prices2 = new ChipIssueValueBuilder<Double>().addIssue("Red", 10.0).addIssue("Green", 20.0).addIssue("Blue", 70.0).build();
				
		UF_LessPrice u2 = new UF_LessPrice(wishlist2, prices2);
		
		
		
		WishList wishlist3 = new WishListBuilder().addWish("Green", 4).addWish("Yellow", 6).addWish("Orange", 40).build();
		ChipIssueValue<Double> prices3 = new ChipIssueValueBuilder<Double>().addIssue("Green", 3.0).addIssue("Yellow", 5.0).addIssue("Orange", 1.0).build();

		UF_LessPrice u3 = new UF_LessPrice(wishlist3, prices3);
		
		
		
		Bundle offer1 = new BundleBuilder()
				.addStack("Red", 1.0, 6)
				.addStack("Green", 3.0, 15)
				.addStack("Purple", 0.10, 10)
				.build();
		
		Bundle offer2 = new BundleBuilder()
				.addStack("Red", 1.0, 1)
				.addStack("Green", 3.0, 1)
				.addStack("Purple", 0.10, 1)			
				.build();	

		Bundle offer3 = new BundleBuilder()		
//				.addStack("Green", 2.0, 3)
//				.addStack("Yellow", 5.0, 4)
//				.addStack("Orange", 1.0, 17)
		//---				
				.addStack("Green", 3.0, 4)		
				.addStack("Yellow", 5.0, 6)
				.addStack("Orange", 1.0, 40)
		//---				
//				.addStack("Green", 10.0, 1)		
//				.addStack("Yellow", 10.0, 1)
//				.addStack("Orange", 10.0, 1)
				.build();

		System.out.println("\nu1 : "+u1 +"\nOffer1 = "+offer1);
		System.out.println("=> "+u1.getUtility(offer1));	
		System.out.println("\nu1 : "+u1 +"\nOffer2 = "+offer2);
		System.out.println("=> "+u1.getUtility(offer2));
		System.out.println("\nu1 : "+u1 +"\nOffer3 = "+offer3);
		System.out.println("=> "+u1.getUtility(offer3));
		
		System.out.println("\nu2 : "+u2 +"\nOffer1 = "+offer1);
		System.out.println("=> "+u2.getUtility(offer1));
		System.out.println("\nu2 : "+u2 +"\nOffer2 = "+offer2);
		System.out.println("=> "+u2.getUtility(offer2));
		System.out.println("\nu2 : "+u2 +"\nOffer3 = "+offer3);
		System.out.println("=> "+u2.getUtility(offer3));
		
		System.out.println("\nu3 : "+u3 +"\nOffer1 = "+offer1);
		System.out.println("=> "+u3.getUtility(offer1));
		System.out.println("\nu3 : "+u3 +"\nOffer2 = "+offer2);
		System.out.println("=> "+u3.getUtility(offer2));
		System.out.println("\nu3 : "+u3 +"\nOffer3 = "+offer3);
		System.out.println("=> "+u3.getUtility(offer3));	
	}	
}
