package waiter;

import jmadem.*;
import jason.asSyntax.*;
import jason.asSemantics.*;

/** 
 * Returns the waiter's preference to use a resource in the bar or to give a product to a
 * customer. This function implements the basic principle of minimum energy, widely 
 * applied by humans at work. The utility value is computed according to the number of
 * tasks performed by each waiter.
 * 
 * @author Francisco Grimaldo
 */
public class Tiredness implements UtilityFunctionInt 
{
	/**
	  * Returns the name of the utility function
	  *
	  * @return	"tiredness"
	  */
    public String getId()
	{
		return "tiredness";
	}
	
	/**
	  * Returns the waiter's preference to use a resource in the bar or to give a product to a
	  * customer. This function implements the basic principle of minimum energy, widely 
	  * applied by humans at work. The utility value is computed according to the number of
	  * tasks performed by each waiter.
	  *
	  * @param	auctioneer	agent asking for preference
	  * @param	alloc	allocation being evaluated
	  * @param	agArch	architecture of the MADeM agent
	  * 
	  * @throws	UtilityFunctionException when any error occurs
	  * @return	number of leadered workers that are free 
	  */
    public float computeUtility(String auctioneer, Allocation a, MADeMAgArch agArch) throws UtilityFunctionException
	{
		// Allocation of the form: execute_actions(Action, Ag, ActionNext, Auctioneer)
		// where Action and ActionNext can be either use(Resource) or give(Resource, RequestPoint)
		Literal alloc = (Literal)a.getTerm();
		Term [] termArray = alloc.getTermsArray();
		
		// No preference when task is allocated to another agent
		if ( !termArray[1].toString().equals(agArch.getAgName()) )
			return 0;
		
		Unifier un = new Unifier();
		Literal l, res;
		float utility = 0;
		float n_use = 0;
		float n_give = 0;
		float nb_orders = 0;
	
		l = Literal.parseLiteral("n_use(_)");
		res = agArch.getTS().getAg().findBel(l, un);
		if (res != null)
			n_use = Float.parseFloat(res.getTerm(0).toString());

		l = Literal.parseLiteral("n_give(_)");
		res = agArch.getTS().getAg().findBel(l, un);
		if (res != null)
			n_give = Float.parseFloat(res.getTerm(0).toString());

		l = Literal.parseLiteral("nb_orders(_)");
		res = agArch.getTS().getAg().findBel(l, un);
		if (res != null)
			nb_orders = Float.parseFloat(res.getTerm(0).toString());
		
		utility = 1 - (n_use + n_give) / (2 * nb_orders);

		return utility;
	}
}

