////////////////////////////////////////////////////////////////////////////////
// Audio.h
// Class for audio playback via SDL
// Copyright Bjoern Ganster
// Developed since 2021
////////////////////////////////////////////////////////////////////////////////

#pragma once

#include "BGBase.h"
#include "BGCPString.h"

class Sound;

// Archived sounds can be replayed without further decoding
struct ArchivedSound {
	BGCPString name;
	Sound* sound;
};

// Subclasses provide audio via callback
class AudioProvider {
public:
	virtual void provideAudio(void* userdata, Uint8* stream, int len) = 0;
};

// Class for audio playback via SDL
class Audio: public VirtualClass {
public:
	// Constructor
	Audio();

	// Destructor
	~Audio() OVERRIDE;

	// Setup audio device, must be called once
	bool setup();

	// Get audio properties
	unsigned char getChannels() const;
	SDL_AudioFormat getFormat() const;
	int getFrequency() const;

	// Queue audio for immediate playback
	void queue(const char* data, size_t dataSize);
	void queue(const Sound& sound);

	// Unpause audio playback
	void unpause();

	// Pause audio playback
	void pause();

	// Get specification of current audio device
	const SDL_AudioSpec& getAudioSpec() const;

	// Return remaining queued audio duration in ms
	DWORD getRemainingQueuedAudioMS() const;

	// Retrieve archived sound
	Sound* getSound(const char* name);

	// Archive sound for later retrieval
	void archiveSound(Sound* sound, const char* name);
private:
	SDL_AudioSpec mAudioSpec;
	SDL_AudioDeviceID mAudioDevice;
	std::vector<ArchivedSound> mArchivedSounds;
};

void prepareAudio();

// Obtain a pointer to the global audio device
Audio* getAudio();

// Specify object to listen to adio callbacks
void setAudioProvider(AudioProvider* newProvider);
