package com.pm.server.registry;

import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import javax.annotation.PostConstruct;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.pm.server.datatype.Coordinate;
import com.pm.server.datatype.GameState;
import com.pm.server.datatype.Player;
import com.pm.server.repository.PlayerRepository;

@Repository
public class PlayerRegistryImpl implements PlayerRegistry {

	@Autowired
	private PlayerRepository playerRepository;

	@Autowired
	private PacdotRegistry pacdotRegistry;

	@Autowired
	private GameStateRegistry gameStateRegistry;

	private static Integer activePowerups = 0;

	/**
	 * Units: Milliseconds
	 */
	private static final Integer POWERUP_TIME = 30 * 1000;

	private final static Logger log =
			LogManager.getLogger(PlayerRegistryImpl.class.getName());

	@PostConstruct
	public void init() throws Exception {
		resetHard();
	}

	@Override
	public Player getPlayerByName(Player.Name name) {
		return playerRepository.getPlayerByName(name);
	}

	@Override
	public List<Player> getAllPlayers() {
		return playerRepository.getAllPlayers();
	}

	@Override
	public boolean allPlayersReady() {
		List<Player> playerList = playerRepository.getAllPlayers();
		for(Player player : playerList) {
			if(player.getState() != Player.State.READY) {
				return false;
			}
		}
		return true;
	}

	@Override
	public void setPlayerLocationByName(Player.Name name, Coordinate location) {
		playerRepository.setPlayerLocationByName(name, location);

		if(name == Player.Name.Pacman &&
		   gameStateRegistry.getCurrentState() == GameState.IN_PROGRESS) {

			Boolean powerDotEaten =
					pacdotRegistry.eatPacdotsNearLocation(location);
			if(powerDotEaten) {
				activatePowerup();
			}

			if(pacdotRegistry.allPacdotsEaten()) {
				gameStateRegistry.setWinnerPacman();
			}

		}

	}

	@Override
	public void setPlayerStateByName(Player.Name name, Player.State state) {
		playerRepository.setPlayerStateByName(name, state);
	}

	@Override
	public void changePlayerStates(Player.State fromState, Player.State toState)
			throws NullPointerException {
		playerRepository.changePlayerStates(fromState, toState);
	}

	@Override
	public Boolean allGhostsCaptured() {

		Boolean atLeastOneCaptured = false;

		for(Player p : playerRepository.getAllPlayers()) {
			if(!p.getName().equals(Player.Name.Pacman)) {
				if(p.getState().equals(Player.State.ACTIVE)) {
					return false;
				}
				else if(p.getState().equals(Player.State.CAPTURED)) {
					atLeastOneCaptured = true;
				}
			}
		}

		return atLeastOneCaptured;
	}

	@Override
	public void reset() {

		List<Player> playerList = playerRepository.getAllPlayers();
		for(Player player : playerList) {
			player.setState(Player.State.UNINITIALIZED);
			player.resetLocation();
		}

	}

	@Override
	public void resetHard() throws NullPointerException, IllegalArgumentException {

		playerRepository.clearPlayers();

		log.debug("Attempting to recreate players");
		Player player;
		for(Player.Name playerName : Player.Name.values()) {
			player = new Player(playerName);
			playerRepository.addPlayer(player);
		}
		log.debug("Recreation of players completed");

	}

	private void activatePowerup() {

		setPlayerStateByName(Player.Name.Pacman, Player.State.POWERUP);
		activePowerups++;

		new Timer().schedule(new TimerTask() {
			@Override
			public void run()
			{

				activePowerups--;
				if(	activePowerups == 0 &&
						(gameStateRegistry.getCurrentState() == GameState.IN_PROGRESS ||
						gameStateRegistry.getCurrentState() == GameState.PAUSED)
						) {
					setPlayerStateByName(Player.Name.Pacman, Player.State.ACTIVE);
				}

			}
		}, POWERUP_TIME);

	}

}

@@ -37,117 +37,172 @@
 ort 
-java.util.List;%0Aimport java.util.Timer;%0Aimport java.util.TimerTask;%0A%0Aimport javax.annotation.PostConstruct
+com.pm.server.datatype.Coordinate;%0Aimport com.pm.server.datatype.GameState;%0Aimport com.pm.server.datatype.Player;%0Aimport com.pm.server.repository.PlayerRepository
 ;%0A
-%0A
 impo
@@ -406,170 +406,113 @@
 ort 
-com.pm.server.datatype.Coordinate;%0Aimport com.pm.server.datatype.GameState;%0Aimport com.pm.server.datatype.Player;%0Aimport com.pm.server.repository.PlayerRepository
+javax.annotation.PostConstruct;%0Aimport java.util.List;%0Aimport java.util.Timer;%0Aimport java.util.TimerTask
 ;%0A%0A@
@@ -583,28 +583,16 @@
 stry %7B%0A%0A
-%09@Autowired%0A
 %09private
@@ -624,36 +624,24 @@
 epository;%0A%0A
-%09@Autowired%0A
 %09private Pac
@@ -673,20 +673,8 @@
 y;%0A%0A
-%09@Autowired%0A
 %09pri
@@ -887,16 +887,16 @@
 r log =%0A
-
 %09%09%09LogMa
@@ -949,16 +949,304 @@
 me());%0A%0A
+%09@Autowired%0A%09public PlayerRegistryImpl(%0A%09%09%09PlayerRepository playerRepository,%0A%09%09%09PacdotRegistry pacdotRegistry,%0A%09%09%09GameStateRegistry gameStateRegistry) %7B%0A%09%09this.playerRepository = playerRepository;%0A%09%09this.pacdotRegistry = pacdotRegistry;%0A%09%09this.gameStateRegistry = gameStateRegistry;%0A%09%7D%0A%0A
 %09@PostCo

Use constructor autowiring in PlayerRegistryImpl