#ifndef INCLUDED_PORTAUDIO_SYSTEM_HXX
#define INCLUDED_PORTAUDIO_SYSTEM_HXX

// ---------------------------------------------------------------------------------------

#include "portaudio.h"

// ---------------------------------------------------------------------------------------

// Forward declaration(s):
namespace portaudio
{
    class Device;
    class Stream;
    class HostApi;
}

// ---------------------------------------------------------------------------------------

// Declaration(s):
namespace portaudio
{


    //////
    /// @brief System singleton which represents the PortAudio system.
    ///
    /// The System is used to initialize/terminate PortAudio and provide
    /// a single access point to the PortAudio System (instance()).
    /// It can be used to iterate through all HostApi 's in the System as
    /// well as all devices in the System. It also provides some utility
    /// functionality of PortAudio.
    ///
    /// Terminating the System will also abort and close the open streams.
    /// The Stream objects will need to be deallocated by the client though
    /// (it's usually a good idea to have them cleaned up automatically).
    //////
    class System
    {
    public:
        class HostApiIterator; // forward declaration
        class DeviceIterator; // forward declaration

        // -------------------------------------------------------------------------------

        static int version();
        static const char *versionText();

        static void initialize();
        static void terminate();

        static System &instance();
        static bool exists();

        // -------------------------------------------------------------------------------

        // host apis:
        HostApiIterator hostApisBegin();
        HostApiIterator hostApisEnd();

        HostApi &defaultHostApi();

        HostApi &hostApiByTypeId(PaHostApiTypeId type);
        HostApi &hostApiByIndex(PaHostApiIndex index);

        int hostApiCount();

        // -------------------------------------------------------------------------------

        // devices:
        DeviceIterator devicesBegin();
        DeviceIterator devicesEnd();

        Device &defaultInputDevice();
        Device &defaultOutputDevice();

        Device &deviceByIndex(PaDeviceIndex index);

        int deviceCount();

        static Device &nullDevice();

        // -------------------------------------------------------------------------------

        // misc:
        void sleep(long msec);
        int sizeOfSample(PaSampleFormat format);

    private:
        System();
        ~System();

        static System *instance_;
        static int initCount_;

        static HostApi **hostApis_;
        static Device **devices_;

        static Device *nullDevice_;
    };


} // namespace portaudio


#endif // INCLUDED_PORTAUDIO_SYSTEM_HXX
