package de.duehl.mp3.player;

/**
 * Diese Klasse nimmt Lautstärke-Berechnungen vor.
 *
 * In der Klasse MP3Player bzw. dem dort verwendeten AdvancedPlayer kommen Volumen im Bereich von
 * -80.0 dB bis +6.0206 dB vor.
 *
 * Da ich das unhandlich finde, bilde ich es hier auf einen Bereich zwischen 0 und 100, also
 * Prozentgrößen (allerdings als Integer-Werte) ab.
 *
 * @version 1.01     2025-08-06
 * @author Christian Dühl
 */

public class VolumeCalculations {

    public static final int MIN_VOLUME_PERCENT = 0;
    public static final int MAX_VOLUME_PERCENT = 100;
    private static final int VOLUME_PERCENT_RANGE = MAX_VOLUME_PERCENT - MIN_VOLUME_PERCENT;

    public static final float MIN_VOLUME_DB = -80.0f;
    public static final float MAX_VOLUME_DB = 0.0f; // 6.0206f;
    private static final float VOLUME_DB_RANGE = MAX_VOLUME_DB - MIN_VOLUME_DB;
    /*
     * Stellt sich nur die Frage, ob man nicht die 0 als Maximum nehmen sollte.
     *
     * Ja sollte man, die 6.0206f, die das eigentliche Maximum darstellen, klingen verzerrt.
     */


    /**
     * Rechnet eine Lautstärke in Prozent (0-100) um in eine Lautstärke in dB (-80.0f bis 6.0206).
     *
     * Hier rechne ich den Bereich von 0 bis 100 (Prozent) auf MIN_VOLUME_DB bis MAX_VOLUME_DB
     * (dB) um:
     *
     *    percentToSet - MIN_VOLUME_PERCENT       dbToSet - MIN_VOLUME_DB
     *    ---------------------------------   =   -----------------------
     *           VOLUME_PERCENT_RANGE                 VOLUME_DB_RANGE
     *
     * ergo:
     *
     *                              percentToSet * VOLUME_DB_RANGE
     * dbToSet = MIN_VOLUME_DB + ------------------------------------
     *                                  VOLUME_PERCENT_RANGE
     */
    public static float volumePercentToVolumeDb(int percent) {
        int percentToSet = toCorrectVolumePercent(percent);
        return MIN_VOLUME_DB + percentToSet * VOLUME_DB_RANGE / VOLUME_PERCENT_RANGE;
    }

    /**
     * Rechnet eine Lautstärke in Prozent (0-100) um in eine Lautstärke in dB ( -80.0f bis 6.0206).
     *
     * Hier rechne ich den Bereich von 0 bis 100 (Prozent) auf MIN_VOLUME_DB bis MAX_VOLUME_DB
     * (dB) um:
     *
     *    percentToSet - MIN_VOLUME_PERCENT       dbToSet - MIN_VOLUME_DB
     *    ---------------------------------   =   -----------------------
     *           VOLUME_PERCENT_RANGE                 VOLUME_DB_RANGE
     *
     * ergo:
     *
     *                                     (dbToSet - MIN_VOLUME_DB) * VOLUME_PERCENT_RANGE
     * persentToSet = MIN_VOLUME_PERCENT + ------------------------------------------------
     *                                                     VOLUME_DB_RANGE
     */
    public static int volumeDbToVolumePercent(float volume) {
        float dbToSet = toCorrectVolumeDb(volume);
        float percentInFloat = (dbToSet - MIN_VOLUME_DB) * VOLUME_PERCENT_RANGE / VOLUME_DB_RANGE;
        if (MAX_VOLUME_PERCENT - percentInFloat < 0.01f) { // ist dann 99.9999
            return MAX_VOLUME_PERCENT;
        }
        else {
            return MIN_VOLUME_PERCENT + (int) percentInFloat;
        }
    }

    /** Normiert eine Lautstärke-Einstellung in Prozent auf den erlaubten Bereich. */
    public static int toCorrectVolumePercent(int percent) {
        if (percent < MIN_VOLUME_PERCENT) {
            return MIN_VOLUME_PERCENT;
        }
        else if (percent > MAX_VOLUME_PERCENT) {
            return MAX_VOLUME_PERCENT;
        }
        else {
            return percent;
        }
    }

    /** Normiert eine Lautstärke-Einstellung in dB auf den erlaubten Bereich. */
    public static float toCorrectVolumeDb(float volume) {
        if (volume < MIN_VOLUME_DB) {
            return MIN_VOLUME_DB;
        }
        else if (volume > MAX_VOLUME_DB) {
            return MAX_VOLUME_DB;
        }
        else {
            return volume;
        }
    }

}
