#pragma once
#ifndef _IMGUI_MANAGER_H_
#define _IMGUI_MANAGER_H_

#include "Logger.h"
#include "sceneManager.h"
#include "fps_limiter.h"

#include <imgui.h>
#include <imgui_impl_dx11.h>
#include <imgui_impl_win32.h>
#include <windows.h>
#include <deque>
#include <functional>

#include "render_texture_class.h"
#include "scene_manager.h"

class application_class;

struct widget_entry
{
	bool* show;
	std::function<void()> func;
};

class imguiManager
{
public:
	imguiManager();
	~imguiManager();

	bool Initialize(HWND hwnd, ID3D11Device* device, ID3D11DeviceContext* deviceContext);
	void Shutdown();
	void Render();
	void NewFrame();
	void SetupDockspace();

	// Widgets
	void WidgetSpeedSlider(float* speed);
	void WidgetButton();
	void WidgetFPS();
	void WidgetAddObject();

	void WidgetObjectWindow();
	void WidgetTerrainWindow();
	void WidgetLightWindow();
	void WidgetEngineSettingsWindow();
	void WidgetRenderWindow(ImVec2 availableSize);
	void WidgetLogWindow();
	void WidgetRenderStats();

	bool ImGuiWidgetRenderer();

	void SetWindowSize(ImVec2 size) { windowSize = size; }
	ImVec2 GetWindowSize() const { return windowSize; }

	// Getters
	void SetApp(application_class* app) { app_ = app; }

	// Shader toggles

	bool m_EnableCelShading;

private:

	// --------------------------------------------- //
	// ----------------- Functions ----------------- //
	// --------------------------------------------- //

	// --------------------------------------------- //
	// ----------------- Variables ----------------- //
	// --------------------------------------------- //

	std::vector<widget_entry> widgets_;

	application_class* app_;
	scene_manager* scene_manager_;
	
	bool showObjectWindow;
	bool showTerrainWindow;
	bool showLightWindow;
	bool showOldSceneWindow;
	bool showEngineSettingsWindow;
	bool showLogWindow;
	bool showStatsWindow;

	int m_SideCount = 0;

	static const int FRAME_HISTORY_COUNT = 3600; // 1min secondes à 60 FPS
	float m_frameTimeHistory[FRAME_HISTORY_COUNT] = {};
	int m_frameTimeHistoryIndex = 0;

	bool m_isPhyiscsEnabled = false;
	bool m_isGravityEnabled = false;

	ImGuiIO* io;

	ID3D11Device* m_device;
	ID3D11DeviceContext* m_deviceContext;
	ImVec2 windowSize;

	render_texture_class* m_renderTexture;

	const std::deque<Logger::LogEntry>& logBuffer = Logger::Get().GetLogBuffer();

	int current_fps_, min_fps_, max_fps_, draw_calls_, total_vertex_count_, total_triangle_count_, visible_triangle_count_;
	float current_frame_time_, min_frame_time_, max_frame_time_ ;
};

#endif