#pragma once
#include <glm/vec2.hpp>
#include <vector>


#include "Graphics.h" // will also include glad or gles3 files as needed
#include "Surface.h"
#include "Objects.h"

struct ImFont; // we need this later for ImGui

class IGraphics;
class Input;




class App
{
public:
	App();
	App(const Input* const input, IGraphics* graphics);
	virtual ~App();
	void Start(); 
	const Input& GetInput() const;
	void Quit();
protected:
	void ProcessInput();

	virtual void Update(float /*gameDeltaTime*/) = 0; // becuase it is 0 an app must be inherited by a class which derives from App, and has these functions
	virtual void Render() = 0;
	virtual void PostRender() = 0;
	virtual void SetupGame() = 0;
	
	const Input* const input;
	bool quitting{false}; // a flag to indicate the main loop has concluded and the app/game can be exited
	float gameDeltaTime;
	Graphics OurGraphics; // create a handy instance of our graphics functions
	IGraphics* graphics;

	// our app needs a few graphic things
	Pixel* TextureLocation = nullptr;  // this will be the location of our frame/back buffer where we keep the data we turn into a texture
	GLuint FrameBufferID = -1; // our frame/back buffer when we make a texture it needs an ID
	Surface* mScreen = nullptr; // this will be the screen surface we draw too.
	uint32_t scr_width, scr_height; // keep track of the height and withd of the screen

	int DrawRectangle(GLuint FrameBufferID);

// our app needs some objects to draw
	std::vector<Objects*> MyObjects; // we will store these objects when we make them


	Surface* m_Screen; // the screenbuffer we plan to write to and turn into a texture for display
	void InitializeOpenGLES(); // sets up the open gl for either target
	void ClearScreen(); // clears the OGL screen and its depth field (could be removed)
	void Swap(); // does the actual trasnfer of the m_screen buffer to the texture for display

	int frameCount{0};

	GLuint PO = -1;
	GLuint textureId = -1;
	Graphics GraphicFunctions;
	GLuint samplerLoc = -1;

private:
};

