/**
******************************************************************************************************************************************************************************************
*@file                       fsm.h
*@author         
*@data                       
*@version                    v1.0
*@par Copyright(c):
*
*@par History:
*     version:author,date,desc
*     v1.0   :create this file
*
*******************************************************************************************************************************************************************************************
*/
#ifndef FSM_H
#define FSM_H
#include "datatype.h"

#define MAX_INST_NAME_LEN		7
#define MAX_TIMER_NAME_LEN		7

typedef void (fsm_func) (UINT8, void *);

struct event {					/* event for the FSM */
	void *arg;					/* event Argument. */
	fsm_func *func;				/* "no status need to be checked" eg: If this is a control fsm func */
	fsm_func *freefunc;			/* Use to free arg */
	UINT8 event;				/* event ID. */
};

enum {
	FSM_INTERNAL = 0,
	FSM_EXTERNAL = 1,
	FSM_EXTERNAL_FOR_C2HMSG = 2
};

/*
* @brief: insert one event in schedule event list.
* @param[0]: will callback this function.
* @param[1]: free param by this function.
* @param[2]: task event number as parameter.
*/
void fsm_event_func(fsm_func *func, fsm_func *freefunc, void *arg, UINT8 event);

/* FSM functions UI interfaces */
/* Internal of SCH thread */
void fsm_free(UINT8 event, void *arg);

#define FsmEventKx(ev_, func_, arg_) 				fsm_event_func(func_, func_, arg_, (ev_))
#define FsmEventFx(func_, arg_) 					fsm_event_func(func_, func_, arg_, 1)/* event not care */
#define FsmEventTx(func_, arg_) 					fsm_event_func(func_, fsm_free, arg_, 1)/* event not care */
#define FsmEventCx(ev_, func_, arg_) 				fsm_event_func(func_, fsm_free, arg_, (ev_))

/* External of SCH thread */
#define DoneLoop() 									fsm_event_func(NULL, NULL, NULL, 0)/* Schloop is going done */
#define FsmEvent_ExternalKx(ev_, func_, arg_) 		fsm_event_func(func_, func_, arg_, (ev_))
#define FsmEvent_ExternalFx(func_, arg_) 			fsm_event_func(func_, func_, arg_, 1)/* event not care */
#define FsmEvent_ExternalTx(func_, arg_)			fsm_event_func(func_, fsm_free, arg_, 1)
#define FsmEvent_ExternalCx(ev_, func_, arg_) 		fsm_event_func(func_, fsm_free, arg_, (ev_))

/* Timer structure for UI */
struct fsm_timer {/* a number, TIMER_ID, user visit as void *, this is forbidden to visit */
	void *forbidden2visit;/* This is a void *, for historial reason */
};

/* Timer structure internal used, forbidden for timer user */
struct fsm_timer_stru {		/* Timer in the fsm instance */
	fsm_func *func;			/* Default Timer expire function */
	void *arg;				/* Argument for the event. */
	TIMER_ID timer_id;		/* System timer id */
	UINT8 event;			/* event when time out. */
}; 


/*
* @brief: restart this timer.
* @param[0]: this pointer for timer.
* @param[1]: timer timeout time.
* @param[2]: timer event number.
* @param[3]: function will be callback when timeout.
* @param[4]: this pointer for function paramter.
*/
struct fsm_timer *timer_restart(struct fsm_timer *ft, UINT32 millisec, UINT8 event, fsm_func *func, void *arg);

/*
* @brief: add this timer.
* @param[1]: timer timeout time.
* @param[2]: timer event number.
* @param[3]: function will be callback when timeout.
* @param[4]: this pointer for function paramter.
* return: this pointer for timer.
*/
struct fsm_timer *timer_add(UINT32 millisec, UINT8 event, fsm_func *func, void *arg);

/*
* @brief: delete a timer by the pointer for timer.
* @param[0]: the pointer fot timer.
*/
UINT8 *timer_del_byp(struct fsm_timer *ft);

/*
* @brief: delete a timer by the pointer for the pointer timer.
* @param[0]: the pointer for the pointer timer.
*/
void timer_del_byp_free(struct fsm_timer **ft);

/* Timer UI interface functions */
#define FsmAddTimer(millisec_, ev_, arg_) 			timer_add(millisec_, ev_, NULL, arg_)
#define FsmAddTimerCx(millisec_, ev_, func_, arg_) 	timer_add(millisec_, ev_, func_, arg_)
#define FsmDelTimer2 												timer_del_byp
#define FSM_DelTimer 												timer_del_byp_free
#define FSM_RestartTimer											timer_restart

/*
* @brief: initialize host schedule.
*/
void init_schedule(void);
/*
* @brief: schedule host task event.
*/
void schedule_loop(void);

#endif/* FSM_H */

