package com.tiedup.remake.client;

import net.minecraft.client.resources.sounds.Sound;
import net.minecraft.client.resources.sounds.SoundInstance;
import net.minecraft.client.resources.sounds.TickableSoundInstance;
import net.minecraft.client.sounds.SoundManager;
import net.minecraft.client.sounds.WeighedSoundEvents;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.sounds.SoundSource;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;

/**
 * Wrapper around a SoundInstance that applies volume and pitch modifiers.
 * Used for the earplugs muffling effect.
 *
 * This delegates all methods to the wrapped sound, but overrides
 * getVolume() and getPitch() to apply modifiers.
 */
@OnlyIn(Dist.CLIENT)
public class MuffledSoundInstance implements SoundInstance {

    private final SoundInstance wrapped;
    private final float volumeMultiplier;
    private final float pitchMultiplier;

    public MuffledSoundInstance(
        SoundInstance wrapped,
        float volumeMultiplier,
        float pitchMultiplier
    ) {
        this.wrapped = wrapped;
        this.volumeMultiplier = volumeMultiplier;
        this.pitchMultiplier = pitchMultiplier;
    }

    @Override
    public ResourceLocation getLocation() {
        return wrapped.getLocation();
    }

    @Override
    public WeighedSoundEvents resolve(SoundManager soundManager) {
        return wrapped.resolve(soundManager);
    }

    @Override
    public Sound getSound() {
        return wrapped.getSound();
    }

    @Override
    public SoundSource getSource() {
        return wrapped.getSource();
    }

    @Override
    public boolean isLooping() {
        return wrapped.isLooping();
    }

    @Override
    public boolean isRelative() {
        return wrapped.isRelative();
    }

    @Override
    public int getDelay() {
        return wrapped.getDelay();
    }

    @Override
    public float getVolume() {
        // Apply muffling to volume
        return wrapped.getVolume() * volumeMultiplier;
    }

    @Override
    public float getPitch() {
        // Apply muffling to pitch
        return wrapped.getPitch() * pitchMultiplier;
    }

    @Override
    public double getX() {
        return wrapped.getX();
    }

    @Override
    public double getY() {
        return wrapped.getY();
    }

    @Override
    public double getZ() {
        return wrapped.getZ();
    }

    @Override
    public Attenuation getAttenuation() {
        return wrapped.getAttenuation();
    }

    /**
     * Check if this is wrapping a tickable sound.
     * Used to handle special cases.
     */
    public boolean isTickable() {
        return wrapped instanceof TickableSoundInstance;
    }

    /**
     * Get the wrapped sound instance.
     */
    public SoundInstance getWrapped() {
        return wrapped;
    }
}
