#ifndef FINISHFRAMEEVENT_HH
#define FINISHFRAMEEVENT_HH

#include "Event.hh"
#include "TclObject.hh"
#include "checked_cast.hh"
#include <tuple>

namespace openmsx {

/**
 * This event is send when a device (v99x8, v9990, video9000, laserdisc)
 * reaches the end of a frame. This event has info on:
 *  - which device generated the event
 *  - which video layer was active
 *  - was the frame actually rendered or not (frameskip)
 * Note that even if a frame was rendered (not skipped) it may not (need to) be
 * displayed because the corresponding video layer is not active. Or also even
 * if the corresponding video layer for a device is not active, the rendered
 * frame may still be displayed as part of a superimposed video layer.
 */
class FinishFrameEvent final : public Event
{
public:
	FinishFrameEvent(int thisSource_, int selectedSource_,
	                 bool skipped_)
		: Event(OPENMSX_FINISH_FRAME_EVENT)
		, thisSource(thisSource_), selectedSource(selectedSource_)
		, skipped(skipped_)
	{
	}

	int getSource()         const { return thisSource; }
	int getSelectedSource() const { return selectedSource; }
	bool isSkipped() const { return skipped; }
	bool needRender() const { return !skipped && (thisSource == selectedSource); }

	void toStringImpl(TclObject& result) const override
	{
		result.addListElement("finishframe");
		result.addListElement(int(thisSource));
		result.addListElement(int(selectedSource));
		result.addListElement(skipped);
	}
	bool lessImpl(const Event& other) const override
	{
		auto& e = checked_cast<const FinishFrameEvent&>(other);
		auto t1 = std::make_tuple(
			getSource(), getSelectedSource(), isSkipped());
		auto t2 = std::make_tuple(
			e.getSource(), e.getSelectedSource(), e.isSkipped());
		return t1 < t2;
	}

private:
	const int thisSource;
	const int selectedSource;
	const bool skipped;
};

} // namespace openmsx

#endif
