package kareltherobot;
import java.awt.Color;
import java.util.Hashtable;

public class StrategyTestMain implements Directions
{	public static void main(String [] args)
	{	// rename the factory that creates decorators so we have a simpler name
		Strategy.Factory factory = Strategy.Factory.asObject(); 
		
		// create a robot to test this with
		ur_Robot karel = new Robot(1, 1, East, 9, Color.red);
		
		// create a move() statement for later execution
		Strategy.Action body = factory.get("move",Strategy.NULL, null, null);
		
		// add two more move() statements to our program fragment
		body = factory.get("move",body,null,null);
		body = factory.get("move",body,null,null);
		
		// add a putBeeper() statement. 
		body = factory.get("putBeeper",body, null, null);

		//Create a predicate that a while strategy can use to loop 4 times 
		// executing the above fragment. 
		// Note that the factory can't create this for us, so we need to do it by hand. 
		Strategy.Predicate next = new CountToNPredicate(body,4);

		// Create a while strategy to use the above predicate
		Strategy.Action whileLoop = factory.get("while",Strategy.NULL, next, null);
		
		// let karel execute this while loop
		whileLoop.doIt(karel, new Hashtable());
		
		// if karel's class implemented DelayedExecutor we could say instead:
		// karel.execute(aStatement, new Hashtable());
		
		// move so that we can see the result. 
		karel.move();

		System.out.println(aStatement.toString());
	}

	static
	{	World.setDelay(1);
		World.setVisible(true);
	}
	

}

// You can write additional actions and predicates beyond what the factory has.
class AssignAction implements Strategy.Action // Like an assignment statement
{	public void doIt(ur_Robot karel, Hashtable data)
	{	data.put(variable, value);
	}
	
	public AssignAction(String variable, Object value)
	{	this.variable = variable;
		this.value = value;
	}
	
	private String variable;
	private Object value;
}

class CountToNPredicate implements Strategy.Predicate // Like a for loop
	{	public void doIt(ur_Robot karel, Hashtable data)
		{	previous.doIt(karel, data);
			i++;
		}
		
		public boolean query(Robot karel, Hashtable data)
		{	return i < n;
		}
		
		public CountToNPredicate(Strategy.Action strategy, int n)
		{	this.previous = strategy;
			this.n = n;
		}
		
		private Strategy.Action previous;
		private int i = 0;
		private int n;
			
		public String toString()
		{	return previous.toString() + "	i++;\n";
		}
		
		public String predicateString()
		{	return "i < n";
		}
	}

