#ifndef PORTMIDI_MOCK_H
#define PORTMIDI_MOCK_H

#define PORTMIDI_INCLUDED

#include "../../../src/packages/common/IZ_common.h"

typedef i32 PmDeviceID;
typedef void PortMidiStream;
typedef i32 PmTimestamp;
typedef PmTimestamp (*PmTimeProcPtr)(void *time_info);
typedef i32 PmMessage;
typedef struct {
	PmMessage message;
	PmTimestamp timestamp;
} PmEvent;
typedef struct {
	int structVersion; /**< @brief this internal structure version */
	const char *interf; /**< @brief underlying MIDI API, e.g.
                                    "MMSystem" or "DirectX" */
	char *name;   /**< @brief device name, e.g. "USB MidiSport 1x1" */
	int input; /**< @brief true iff input is available */
	int output; /**< @brief true iff output is available */
	int opened; /**< @brief used by generic PortMidi for error checking */
	int is_virtual; /**< @brief true iff this is/was a virtual device */
} PmDeviceInfo;

#define PmStream PortMidiStream

static PmDeviceInfo MOCK_DEVICE_INFO = {
	.output = 1,
	.input = 1,
	.name = "Mock MIDI Device",
	.interf = "MMSystem",
	.is_virtual = 0,
	.opened = 0,
	.structVersion = 1,
};

mock(Pm_Initialize) i32 Pm_Initialize(void) {
	mock_return(Pm_Initialize) 0;
}

mock(Pm_GetDeviceInfo) const PmDeviceInfo* Pm_GetDeviceInfo(PmDeviceID id) {
	mock_return(Pm_GetDeviceInfo) &MOCK_DEVICE_INFO;
}

mock(Pm_OpenInput) i32 Pm_OpenInput(
	PortMidiStream** stream,
	PmDeviceID inputDevice,
	void* inputDriverInfo,
	i32 bufferSize,
	PmTimeProcPtr time_proc,
	void* time_info
) {
	mock_return(Pm_OpenInput) 0;
}

mock(Pm_Close) i32 Pm_Close(PortMidiStream* stream) {
	mock_return(Pm_Close) 0;
}

#define MOCK_OPEN_MIDI_DEVICES 1

mock(Pm_CountDevices) i32 Pm_CountDevices(void) {
	mock_return(Pm_CountDevices) MOCK_OPEN_MIDI_DEVICES;
}

#endif
