/**
 * @author Rémi Heredero (remi@heredero.ch)
 * @version. 1.0.0
 * @date 2023-06-15
 */
#ifndef BUTTON_H
#define BUTTON_H

#include <stdint.h>
#include <stdbool.h>
#include "../../xf/xf.h"

#define PB_POLL_TIME 20 // Poll time for BUTTON

typedef enum {
    ST_PBINIT,
    ST_PBRELEASED,
    ST_PBPRESSED
}  BUTTON_STATES;

typedef enum {
    evPBInit=50,
    evPBPoll
} BUTTON_EVENTS;

// Calback function
typedef void (*fButtonCallback)(void*); 
typedef struct {
    fButtonCallback fCallBack;
    void* param;
} buttonCallBack;

typedef struct {
    uint8_t id; // Id of the button
    BUTTON_STATES state; // Actual state 
    buttonCallBack press; // Callback for the rising edge of the button
    buttonCallBack release;  // Callback for the falling edge of the button
} BUTTON;

/**
 * @brief Initialize the button
 * 
 * @param me button itself
 * @param id The id of the button
 */
void BUTTON_init(BUTTON* me, uint8_t id);

/**
 * @brief Initialize the hardware of the button
 * 
 * @param me button itself
 */
void BUTTON_initHW(BUTTON* me);

/**
 * @brief Set both callback event functions
 * 
 * @param me button itself
 * @param fPress callback function when the button have a rising edge
 * @param release callback function whent the  have a falling edge
 */
void BUTTON_setEventFunctions(BUTTON* me, buttonCallBack fPress, buttonCallBack release);

/**
 * @brief Check if the button is pressed
 * The function returns true if the button is pressed, false otherwise
 * 
 * @param me button itself
 * @return true if the button is pressed
 * @return false if the button is not pressed
 */
bool BUTTON_isPressed(BUTTON* me);

/**
 * @biref Start state machine of the BUTTON
 * 
 * @param me the button itself
 */
void BUTTON_startBehaviour(BUTTON* me);

/**
 * @brief State machine of the BUTTON
 * 
 * @param ev event to process on the state machine
 */
bool BUTTON_processEvent(Event* ev);

/**
 * @brief Define a callback for BUTTON
 * 
 * @param f callback function
 * @param param callback parameter for the function
 * @return the callback struct
 */
buttonCallBack BUTTON_defineCallBack(fButtonCallback f, void* param);

#endif	/* BUTTON_H */