package com.tiedup.remake.util;

import com.tiedup.remake.core.SettingsAccessor;

/**
 * GagMaterial DNA - Defines the "sound" and behavior of different gag materials.
 *
 */
public enum GagMaterial {
    // Original materials
    CLOTH(
        new String[] { "m", "h", "f", "p" },
        new String[] { "ph", "ff", "mm" },
        0.4f,
        15.0,
        "mm",
        "ah", // dominant consonant, vowel
        0.3f,
        0.5f,
        0.9f,
        0.3f,
        0.6f // plosive, fricative, nasal, liquid, vowel bleed
    ),
    BALL(
        new String[] { "b", "h", "m", "p" },
        new String[] { "oo", "uu", "mm", "ou" },
        0.2f,
        10.0,
        "mm",
        "uu",
        0.1f,
        0.2f,
        0.9f,
        0.1f,
        0.4f
    ),
    TAPE(
        new String[] { "m", "n" },
        new String[] { "mm", "nn", "mnm" },
        0.05f,
        5.0,
        "mm",
        "mm",
        0.0f,
        0.1f,
        0.8f,
        0.0f,
        0.1f
    ),
    STUFFED(
        new String[] { "m" },
        new String[] { "mm" },
        0.0f,
        3.0,
        "mm",
        "mm",
        0.0f,
        0.0f,
        0.5f,
        0.0f,
        0.0f
    ),

    PANEL(
        new String[] { "m", "n" },
        new String[] { "mm", "nn" },
        0.05f,
        4.0,
        "mm",
        "mm",
        0.0f,
        0.1f,
        0.7f,
        0.0f,
        0.1f
    ),
    LATEX(
        new String[] { "m", "h" },
        new String[] { "mm", "uu" },
        0.1f,
        6.0,
        "mm",
        "uu",
        0.05f,
        0.15f,
        0.8f,
        0.05f,
        0.2f
    ),
    RING(
        new String[] { "a", "h", "l" },
        new String[] { "aa", "ah", "la" },
        0.5f,
        12.0,
        "h",
        "ah",
        0.7f,
        0.8f,
        0.95f,
        0.8f,
        0.9f // Very open, most sounds pass
    ),
    BITE(
        new String[] { "h", "g", "n" },
        new String[] { "eh", "ah", "ng" },
        0.3f,
        10.0,
        "gh",
        "eh",
        0.4f,
        0.6f,
        0.9f,
        0.5f,
        0.7f
    ),
    SPONGE(
        new String[] { "m" },
        new String[] { "mm" },
        0.0f,
        2.0,
        "mm",
        "mm",
        0.0f,
        0.0f,
        0.3f,
        0.0f,
        0.0f // Absorbs almost everything
    ),
    BAGUETTE(
        new String[] { "b", "m", "f" },
        new String[] { "om", "am", "um" },
        0.25f,
        8.0,
        "mm",
        "om",
        0.2f,
        0.3f,
        0.8f,
        0.2f,
        0.5f
    );

    public final String[] consonants;
    public final String[] vowels;
    private final float defaultComprehension;
    private final double defaultTalkRange;

    private final String dominantConsonant;
    private final String dominantVowel;
    private final float plosiveBleed; // b,d,g,k,p,t - require lip/tongue
    private final float fricativeBleed; // f,h,s,v,z - air-based
    private final float nasalBleed; // m,n - through nose
    private final float liquidBleed; // l,r - tongue-dependent
    private final float vowelBleed; // a,e,i,o,u,y - mouth shape

    GagMaterial(
        String[] c,
        String[] v,
        float comp,
        double range,
        String domCons,
        String domVowel,
        float plosive,
        float fricative,
        float nasal,
        float liquid,
        float vowel
    ) {
        this.consonants = c;
        this.vowels = v;
        this.defaultComprehension = comp;
        this.defaultTalkRange = range;
        this.dominantConsonant = domCons;
        this.dominantVowel = domVowel;
        this.plosiveBleed = plosive;
        this.fricativeBleed = fricative;
        this.nasalBleed = nasal;
        this.liquidBleed = liquid;
        this.vowelBleed = vowel;
    }

    public float getComprehension() {
        return SettingsAccessor.getGagComprehension(
            this.name().toLowerCase(), defaultComprehension
        );
    }

    public double getTalkRange() {
        return SettingsAccessor.getGagTalkRange(
            this.name().toLowerCase(), defaultTalkRange
        );
    }

    /**
     * Get the dominant consonant sound for this material.
     * Used when a consonant is completely blocked.
     */
    public String getDominantConsonant() {
        return dominantConsonant;
    }

    /**
     * Get the dominant vowel sound for this material.
     * Used when a vowel is completely blocked.
     */
    public String getDominantVowel() {
        return dominantVowel;
    }

    /**
     * Get bleed-through rate for plosive consonants (b,d,g,k,p,t).
     */
    public float getPlosiveBleed() {
        return plosiveBleed;
    }

    /**
     * Get bleed-through rate for fricative consonants (f,h,s,v,z).
     */
    public float getFricativeBleed() {
        return fricativeBleed;
    }

    /**
     * Get bleed-through rate for nasal consonants (m,n).
     */
    public float getNasalBleed() {
        return nasalBleed;
    }

    /**
     * Get bleed-through rate for liquid consonants (l,r).
     */
    public float getLiquidBleed() {
        return liquidBleed;
    }

    /**
     * Get bleed-through rate for vowels.
     */
    public float getVowelBleed() {
        return vowelBleed;
    }

    /**
     * Calculate the effective bleed rate for a specific character.
     */
    public float getBleedRateFor(char c) {
        char lower = Character.toLowerCase(c);

        // Vowels
        if ("aeiouy".indexOf(lower) >= 0) {
            return vowelBleed;
        }

        // Nasals - almost always pass
        if (lower == 'm' || lower == 'n') {
            return nasalBleed;
        }

        // Plosives - blocked by most gags
        if ("bdgkpt".indexOf(lower) >= 0) {
            return plosiveBleed;
        }

        // Fricatives - air-based
        if ("fhsvz".indexOf(lower) >= 0) {
            return fricativeBleed;
        }

        // Liquids - tongue-dependent
        if (lower == 'l' || lower == 'r') {
            return liquidBleed;
        }

        // Default to average of consonant bleeds
        return (plosiveBleed + fricativeBleed + nasalBleed + liquidBleed) / 4f;
    }
}
