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

#ifndef __GameScreen_H__
#define __GameScreen_H__

typedef struct GameScreen GameScreen;
#define GameScreen_superclass Screen

#include "gamepad/Gamepad.h"
#include "screenmanager/Screen.h"
#include "uitoolkit/UIContainer.h"

#define GameScreen_ivars \
	Screen_ivars \
	\
	UIContainer * rootContainer; \
	RenderLayer * renderLayer; \
	Vector2f lastMousePosition; \
	bool active; \
	bool backgrounded;

#define GameScreen_vtable(self_type) \
	Screen_vtable(self_type) \
	\
	void (* update)(self_type * self, double deltaTime); \
	void (* resized)(self_type * self); \
	bool (* mouseDown)(self_type * self, unsigned int buttonNumber, unsigned int buttonMask, float x, float y, unsigned int modifiers, double timestamp); \
	bool (* mouseUp)(self_type * self, unsigned int buttonNumber, unsigned int buttonMask, float x, float y, unsigned int modifiers, double timestamp); \
	bool (* mouseMoved)(self_type * self, float x, float y, float deltaX, float deltaY, unsigned int modifiers, double timestamp); \
	bool (* mouseDragged)(self_type * self, unsigned int buttonMask, float x, float y, float deltaX, float deltaY, unsigned int modifiers, double timestamp); \
	bool (* mouseLeave)(self_type * self, unsigned int modifiers, double timestamp); \
	bool (* scrollWheel)(self_type * self, float x, float y, int deltaX, int deltaY, unsigned int buttonMask, unsigned int modifiers, double timestamp); \
	bool (* keyDown)(self_type * self, unsigned int charCode, unsigned int keyCode, unsigned int modifiers, bool isRepeat, double timestamp); \
	bool (* keyUp)(self_type * self, unsigned int keyCode, unsigned int modifiers, double timestamp); \
	bool (* keyModifiersChanged)(self_type * self, unsigned int modifiers, unsigned int lastModifiers, double timestamp); \
	bool (* gamepadAxisMoved)(self_type * self, struct Gamepad_device * device, unsigned int axisID, float value, float lastValue, double timestamp); \
	bool (* gamepadButtonDown)(self_type * self, struct Gamepad_device * device, unsigned int buttonID, double timestamp); \
	bool (* gamepadButtonUp)(self_type * self, struct Gamepad_device * device, unsigned int buttonID, double timestamp); \
	bool (* gamepadAttached)(self_type * self, struct Gamepad_device * device); \
	bool (* gamepadDetached)(self_type * self, struct Gamepad_device * device); \
	bool (* needsRedraw)(self_type * self); \
	void (* listRenderables)(self_type * self, RenderableIO * renderableIO, int drawOrderOffset, Rect4i clipBounds);

stemobject_declare(GameScreen)

GameScreen * GameScreen_create(void);
bool GameScreen_init(GameScreen * self);
void GameScreen_dispose(GameScreen * self);

void GameScreen_update(GameScreen * self, double deltaTime);
void GameScreen_resized(GameScreen * self);
bool GameScreen_mouseDown(GameScreen * self, unsigned int buttonNumber, unsigned int buttonMask, float x, float y, unsigned int modifiers, double timestamp);
bool GameScreen_mouseUp(GameScreen * self, unsigned int buttonNumber, unsigned int buttonMask, float x, float y, unsigned int modifiers, double timestamp);
bool GameScreen_mouseMoved(GameScreen * self, float x, float y, float deltaX, float deltaY, unsigned int modifiers, double timestamp);
bool GameScreen_mouseDragged(GameScreen * self, unsigned int buttonMask, float x, float y, float deltaX, float deltaY, unsigned int modifiers, double timestamp);
bool GameScreen_mouseLeave(GameScreen * self, unsigned int modifiers, double timestamp);
bool GameScreen_scrollWheel(GameScreen * self, float x, float y, int deltaX, int deltaY, unsigned int buttonMask, unsigned int modifiers, double timestamp);
bool GameScreen_keyDown(GameScreen * self, unsigned int charCode, unsigned int keyCode, unsigned int modifiers, bool isRepeat, double timestamp);
bool GameScreen_keyUp(GameScreen * self, unsigned int keyCode, unsigned int modifiers, double timestamp);
bool GameScreen_keyModifiersChanged(GameScreen * self, unsigned int modifiers, unsigned int lastModifiers, double timestamp);
bool GameScreen_gamepadAxisMoved(GameScreen * self, struct Gamepad_device * device, unsigned int axisID, float value, float lastValue, double timestamp);
bool GameScreen_gamepadButtonDown(GameScreen * self, struct Gamepad_device * device, unsigned int buttonID, double timestamp);
bool GameScreen_gamepadButtonUp(GameScreen * self, struct Gamepad_device * device, unsigned int buttonID, double timestamp);
bool GameScreen_gamepadAttached(GameScreen * self, struct Gamepad_device * device);
bool GameScreen_gamepadDetached(GameScreen * self, struct Gamepad_device * device);
bool GameScreen_needsRedraw(GameScreen * self);
void GameScreen_listRenderables(GameScreen * self, RenderableIO * renderableIO, int drawOrderOffset, Rect4i clipBounds);
void GameScreen_activate(GameScreen * self, Screen * lastScreen, const char * transitionName);
void GameScreen_deactivate(GameScreen * self, Screen * lastScreen, const char * transitionName);

#endif
