package org.academiadecodigo.bootcamp11.rockpaperscissors;

/**
 * MIT License
 * (c) 2017 Ricardo Constantino
 */
public class Game {
    private int round;
    private int realRounds;
    private int maxRounds;
    private Player playerOne;
    private Player playerTwo;
    private Flavor flavor;

    public Game(int maxRounds, Player one, Player two, Flavor flavor) {
        this.maxRounds = maxRounds;
        this.playerOne = one;
        this.playerTwo = two;
        this.flavor = flavor;
        addHandCounters();
    }

    public void start() {
        this.round = 0;

        while (round < maxRounds && whoWon() == null) {
            this.round++;
            playRound();
            this.realRounds++;
        }

        Player whoWon = whoWon();
        System.out.println("======================================");
        System.out.println("The gods favoured " + whoWon.getName() +
                " with " + whoWon.getWins() + " wins after " +
                this.realRounds + " rounds!");
    }

    private void countDown() {
        String playerOne = this.playerOne.getName();
        String playerTwo = this.playerTwo.getName();
        System.out.println(playerOne + "+" + playerTwo + ": ジャン！ケン！ポン！！");
    }

    private void playRound() {
        System.out.println("\n===============");
        System.out.printf( "Round %d start!\n", this.round);
        System.out.println("===============\n");

        countDown();

        Hand handOne = this.playerOne.chooseHand(this.flavor);
        Hand handTwo = this.playerTwo.chooseHand(this.flavor);

        System.out.println(this.playerOne.getName() + ": " + handOne.getName());
        System.out.println(this.playerTwo.getName() + ": " + handTwo.getName());

        if (handOne == handTwo) {
            this.round--;
            System.out.println("It's a tie. No one gets the win.");
            return;
        } else {
            if (!handOne.losesTo(handTwo)) {
                playerOne.addWin();
            } else {
                playerTwo.addWin();
            }
        }
    }

    private Player whoWon() {
        if (playerOne.getWins() >= 2) {
            return playerOne;
        } else if (playerTwo.getWins() >= 2) {
            return playerTwo;
        } else {
            return null;
        }
    }

    private void addHandCounters() {
        Hand[] rockCounters = { Hand.PAPER, Hand.SPOCK };
        Hand[] scissorCounters = { Hand.ROCK, Hand.SPOCK };
        Hand[] paperCounters = { Hand.SCISSORS, Hand.LIZARD };
        Hand.ROCK.addLosesTo(rockCounters);
        Hand.SCISSORS.addLosesTo(scissorCounters);
        Hand.PAPER.addLosesTo(paperCounters);

        if (this.flavor == Flavor.RPSLS) {
            Hand[] lizardCounters = { Hand.SCISSORS, Hand.ROCK };
            Hand[] spockCounters = { Hand.PAPER, Hand.LIZARD };
            Hand.LIZARD.addLosesTo(lizardCounters);
            Hand.SPOCK.addLosesTo(spockCounters);
        }
    }
}
