// Copyright (c) 2023 Alex Diener. All rights reserved.

#ifndef __RoomState_H__
#define __RoomState_H__

typedef struct RoomState RoomState;
#define RoomState_superclass StemObject

#include "stemobject/StemObject.h"
#include "PROJECT_NAME/EntityPlayer.h"
#include "PROJECT_NAME/GameData.h"
#include "PROJECT_NAME/GameEntity.h"
#include "PROJECT_NAME/RoomSavedState.h"
#include "PROJECT_NAME/SharedDefinitions.h"
#include "utilities/EventDispatcher.h"

// ATOM_event_entity_added: GameEntity *
// ATOM_event_entity_removed: GameEntity *

struct RoomState_entity {
	GameEntity * entity;
	bool owned;
};

typedef struct RoomStateUndoData {
	unsigned int entityCount;
	struct RoomState_entity * entities;
} RoomStateUndoData;

#define RoomState_ivars \
	StemObject_ivars \
	\
	EventDispatcher * eventDispatcher; \
	unsigned int roomID; \
	bool visited; \
	RoomData * roomData; \
	struct GameState * gameState; \
	unsigned int entityCount; \
	unsigned int private_ivar(entityAllocatedCount); \
	struct RoomState_entity * entities;

#define RoomState_vtable(self_type) \
	StemObject_vtable(self_type)

stemobject_declare(RoomState)

RoomState * RoomState_create(unsigned int roomID, RoomData * roomData, struct GameState * gameState, bool initEntities);
bool RoomState_init(RoomState * self, unsigned int roomID, RoomData * roomData, struct GameState * gameState, bool initEntities);
RoomState * RoomState_copy(RoomState * self);
void RoomState_dispose(RoomState * self);

void RoomState_entered(RoomState * self);
void RoomState_exited(RoomState * self);
void RoomState_advanceTurn(RoomState * self);
void RoomState_undoActionPerformed(RoomState * self);
void RoomState_addEntity(RoomState * self, compat_type(GameEntity *) entity, bool takeOwnership);
void RoomState_insertEntity(RoomState * self, unsigned int insertIndex, compat_type(GameEntity *) entity, bool takeOwnership);
void RoomState_removeEntity(RoomState * self, compat_type(GameEntity *) entity);
void RoomState_removeEntityAtIndex(RoomState * self, unsigned int entityIndex);
TilePropertyBits RoomState_getTilePropertiesAtPosition(RoomState * self, Vector2i position);
unsigned int RoomState_getEntityCountAtPosition(RoomState * self, Vector2i position);
GameEntity * RoomState_getEntityAtPositionAtIndex(RoomState * self, Vector2i position, unsigned int index);

RoomSavedState * RoomState_createSave(RoomState * self);
void RoomState_loadSavedState(RoomState * self, RoomSavedState * savedState);

RoomStateUndoData RoomState_createUndoData(RoomState * self);
void disposeRoomStateUndoData(RoomStateUndoData * undoData);

#endif
