#include "decoder.h"
#include "soundloader.h"
#include <vector>
#include <string>
#include "SDL/SDL.h"
#include <stdio.h>

#define SDL 0
#define WINMM 1
#define ALSA 2

#ifndef SOUND_SYSTEM
    #define SOUND_SYSTEM SDL
#endif
#if SOUND_SYSTEM == SDL
    #include "SDL/SDL_audio.h"
#endif
#if SOUND_SYSTEM == WINMM
    #ifndef _WIN32
        #error Not supported on this platform
    #else
        #include <windows.h>
        #include <winuser.h>
    #endif
#endif
#if SOUND_SYSTEM == ALSA
    #error Not implemented
    #ifdef _WIN32
        #error Not supported on this platform
    #endif
#endif




struct audiomanager{
    public:
        struct sound{
            friend struct audiomanager;
            private:
                decoder* data;

                int attenuate;
                bool playing;
                bool looping;
                std::string filename;
                bool isnull;
                audiomanager* parent;
                void pull_samples(int16_t* buffer, size_t len, bool replace = true);
                double ripwid;
                double rippos;
                int playnum;
            public:
                sound(std::string fname, audiomanager* prnt );
                ~sound();
                void play( int which );
                void seek( int whence, size_t offset );
                void loop( int which );
                void set_attenuation( int a );
                void cache(const char* fname);
                void uncache();
                decoder* getdata();
                void setrip(double val);

        };
        friend struct sound;
    private:
        struct linkedlist{
            struct node{
                sound* a;
                node *p,*n;
            };
            size_t len;
            node *first,*last;
            node *curr;


            linkedlist();
            ~linkedlist();
            sound* next();
            void rmcurr();
            void rewind();
            void clear();
            void push( sound* val );
        };
        #if SOUND_SYSTEM == SDL
            static void sdlmixaudio(void *a, Uint8 *stream, int len);
        #elif SOUND_SYSTEM == WINMM
            int* winmmsignal;
            HWAVEOUT winmmsoundout;
            static int winmmsoundloop( void* self );
        #elif SOUND_SYSTEM == ALSA
            #error
        #endif

        sound* nullsound;

        std::vector<sound*> sounds;
        linkedlist* playing;
        bool ucol;
    public:
        audiomanager();
        ~audiomanager();
        int load( const char* fname );
        void free( int id );
        void replace( int id, const char* fname );
        void uncacheonload( int which );
        sound* operator[](int index);
};
