#pragma once

#include "style.h"
#include "player.h"
#include "schain.h"
#include "camship.h"
#include "graph2d.h"
#include "slot.h"

//##########################################################################
//#################    CameraDirector::AttachCameraShip    #################
//##########################################################################

class CameraDirector__AttachCameraShipMessage:
	public Player::Message
{
	public:

	EntityID
		cameraShipID;

	CameraDirector__AttachCameraShipMessage(
		Receiver::MessageID message_ID,
		size_t length,
		EntityID camera_ship_ID
	):
		Entity::Message(message_ID, length),
		cameraShipID(camera_ship_ID)
			{}
};

//##########################################################################
//############################# CameraDirector #############################
//##########################################################################

class CameraDirector:
	public Player
{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Shared Data support
//
public:

	static Derivation *GetClassDerivations();
	static SharedData DefaultData;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Messaging support
//
public:
	friend class CameraDirector__AttachCameraShipMessage;

	enum{
		AttachCameraShipMessageID = Entity::NextMessageID,
		NextMessageID
	};

	typedef CameraDirector__AttachCameraShipMessage AttachCameraShipMessage;

	void
		AttachCameraShipMessageHandler(AttachCameraShipMessage *message);

protected:
	static const HandlerEntry
		MessageHandlerEntries[];
	static MessageHandlerSet
		MessageHandlers;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Simulation Support
//
public:
	typedef void
		(CameraDirector::*Performance)(Scalar time_slice);

	void
		SetPerformance(Performance performance)
			{
				Check(this);
				activePerformance = (Simulation::Performance)performance;
			}

	void
		CreateCameraShip(Scalar time_slice);
	void
		BeADirector(Scalar time_slice);
	void
		UpdateHUD(Scalar time_slice);

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Construction and Destruction Support
//
public:
	CameraDirector(
		MakeMessage	*creation_message,
		SharedData &virtual_data = DefaultData
	);

	static CameraDirector*
		CameraDirector::Make(CameraDirector::MakeMessage *creation_message);

	~CameraDirector();

	Logical
		TestInstance() const;

	enum {
		DefaultFlags = Entity::DefaultFlags | PreRunFlag | CameraShipPlayerFlag
	};

	static Player*
		FindPlayerByRank(int rank_to_find);

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Simulation Support Data & Functions
//
protected:

	SlotOf<Entity*>
		goalEntity;

	void
		SetGoalEntity(Entity *goal_entity)
			{
				Check(this);
				goalEntity.Remove();
				Check(goal_entity);
				goalEntity.Add(goal_entity);
			}

	Entity*
		GetGoalEntity()
			{Check(this); return goalEntity.GetCurrent(); }

	Scalar
		timeLeftOnPlayer;

	CameraShip
		*cameraShip;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// HUD Support
//
public:

	int
		goalPlayerIndex;

	Logical
		displayRankingWindow;

	Scalar
		timeDisplayed,
		timeTillDisplayed,
		displayIntervalOn,
		displayIntervalOff;
};
