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

#ifndef __GameView_H__
#define __GameView_H__

typedef struct GameView GameView;
#define GameView_superclass StemObject

#include "gamemath/Vector2f.h"
#include "renderer/Renderable.h"
#include "renderer/RenderableIO.h"
#include "stemobject/StemObject.h"
#include "PROJECT_NAME/GameState.h"
#include "PROJECT_NAME/RoomTransition.h"
#include "PROJECT_NAME/RoomVisual.h"
#include "PROJECT_NAME/ShaderConfigurationRoom.h"
#include "PROJECT_NAME/VisualEffect.h"
#include "tileset/TileMapVisual.h"
#include "utilities/HashTable.h"

#define GameView_ivars \
	StemObject_ivars \
	\
	GameState * gameState; \
	unsigned int visualEffectCount; \
	unsigned int visualEffectAllocatedCount; \
	VisualEffect ** visualEffects; \
	ShaderConfigurationRoom * roomShaderConfiguration; \
	Renderable * roomRenderable; \
	Renderable * entityRenderable; \
	Renderable * visualEffectRenderable; \
	RoomVisual * roomVisual; \
	RoomTransition * roomTransition; \
	unsigned int previousRoomIndex; \
	VertexBuffer * roomVertexBuffer; \
	double screenShakeTime; \
	double screenShakeMaxTime; \
	float screenShakeRadius; \
	Vector2f screenShakeOffset; \
	Vector2f roomCameraPosition; \
	double animationReferenceTime; \
	double turnInterpolationRemainingTime; \
	Vector2i mouseoverTile;

#define GameView_vtable(self_type) \
	StemObject_vtable(self_type)

stemobject_declare(GameView)

GameView * GameView_create(GameState * gameState);
bool GameView_init(GameView * self, GameState * gameState);
void GameView_dispose(GameView * self);
void GameView_update(GameView * self, double deltaTime);
void GameView_listRenderables(GameView * self, RenderableIO * renderableIO, int drawOrderOffset, Rect4i clipBounds);
void GameView_beginRoomTransition(GameView * self, unsigned int fromRoomIndex);
bool GameView_mouseMoved(GameView * self, float x, float y, float deltaX, float deltaY, unsigned int modifiers, double referenceTime);
void GameView_hideMouseover(GameView * self);

// Takes ownership of visualEffect
void GameView_addVisualEffect(GameView * self, compat_type(VisualEffect *) visualEffect);
void GameView_shakeScreen(GameView * self, double duration, float radius);
Vector2f GameView_getPlayerScreenPosition(GameView * self);
Rect4f GameView_getVisibleScreenBounds(GameView * self);

#endif
