/*
 * XFState.h
 *
 *  Created on: 23 nov. 2023
 *      Author: remi.heredero
 */

#ifndef XFSTATE_H_
#define XFSTATE_H_

#include "xf/interface/reactive.h"
#include "xf/interface/dispatcher.h"
#include "xf/eventstatus.h"
#include "xf/initialevent.h"
#include "xf/nulltransition.h"
#include "xf/timeout.h"
class XFBehavior;

#include <list>

class XFState {
	friend class XFBehavior;
public:
	XFState(XFBehavior* behavior);
	~XFState() = default;

	inline void setNextState(XFState* state) { setNextState(XFEvent::Initial, XFEvent::XFEventType::Initial, state); };
	inline void setNextState(const int evid, XFState* state) { setNextState(evid, XFEvent::XFEventType::Event, state); };

	inline void setTimeout(int time, XFState* nextState) { setNextState(XFEvent::Timeout, time, XFEvent::XFEventType::Timeout, nextState); };
	typedef void (XFBehavior::*callback)(const XFEvent* ev);
	inline void registerOnEntry(callback cbEntry) { cbEntry_ = cbEntry; };
	inline void registerOnExit(callback cbExit) { cbExit_ = cbExit; };

protected:
	inline void setNextState(const int evid, XFEvent::XFEventType type, XFState* state) {setNextState(evid, 0, type, state); };
	void setNextState(const int evid, const int time, XFEvent::XFEventType type, XFState* state);

	XFEventStatus onState(const XFEvent* ev);
	void onEntry(const XFEvent* ev);
	void onExit(const XFEvent* ev);

protected:
	XFBehavior* const pBehavior;
	typedef struct {
		int evid;
		int time;
		XFEvent::XFEventType evType;
		XFState* nextState;
	} transition;
	std::list<transition> transitions_;

	callback cbEntry_;
	callback cbExit_;

};

#endif /* XFSTATE_H_ */
