package floor;

import java.util.HashSet;
import java.util.Set;

import common.Direction;
import communication.messages.FloorArrivalMessage;
import floor.input.InputEvent;

/**
 * Class to represent a floor
 */
public class Floor {

	private Light up;
	private Light down;
	private final int floorNumber;
	private final Set<Integer> requestedFloorsUp;
	private final Set<Integer> requestedFloorsDown;

	/**
	 * Create new floor
	 *
	 * @param floorNumber
	 */
	public Floor(int floorNumber) {
		this.floorNumber = floorNumber;
		requestedFloorsUp = new HashSet<>();
		requestedFloorsDown = new HashSet<>();
		up = Light.OFF;
		down = Light.OFF;
	}

	/**
	 * Turns the direction lamp off
	 * @param inputEvent
	 */
	public void handleFloorMessage(FloorArrivalMessage message) {
		toggleFloorDirectionLamp(message.getDirectionButton(), false);
	}

	/**
	 * Turns the direction lamp on and
	 * adds to requested floors
	 * @param inputEvent
	 */
	public void handleInputEvent(InputEvent inputEvent) {
		toggleFloorDirectionLamp(inputEvent.getDirectionButton(), true);
		addToRequestedFloors(inputEvent.getCarButton());
	}

	private void addToRequestedFloors(int carButton) {
		if (carButton < this.floorNumber) {
			requestedFloorsDown.add(carButton);
		} else if (carButton > this.floorNumber) {
			requestedFloorsUp.add(carButton);
		}
	}

	private synchronized void toggleFloorDirectionLamp(Direction button, boolean isInputEvent) {
		switch (button) {
			case UP:
				up = isInputEvent ? Light.ON : Light.OFF;
				break;
			case DOWN:
				down = isInputEvent ? Light.ON : Light.OFF;
				break;
		}
	}

	public Light getUp() {
		return up;
	}

	public void setUp(Light up) {
		this.up = up;
	}

	public Light getDown() {
		return down;
	}

	public void setDown(Light down) {
		this.down = down;
	}

	private enum Light {
		ON, OFF
	}

	@Override
	public String toString() {
		return "Floor: " + floorNumber + ", with lights: "
			+ "UP - "+ up + ", DOWN - " + down;
	}

	public Set<Integer> getRequestedFloorsDown() {
		return requestedFloorsDown;
	}

	public Set<Integer> getRequestedFloorsUp() {
		return requestedFloorsUp;
	}
}
