#ifndef FSM_H
#define FSM_H

#include "common.h"

//=========================== defines =======================================

// Length of FSM queue
#define FSM_QUEUE_LEN               8

//===== FSM states
#define FSM_STATE_START	0x00
#define FSM_STATE_DISCONNECTED	  0x01
#define FSM_STATE_PRE_JOIN			  0x02
#define FSM_STATE_JOINING			    0x03
//#define FSM_STATE_REQ_SERVICE	  	0x04 //not used
#define FSM_STATE_RESETTING		  	0x05
//#define FSM_STATE_PROMISCUOUS	  	0x06 // not used
#define FSM_STATE_SUSPENDED       0x07  
//#define FSM_STATE_NOT_INITIALIZED          0x08
#define FSM_STATE_CONNECTED		  	0x0f
#define FSM_STATE_PUBLISHING			    0x10
#define FSM_STATE_SEND_FAILED	  	0x11
//#define FSM_STATE_PREVIOUS        0xFF  // this is used when returning to normal operationg after request from maintenance port

//===== Timing
#define MIN_TX_INTERPACKET_DELAY_MS	20   // Minimum delay between each packet sent to the mote
#define CMD_PERIOD_MS				        1000 //MIN_TX_INTERPACKET_DELAY_MS * 5 // Delay between each command sent to mote
#define SEND_PERIOD_MS              1000
#define IMMEDIATELY                 1

//timeouts
#define SERIAL_RESPONSE_TIMEOUT_MS  500  // Very conservative; commands are expected to be answered within 125 ms
#define CONNECT_TIMEOUT_S			      180  // Usually takes 10-60 s, but service req. and promiscuous search can add 60 s each.
#define SEND_TIMEOUT_MS				      1000 // Usually takes < 20 ms

//===== Reset/disconnect
/*
 Disconnecting will be more graceful, as the mote first notifies neighbors of
 its imminent software reset. It does, however, take much longer:
 About 20 seconds for disconnect vs 5 seconds for reset only.
 */
#define MOTE_DISCONNECT_BEFORE_RESET false	

//=========================== typedef =======================================

typedef void (*fsm_timer_cbt)(void);

//=========================== prototypes ====================================

// fsm
int16_t fsm_scheduleEvent(uint16_t delay_ms, fsm_timer_cbt cb);
void    fsm_enterState(uint16_t specificDelay, uint8_t newState);
bool    fsm_ready(void);
uint8_t fsm_getState(void);

#endif
