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

#ifndef BLINKER_H
#define	BLINKER_H

#include "../xf/xf.h"

typedef enum {
    STBL_INIT,
    STBL_WAIT,
    STBL_ON,
    STBL_OFF
} BLINKER_STATES;

typedef enum {
    evBLinit = 200,
    evBLblink,
    evBLblinkN,
    evBLtimer,
    evEndBlink
} BLINKER_EVENTS;

typedef void (*fBlinkerCallBack)(void*);
typedef struct {
    fBlinkerCallBack fCallBack;
    void* param;
} blinkerCallBack;

typedef struct {
    BLINKER_STATES state; // Actual state
    uint16_t tON; // Time on
    uint16_t tOFF; // Time off
    uint8_t nBlink; // Number of blink for this blinker when start with blinkN
    bool nBlinkIsOn; // If the nBlink way is enable
    uint8_t remainBlinks; // Actual remain blink
    blinkerCallBack turnOn; // Callback for turnOn
    blinkerCallBack turnOff; // Calbback for turnOff
    blinkerCallBack finished; // Callback for finish n blink
}BLINKER;

/**
 * Initialize the blinker
 * @param me blinker itself
 */
void BLINKER_init(BLINKER* me);

/**
 * Define a callback for BLINKER    
 * @param f callback for BLINKER
 * @param param callback paramater for ther function 
 * @return the callback struct
 */
blinkerCallBack BLINKER_defineCallBack(fBlinkerCallBack f, void* param);

/**
 * Start state machine of the BLINKER
 * @param me the blinker itself
 */
void BLINKER_starBehaviour(BLINKER* me);

/**
 * Set callback event functions for turn on
 * @param me the blinker itself
 * @param callBack function when the blinker is on
 */
void BLINKER_setTurnOn(BLINKER* me, blinkerCallBack callBack);

/**
 * Set callback event functions for turn off
 * @param me the blinker itself
 * @param callBack function when the blinker is off
 */
void BLINKER_setTurnOff(BLINKER* me, blinkerCallBack callBack);

/**
 * Set callback event functions for when the blinker has blink n times
 * @param me the blinker itseld
 * @param callBack callBack function when the blinker has blink n times
 */
void BLINKER_setFinished(BLINKER* me, blinkerCallBack callBack);

/**
 * define number of time the Blinker have to blink
 * @param me the blinker itself
 * @param n number of blink
 */
void BLINKER_defineNblink(BLINKER* me, uint8_t n);

/**
 * define time to stay ON
 * @param me the blinker itself
 * @param t the time to stay ON
 */
void BLINKER_setTimeOn(BLINKER*me, uint16_t t);

/**
 * define time to stay OFF
 * @param me the blinker itself
 * @param t the time to stay OFF
 */
void BLINKER_setTimeOff(BLINKER*me, uint16_t t);

/**
 * Start to blink n time
 * @param me the blinker itself
 */
void BLINKER_blinkN(BLINKER* me);

/**
 * Start to blink indefinitely
 * @param me the blinker itself
 */
void BLINKER_blink(BLINKER* me);

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

/**
 * Stop to blink if it was indefinitely blinking
 * @param me the blinker itself
 */
void BLINKER_endBlink(BLINKER* me);

void BLINKER_toggle(BLINKER* me);


#endif	/* BLINKER_H */

