package de.duehl.vocabulary.japanese.common.color;

import org.junit.jupiter.api.Test;

import de.duehl.vocabulary.japanese.common.color.data.ColorModificationType;
import de.duehl.vocabulary.japanese.common.color.data.DefaultColors;
import de.duehl.vocabulary.japanese.common.data.InternalAdditionalVocableData;
import de.duehl.vocabulary.japanese.common.data.TranslationDirection;

import static org.junit.jupiter.api.Assertions.*;

import java.awt.Color;
import java.util.List;

public class VocabularyColorToolsTest {

    @Test
    public void determineColorIndex0From10() {
        int total = 10;
        int correct = 0;
        int actual = VocableColors.determineColorIndex(total, correct);
        int expected = 0;
        assertEquals(expected, actual);
    }

    @Test
    public void determineColorIndex1From10() {
        int total = 10;
        int correct = 1;
        int actual = VocableColors.determineColorIndex(total, correct);
        int expected = 1;
        assertEquals(expected, actual);
    }

    @Test
    public void determineColorIndex2From10() {
        int total = 10;
        int correct = 2;
        int actual = VocableColors.determineColorIndex(total, correct);
        int expected = 2;
        assertEquals(expected, actual);
    }

    @Test
    public void determineColorIndex3From10() {
        int total = 10;
        int correct = 3;
        int actual = VocableColors.determineColorIndex(total, correct);
        int expected = 3;
        assertEquals(expected, actual);
    }

    @Test
    public void determineColorIndex4From10() {
        int total = 10;
        int correct = 4;
        int actual = VocableColors.determineColorIndex(total, correct);
        int expected = 4;
        assertEquals(expected, actual);
    }

    @Test
    public void determineColorIndex5From10() {
        int total = 10;
        int correct = 5;
        int actual = VocableColors.determineColorIndex(total, correct);
        int expected = 5;
        assertEquals(expected, actual);
    }

    @Test
    public void determineColorIndex6From10() {
        int total = 10;
        int correct = 6;
        int actual = VocableColors.determineColorIndex(total, correct);
        int expected = 6;
        assertEquals(expected, actual);
    }

    @Test
    public void determineColorIndex7From10() {
        int total = 10;
        int correct = 7;
        int actual = VocableColors.determineColorIndex(total, correct);
        int expected = 7;
        assertEquals(expected, actual);
    }

    @Test
    public void determineColorIndex8From10() {
        int total = 10;
        int correct = 8;
        int actual = VocableColors.determineColorIndex(total, correct);
        int expected = 8;
        assertEquals(expected, actual);
    }

    @Test
    public void determineColorIndex9From10() {
        int total = 10;
        int correct = 9;
        int actual = VocableColors.determineColorIndex(total, correct);
        int expected = 9;
        assertEquals(expected, actual);
    }

    @Test
    public void determineColorIndex10From10() {
        int total = 10;
        int correct = 10;
        int actual = VocableColors.determineColorIndex(total, correct);
        int expected = 10;
        assertEquals(expected, actual);
    }

    @Test
    public void determineColorIndex2From5() {
        int total = 5;
        int correct = 2;
        int actual = VocableColors.determineColorIndex(total, correct);
        int expected = 4;
        assertEquals(expected, actual);
    }

    @Test
    public void determineColorIndex4From5() {
        int total = 5;
        int correct = 4;
        int actual = VocableColors.determineColorIndex(total, correct);
        int expected = 8;
        assertEquals(expected, actual);
    }

    private VocableColors createVocableColors() {
        List<Color> colors = DefaultColors.INTENSIVE_COLORS;
        int deltaForForegroundColor = -110;
        int deltaForBackgroundColor = 180;
        ColorModificationType colorModificationType = ColorModificationType.MULTIPLICATIVE;
        return new VocableColors(colors, deltaForForegroundColor, deltaForBackgroundColor,
                colorModificationType);
    }

    @Test
    public void determineForegroundColor0From10() {
        int total = 10;
        int correct = 0;
        VocableColors vocableColors = createVocableColors();
        Color actual = vocableColors.determineForegroundColor(total, correct);
        int actualIndex = VocableColors.determineColorIndex(total, correct);
        int expectedIndex = 0;
        assertEquals(expectedIndex, actualIndex);
        Color expected = vocableColors.createForegroundColor(actualIndex);
        assertEquals(expected, actual);
        Color expected2 = new Color(145, 0, 0);
        assertEquals(expected2, actual);
    }

    @Test
    public void determineForegroundColor1From10() {
        int total = 10;
        int correct = 1;
        VocableColors vocableColors = createVocableColors();
        Color actual = vocableColors.determineForegroundColor(total, correct);
        int actualIndex = VocableColors.determineColorIndex(total, correct);
        int expectedIndex = 1;
        assertEquals(expectedIndex, actualIndex);
        Color expected = vocableColors.createForegroundColor(actualIndex);
        assertEquals(expected, actual);
        Color expected2 = new Color(145, 29, 0);
        assertEquals(expected2, actual);
    }

    @Test
    public void determineForegroundColor2From10() {
        int total = 10;
        int correct = 2;
        VocableColors vocableColors = createVocableColors();
        Color actual = vocableColors.determineForegroundColor(total, correct);
        int actualIndex = VocableColors.determineColorIndex(total, correct);
        int expectedIndex = 2;
        assertEquals(expectedIndex, actualIndex);
        Color expected = vocableColors.createForegroundColor(actualIndex);
        assertEquals(expected, actual);
        Color expected2 = new Color(145, 58, 0);
        assertEquals(expected2, actual);
    }

    @Test
    public void determineForegroundColor3From10() {
        int total = 10;
        int correct = 3;
        VocableColors vocableColors = createVocableColors();
        Color actual = vocableColors.determineForegroundColor(total, correct);
        int actualIndex = VocableColors.determineColorIndex(total, correct);
        int expectedIndex = 3;
        assertEquals(expectedIndex, actualIndex);
        Color expected = vocableColors.createForegroundColor(actualIndex);
        assertEquals(expected, actual);
        Color expected2 = new Color(145, 87, 0);
        assertEquals(expected2, actual);
    }

    @Test
    public void determineForegroundColor4From10() {
        int total = 10;
        int correct = 4;
        VocableColors vocableColors = createVocableColors();
        Color actual = vocableColors.determineForegroundColor(total, correct);
        int actualIndex = VocableColors.determineColorIndex(total, correct);
        int expectedIndex = 4;
        assertEquals(expectedIndex, actualIndex);
        Color expected = vocableColors.createForegroundColor(actualIndex);
        assertEquals(expected, actual);
        Color expected2 = new Color(145, 116, 0);
        assertEquals(expected2, actual);
    }

    @Test
    public void determineForegroundColor5From10() {
        int total = 10;
        int correct = 5;
        VocableColors vocableColors = createVocableColors();
        Color actual = vocableColors.determineForegroundColor(total, correct);
        int actualIndex = VocableColors.determineColorIndex(total, correct);
        int expectedIndex = 5;
        assertEquals(expectedIndex, actualIndex);
        Color expected = vocableColors.createForegroundColor(actualIndex);
        assertEquals(expected, actual);
        Color expected2 = new Color(145, 145, 0);
        assertEquals(expected2, actual);
    }

    @Test
    public void determineForegroundColor6From10() {
        int total = 10;
        int correct = 6;
        VocableColors vocableColors = createVocableColors();
        Color actual = vocableColors.determineForegroundColor(total, correct);
        int actualIndex = VocableColors.determineColorIndex(total, correct);
        int expectedIndex = 6;
        assertEquals(expectedIndex, actualIndex);
        Color expected = vocableColors.createForegroundColor(actualIndex);
        assertEquals(expected, actual);
        Color expected2 = new Color(116, 145, 0);
        assertEquals(expected2, actual);
    }

    @Test
    public void determineForegroundColor7From10() {
        int total = 10;
        int correct = 7;
        VocableColors vocableColors = createVocableColors();
        Color actual = vocableColors.determineForegroundColor(total, correct);
        int actualIndex = VocableColors.determineColorIndex(total, correct);
        int expectedIndex = 7;
        assertEquals(expectedIndex, actualIndex);
        Color expected = vocableColors.createForegroundColor(actualIndex);
        assertEquals(expected, actual);
        Color expected2 = new Color(87, 145, 0);
        assertEquals(expected2, actual);
    }

    @Test
    public void determineForegroundColor8From10() {
        int total = 10;
        int correct = 8;
        VocableColors vocableColors = createVocableColors();
        Color actual = vocableColors.determineForegroundColor(total, correct);
        int actualIndex = VocableColors.determineColorIndex(total, correct);
        int expectedIndex = 8;
        assertEquals(expectedIndex, actualIndex);
        Color expected = vocableColors.createForegroundColor(actualIndex);
        assertEquals(expected, actual);
        Color expected2 = new Color(58, 145, 0);
        assertEquals(expected2, actual);
    }

    @Test
    public void determineForegroundColor9From10() {
        int total = 10;
        int correct = 9;
        VocableColors vocableColors = createVocableColors();
        Color actual = vocableColors.determineForegroundColor(total, correct);
        int actualIndex = VocableColors.determineColorIndex(total, correct);
        int expectedIndex = 9;
        assertEquals(expectedIndex, actualIndex);
        Color expected = vocableColors.createForegroundColor(actualIndex);
        assertEquals(expected, actual);
        Color expected2 = new Color(29, 145, 0);
        assertEquals(expected2, actual);
    }

    @Test
    public void determineForegroundColor10From10() {
        int total = 10;
        int correct = 10;
        VocableColors vocableColors = createVocableColors();
        Color actual = vocableColors.determineForegroundColor(total, correct);
        int actualIndex = VocableColors.determineColorIndex(total, correct);
        int expectedIndex = 10;
        assertEquals(expectedIndex, actualIndex);
        Color expected = vocableColors.createForegroundColor(actualIndex);
        assertEquals(expected, actual);
        Color expected2 = new Color(0, 145, 0);
        assertEquals(expected2, actual);
    }

    @Test
    public void determineForegroundColor2From5() {
        int total = 5;
        int correct = 2;
        VocableColors vocableColors = createVocableColors();
        Color actual = vocableColors.determineForegroundColor(total, correct);
        int actualIndex = VocableColors.determineColorIndex(total, correct);
        int expectedIndex = 4;
        assertEquals(expectedIndex, actualIndex);
        Color expected = vocableColors.createForegroundColor(actualIndex);
        assertEquals(expected, actual);
        Color expected2 = new Color(145, 116, 0);
        assertEquals(expected2, actual);
    }

    @Test
    public void determineForegroundColor4From5() {
        int total = 5;
        int correct = 4;
        VocableColors vocableColors = createVocableColors();
        Color actual = vocableColors.determineForegroundColor(total, correct);
        int actualIndex = VocableColors.determineColorIndex(total, correct);
        int expectedIndex = 8;
        assertEquals(expectedIndex, actualIndex);
        Color expected = vocableColors.createForegroundColor(actualIndex);
        assertEquals(expected, actual);
        Color expected2 = new Color(58, 145, 0);
        assertEquals(expected2, actual);
    }

    @Test
    public void determineBackgroundColor0From10() {
        int total = 10;
        int correct = 0;
        VocableColors vocableColors = createVocableColors();
        Color actual = vocableColors.determineBackgroundColor(total, correct);
        int actualIndex = VocableColors.determineColorIndex(total, correct);
        int expectedIndex = 0;
        assertEquals(expectedIndex, actualIndex);
        Color expected = vocableColors.createBackgroundColor(actualIndex);
        assertEquals(expected, actual);
        Color expected2 = new Color(255, 180, 180);
        assertEquals(expected2, actual);
    }

    @Test
    public void determineBackgroundColor1From10() {
        int total = 10;
        int correct = 1;
        VocableColors vocableColors = createVocableColors();
        Color actual = vocableColors.determineBackgroundColor(total, correct);
        int actualIndex = VocableColors.determineColorIndex(total, correct);
        int expectedIndex = 1;
        assertEquals(expectedIndex, actualIndex);
        Color expected = vocableColors.createBackgroundColor(actualIndex);
        assertEquals(expected, actual);
        Color expected2 = new Color(255, 195, 180);
        assertEquals(expected2, actual);
    }

    @Test
    public void determineBackgroundColor2From10() {
        int total = 10;
        int correct = 2;
        VocableColors vocableColors = createVocableColors();
        Color actual = vocableColors.determineBackgroundColor(total, correct);
        int actualIndex = VocableColors.determineColorIndex(total, correct);
        int expectedIndex = 2;
        assertEquals(expectedIndex, actualIndex);
        Color expected = vocableColors.createBackgroundColor(actualIndex);
        assertEquals(expected, actual);
        Color expected2 = new Color(255, 210, 180);
        assertEquals(expected2, actual);
    }

    @Test
    public void determineBackgroundColor3From10() {
        int total = 10;
        int correct = 3;
        VocableColors vocableColors = createVocableColors();
        Color actual = vocableColors.determineBackgroundColor(total, correct);
        int actualIndex = VocableColors.determineColorIndex(total, correct);
        int expectedIndex = 3;
        assertEquals(expectedIndex, actualIndex);
        Color expected = vocableColors.createBackgroundColor(actualIndex);
        assertEquals(expected, actual);
        Color expected2 = new Color(255, 225, 180);
        assertEquals(expected2, actual);
    }

    @Test
    public void determineBackgroundColor4From10() {
        int total = 10;
        int correct = 4;
        VocableColors vocableColors = createVocableColors();
        Color actual = vocableColors.determineBackgroundColor(total, correct);
        int actualIndex = VocableColors.determineColorIndex(total, correct);
        int expectedIndex = 4;
        assertEquals(expectedIndex, actualIndex);
        Color expected = vocableColors.createBackgroundColor(actualIndex);
        assertEquals(expected, actual);
        Color expected2 = new Color(255, 240, 180);
        assertEquals(expected2, actual);
    }

    @Test
    public void determineBackgroundColor5From10() {
        int total = 10;
        int correct = 5;
        VocableColors vocableColors = createVocableColors();
        Color actual = vocableColors.determineBackgroundColor(total, correct);
        int actualIndex = VocableColors.determineColorIndex(total, correct);
        int expectedIndex = 5;
        assertEquals(expectedIndex, actualIndex);
        Color expected = vocableColors.createBackgroundColor(actualIndex);
        assertEquals(expected, actual);
        Color expected2 = new Color(255, 255, 180);
        assertEquals(expected2, actual);
    }

    @Test
    public void determineBackgroundColor6From10() {
        int total = 10;
        int correct = 6;
        VocableColors vocableColors = createVocableColors();
        Color actual = vocableColors.determineBackgroundColor(total, correct);
        int actualIndex = VocableColors.determineColorIndex(total, correct);
        int expectedIndex = 6;
        assertEquals(expectedIndex, actualIndex);
        Color expected = vocableColors.createBackgroundColor(actualIndex);
        assertEquals(expected, actual);
        Color expected2 = new Color(240, 255, 180);
        assertEquals(expected2, actual);
    }

    @Test
    public void determineBackgroundColor7From10() {
        int total = 10;
        int correct = 7;
        VocableColors vocableColors = createVocableColors();
        Color actual = vocableColors.determineBackgroundColor(total, correct);
        int actualIndex = VocableColors.determineColorIndex(total, correct);
        int expectedIndex = 7;
        assertEquals(expectedIndex, actualIndex);
        Color expected = vocableColors.createBackgroundColor(actualIndex);
        assertEquals(expected, actual);
        Color expected2 = new Color(225, 255, 180);
        assertEquals(expected2, actual);
    }

    @Test
    public void determineBackgroundColor8From10() {
        int total = 10;
        int correct = 8;
        VocableColors vocableColors = createVocableColors();
        Color actual = vocableColors.determineBackgroundColor(total, correct);
        int actualIndex = VocableColors.determineColorIndex(total, correct);
        int expectedIndex = 8;
        assertEquals(expectedIndex, actualIndex);
        Color expected = vocableColors.createBackgroundColor(actualIndex);
        assertEquals(expected, actual);
        Color expected2 = new Color(210, 255, 180);
        assertEquals(expected2, actual);
    }

    @Test
    public void determineBackgroundColor9From10() {
        int total = 10;
        int correct = 9;
        VocableColors vocableColors = createVocableColors();
        Color actual = vocableColors.determineBackgroundColor(total, correct);
        int actualIndex = VocableColors.determineColorIndex(total, correct);
        int expectedIndex = 9;
        assertEquals(expectedIndex, actualIndex);
        Color expected = vocableColors.createBackgroundColor(actualIndex);
        assertEquals(expected, actual);
        Color expected2 = new Color(195, 255, 180);
        assertEquals(expected2, actual);
    }

    @Test
    public void determineBackgroundColor10From10() {
        int total = 10;
        int correct = 10;
        VocableColors vocableColors = createVocableColors();
        Color actual = vocableColors.determineBackgroundColor(total, correct);
        int actualIndex = VocableColors.determineColorIndex(total, correct);
        int expectedIndex = 10;
        assertEquals(expectedIndex, actualIndex);
        Color expected = vocableColors.createBackgroundColor(actualIndex);
        assertEquals(expected, actual);
        Color expected2 = new Color(180, 255, 180);
        assertEquals(expected2, actual);
    }

    @Test
    public void determineBackgroundColor2From5() {
        int total = 5;
        int correct = 2;
        VocableColors vocableColors = createVocableColors();
        Color actual = vocableColors.determineBackgroundColor(total, correct);
        int actualIndex = VocableColors.determineColorIndex(total, correct);
        int expectedIndex = 4;
        assertEquals(expectedIndex, actualIndex);
        Color expected = vocableColors.createBackgroundColor(actualIndex);
        assertEquals(expected, actual);
        Color expected2 = new Color(255, 240, 180);
        assertEquals(expected2, actual);
    }

    @Test
    public void determineBackgroundColor4From5() {
        int total = 5;
        int correct = 4;
        VocableColors vocableColors = createVocableColors();
        Color actual = vocableColors.determineBackgroundColor(total, correct);
        int actualIndex = VocableColors.determineColorIndex(total, correct);
        int expectedIndex = 8;
        assertEquals(expectedIndex, actualIndex);
        Color expected = vocableColors.createBackgroundColor(actualIndex);
        assertEquals(expected, actual);
        Color expected2 = new Color(210, 255, 180);
        assertEquals(expected2, actual);
    }

    @Test
    public void determineBackgroundColorOfNotTestedInternalData() {
        InternalAdditionalVocableData data = new InternalAdditionalVocableData();
        boolean colorVocableDependingOnLastSuccess = true;
        TranslationDirection translationDirection = TranslationDirection.JAPANESE_TO_GERMAN;
        VocableColors vocableColors = createVocableColors();
        Color actualColor = vocableColors.determineBackgroundColor(data,
                colorVocableDependingOnLastSuccess, translationDirection);

        Color expectedColor = Color.WHITE;
        assertEquals(expectedColor , actualColor);
    }

    @Test
    public void determineBackgroundColorOfInternalDataJitensha() {
        InternalAdditionalVocableData data = new InternalAdditionalVocableData();
        data.setCorrectJapaneseToGermanTestCount(76);
        data.setCorrectJapaneseToGermanTestCount(77);
        data.initLastTenJapaneseToGermanTestResultsFromStorageString("++++++++++"); // das zählt

        boolean colorVocableDependingOnLastSuccess = true;
        TranslationDirection translationDirection = TranslationDirection.JAPANESE_TO_GERMAN;
        VocableColors vocableColors = createVocableColors();
        Color actualColor = vocableColors.determineBackgroundColor(data,
                colorVocableDependingOnLastSuccess, translationDirection);

        Color expectedColor = new Color(180, 255, 180);
        assertEquals(expectedColor , actualColor);
    }

    @Test
    public void determineBackgroundColorOfInternalDataAnnaijo() {
        InternalAdditionalVocableData data = new InternalAdditionalVocableData();
        data.setCorrectJapaneseToGermanTestCount(23);
        data.setCorrectJapaneseToGermanTestCount(15);
        data.initLastTenJapaneseToGermanTestResultsFromStorageString("++++++++++"); // das zählt

        boolean colorVocableDependingOnLastSuccess = true;
        TranslationDirection translationDirection = TranslationDirection.JAPANESE_TO_GERMAN;
        VocableColors vocableColors = createVocableColors();
        Color actualColor = vocableColors.determineBackgroundColor(data,
                colorVocableDependingOnLastSuccess, translationDirection);

        Color expectedColor = new Color(180, 255, 180);
        assertEquals(expectedColor , actualColor);
    }

    @Test
    public void determineBackgroundColorOfInternalDataKame() {
        InternalAdditionalVocableData data = new InternalAdditionalVocableData();
        data.setCorrectJapaneseToGermanTestCount(76);
        data.setCorrectJapaneseToGermanTestCount(58);
        data.initLastTenJapaneseToGermanTestResultsFromStorageString("-++-++++++"); // das zählt

        boolean colorVocableDependingOnLastSuccess = true;
        TranslationDirection translationDirection = TranslationDirection.JAPANESE_TO_GERMAN;
        VocableColors vocableColors = createVocableColors();
        Color actualColor = vocableColors.determineBackgroundColor(data,
                colorVocableDependingOnLastSuccess, translationDirection);

        Color expectedColor = new Color(210, 255, 180);
        assertEquals(expectedColor , actualColor);
    }

    @Test
    public void determineBackgroundColorOfInternalDataTaiiku() {
        InternalAdditionalVocableData data = new InternalAdditionalVocableData();
        data.setCorrectJapaneseToGermanTestCount(12);
        data.setCorrectJapaneseToGermanTestCount(9);
        data.initLastTenJapaneseToGermanTestResultsFromStorageString("--++++++++"); // das zählt

        boolean colorVocableDependingOnLastSuccess = true;
        TranslationDirection translationDirection = TranslationDirection.JAPANESE_TO_GERMAN;
        VocableColors vocableColors = createVocableColors();
        Color actualColor = vocableColors.determineBackgroundColor(data,
                colorVocableDependingOnLastSuccess, translationDirection);

        Color expectedColor = new Color(210, 255, 180);
        assertEquals(expectedColor , actualColor);
    }

    @Test
    public void determineBackgroundColorOfInternalDataFuutou() {
        InternalAdditionalVocableData data = new InternalAdditionalVocableData();
        data.setCorrectJapaneseToGermanTestCount(18);
        data.setCorrectJapaneseToGermanTestCount(12);
        data.initLastTenJapaneseToGermanTestResultsFromStorageString("++++++++++"); // das zählt

        boolean colorVocableDependingOnLastSuccess = true;
        TranslationDirection translationDirection = TranslationDirection.JAPANESE_TO_GERMAN;
        VocableColors vocableColors = createVocableColors();
        Color actualColor = vocableColors.determineBackgroundColor(data,
                colorVocableDependingOnLastSuccess, translationDirection);

        Color expectedColor = new Color(180, 255, 180);
        assertEquals(expectedColor , actualColor);
    }

}
