#include "common.hpp"

struct ThreeDeeSound {
    Sound ref;
    float pitch;
    float volume;
    Vector3 position;
    float seconds;
};
std::vector<ThreeDeeSound> sounds;

static void SetSoundPosition(Sound sound, Vector3 position, float maxDist, Camera camera)
{
    // Calculate direction vector and distance between listener and sound source
    Vector3 direction = Vector3Subtract(position, camera.position);
    float distance = Vector3Length(direction);

    // Apply logarithmic distance attenuation and clamp between 0-1
    float attenuation = 1.0f/(1.0f + (distance/maxDist));
    attenuation = Clamp(attenuation, 0.0f, 1.0f);

    // Calculate normalized vectors for spatial positioning
    Vector3 normalizedDirection = Vector3Normalize(direction);
    Vector3 forward = Vector3Normalize(camera.target-camera.position);
    Vector3 right = Vector3Normalize(Vector3CrossProduct({0, 1, 0}, forward));

    // Reduce volume for sounds behind the listener
    float dotProduct = Vector3DotProduct(forward, normalizedDirection);
    if (dotProduct < 0.0f) attenuation *= (1.0f + dotProduct*0.5f);

    // Set stereo panning based on sound position relative to listener
    float pan = -Vector3DotProduct(normalizedDirection, right);

    if(distance > maxDist) {
        attenuation *= 1-Clamp((distance - maxDist) / 10.0f, 0, 1);
    }
    // Apply final sound properties
    SetSoundVolume(sound, attenuation);
    SetSoundPan(sound, pan);
}

void MS_PlaySound(Sound src, float pitch, float volume, Vector3 position) {
    ThreeDeeSound snd = {};
    snd.ref = LoadSoundAlias(src);
    snd.pitch = pitch;
    snd.volume = volume;
    snd.position = position;
    SetSoundVolume(snd.ref, 0);
    PlaySound(snd.ref);
    sounds.push_back(snd);
}

void MS_Update(float dt, Camera camera) {
    for (int i = 0; i < sounds.size(); i++)
    {
        ThreeDeeSound snd = sounds[i];
        if(snd.seconds > 3) sounds.erase(sounds.begin() + i); // TODO: make better
        SetSoundPosition(snd.ref, snd.position, 40, camera);
        SetSoundPitch(snd.ref, snd.pitch);
        //SetSoundVolume(snd.ref, snd.volume);
    }
}