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

#include "xf/XFState.h"
#include "xf/include/xf/behavior.h"
#include <cassert>
#include "xf/event.h"
#include "trace/trace.h"

XFState::XFState(XFBehavior* behavior)
	: pBehavior(behavior) {
	assert(behavior != nullptr);
}

void XFState::setNextState(const int evid, const int time, XFEvent::XFEventType type, XFState* state) {
	assert(state != nullptr);
	transition t;
	t.evid = evid;
	t.time = time;
	t.evType = type;
	t.nextState = state;
	transitions_.push_back(t);
}

XFEventStatus XFState::onState(const XFEvent* ev) {

	assert(ev != nullptr);
	assert(pBehavior != nullptr);

	for(transition t : transitions_) {
		assert(t.nextState != nullptr);

		if(t.evType == XFEvent::XFEventType::Initial){
			pBehavior->curentXFState_ = t.nextState;
			pBehavior->changeXFState = true;
			return XFEventStatus::Consumed;
		}

		if(t.evType == XFEvent::XFEventType::Timeout) {
			pBehavior->curentXFState_ = t.nextState;
			pBehavior->changeXFState = true;
			return XFEventStatus::Consumed;
		}

		if(t.evid == ev->getId()) {
			pBehavior->curentXFState_ = t.nextState;
			pBehavior->changeXFState = true;
			return XFEventStatus::Consumed;
		}

	}

	return XFEventStatus::NotConsumed;
}

void XFState::onEntry(const XFEvent* ev) {
	if(cbEntry_ != nullptr) {
		(pBehavior->*cbEntry_)(ev);
	}

	for(transition t : transitions_) {
		assert(t.nextState != nullptr);

		if(t.evType == XFEvent::XFEventType::Timeout) {
			pBehavior->scheduleTimeout(XFEvent::Timeout, t.time);
		}

	}
}
void XFState::onExit(const XFEvent* ev) {
	if(cbExit_ != nullptr) {
		(pBehavior->*cbExit_)(ev);
	}
}
