import java.util.*;

public class Commands {

	//variable that counts the method calls
	protected int commandCount = 0;
	
	//variable that counts the executed methods
	protected int executedCount = 0;
	
	//reference variable for the corresponding RobotAgent
	protected RobotAgent myAgent;
	
	//variables representing the state of the action-behaviour
	protected boolean finished;
	
	
	public Commands(RobotAgent agent) {
		this.myAgent = agent;
	}
	
	

	
	//most important method for furure Robot-agents which extend the class RobotAction
	//the programmer must override this method (with empty body) in his RobotAction subclass
	//to start the Robot-execution
	public void execute() { }
	
	
	//methods to perform intended action properly
	
	
	//touch sensor
	protected boolean touch() {
		commandCount++;
		int count = commandCount;
				
		while ( (executedCount+1 != count) || (myAgent.getActionState() == true)) { 
			  try {
				Thread.sleep(200);
			} catch(InterruptedException e) { }
		}
		
		myAgent.touch();
		
		while ( myAgent.getDataStore() == false) { 
			try {
				Thread.sleep(200);
			} catch(InterruptedException e) { }
		}
		
		myAgent.setDataStore(false);		
		
		if ( myAgent.getSensorData().equals("true") ) {
			executedCount++;
			return true;
		} else {
			executedCount++;
			return false;
		}
	}
	
	
	//humidity sensor
	protected boolean humidity() {
		commandCount++;
		int count = commandCount;
				
		while ( (executedCount+1 != count) || (myAgent.getActionState() == true)) { 
			  try {
				Thread.sleep(200);
			} catch(InterruptedException e) { }
		}
		
		myAgent.humidity();
		
		while ( myAgent.getDataStore() == false) { 
			try {
				Thread.sleep(200);
			} catch(InterruptedException e) { }
		}
		
		myAgent.setDataStore(false);		
		
		if ( myAgent.getSensorData().equals("true") ) {
			executedCount++;
			return true;
		} else {
			executedCount++;
			return false;
		}
	}
	
	
	//metall sensor
	protected boolean metall() {
		commandCount++;
		int count = commandCount;
				
		while ( (executedCount+1 != count) || (myAgent.getActionState() == true)) {
			try {
				Thread.sleep(200);
			} catch(InterruptedException e) { }
		}
		
		myAgent.metall();
		
		while ( myAgent.getDataStore() == false) {
			try {
				Thread.sleep(200);
			} catch(InterruptedException e) { }
		}
		
		myAgent.setDataStore(false);
		
		if ( myAgent.getSensorData().equals("true") ) {
			executedCount++;
			return true;
		} else {
			executedCount++;
			return false;
		}
	}
	
	
	//optic sensor
	protected String optic() {
		commandCount++;
		int count = commandCount;
				
		while ( (executedCount+1 != count) || (myAgent.getActionState() == true)) {
			try {
				Thread.sleep(200);
			} catch(InterruptedException e) { }
		}
		
		myAgent.optic();
		
		while ( myAgent.getDataStore() == false) {
			try {
				Thread.sleep(200);
			} catch(InterruptedException e) { }
		}
		
		myAgent.setDataStore(false);		
		executedCount++;		
		return myAgent.getSensorData();		
	}
	
	
	//infra-red sensor
	protected String infraRed() {
		commandCount++;
		int count = commandCount;
				
		while ( (executedCount+1 != count) || (myAgent.getActionState() == true)) {
			try {
				Thread.sleep(200);
			} catch(InterruptedException e) { }
		}
		
		myAgent.infraRed();
		
		while ( myAgent.getDataStore() == false) {
			try {
				Thread.sleep(200);
			} catch(InterruptedException e) { }
		}
		
		myAgent.setDataStore(false);		
		executedCount++;		
		return myAgent.getSensorData();		
	}
	
	
	
	//turn action
	protected void turn(int direction) {
		commandCount++;
		int count = commandCount;
		
		while ( (executedCount+1 != count) || (myAgent.getActionState() == true)) {
			try {
				Thread.sleep(200);
			} catch(InterruptedException e) { }
		}
		
		myAgent.turn(direction);
		executedCount++;
	}
	
	
	//right_turn action
	protected void turnRight() {
		commandCount++;
		int count = commandCount;
		
		while ( (executedCount+1 != count) || (myAgent.getActionState() == true)) {
			try {
				Thread.sleep(200);
			} catch(InterruptedException e) { }
		}
		
		int direction = myAgent.getDirection();
		if (direction == 8) {
			direction = 1;
		} else {
			direction++;
		}
		
		myAgent.turn(direction);
		executedCount++;
	}
	
	
	//left_turn action
	protected void turnLeft() {
		commandCount++;
		int count = commandCount;
		
		while ( (executedCount+1 != count) || (myAgent.getActionState() == true)) {
			try {
				Thread.sleep(200);
			} catch(InterruptedException e) { }
		}
		
		int direction = myAgent.getDirection();
		if (direction == 1) {
			direction = 8;
		} else {
			direction--;
		}
		
		myAgent.turn(direction);
		executedCount++;
	}


	//simple move action
	protected void move() {
		commandCount++;
		int count = commandCount;
		
		while ( (executedCount+1 != count) || (myAgent.getActionState() == true)) {
			try {
				Thread.sleep(200);
			} catch(InterruptedException e) { }
		}
				
		myAgent.move(1);
		executedCount++;
	}
	
	
	//gets the view direction of the robot
	protected int getDirection() {
		commandCount++;
		int count = commandCount;
		
		while ( (executedCount+1 != count) || (myAgent.getActionState() == true)) {
			try {
				Thread.sleep(200);
			} catch(InterruptedException e) { }
		}
				
		executedCount++;
		return myAgent.getDirection();
	}
	
	
	//sends a message to another RobotAgent
	protected void sendMessage(String receiver, String content) {
		commandCount++;
		int count = commandCount;
		
		while ( (executedCount+1 != count) || (myAgent.getActionState() == true)) {
			try {
				Thread.sleep(200);
			} catch(InterruptedException e) { }
		}
		
		myAgent.sendSimpleMessage(receiver, content);
		executedCount++;
	}
	
	
	//receives a message from another RobotAgent
	protected String receiveMessage() {
		commandCount++;
		int count = commandCount;
		
		while ( (executedCount+1 != count) || (myAgent.getActionState() == true)) {
			try {
				Thread.sleep(200);
			} catch(InterruptedException e) { }
		}
		
		String message = myAgent.receiveSimpleMessage();
		executedCount++;
		return message;
	}
	
	
	//sets the simulation-speed
	protected void setWaitCycle(int millis) {
		myAgent.setWaitCycle(millis);
	}
}