package net.halbear.Terrain4J.EngineCore.Audio;

import org.lwjgl.stb.STBVorbisInfo;
import org.lwjgl.system.MemoryStack;
import org.lwjgl.system.MemoryUtil;

import java.nio.IntBuffer;
import java.nio.ShortBuffer;

import static java.sql.Types.NULL;
import static org.lwjgl.openal.AL10.*;
import static org.lwjgl.stb.STBVorbis.*;

public class SoundBuffer {
    private final int BufferID;
    private final ShortBuffer pcm;

    public SoundBuffer(String FilePath){
        this.BufferID = alGenBuffers();
        try(STBVorbisInfo info = STBVorbisInfo.malloc()){
            pcm = ReadVorbis(FilePath, info);
            alBufferData(BufferID, info.channels() == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16, pcm, info.sample_rate());
        }
    }

    public void CleanUp(){
        alDeleteBuffers(this.BufferID);
        if(pcm != null){
            MemoryUtil.memFree(pcm);
        }
    }
    public int GetBufferID(){
        return this.BufferID;
    }
    private ShortBuffer ReadVorbis(String FilePath, STBVorbisInfo info){
        try(var MemStack = MemoryStack.stackPush()){
            IntBuffer error = MemStack.mallocInt(1);
            long Decoder = stb_vorbis_open_filename(FilePath,error,null);
            if(Decoder == NULL){
                throw new RuntimeException("Failed to open OGG Vorbis File, error -> " + error.get(0));
            }
            stb_vorbis_get_info(Decoder, info);
            int Channels = info.channels();
            int LengthSamples = stb_vorbis_stream_length_in_samples(Decoder);

            ShortBuffer result = MemoryUtil.memAllocShort(LengthSamples * Channels);
            result.limit(stb_vorbis_get_samples_short_interleaved(Decoder,Channels,result) * Channels);
            stb_vorbis_close(Decoder);
            return result;
        }
    }
}
