package pp.monopoly.client;

import java.lang.System.Logger;
import java.lang.System.Logger.Level;
import java.util.prefs.Preferences;

import com.jme3.app.Application;
import com.jme3.app.state.AbstractAppState;
import com.jme3.app.state.AppStateManager;
import com.jme3.audio.AudioData;
import com.jme3.audio.AudioNode;

import pp.monopoly.notification.GameEventListener;
import pp.monopoly.notification.SoundEvent;
import static pp.util.PreferencesUtils.getPreferences;

/**
 * An application state that plays sounds based on game events.
 */
public class GameSound extends AbstractAppState implements GameEventListener {
    private static final Logger LOGGER = System.getLogger(GameSound.class.getName());
    private static final Preferences PREFERENCES = getPreferences(GameSound.class);
    private static final String ENABLED_PREF = "enabled";

    private Application app; // Feld zum Speichern der Application-Instanz

    /**
     * Checks if sound is enabled in the preferences.
     *
     * @return {@code true} if sound is enabled, {@code false} otherwise.
     */
    public static boolean enabledInPreferences() {
        return PREFERENCES.getBoolean(ENABLED_PREF, true);
    }

    /**
     * Toggles the game sound on or off.
     */
    public void toggleSound() {
        setEnabled(!isEnabled());
    }

    /**
     * Sets the enabled state of this AppState.
     *
     * @param enabled {@code true} to enable the AppState, {@code false} to disable it.
     */
    @Override
    public void setEnabled(boolean enabled) {
        if (isEnabled() == enabled) return;
        super.setEnabled(enabled);
        LOGGER.log(Level.INFO, "Sound enabled: {0}", enabled);
        PREFERENCES.putBoolean(ENABLED_PREF, enabled);
    }

    /**
     * Initializes the sound effects for the game and stores the application reference.
     *
     * @param stateManager The state manager
     * @param app          The application instance
     */
    @Override
    public void initialize(AppStateManager stateManager, Application app) {
        super.initialize(stateManager, app);
        this.app = app; // Speichert die Application-Instanz
    }

    /**
     * Loads a sound from the specified file.
     *
     * @param name The name of the sound file.
     * @return The loaded AudioNode.
     */
    private AudioNode loadSound(String name) {
        try {
            AudioNode sound = new AudioNode(app.getAssetManager(), name, AudioData.DataType.Buffer);
            sound.setLooping(false);
            sound.setPositional(false);
            return sound;
        } catch (Exception ex) {
            LOGGER.log(Level.ERROR, ex.getMessage(), ex);
        }
        return null;
    }

    /**
     * Handles sound-related game events to play specific sounds.
     *
     * @param event The sound event received.
     */
    @Override
    public void receivedEvent(SoundEvent event) {
        if (isEnabled()) {
            AudioNode sound = loadSound(event.getSoundFileName());
            if (sound != null) {
                sound.play();
            }
        }
    }
}//heloo
