// Title:       Add Agent
// Author:      Deepak Rautala
// Modified by: Adam Cheyer
// Description: A simple example agent that returns the sum of
//              two numbers.  The solvable is:  add(Num1,Num2,Sum)

import com.sri.oaa2.com.*;
import com.sri.oaa2.lib.*;
import com.sri.oaa2.icl.*;

public class AddAgent
{

	public static void main(String[] args)
	{
		/* Create instance of OAA library using TCP as protocol */
		LibOaa myOaa = new LibOaa(new LibCom(new LibComTcpProtocol(),args));

			System.out.println("Adder Agent starting");

			/* Connect to the facilitator using the host/port defined in file "setup.pl" */
			if (!myOaa.getComLib().comConnect("parent",IclUtils.icl("tcp(A,B)"),(IclList)IclUtils.icl("[]")))
			{
       	 			System.out.println("Couldnt connect to facilitator");
      	 			return;
    	 		}

    	 		/* Register the agent's info along the connection:  
    	 		      This agent's name will be "adder" and the list of capabilities the agent exposes to
    	 		      the agent community (that other agents can call) is "[add(Num1,Num2,Sum)]"
    	 		*/    	 		
			if (!myOaa.oaaRegister("parent", "adder", IclUtils.icl("[add(Num1,Num2,Sum)]"), (IclList)IclUtils.icl("[]")))
			{
				System.out.println("Could not register");
				return;
			}

			/* Attach a callback listener to catch events sent to me from the Facilitator */
    			myOaa.oaaRegisterCallback("oaa_AppDoEvent",new OAAEventListener() {
					  public boolean doOAAEvent(IclTerm goal, IclList param, IclList answers)
					  {

							/* If the event coming in is "add", grab args and return response */
							if (goal.iclStr().toString().equals("add"))
							{

								  int Num1 = goal.iclNthTerm(1).iclInt();
								  int Num2 = goal.iclNthTerm(2).iclInt();
								  int Sum  = Num1+Num2;

								  /* The answers returned must "match" the goal, but with
								     variables filled in.  So since requests will arrive
								     as  "add(1,2,X)", we should return "add(1,2,3)".
								     OAA is currently not set up to handle functions, 
								        ie. "add(1,2)"  returns "3", because some languages
								        (e.g. Prolog) do not work well in this mode.
								     Note: OAA can handle if there are multiple answers
								        to a question, which is why answers is a list.
								     Example:  "sqrt(4, X)" should return two answers,
								        "sqrt(4, 2)" and "sqrt(4, -2)"
								  */
								  answers.iclAddToList(
								     new IclStruct("add",new IclInt(Num1), new IclInt(Num2),
								                         new IclInt(Sum)));

								  return true;
							}

							return false;

					   }
				});

			/* Let the Facilitator know I'm finished with any initialization and ready to participate
			   as a member of the agent community.  Send me work!
			*/
    			myOaa.oaaReady(true);
    }

}

