//
// Created by sebastian on 04.08.26.
//

#ifndef COLORRACE_SOUNDSOURCE_H
#define COLORRACE_SOUNDSOURCE_H
#include "al.h"
#include "AudioDevice.h"
#include "SoundBuffer.h"

namespace engine::audio {

    class SoundSource {
    public:
        SoundSource() {
            alGenSources(1, &m_source);
        }

        ~SoundSource() {
            if (m_source) alDeleteSources(1, &m_source);
        }

        SoundSource(const SoundSource&) = delete;
        SoundSource& operator=(const SoundSource&) = delete;

        SoundSource(SoundSource&& other) noexcept
        : m_source(other.m_source)
        {
            other.m_source = 0;
        }

        SoundSource& operator=(SoundSource&& other) noexcept
        {
            if (this != &other) {
                release();

                m_source = other.m_source;
                other.m_source = 0;
            }

            return *this;
        }

        void setBuffer(const SoundBuffer& buffer) {
            alSourcei(m_source, AL_BUFFER, static_cast<ALint>(buffer.id()));
            checkAlError("alSourcei(AL_BUFFER)");
        }

        void setPosition(float x, float y, float z) {
            alSource3f(m_source, AL_POSITION, x, y, z);
        }

        void setGain(float gain) {
            alSourcef(m_source, AL_GAIN, gain);
        }

        void setLooping(bool loop) {
            alSourcei(m_source, AL_LOOPING, loop ? AL_TRUE : AL_FALSE);
        }

        void play()  { alSourcePlay(m_source); }
        void stop()  { alSourceStop(m_source); }

        bool isPlaying() const {
            ALint state;
            alGetSourcei(m_source, AL_SOURCE_STATE, &state);
            return state == AL_PLAYING;
        }
    private:
        ALuint m_source = 0;

        void release()
        {
            if (m_source != 0) {
                alDeleteSources(1, &m_source);
                m_source = 0;
            }
        }
    };

    inline void updateListener(float px, float py, float pz,
                            float fx, float fy, float fz,
                            float ux, float uy, float uz) {
        alListener3f(AL_POSITION, px, py, pz);
        ALfloat orientation[] = { fx, fy, fz, ux, uy, uz };
        alListenerfv(AL_ORIENTATION, orientation);
    }
} // engine

#endif //COLORRACE_SOUNDSOURCE_H
