#pragma once

#include "AABB.h"
#include "EntityContext.h"
#include "Inventory.h"
#include "MoveInputState.h"
#include "ActorRuntimeID.h"
#include "ActorType.h"
#include "BaseAttributeMap.h"
#include "ShapeType.h"
#include "SerializedSkin.h"

struct StateVectorComponent {
	glm::vec3 mPos;
	glm::vec3 mPosPrev;
	glm::vec3 mPosDelta;
};

struct AABBShapeComponent {
	AABB mAABB;
	glm::vec2 mBBDim;
};

struct ActorRotationComponent {
	glm::vec2 mRotationDegree;
	glm::vec2 mRotationDegreePrevious;
};

struct ActorEquipmentComponent {
	Inventory* offhand;
	Inventory* armor;
};

struct MoveInputComponent {
	MoveInputState mInputState;
	MoveInputState mRawInputState;
	std::chrono::steady_clock::time_point mHoldAutojumpInWaterUtil;
	glm::vec2 mMove;
	glm::vec2 mLookDelta;
	glm::vec2 mInteractDir;
	glm::vec3 mDisplacement;
	glm::vec3 mDisplacementDelta;
	glm::vec3 mCameraOrientation;
	bool mSneaking;
	bool mSprinting;
	bool mWantUp;
	bool mWantDown;
	bool mJumping;
	bool mAutoJumpingInWater;
	bool mMoveInputStateLocked;
	bool mPersistSneak;
	bool mAutoJumpEnabled;
	bool mIsCameraRelativeMovementEnabled;
	bool mIsRotControlledByMoveDirection;
	std::array<bool, 2> mIsPaddling;
};

struct RuntimeIDComponent {
	ActorRuntimeID mRuntimeID;
};

struct ActorTypeComponent {
	ActorType mType;
};

struct AttributeComponent {
	BaseAttributeMap baseattributes{};
};

struct RenderPositionComponent {
	glm::vec3 mValue;
};

struct ActorWalkAnimationComponent {
	float mWalkAnimSpeedMultiplier;
	float mWalkAnimSpeedO;
	float mWalkAnimSpeed;
	float mWalkAnimPos;
	float mMovementThisTick;
};

class Actor {
public:
	auto getEntityContext() -> EntityContext&;
	
	auto getStateVectorComponent() -> StateVectorComponent*;
	auto getAABBShapeComponent() -> AABBShapeComponent*;
	auto getActorRotationComponent() -> ActorRotationComponent*;
	auto getActorWalkAnimationComponent() -> ActorWalkAnimationComponent*;
	auto getActorEquipmentComponent() -> ActorEquipmentComponent*;
	auto getMoveInputComponent() -> MoveInputComponent*;
	auto getRuntimeIDComponent() -> RuntimeIDComponent*;
	auto getActorTypeComponent() -> ActorTypeComponent*;
	auto getAttributeComponent() -> AttributeComponent*;
	auto getRenderPositionComponent() -> RenderPositionComponent*;

	auto getHurtTime() -> int16_t;

	auto isInvisible() -> bool;
	auto isAlive() -> bool;
	auto isOnFire() -> bool;
	auto canSee(const Actor&, ShapeType) -> bool;
	auto getNameTag() -> std::string;
	auto getLocalNameTag() -> std::string;
	auto getEntityIdentifier() -> std::string;
	auto getSkin() -> SerializedSkin*;
};
