#ifndef __SOUND_H
#define __SOUND_H

#ifdef __cplusplus
extern "C" {
#endif

#define INPUT_SIZE (4096)
#define OUTPUT_SIZE (16384)

#include <stdint.h>

#include "soundsource.h"
#include "ringbuffer.h"
#include "fft.h"
#include "light.h"

typedef enum
{
	SOUND_UNLOADED,
	SOUND_STOPPED,
	SOUND_PLAYING,
	SOUND_PAUSED
} SoundState;

class Sound
{
	public:
		Sound();
		~Sound();
		
		void update();
		
		int loadSound(const char *url);
		void playSound();
		void stopSound();
		void pauseSound();
		void closeSound();
		
		int getSoundLength();
		int getSoundPosition();
		void setSoundPosition(int pos);
		SoundState getSoundState();
		
		void resetNaturalFinish();
		int finishedNaturally();
		
		void getNowPlaying(char *str);
		void getFFTResult(int *result);
		
		int playsFormat(const char *url);
		
		void enableDiskLight(bool enabled);
		bool getDiskLightEnabled();
	private:
		static int instance;
		
		static Light light;
		static bool _lenabled;
		
		static FFT fft;
		static File sourceFile;
		static SoundSource *soundSource;
		static SoundSource **availableSources;
		
		static int started;
		static int finished;
		static int paused;
		static int naturalFinish;
};

typedef struct _eqstate_s
{
	f32 lf;
	f32 f1p0;
	f32 f1p1;
	f32 f1p2;
	f32 f1p3;
	
	f32 hf;
	f32 f2p0;
	f32 f2p1;
	f32 f2p2;
	f32 f2p3;
	
	f32 sdm1;
	f32 sdm2;
	f32 sdm3;
	
	f32 lg;
	f32 mg;
	f32 hg;
} EQState;

typedef struct
{
	u8 outBuffer[2][OUTPUT_SIZE];
	RingBuffer ringBuf; 
	
	EQState eqs[2];
	
	int fftResult[2][16];
	int lastPassedResult;
	int countPassedResult;
	int totalPassedResult;
	
	int currentBuffer;
	int needsUpdate;
} SOUND_BUFFER;

typedef union 
{
	struct 
	{
		u16 hi;
		u16 lo;
	} aword;
	u32 adword;
} dword;

#ifdef __cplusplus
}
#endif

#endif
