#pragma once

#include <stdbool.h>

#include "rtapi.h"

#define HAL_NAME_LEN 64

typedef enum {
    HAL_TYPE_UNINITIALIZED = 0,
    HAL_BIT,
    HAL_FLOAT,
    HAL_S32,
    HAL_U32,
    HAL_S64,
    HAL_U64
} hal_type_t;

typedef enum {
    HAL_DIR_UNSPECIFIED = -1,
    HAL_IN = 16,
    HAL_OUT = 32,
    HAL_IO = (HAL_IN | HAL_OUT),
    HAL_RW = HAL_IO,
} hal_pin_dir_t;

typedef union {
    bool b;
    double f;
    int s;
    unsigned int u;
    long long ls;
    unsigned long long lu;
} hal_data_u;

typedef bool hal_bit_t;
typedef double real_t;
typedef double hal_float_t;
typedef int hal_s32_t;
typedef unsigned int hal_u32_t;
typedef long long hal_s64_t;
typedef unsigned long long hal_u64_t;

int hal_init(const char *);
int hal_ready(int);
int hal_exit(int);
void *hal_malloc(long int);
int hal_pin_bit_new(const char *, hal_pin_dir_t, hal_bit_t **, int);
int hal_pin_float_new(const char *, hal_pin_dir_t, hal_float_t **, int);
int hal_pin_u32_new(const char *, hal_pin_dir_t, hal_u32_t **, int);
int hal_pin_s32_new(const char *, hal_pin_dir_t, hal_s32_t **, int);
int hal_pin_u64_new(const char *, hal_pin_dir_t, hal_u64_t **, int);
int hal_pin_s64_new(const char *, hal_pin_dir_t, hal_s64_t **, int);
int hal_pin_bit_newf(hal_pin_dir_t, hal_bit_t **, int, const char *, ...);
int hal_pin_float_newf(hal_pin_dir_t, hal_float_t **, int, const char *, ...);
int hal_pin_u32_newf(hal_pin_dir_t, hal_u32_t **, int, const char *, ...);
int hal_pin_s32_newf(hal_pin_dir_t, hal_s32_t **, int, const char *, ...);
int hal_pin_u64_newf(hal_pin_dir_t, hal_u64_t **, int, const char *, ...);
int hal_pin_s64_newf(hal_pin_dir_t, hal_s64_t **, int, const char *, ...);
int hal_param_float_newf(hal_pin_dir_t, hal_float_t *, int, const char *, ...);
int hal_get_pin_value_by_name(const char *, hal_type_t *, hal_data_u **, bool *);
int hal_get_signal_value_by_name(const char *, hal_type_t *, hal_data_u **, bool *);
int hal_get_param_value_by_name(const char *, hal_type_t *, hal_data_u **);
