// HARFANG(R) Copyright (C) 2021 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details.

#pragma once

#include <foundation/matrix4.h>
#include <foundation/time.h>
#include <foundation/vector3.h>

#include <engine/audio_stream_interface.h>

namespace hg {

bool AudioInit();
void AudioShutdown();
bool IsAudioUp();

//
void SetListener(const hg::Mat4 &world, const hg::Vec3 &velocity);

//
enum SourceRepeat { SR_Once, SR_Loop };

struct StereoSourceState {
	float volume{1.f};
	SourceRepeat repeat{SR_Once};

	float panning{0.f}; // from -1 to 1 with 0 as the center
};

struct SpatializedSourceState {
	hg::Mat4 mtx{Mat4::Identity};

	float volume{1.f};
	SourceRepeat repeat{SR_Once};

	hg::Vec3 vel{}; // for Doppler effect
};

//
using SoundRef = int;
static const SoundRef InvalidSoundRef = -1;

SoundRef LoadWAVSoundFile(const char *path);
SoundRef LoadWAVSoundAsset(const char *name);

void UnloadSound(SoundRef snd);

//
using SourceRef = int;
static const SourceRef InvalidSourceRef = -1;

SourceRef PlayStereo(SoundRef snd, const StereoSourceState &state);
SourceRef PlaySpatialized(SoundRef snd, const SpatializedSourceState &state);

SourceRef StreamWAVFileStereo(const char *path, const StereoSourceState &state);
SourceRef StreamWAVAssetStereo(const char *name, const StereoSourceState &state);
SourceRef StreamWAVFileSpatialized(const char *path, const SpatializedSourceState &state);
SourceRef StreamWAVAssetSpatialized(const char *name, const SpatializedSourceState &state);

//
// time_ns GetSourceDuration(SourceRef source);
time_ns GetSourceTimecode(SourceRef src);
// [unimplemented] bool SetSourceStreamTimecode(SourceRef source, time_ns t);

//
void SetSourceVolume(SourceRef src, float volume);
void SetSourcePanning(SourceRef src, float panning);
void SetSourceRepeat(SourceRef src, SourceRepeat repeat);
void SetSourceTransform(SourceRef src, const hg::Mat4 &world, const hg::Vec3 &velocity);

//
enum SourceState { SS_Initial, SS_Playing, SS_Paused, SS_Stopped, SS_Invalid };

SourceState GetSourceState(SourceRef src);

void PauseSource(SourceRef src);

void StopSource(SourceRef src);
void StopAllSources();

// [todo] loop point?

} // namespace hg
