DasherJava / src / dasherJava / core / startStop / CircleStartStopHandler.java
CircleStartStopHandler.java
Raw
package dasherJava.core.startStop;

import java.util.ArrayList;
import java.util.List;

import dasherJava.DasherJava;
import dasherJava.core.alphabets.RGBAColor;
import dasherJava.core.world.SquareWorldView;
import dasherJava.core.world.WorldGraphics.WorldGraphicsDrawCommand;
import dasherJava.core.world.WorldGraphics.WorldGraphicsFillOvalCommand;

public class CircleStartStopHandler implements StartStopHandler<SquareWorldView> {
	
	private CircleState circleState = CircleState.STOPPED_INSIDE;
	private long waitStartTime;
	
	@Override
	public StartStopAction processInput(float inputX, float inputY, boolean started, SquareWorldView parameters) {
		//Scale input based on aspect ratio of the panel:
		int width = parameters.getWidth();
		int height = parameters.getHeight();
		float scaledInputX = width>height ? inputX*width/height : inputX;
		float scaledInputY = width<height ? inputY*height/width : inputY;
		float circleSizeFraction = DasherJava.getSettings().getCircleSize();
		boolean inCircle = scaledInputX*scaledInputX+scaledInputY*scaledInputY<=circleSizeFraction*circleSizeFraction;
		if (started && (circleState==CircleState.STOPPED_OUTSIDE || circleState==CircleState.STOPPED_INSIDE
				|| circleState==CircleState.WAITING_TO_START)) { //externally started
			circleState=inCircle ? CircleState.STARTED_INSIDE : CircleState.STARTED_OUTSIDE;
			return StartStopAction.NOTHING_BUT_NEED_REPAINT;
		}
		if (!started && (circleState==CircleState.STARTED_OUTSIDE || circleState==CircleState.STARTED_INSIDE
				|| circleState==CircleState.WAITING_TO_STOP)) { //externally stopped
			circleState=inCircle ? CircleState.STOPPED_INSIDE : CircleState.STOPPED_OUTSIDE;
			return StartStopAction.NOTHING_BUT_NEED_REPAINT;
		}
		switch (circleState) {
			case STOPPED_INSIDE:
				if (!inCircle) {
					circleState=CircleState.STOPPED_OUTSIDE;
					return StartStopAction.NOTHING_BUT_NEED_REPAINT;
				}
				break;
			case STOPPED_OUTSIDE:
				if (inCircle) {
					circleState=CircleState.WAITING_TO_START;
					waitStartTime=System.nanoTime();
					return StartStopAction.NOTHING_BUT_NEED_REPAINT;
				}
				break;
			case WAITING_TO_START:
				if (!inCircle) { //cancel start
					circleState=CircleState.STOPPED_OUTSIDE;
					return StartStopAction.NOTHING_BUT_NEED_REPAINT;
				}
				if (System.nanoTime()-waitStartTime>=DasherJava.getSettings().getCircleHoldStartTime()*1000000L) {
					circleState=CircleState.STARTED_INSIDE; //start
					return StartStopAction.START;
				}
				break;
			case STARTED_INSIDE:
				if (!inCircle) {
					circleState=CircleState.STARTED_OUTSIDE;
					return StartStopAction.NOTHING_BUT_NEED_REPAINT;
				}
				break;
			case STARTED_OUTSIDE:
				if (inCircle) {
					circleState=CircleState.WAITING_TO_STOP;
					waitStartTime=System.nanoTime();
					return StartStopAction.NOTHING_BUT_NEED_REPAINT;
				}
				break;
			case WAITING_TO_STOP:
				if (!inCircle) { //cancel stop
					circleState=CircleState.STARTED_OUTSIDE;
					return StartStopAction.NOTHING_BUT_NEED_REPAINT;
				}
				if (System.nanoTime()-waitStartTime>=DasherJava.getSettings().getCircleHoldStopTime()*1000000L) {
					circleState=CircleState.STOPPED_INSIDE; //stop
					return StartStopAction.STOP;
				}
				break;
		}
		return StartStopAction.NOTHING;
	}
	
	@Override
	public List<WorldGraphicsDrawCommand> getUIDrawCommands(SquareWorldView parameters) {
		int circleRadius = Math.round(DasherJava.getSettings().getCircleSize()
				*Math.min(parameters.getWidth(), parameters.getHeight())/2);
		RGBAColor fillColor = null;
		RGBAColor outlineColor = DasherJava.getGUIColors().getCircleOutlineColor();
		float outlineThickness = DasherJava.getSettings().getCircleOutlineThickness();
		switch (circleState) {
			case STOPPED_INSIDE:
			case STOPPED_OUTSIDE:
				fillColor=DasherJava.getGUIColors().getCircleStoppedColor();
				break;
			case WAITING_TO_START:
				fillColor=DasherJava.getGUIColors().getCircleWaitingColor();
				break;
			case STARTED_INSIDE:
			case STARTED_OUTSIDE:
				outlineColor=DasherJava.getGUIColors().getCircleStartedColor();
				break;
			case WAITING_TO_STOP:
				outlineColor=DasherJava.getGUIColors().getCircleStartedColor();
				outlineThickness=DasherJava.getSettings().getCircleOutlineThicknessHold();
				break;
		}
		List<WorldGraphicsDrawCommand> uiDrawCommands = new ArrayList<>(1);
		uiDrawCommands.add(new WorldGraphicsFillOvalCommand(
				parameters.getWidth()/2-circleRadius, parameters.getHeight()/2-circleRadius,
				2*circleRadius, 2*circleRadius, fillColor, outlineColor, outlineThickness));
		return uiDrawCommands;
	}
	
	private enum CircleState {
		STOPPED_INSIDE,
		STOPPED_OUTSIDE,
		WAITING_TO_START,
		STARTED_INSIDE,
		STARTED_OUTSIDE,
		WAITING_TO_STOP
	}
}