#ifndef RENDER_HPP
#define RENDER_HPP
#include <core/inc.hpp>

extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam );

namespace render
{
	enum class setup_error_code
	{
		render_invalid_pid,
		render_invalid_common_error,
		render_invalid_window,
		render_invalid_d3d_failure,
		system_operational,
		render_overlay_failure
	};

	class c_render
	{
	public:
		MARGINS m_margin{ -1 };
		RECT m_rect{ };
		MSG m_msg{ };

		std::uint32_t m_pid{ };

		HWND window_target{ };
		HWND overlay{ };

		int width{ };
		int height{ };

		int width_center{ };
		int height_center{ };

		bool is_spoofed;

	public:
		IDirect3D9* p_object = NULL;
		IDirect3DDevice9* p_device = NULL;
		D3DPRESENT_PARAMETERS p_params = { NULL };


		[[nodiscard]] setup_error_code setup( const std::wstring& proc_name );

		HWND get_window_handle( std::uint32_t pid );

		bool get_screen_status( );
		bool get_window( );

		void tick( );

		void end_scene( );
		void begin_scene( );

	public:
		void update_cursor( )
		{
			ImGuiIO& io = ImGui::GetIO( );
			io.MouseDown[ 0 ] = GetAsyncKeyState( VK_LBUTTON ) & 0x8000;
			io.MouseDown[ 1 ] = GetAsyncKeyState( VK_RBUTTON ) & 0x8000;
			io.MouseDown[ 2 ] = GetAsyncKeyState( VK_MBUTTON ) & 0x8000;
			io.MouseDown[ 3 ] = GetAsyncKeyState( VK_XBUTTON1 ) & 0x8000;
			io.MouseDown[ 4 ] = GetAsyncKeyState( VK_XBUTTON2 ) & 0x8000;
			io.KeysDown[ VK_BACK ] = ( GetAsyncKeyState( VK_BACK ) & 0x8000 ) != 0;
			io.KeyMap[ ImGuiKey_Backspace ] = VK_BACK;

			POINT cursorPos;
			GetCursorPos( &cursorPos );
			ScreenToClient( overlay, &cursorPos );
			io.MousePos = ImVec2( static_cast< float >( cursorPos.x ), static_cast< float >( cursorPos.y ) );

			for ( int i = 0; i < ImGuiKey_COUNT; i++ )
			{
				if ( GetAsyncKeyState( i ) & 1 )
				{
					io.KeysDown[ i ] = true;
					io.AddInputCharacter( static_cast< ImWchar >( i ) );
				}
			}

			SHORT wheelDelta = GetKeyState( VK_SCROLL );
			if ( wheelDelta & 0x8000 )
			{
				io.MouseWheel += 1.0f;  
			}
			else if ( wheelDelta & 0x1000 )
			{
				io.MouseWheel -= 1.0f; 
			}
		}
	};
} inline std::shared_ptr<render::c_render> g_render = std::make_shared<render::c_render>( );

#endif // ! guard