#pragma once
#include "global.h"
//前置声明
class Entity;
struct MyView;
struct MyMapLayer;
struct MapLayer;
struct EntityLayer;
struct GameFunc;
struct PxaData;
struct EntityLoad;
struct PathCell;
struct PathGrid;
class GameMap;
class GamePxa;
class GamePid;
class Pathfinding;
//分组绘制
struct GroupByDraw
{
	MyRect src, dst;
	DWORD color;
};

//实体管理器以及绘制
class EntityRes
{
public:
	//GameFunc
	static std::unordered_map<MapLayer*, EntityLayer>* GetLoadedEntity(EntityRes* entityRes);
	//EntityRes
	EntityRes() = default;
	virtual ~EntityRes();
	EntityRes(const EntityRes&) = delete;//禁止对象实例复制
	EntityRes& operator=(const EntityRes&) = delete;//禁止对象实例复制
	void Init(MyDX11Renderer* pRenderer, MySDLInput* pInput, MyView* pView, int* pMapW, int* pMapH, GamePid* gamePid, GameFunc* gameFunc,
		std::weak_ptr<Entity>* mychar_ptr_Player1, std::weak_ptr<Entity>* mychar_ptr_Player1_menuKeyboard, std::weak_ptr<Entity>* mychar_ptr_Player2, std::weak_ptr<Entity>* mychar_ptr_Player2_menuKeyboard,
		int* pCheckEventPlayerIndex, std::list<std::shared_ptr<Entity>>* globalEntity);
	void InitFrom(const EntityRes* otherEntityRes);
	void SetView(MyView* pView);
	void Reset();//重置
	EntityLayer* LoadLayer(MyMapLayer* pLayer);//载入一个实体层
	void StepEntityLayer(MyMapLayer* pLayer);//执行一个实体层
	void StepEntityLayerPe(MyMapLayer* pLayer);//只执行该实体层中的效果实体
	void DrawEntityLayer(MyMapLayer* pLayer, bool inTopDraw = false);//绘制一个实体层
	void DeltaTimeEntityLayer(MyMapLayer* pLayer, float deltaTime);//执行一个实体层
	void DrawAddEntity(std::shared_ptr<Entity>& we, bool inTopDraw = false);
	void DrawShaderEntity(std::shared_ptr<Entity>& we, bool inTopDraw = false);//绘制着色器实体
	void DrawEntity();//绘制实体
	void DrawEntityText(std::weak_ptr<Entity> e, DWORD color, bool inTopDraw = false);//绘制实体文本
	void DrawEntityCbRectLayer(MyMapLayer* pLayer);//绘制实体碰撞框
	void DrawEntityEventNameLayer(MyMapLayer* pLayer);//绘制实体事件名
	void StepList(std::list<std::shared_ptr<Entity>>* entityList);
	void DeleteStepList(std::list<std::shared_ptr<Entity>>* entityList);//只运行删除操作的版本
	void MoveEntity(std::weak_ptr<Entity> e, int x, int y);
	void MoveEntity(std::weak_ptr<Entity> e, const wchar_t* eventName);
	std::weak_ptr<Entity> SetNpc(MyMapLayer* pLayer, const wchar_t* npcName, float xPos, float yPos, int stateID, int lr);
	std::weak_ptr<Entity> SetNpc(const wchar_t* npcName, int x, int y, int lr, const wchar_t* layerName, const wchar_t* eventName);
	std::weak_ptr<Entity> SetNpc(const wchar_t* npcName, int x, int y, int lr, const wchar_t* layerName, const wchar_t* eventName, const wchar_t* triggerName);
	int DeleteNpc(const wchar_t* eventName);
	void DeleteNpc(std::weak_ptr<Entity> e);
	std::weak_ptr<Entity> GetMyChar_Player1();
	std::weak_ptr<Entity> GetMyChar_Player1_menuKeyboard();
	std::weak_ptr<Entity> GetMyChar_Player2();
	std::weak_ptr<Entity> GetMyChar_Player2_menuKeyboard();
	std::weak_ptr<Entity> GetEntity(const wchar_t* eventName);
	void ANP(const wchar_t* eventName, int stateID, int lr);
	void ANP(const wchar_t* eventName, int stateID);
	void ANP(const wchar_t* eventName, const wchar_t* stateName, int lr);
	void ANP(const wchar_t* eventName, const wchar_t* stateName);
	void ATP(const wchar_t* npcName, const wchar_t* stateName);
	void ChangeNpc(const wchar_t* eventName, const wchar_t* npcName, int stateID, int lr);
	void ChangeNpc(const wchar_t* eventName, const wchar_t* npcName, int stateID);
	void MoveNpc(const wchar_t* eventName, int x, int y, int lr);
	void MoveNpc(const wchar_t* eventName, const wchar_t* dstEventName);
	int KillNpc(const wchar_t* npcName, int damage);
	void SetNpcTopDraw(const wchar_t* eventName, bool enable);
	void ResetEnemy(std::vector<std::wstring>& nameArr);//复位该关卡的所有敌人
	void OnResetScale();
	void EntityAniStep(std::shared_ptr<Entity>& we);
	void AmStep(EntityLayer* entityLayer);//弹药抛射物的碰撞
	bool AmTarget(std::shared_ptr<Entity>& am, std::shared_ptr<Entity>& target);
	static void CollisionEntity(std::weak_ptr<Entity> e, std::vector<LONG>* pxmArr, std::vector<int>* pxaArr, std::map<LONG, LONG>* updatedPxmArr, int pxmArr_w, int pxaArr_w);
	static void CollisionEntityBig(std::weak_ptr<Entity> e, std::vector<LONG>* pxmArr, std::vector<int>* pxaArr, std::map<LONG, LONG>* updatedPxmArr, int pxmArr_w, int pxaArr_w);
	static void CollisionEntitySmall(std::weak_ptr<Entity> e, std::vector<LONG>* pxmArr, std::vector<int>* pxaArr, std::map<LONG, LONG>* updatedPxmArr, int pxmArr_w, int pxaArr_w);
	void CollisionMovingPlatform(std::weak_ptr<Entity> e);
	void SetCollisionEntityLayer(MyMapLayer* pLayer, PxaData* pxaData);
	void GetDebugEntityNum(int* outLsNum, int* outAmNum, int* outPeNum);
	void EntitySaveData();//让所有实体写入数据到缓存
	void EntityLoadData();//让所有实体读取数据到缓存
	void ReloadLanguage();//调用所有实体的ReloadLanguage消息
	ID3D11VertexShader* GetVertexShader(const wchar_t* vsName);//取顶点着色器
	ID3D11PixelShader* GetPixelShader(const wchar_t* psName);//取像素着色器
	static void GetDisplayInfo(EntityRes* pEntityRes, float* outWindow_w, float* outWindow_h, float* outScale, float* outOffX, float* outOffY);
	static void GetMousePos(EntityRes* pEntityRes, float* pX, float* pY);
	static bool InScreen(EntityRes* pEntityRes, float x, float y);//该坐标是否在屏幕显示范围内
	static void GridTouch(EntityRes* entityRes, std::weak_ptr<Entity> src, EntityLayer* targetLayer);//取与这个实体框接触的所有实体
	void ClearLightList();//清除上一次的发光实体记录
	void DrawLightEntity(MyMapLayer* pLayer);//绘制发光实体
	void MarkLightEntity(MyMapLayer* pLayer);//标记当前层所有的灯光实体
	void SetELTable(const wchar_t* eventName, EntityLoad* pEl);
	void DelELTable(const wchar_t* eventName);
	void ClrELTable();
	static PathCell* GetPath(std::weak_ptr<Entity> e, float dstX, float dstY, float srcX, float srcY);
	static bool LineTest(std::weak_ptr<Entity> e, float srcX, float srcY, float dstX, float dstY);
	void DrawPath();//绘制寻路系统
	void UpdatePathFinder();
	GameFunc* GetGameFunc();
	void DrawEntityGlobalIDName(std::weak_ptr<Entity> e);
	void DrawQuadTree(MyMapLayer* entityLayer);
	void GridRemoveEntity(std::shared_ptr<Entity>& we);
	void GridSetEntity(std::shared_ptr<Entity>& we);
	void SetStarBlockBreakEffect(std::wstring smokeNpcName, int setNum, std::wstring breakSoundName);
private:
	MyDX11Renderer* pRenderer = nullptr;
	MySDLInput* pInput = nullptr;
	MyView* pView = nullptr;
	int* pMapW = nullptr;
	int* pMapH = nullptr;
	GamePid* gamePid = nullptr;
	GameFunc* gameFunc = nullptr;
	std::weak_ptr<Entity>* mychar_ptr_Player1 = nullptr;
	std::weak_ptr<Entity>* mychar_ptr_Player1_menuKeyboard = nullptr;
	std::weak_ptr<Entity>* mychar_ptr_Player2 = nullptr;
	std::weak_ptr<Entity>* mychar_ptr_Player2_menuKeyboard = nullptr;
	int* pCheckEventPlayerIndex = nullptr;
	std::list<std::shared_ptr<Entity>>* globalEntity = nullptr;
	std::unordered_map<MyMapLayer*, EntityLayer> loadedEntity;
	std::unordered_map<wchar_t, MyFontData> fontMap;
	TTF_Font* myfont14 = nullptr;
	std::unordered_map<wchar_t, MyFontData> fontMap_myfont14;
	std::unordered_map<std::wstring, std::vector<GroupByDraw>> groupByDraw;
	//线条绘制
	std::vector<MyDX11PenVertex> lineList;
	std::vector<MyDX11PenVertex> fillList;
	EntityLayer* GetEntityLayer(MyMapLayer* pLayer);
	std::weak_ptr<Entity> LoadEntity(const EntityLoad* el, MapLayer* mapLayer, EntityLayer* entityLayer);
	void DrawAddEntityCbRect(std::weak_ptr<Entity> e, DWORD c);
	void DrawEntityEventName(std::weak_ptr<Entity> e);
	//着色器
	std::unordered_map<std::wstring, ID3D11VertexShader*> loadedVertexShader;//载入的顶点着色器
	std::unordered_map<std::wstring, ID3D11PixelShader*> loadedPixelShader;//载入的像素着色器
	//实体预渲染
	ExTextureBuffer preTexture;
	ID3D11Texture2D* GetPreTexture(UINT w, UINT h);
	//光线实体
	std::vector<std::weak_ptr<Entity>> lightList;//光线实体
	//碰撞优化
	void GridItemTarget(std::shared_ptr<Entity>& we);
	bool GridAmTarget(std::shared_ptr<Entity>& we);
	//设置实体预处理表
	std::unordered_map<std::wstring, EntityLoad> elTable;
	//寻路系统
	std::unordered_map<EntityLayer*, Pathfinding> pfSys;
	PathGrid* lastPathGrid = nullptr;
	//星星砖
	std::wstring starblock_smokeNpcName;
	int starblock_setnum = 4;
	std::wstring starblock_breakSoundName;
};
