#pragma once

#include "ehs/EHS.h"
#include "BaseAudioDevice.h"

#include <pipewire/pipewire.h>
#include <pipewire/loop.h>
#include <pipewire/context.h>
#include <pipewire/stream.h>
#include <spa/param/audio/format-utils.h>

namespace ehs
{
	class EHS_LIB_IO AudioDevice final : public BaseAudioDevice
	{
	private:
		static Array<AudioDevice> devices;
		static AudioDevice defOut;
		static AudioDevice defIn;

		UInt_32 id;
		Str_8 name;
		pw_loop *loop;
		pw_context *context;
		pw_core *core;
		pw_stream *input;
		pw_stream *output;

		static void RegistryEventGlobal(void *data, UInt_32 id, UInt_32 permissions, const char *type, UInt_32 version, const spa_dict *props);

		static void RegistryEventGlobalRemove(void *data, UInt_32 id);

		static void OnParamChanged(void *data, UInt_32 id, const spa_pod *param);

	public:
		~AudioDevice() override;

		AudioDevice();

		AudioDevice(AudioDevice&& device) noexcept;

		AudioDevice(const AudioDevice& device);

		AudioDevice& operator=(AudioDevice&& device) noexcept;

		AudioDevice& operator=(const AudioDevice& device);

		void OpenStream() override;

		void CloseStream() override;

		UInt_64 SendStream(const void *data, UInt_64 size) override;

		UInt_64 ReceiveStream(void *data, UInt_64 size) override;

		bool IsStreaming() const override;

		bool IsValid() const override;

		static AudioDevice GetDefault(AudioDeviceType type);

		static Array<AudioDevice> Get(AudioDeviceType type, AudioDeviceState state);

	private:
		Str_8 GetCategory() const;
	};
}