package domain;

import java.util.ArrayList;
import java.util.Arrays;

public class Box {

    private int categoryOne;
    private int categoryTwo;
    private int categoryThree;
    private int categoryFour;
    private int categoryFive;
    private int categorySix;
    private int categorySeven;
    private int categoryEight;

    private Integer setCategoryOne;
    private Integer setCategoryTwo;
    private Integer setCategoryThree;
    private Integer setCategoryFour;
    private Integer setCategoryFive;
    private Integer setCategorySix;
    private Integer setCategorySeven;
    private Integer setCategoryEight;

    private Integer upperBoxScore;

    private int categoryTripleMatch;
    private int categoryFourOfAKind;
    private int categoryFullHouse;
    private int categorySmallStreet;
    private int categoryBigStreet;
    private int categoryYahtzee;
    private int categoryChance;
    private int categoryStarWarsDay;
    private int categoryR2D2;

    private Integer setCategoryTripleMatch;
    private Integer setCategoryFourOfAKind;
    private Integer setCategoryFullHouse;
    private Integer setCategorySmallStreet;
    private Integer setCategoryBigStreet;
    private Integer setCategoryYahtzee;
    private Integer setCategoryChance;
    private Integer setCategoryStarWarsDay;
    private Integer setCategoryR2D2;

    private Integer lowerBoxScore;

    private Integer totalScore;

    private Integer bonus;
    private int counter[] = new int[8];
    private String savedGamemode;

    public Box(String gamemode) {

        this.savedGamemode = gamemode;
    }

    private void evaluateUpperBoxOptions(ArrayList<Integer> diceNumbers) {

        if (diceNumbers.contains(1))
            for (int i = 0; i < diceNumbers.size(); i++) {
                if (diceNumbers.get(i) == 1)
                    this.categoryOne += diceNumbers.get(i);
            }
        if (diceNumbers.contains(2))
            for (int i = 0; i < diceNumbers.size(); i++) {
                if (diceNumbers.get(i) == 2)
                    this.categoryTwo += diceNumbers.get(i);
            }
        if (diceNumbers.contains(3))
            for (int i = 0; i < diceNumbers.size(); i++) {
                if (diceNumbers.get(i) == 3)
                    this.categoryThree += diceNumbers.get(i);
            }
        if (diceNumbers.contains(4))
            for (int i = 0; i < diceNumbers.size(); i++) {
                if (diceNumbers.get(i) == 4)
                    this.categoryFour += diceNumbers.get(i);
            }
        if (diceNumbers.contains(5))
            for (int i = 0; i < diceNumbers.size(); i++) {
                if (diceNumbers.get(i) == 5)
                    this.categoryFive += diceNumbers.get(i);
            }
        if (diceNumbers.contains(6))
            for (int i = 0; i < diceNumbers.size(); i++) {
                if (diceNumbers.get(i) == 6)
                    this.categorySix += diceNumbers.get(i);
            }
        if (diceNumbers.contains(7))
            for (int i = 0; i < diceNumbers.size(); i++) {
                if (diceNumbers.get(i) == 7)
                    this.categorySeven += diceNumbers.get(i);
            }
        if (diceNumbers.contains(8))
            for (int i = 0; i < diceNumbers.size(); i++) {
                if (diceNumbers.get(i) == 8)
                    this.categoryEight += diceNumbers.get(i);
            }
    }

    private void evaluateLowerBoxOptions(ArrayList<Integer> diceNumbers) {
        int sumOfAllNumbers = 0;

        for (int i = 0; i < diceNumbers.size(); i++) {
            if (diceNumbers.get(i) == 1)
                counter[0]++;
            else if (diceNumbers.get(i) == 2)
                counter[1]++;
            else if (diceNumbers.get(i) == 3)
                counter[2]++;
            else if (diceNumbers.get(i) == 4)
                counter[3]++;
            else if (diceNumbers.get(i) == 5)
                counter[4]++;
            else if (diceNumbers.get(i) == 6)
                counter[5]++;
            else if (diceNumbers.get(i) == 7)
                counter[6]++;
            else if (diceNumbers.get(i) == 8)
                counter[7]++;
        }

        for (int i = 0; i < diceNumbers.size(); i++) {
            sumOfAllNumbers += diceNumbers.get(i);
        }

        categoryStarWarsDay = (counter[3] * 4) + (counter[4] * 5);
        categoryChance = sumOfAllNumbers;

        for (int i = 0; i < counter.length; i++) {
            if (counter[i] >= 3)
                categoryTripleMatch = sumOfAllNumbers;
            if (counter[i] >= 4)
                categoryFourOfAKind = sumOfAllNumbers;
            if (counter[i] == 5) {
                categoryYahtzee = 50;
            }
            for (int s = 0; s < counter.length; s++) {
                if (counter[i] == 3 && counter[s] == 2)
                    categoryFullHouse = 25;
            }

        }

        for (int i = 0; i < 5; i++) {

            if (counter[i] >= 1 && counter[i + 1] >= 1 && counter[i + 2] >= 1 && counter[i + 3] >= 1)
                categorySmallStreet = 30;

        }

        for (int i = 0; i < 4; i++) {

            if (counter[i] == 1 && counter[i + 1] == 1 && counter[i + 2] == 1 && counter[i + 3] == 1
                    && counter[i + 3] == 1)
                categoryBigStreet = 40;

        }

        if (counter[0] == 1 && counter[1] == 2 && counter[3] == 1 && counter[7] == 1)
            categoryR2D2 = 42;

    }

    public void evaluateBoxOptions(ArrayList<Integer> diceNumbers) {

        evaluateUpperBoxOptions(diceNumbers);
        evaluateLowerBoxOptions(diceNumbers);

    }

    public ArrayList<String> getAllOptions() {
        ArrayList<String> res = new ArrayList<>();

        if (categoryOne > 0 && (setCategoryOne == null))
            res.add("One: " + categoryOne);
        if (categoryTwo > 0 && (setCategoryTwo == null))
            res.add("Two: " + categoryTwo);
        if (categoryThree > 0 && (setCategoryThree == null))
            res.add("Three: " + categoryThree);
        if (categoryFour > 0 && (setCategoryFour == null))
            res.add("Four: " + categoryFour);
        if (categoryFive > 0 && (setCategoryFive == null))
            res.add("Five: " + categoryFive);
        if (categorySix > 0 && (setCategorySix == null))
            res.add("Six: " + categorySix);
        if (categorySeven > 0 && (setCategorySeven == null))
            res.add("Seven: " + categorySeven);
        if (categoryEight > 0 && (setCategoryEight == null))
            res.add("Eight: " + categoryEight);
        if (categoryTripleMatch > 0 && (setCategoryTripleMatch == null))
            res.add("TripleMatch: " + categoryTripleMatch);
        if (categoryFourOfAKind > 0 && (setCategoryFourOfAKind == null))
            res.add("FourOfAKind: " + categoryFourOfAKind);
        if (categoryFullHouse > 0 && (setCategoryFullHouse == null))
            res.add("FullHouse: " + categoryFullHouse);
        if (categorySmallStreet > 0 && (setCategorySmallStreet == null))
            res.add("SmallStreet: " + categorySmallStreet);
        if (categoryBigStreet > 0 && (setCategoryBigStreet == null))
            res.add("BigStreet: " + categoryBigStreet);
        if (categoryYahtzee > 0)
            res.add("Yahtzee: " + categoryYahtzee);
        if (categoryChance > 0 && (setCategoryChance == null))
            res.add("Chance: " + categoryChance);
        if (categoryStarWarsDay > 0 && (setCategoryStarWarsDay == null))
            res.add("StarWarsDay: " + categoryStarWarsDay);
        if (categoryR2D2 > 0 && (setCategoryR2D2 == null))
            res.add("R2D2: " + categoryR2D2);

        if (res.isEmpty()) {
            if (setCategoryOne == null)
                res.add("One: " + categoryOne);
            if (setCategoryTwo == null)
                res.add("Two: " + categoryTwo);
            if (setCategoryThree == null)
                res.add("Three: " + categoryThree);
            if (setCategoryFour == null)
                res.add("Four: " + categoryFour);
            if (setCategoryFive == null)
                res.add("Five: " + categoryFive);
            if (setCategorySix == null)
                res.add("Six: " + categorySix);
            if (setCategorySeven == null && savedGamemode.equalsIgnoreCase("Special8"))
                res.add("Seven: " + categorySeven);
            if (setCategoryEight == null && savedGamemode.equalsIgnoreCase("Special8"))
                res.add("Eight: " + categoryEight);
            if (setCategoryTripleMatch == null)
                res.add("TripleMatch: " + categoryTripleMatch);
            if (setCategoryFourOfAKind == null)
                res.add("FourOfAKind: " + categoryFourOfAKind);
            if (setCategoryFullHouse == null)
                res.add("FullHouse: " + categoryFullHouse);
            if (setCategorySmallStreet == null)
                res.add("SmallStreet: " + categorySmallStreet);
            if (setCategoryBigStreet == null)
                res.add("BigStreet: " + categoryBigStreet);
            if (setCategoryYahtzee == null)
                res.add("Yahtzee: " + categoryYahtzee);
            if (setCategoryChance == null)
                res.add("Chance: " + categoryChance);
            if (setCategoryStarWarsDay == null)
                res.add("StarWarsDay: " + categoryStarWarsDay);
            if (setCategoryR2D2 == null && savedGamemode.equalsIgnoreCase("Special8"))
                res.add("R2D2: " + categoryR2D2);
        }

        return res;

    }

    public boolean onlyOneOption() {

        return getAllOptions().size() == 1;

    }

    public void selectOption(String option) {

        if (option.equalsIgnoreCase("One"))
            setCategoryOne = categoryOne;
        else if (option.equalsIgnoreCase("Two"))
            setCategoryTwo = categoryTwo;
        else if (option.equalsIgnoreCase("Three"))
            setCategoryThree = categoryThree;
        else if (option.equalsIgnoreCase("Four"))
            setCategoryFour = categoryFour;
        else if (option.equalsIgnoreCase("Five"))
            setCategoryFive = categoryFive;
        else if (option.equalsIgnoreCase("Six"))
            setCategorySix = categorySix;
        else if (option.equalsIgnoreCase("Seven"))
            setCategorySeven = categorySeven;
        else if (option.equalsIgnoreCase("Eight"))
            setCategoryEight = categoryEight;
        else if (option.equalsIgnoreCase("TripleMatch"))
            setCategoryTripleMatch = categoryTripleMatch;
        else if (option.equalsIgnoreCase("FourOfAKind"))
            setCategoryFourOfAKind = categoryFourOfAKind;
        else if (option.equalsIgnoreCase("FullHouse"))
            setCategoryFullHouse = categoryFullHouse;
        else if (option.equalsIgnoreCase("SmallStreet"))
            setCategorySmallStreet = categorySmallStreet;
        else if (option.equalsIgnoreCase("BigStreet"))
            setCategoryBigStreet = categoryBigStreet;
        else if (option.equalsIgnoreCase("Yahtzee")) {
            if (setCategoryYahtzee != null) {
                setCategoryYahtzee += 50;
                if (counter[0] == 5)
                    setCategoryOne = 5;
                else if (counter[1] == 5)
                    setCategoryTwo = 10;
                else if (counter[2] == 5)
                    setCategoryThree = 15;
                else if (counter[3] == 5)
                    setCategoryFour = 20;
                else if (counter[4] == 5)
                    setCategoryFive = 25;
                else if (counter[5] == 5)
                    setCategorySix = 30;
                else if (counter[6] == 5)
                    setCategorySeven = 35;
                else if (counter[7] == 5)
                    setCategoryEight = 40;
            } else
                setCategoryYahtzee = categoryYahtzee;

        } else if (option.equalsIgnoreCase("categoryChance"))
            setCategoryChance = categoryChance;
        else if (option.equalsIgnoreCase("Chance"))
            setCategoryChance = categoryChance;
        else if (option.equalsIgnoreCase("StarWarsDay"))
            setCategoryStarWarsDay = categoryStarWarsDay;
        else if (option.equalsIgnoreCase("R2D2"))
            setCategoryR2D2 = categoryR2D2;

    }

    public void resetOptions() {

        categoryOne = categoryTwo = categoryThree = categoryFour = categoryFive = categorySix = categorySeven = categoryEight = categoryTripleMatch = categoryFourOfAKind = categoryFullHouse = categorySmallStreet = categoryBigStreet = categoryYahtzee = categoryChance = categoryStarWarsDay = categoryR2D2 = 0;

        Arrays.fill(counter, 0);

    }

    public boolean gameOver() {

        if (this.savedGamemode.equalsIgnoreCase("Special8"))
            return setCategoryOne != null &&
                    setCategoryTwo != null &&
                    setCategoryThree != null &&
                    setCategoryFour != null &&
                    setCategoryFive != null &&
                    setCategorySix != null &&
                    setCategorySeven != null &&
                    setCategoryEight != null &&
                    setCategoryTripleMatch != null &&
                    setCategoryFourOfAKind != null &&
                    setCategoryFullHouse != null &&
                    setCategorySmallStreet != null &&
                    setCategoryBigStreet != null &&
                    setCategoryYahtzee != null &&
                    setCategoryChance != null &&
                    setCategoryStarWarsDay != null &&
                    setCategoryR2D2 != null;

        else
            return setCategoryOne != null &&
                    setCategoryTwo != null &&
                    setCategoryThree != null &&
                    setCategoryFour != null &&
                    setCategoryFive != null &&
                    setCategorySix != null &&
                    setCategoryTripleMatch != null &&
                    setCategoryFourOfAKind != null &&
                    setCategoryFullHouse != null &&
                    setCategorySmallStreet != null &&
                    setCategoryBigStreet != null &&
                    setCategoryYahtzee != null &&
                    setCategoryChance != null &&
                    setCategoryStarWarsDay != null;

    }

    public void updateBonus() {

        if (savedGamemode.equalsIgnoreCase("Special8")) {

            if (nullCheckInt(setCategoryOne) + nullCheckInt(setCategoryTwo) + nullCheckInt(setCategoryThree)
                    + nullCheckInt(setCategoryFour)
                    + nullCheckInt(setCategoryFive) + nullCheckInt(setCategorySix) + nullCheckInt(setCategorySeven)
                    + nullCheckInt(setCategoryEight) >= 108) {
                this.bonus = 35;
            }

        } else

        if (nullCheckInt(setCategoryOne) + nullCheckInt(setCategoryTwo) + nullCheckInt(setCategoryThree)
                + nullCheckInt(setCategoryFour)
                + nullCheckInt(setCategoryFive) + nullCheckInt(setCategorySix) >= 63) {
            this.bonus = 35;
        }

    }

    public int returnTotalPoints() {

        if (savedGamemode.equalsIgnoreCase("Special8"))
            return setCategoryOne + setCategoryTwo + setCategoryThree + setCategoryFour + setCategoryFive
                    + setCategorySix + setCategorySeven + setCategoryEight + nullCheckInt(bonus)
                    + setCategoryTripleMatch
                    + setCategoryFourOfAKind
                    + setCategoryFullHouse + setCategorySmallStreet + setCategoryBigStreet + setCategoryYahtzee
                    + setCategoryChance + setCategoryStarWarsDay
                    + setCategoryR2D2;
        else

            return setCategoryOne + setCategoryTwo + setCategoryThree + setCategoryFour + setCategoryFive
                    + setCategorySix + nullCheckInt(bonus) + setCategoryTripleMatch + setCategoryFourOfAKind
                    + setCategoryFullHouse + setCategorySmallStreet + setCategoryBigStreet + setCategoryYahtzee
                    + setCategoryChance + setCategoryStarWarsDay;

    }

    public String selectedOptionsPrinted() {

        StringBuilder sb = new StringBuilder();

        if (savedGamemode.equalsIgnoreCase("Special8")) {
            sb.append("\n--------------------------\n\n");
            sb.append("One: " + nullCheck(setCategoryOne) + "\n");
            sb.append("Two: " + nullCheck(setCategoryTwo) + "\n");
            sb.append("Three: " + nullCheck(setCategoryThree) + "\n");
            sb.append("Four: " + nullCheck(setCategoryFour) + "\n");
            sb.append("Five: " + nullCheck(setCategoryFive) + "\n");
            sb.append("Six: " + nullCheck(setCategorySix) + "\n");
            sb.append("Seven: " + nullCheck(setCategorySeven) + "\n");
            sb.append("Eight: " + nullCheck(setCategoryEight) + "\n");
            sb.append("\nbonus: " + nullCheck(bonus) + "\n");
            sb.append("\ntotal upper box: " + nullCheck(upperBoxScore) + "\n");
            sb.append("\n--------------------------\n\n");
            sb.append("TripleMatch: " + nullCheck(setCategoryTripleMatch) + "\n");
            sb.append("FourOfAKind: " + nullCheck(setCategoryFourOfAKind) + "\n");
            sb.append("FullHouse: " + nullCheck(setCategoryFullHouse) + "\n");
            sb.append("SmallStreet: " + nullCheck(setCategorySmallStreet) + "\n");
            sb.append("BigStreet: " + nullCheck(setCategoryBigStreet) + "\n");
            sb.append("Yahtzee: " + nullCheck(setCategoryYahtzee) + "\n");
            sb.append("Chance: " + nullCheck(setCategoryChance) + "\n");
            sb.append("StarWarsDay: " + nullCheck(setCategoryStarWarsDay) + "\n");
            sb.append("R2D2: " + nullCheck(setCategoryR2D2) + "\n");
            sb.append("\ntotal lower box: " + nullCheck(lowerBoxScore) + "\n");
            sb.append("\n--------------------------\n\n");
            sb.append("\ntotal score: " + nullCheck(totalScore) + "\n");
        } else {
            sb.append("\n--------------------------\n\n");
            sb.append("One: " + nullCheck(setCategoryOne) + "\n");
            sb.append("Two: " + nullCheck(setCategoryTwo) + "\n");
            sb.append("Three: " + nullCheck(setCategoryThree) + "\n");
            sb.append("Four: " + nullCheck(setCategoryFour) + "\n");
            sb.append("Five: " + nullCheck(setCategoryFive) + "\n");
            sb.append("Six: " + nullCheck(setCategorySix) + "\n");
            sb.append("\nbonus: " + nullCheck(bonus) + "\n");
            sb.append("\ntotal upper box: " + nullCheck(upperBoxScore) + "\n");
            sb.append("\n--------------------------\n\n");
            sb.append("TripleMatch: " + nullCheck(setCategoryTripleMatch) + "\n");
            sb.append("FourOfAKind: " + nullCheck(setCategoryFourOfAKind) + "\n");
            sb.append("FullHouse: " + nullCheck(setCategoryFullHouse) + "\n");
            sb.append("SmallStreet: " + nullCheck(setCategorySmallStreet) + "\n");
            sb.append("BigStreet: " + nullCheck(setCategoryBigStreet) + "\n");
            sb.append("Yahtzee: " + nullCheck(setCategoryYahtzee) + "\n");
            sb.append("Chance: " + nullCheck(setCategoryChance) + "\n");
            sb.append("StarWarsDay: " + nullCheck(setCategoryStarWarsDay) + "\n");
            sb.append("\ntotal lower box: " + nullCheck(lowerBoxScore) + "\n");
            sb.append("\n--------------------------\n\n");
            sb.append("\ntotal score: " + nullCheck(totalScore) + "\n");
        }
        return sb.toString();

    }

    public void updateUpperBoxScore() {

        if (savedGamemode.equalsIgnoreCase("Special8"))

            this.upperBoxScore = nullCheckInt(setCategoryOne) + nullCheckInt(setCategoryTwo)
                    + nullCheckInt(setCategoryThree) + nullCheckInt(setCategoryFour)
                    + nullCheckInt(setCategoryFive) + nullCheckInt(setCategorySix) + nullCheckInt(setCategorySeven)
                    + nullCheckInt(setCategoryEight) + nullCheckInt(bonus);

        else

            this.upperBoxScore = nullCheckInt(setCategoryOne) + nullCheckInt(setCategoryTwo)
                    + nullCheckInt(setCategoryThree) + nullCheckInt(setCategoryFour)
                    + nullCheckInt(setCategoryFive) + nullCheckInt(setCategorySix) + nullCheckInt(bonus);

    }

    public void updateLowerBoxScore() {

        if (savedGamemode.equalsIgnoreCase("Special8"))

            this.lowerBoxScore = nullCheckInt(setCategoryTripleMatch) + nullCheckInt(setCategoryFourOfAKind)
                    + nullCheckInt(setCategoryFullHouse) + nullCheckInt(setCategorySmallStreet)
                    + nullCheckInt(setCategoryBigStreet) + nullCheckInt(setCategoryYahtzee)
                    + nullCheckInt(setCategoryChance) + nullCheckInt(setCategoryStarWarsDay)
                    + nullCheckInt(setCategoryR2D2);

        else

            this.lowerBoxScore = nullCheckInt(setCategoryTripleMatch) + nullCheckInt(setCategoryFourOfAKind)
                    + nullCheckInt(setCategoryFullHouse) + nullCheckInt(setCategorySmallStreet)
                    + nullCheckInt(setCategoryBigStreet) + nullCheckInt(setCategoryYahtzee)
                    + nullCheckInt(setCategoryChance) + nullCheckInt(setCategoryStarWarsDay);

    }

    public void updateTotalScore() {

        this.totalScore = nullCheckInt(upperBoxScore) + nullCheckInt(lowerBoxScore);
    }

    public String nullCheck(Integer i) {

        if (i == null)
            return "___";
        else
            return "" + i;
    }

    public int nullCheckInt(Integer i) {

        if (i == null)
            return 0;
        else
            return i;
    }
}
