#ifndef _H_COMMAND_H
#define _H_COMMAND_H

#include <functional>

#include "utility/mousestate.h"

class GameActor;

class Command
{
public:
	virtual ~Command() {  }
	virtual void execute(GameActor& actor) = 0;
};

class MouseCommand
{
public:
	virtual ~MouseCommand() {  }
	virtual void execute(GameActor& actor, const MouseState& mouse_state) = 0;
};

class LambdaCommand : public Command
{
public:
	LambdaCommand(std::function<void(GameActor&)> func) : func(func) {};
	void execute(GameActor& actor) override { func(actor); }
private:
	std::function<void(GameActor&)> func;
};

class MoveUpCommand : public Command
{
public:
	MoveUpCommand() {}
	void execute(GameActor& actor) override;
};

class MoveDownCommand : public Command
{
public:
	MoveDownCommand() {}
	void execute(GameActor& actor) override;
};

class MoveLeftCommand : public Command
{
public:
	MoveLeftCommand() {}
	void execute(GameActor& actor) override;
};

class MoveRightCommand : public Command
{
public:
	MoveRightCommand() {}
	void execute(GameActor& actor) override;
};

class MoveForwardCommand : public Command
{
public:
	MoveForwardCommand() {}
	void execute(GameActor& actor) override;
};

class MoveBackwardCommand : public Command
{
public:
	MoveBackwardCommand() {}
	void execute(GameActor& actor) override;
};

class StrafeLeftCommand : public Command
{
public:
	StrafeLeftCommand() {}
	void execute(GameActor& actor) override;
};

class StrafeRightCommand : public Command
{
public:
	StrafeRightCommand() {}
	void execute(GameActor& actor) override;
};

class CycleUpCommand : public Command
{
public:
	CycleUpCommand() {}
	void execute(GameActor& actor) override;
};

class CycleDownCommand : public Command
{
public:
	CycleDownCommand() {}
	void execute(GameActor& actor) override;
};

class CycleCommand : public MouseCommand
{
public:
	CycleCommand() {}
	void execute(GameActor& actor, const MouseState& mouse_state) override;
};

class ShootCommand : public MouseCommand
{
public:
	ShootCommand() {}
	void execute(GameActor& actor, const MouseState& mouse_state) override;
};

class FollowMouseCommand : public MouseCommand
{
public:
	void execute(GameActor& actor, const MouseState& mouse_state) override;
};

#endif //_H_COMMAND_H