#ifndef _SYSTEMCLASS_H_
#define _SYSTEMCLASS_H_

#define WIN32_LEAN_AND_MEAN

#include "Logger.h"

#include "input_class.h"
#include "application_class.h"
#include "imguiManager.h"
#include <mutex>
#include <filesystem>
#include <commdlg.h>

#include "../resources.h"
#include <chrono>

// global variables 
inline bool DEBUG_MODE = false;

class system_class
{
public:
	system_class();
	system_class(const system_class&);
	~system_class();

	bool initialize();
	void shutdown();
	void run();

	LRESULT CALLBACK message_handler(HWND, UINT, WPARAM, LPARAM);

	void send_path(wchar_t* path, std::filesystem::path w_folder);

	std::shared_ptr<application_class> get_application_class() const { return application_; }
	void set_application_class(std::shared_ptr<application_class> application) { application_ = std::move(application); }

	std::shared_ptr<input_class> get_input_class() const { return input_; }
	void set_input(std::shared_ptr<input_class> input) { input_ = std::move(input); }

	HWND get_hwnd() const { return hwnd_; }

	void set_d_3D_mock(d_3d_class* mock) {application_->set_direct_3d(mock);}
	

protected:
	bool frame();
	void initialize_windows(int&, int&);
	void shutdown_windows();

private:
	LPCWSTR application_name_;
	HINSTANCE hinstance_;
	HWND hwnd_;

	std::shared_ptr<input_class> input_;
	std::shared_ptr<application_class> application_;
	std::shared_ptr<imguiManager> imgui_manager_;

	int initial_window_width_;
	int initial_window_height_;
	bool is_direct_3d_initialized_;
	bool is_resizing_ = false;
	bool is_debug_key_pressed_ = false;

	std::mutex render_mutex_;

	std::unique_ptr<fps_limiter> fps_limiter_ = std::make_unique<fps_limiter>(60);
	
};


/////////////////////////
// FUNCTION PROTOTYPES //
/////////////////////////
static LRESULT CALLBACK wnd_proc(HWND, UINT, WPARAM, LPARAM);


/////////////
// GLOBALS //
/////////////
static system_class* application_handle = 0;


#endif