
#ifndef ETHERCAT_SLAVE_MDP_H
#define ETHERCAT_SLAVE_MDP_H

#include "../ethercat_types.h"
#include "../internal/ordinals.h"
#include <stdint.h>
#ifdef _WIN32
#include <windows.h>
#endif

#ifdef __cplusplus
extern "C" {
#endif

#define _DARRA_MDP_STRINGIFY(x) #x
#define _DARRA_MDP_TOSTR(x) _DARRA_MDP_STRINGIFY(x)

typedef int (*pfn_MDPGetConfigModuleList_t)(uint16_t mi, uint16_t si, uint32_t* out_idents, int max);
typedef int (*pfn_MDPGetDetectedModuleList_t)(uint16_t mi, uint16_t si, uint32_t* out_idents, int max);
typedef int (*pfn_MDPCheckModuleMatch_t)(uint16_t mi, uint16_t si, int* out_first_mismatch);

static __inline int mdp_get_config_module_list(void* dll_handle, uint16_t master, uint16_t slave,
                                                     uint32_t* out_idents, int max)
{
#ifdef _WIN32
    pfn_MDPGetConfigModuleList_t fn = (pfn_MDPGetConfigModuleList_t)GetProcAddress(
        (HMODULE)dll_handle, "D_" _DARRA_MDP_TOSTR(ORD_MDPGetConfigModuleList));
    if (!fn) return -1;
    return fn(master, slave, out_idents, max);
#else
    (void)dll_handle; (void)master; (void)slave; (void)out_idents; (void)max;
    return -1;
#endif
}

static __inline int mdp_get_detected_module_list(void* dll_handle, uint16_t master, uint16_t slave,
                                                       uint32_t* out_idents, int max)
{
#ifdef _WIN32
    pfn_MDPGetDetectedModuleList_t fn = (pfn_MDPGetDetectedModuleList_t)GetProcAddress(
        (HMODULE)dll_handle, "D_" _DARRA_MDP_TOSTR(ORD_MDPGetDetectedModuleList));
    if (!fn) return -1;
    return fn(master, slave, out_idents, max);
#else
    (void)dll_handle; (void)master; (void)slave; (void)out_idents; (void)max;
    return -1;
#endif
}

static __inline int mdp_check_module_match(void* dll_handle, uint16_t master, uint16_t slave,
                                                 int* out_first_mismatch)
{
#ifdef _WIN32
    pfn_MDPCheckModuleMatch_t fn = (pfn_MDPCheckModuleMatch_t)GetProcAddress(
        (HMODULE)dll_handle, "D_" _DARRA_MDP_TOSTR(ORD_MDPCheckModuleMatch));
    if (!fn) { if (out_first_mismatch) *out_first_mismatch = -1; return -1; }
    return fn(master, slave, out_first_mismatch);
#else
    (void)dll_handle; (void)master; (void)slave;
    if (out_first_mismatch) *out_first_mismatch = -1;
    return -1;
#endif
}

#ifdef __cplusplus
}
#endif

#endif
