/*
 * 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 addTransition(const int evid, XFState* state) { addTransition(XFEvent::XFEventType::Event, evid, 0, state); };

	inline void setTimeout(int time, XFState* nextState) { addTransition(XFEvent::XFEventType::Timeout, XFEvent::Timeout, time, nextState); };
	typedef void (XFBehavior::*callback)();
	typedef void (XFBehavior::*callbackEv)(const XFEvent* ev);
	//inline void registerOnState(callback cbState) { cbState_ = cbState; };
	inline void registerOnEntry(callback cbEntry) { cbEntry_ = cbEntry; };
	inline void registerOnExit(callback cbExit) { cbExit_ = cbExit; };
	//inline void registerOnState(callbackEv cbState) { cbEvState_ = cbState; };
	inline void registerOnEntry(callbackEv cbEntry) { cbEvEntry_ = cbEntry; };
	inline void registerOnExit(callbackEv cbExit) { cbEvExit_ = cbExit; };

protected:
	void addTransition(XFEvent::XFEventType type, const int evid, const int time, 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 cbState_;
	callback cbEntry_;
	callback cbExit_;
	callbackEv cbEvState_;
	callbackEv cbEvEntry_;
	callbackEv cbEvExit_;

};


class XFInitialState : public XFState {
public:
	inline XFInitialState(XFBehavior* behavior) : XFState(behavior) {};
	~XFInitialState() = default;
	inline void addInitialTransition(XFState* state) { addTransition(XFEvent::XFEventType::Initial, XFEvent::Initial, 0, state); };
};
#endif /* XFSTATE_H_ */
