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

#define _USE_MATH_DEFINES
#include <math.h>

#define BOG_TO_GRD( BOG ) ( ( 180 / M_PI ) * BOG );
#define GRD_TO_BOG( GRD ) ( ( M_PI / 180 ) * GRD );

auto cheat_interface::c_visual::render_indicators( ) -> void
{
	try {

		auto theme = ImColor(
			252, 72, 72
		);

		auto center_padding = 10.00f;
	
		icons_data::icon_data_map data = g_icons->get_icon_data( g_vars->name.branding );

		ImVec2 top_left( 10.0f, 10.f );
		ImVec2 bottom_right( top_left.x + data.icon_size.x, top_left.y + data.icon_size.y );

		if ( data.texture )
			g_framework->add_image(
				data.texture,
				top_left,
				bottom_right,
				ImColor( 255, 0, 0, 128 )
			);
		
		if ( g_vars->misc.fps )
		{
			std::string fps = std::to_string( static_cast< int >( ImGui::GetIO( ).Framerate ) ) + hash_str( " FPS" );

			auto game_padding = 5.00f;

			ImVec2 fps_size = ImGui::CalcTextSize( fps.c_str( ) );
			ImVec2 fps_pos( 10, g_render->height - fps_size.y - game_padding );

			ImColor color = static_cast< int >( ImGui::GetIO( ).Framerate ) < 60 ? ImColor( 255, 0, 0 ) : ImColor( 255, 255, 255 );

			g_framework->text(
				fps.c_str( ),
				fps_pos,
				color,
				g_vars->font.size,
				g_framework->esp_font
			);
		}

		if ( g_vars->misc.fov )
		{
			g_framework->circle(
				g_render->width_center, g_render->height_center,
				( g_vars->aim.fov_c / g_engine->field_of_view ) * 90,
				ImColor( g_vars->colors.fov_color [ 0 ], g_vars->colors.fov_color [ 1 ], g_vars->colors.fov_color [ 2 ], g_vars->colors.fov_color [ 3 ] ),
				1.50f
			);
		}

		if ( g_vars->misc.crosshair )
		{
			ImVec2 center = ImVec2( g_render->width_center, g_render->height_center );

			ImColor crosshair_color = ImColor( g_vars->colors.crosshair_color [ 0 ], g_vars->colors.crosshair_color [ 1 ], g_vars->colors.crosshair_color [ 2 ] );
			ImColor crosshair_outline = ImColor( 0, 0, 0 );

			auto length = g_vars->crosshair.length;
			auto thickness = g_vars->crosshair.thickness;
			auto gap = g_vars->crosshair.gap;
			auto outline = g_vars->crosshair.outline;

			if ( g_vars->misc.aqua_is_not_going_to_be_happy == 69 )
			{
				static float rotation = 0.0f;
				float speed = 3.0f;

				rotation += speed * ImGui::GetIO( ).DeltaTime;
				if ( rotation > 2 * M_PI ) {
					rotation -= 2 * M_PI;
				}

				float size = length;

				ImVec2 points[ 4 ] = {
					ImVec2( center.x + cosf( rotation ) * size, center.y + sinf( rotation ) * size ),
					ImVec2( center.x - cosf( rotation ) * size, center.y - sinf( rotation ) * size ),
					ImVec2( center.x + sinf( rotation ) * size, center.y - cosf( rotation ) * size ),
					ImVec2( center.x - sinf( rotation ) * size, center.y + cosf( rotation ) * size )
				};

				ImVec2 haken[ 4 ] = {
					ImVec2( points[ 2 ].x + size, points[ 2 ].y ),
					ImVec2( points[ 0 ].x, points[ 0 ].y + size ),
					ImVec2( points[ 3 ].x - size, points[ 3 ].y ),
					ImVec2( points[ 1 ].x, points[ 1 ].y - size )
				};

				g_framework->line( points[ 1 ], points[ 0 ], crosshair_color, thickness );
				g_framework->line( points[ 2 ], points[ 3 ], crosshair_color, thickness );
				g_framework->line( points[ 2 ], haken[ 0 ], crosshair_color, thickness );
				g_framework->line( points[ 0 ], haken[ 1 ], crosshair_color, thickness );
				g_framework->line( points[ 3 ], haken[ 2 ], crosshair_color, thickness );
				g_framework->line( points[ 1 ], haken[ 3 ], crosshair_color, thickness );
			}
			else if ( g_vars->misc.selected_crosshair == 0 )
			{
				ImVec2 h_start_left( center.x - gap - length, center.y );
				ImVec2 h_end_left( center.x - gap, center.y );
				ImVec2 h_start_right( center.x + gap, center.y );
				ImVec2 h_end_right( center.x + gap + length, center.y );

				ImVec2 v_start_top( center.x, center.y - gap - length );
				ImVec2 v_end_top( center.x, center.y - gap );
				ImVec2 v_start_bottom( center.x, center.y + gap );
				ImVec2 v_end_bottom( center.x, center.y + gap + length );

				if ( outline > 0 ) {
					auto outline_thickness = thickness + 2 * outline;

					g_framework->line( ImVec2( h_start_left.x - outline, h_start_left.y ), ImVec2( h_end_left.x + outline, h_end_left.y ), crosshair_outline, outline_thickness );
					g_framework->line( ImVec2( h_start_right.x - outline, h_start_right.y ), ImVec2( h_end_right.x + outline, h_end_right.y ), crosshair_outline, outline_thickness );

					g_framework->line( ImVec2( v_start_top.x, v_start_top.y - outline ), ImVec2( v_end_top.x, v_end_top.y + outline ), crosshair_outline, outline_thickness );
					g_framework->line( ImVec2( v_start_bottom.x, v_start_bottom.y - outline ), ImVec2( v_end_bottom.x, v_end_bottom.y + outline ), crosshair_outline, outline_thickness );
				}

				g_framework->line( h_start_left, h_end_left, crosshair_color, thickness );
				g_framework->line( h_start_right, h_end_right, crosshair_color, thickness );
				g_framework->line( v_start_top, v_end_top, crosshair_color, thickness );
				g_framework->line( v_start_bottom, v_end_bottom, crosshair_color, thickness );
			}
			else if ( g_vars->misc.selected_crosshair == 1 )
			{
				auto filled = g_vars->crosshair.circle_filled;
				auto radius = thickness / 2;
				auto outline_thickness = thickness + 2 * outline;

				if ( g_vars->crosshair.outline > 0 )
					g_framework->circle( center.x, center.y, radius + outline_thickness, crosshair_outline, outline_thickness, filled );

				g_framework->circle( center.x, center.y, radius, crosshair_color, thickness, filled );
			}
			else if ( g_vars->misc.selected_crosshair == 2 )
			{
				auto speed = 2.00f;

				g_vars->crosshair.rotation += speed * ImGui::GetIO( ).DeltaTime;
				if ( g_vars->crosshair.rotation > 2 * M_PI ) {
					g_vars->crosshair.rotation -= 2 * M_PI;
				}

				ImVec2 points [ 3 ];
				for ( int i = 0; i < 3; i++ ) {
					float angle = g_vars->crosshair.rotation + ( i * 2 * M_PI / 3 );
					points [ i ] = ImVec2(
						center.x + cosf( angle ) * length,
						center.y + sinf( angle ) * length
					);
				}

				for ( int i = 0; i < 3; i++ )
				{
					g_framework->line(
						center,
						points [ i ],
						crosshair_color,
						thickness
					);
				}
			}
		}

		if ( g_vars->weapon_config.enable )
		{
			auto ctx = prediction::prediction_context();
			ctx.animation_type = g_ctx->localplayer.animation_type;

			if ( g_prediction->is_rifle( ctx ) && g_vars->weapon_config.ars.enabled )
			{
				g_vars->aim.fov_c = g_vars->weapon_config.ars.weapon_fov;
				g_vars->aim.smooth = g_vars->weapon_config.ars.smooth;
				g_vars->aim.target_bone = g_vars->weapon_config.ars.target_bone;
			}

			else if ( g_prediction->is_shotgun( ctx ) && g_vars->weapon_config.shotgun.enabled )
			{
				g_vars->aim.fov_c = g_vars->weapon_config.shotgun.weapon_fov;
				g_vars->aim.smooth = g_vars->weapon_config.shotgun.smooth;
				g_vars->aim.target_bone = g_vars->weapon_config.shotgun.target_bone;
			}

			else if ( g_prediction->is_smg( ctx ) && g_vars->weapon_config.smg.enabled )
			{
				g_vars->aim.fov_c = g_vars->weapon_config.smg.weapon_fov;
				g_vars->aim.smooth = g_vars->weapon_config.smg.smooth;
				g_vars->aim.target_bone = g_vars->weapon_config.smg.target_bone;
			}

			else if ( g_prediction->is_pistol( ctx ) && g_vars->weapon_config.pistol.enabled )
			{
				g_vars->aim.fov_c = g_vars->weapon_config.pistol.weapon_fov;
				g_vars->aim.smooth = g_vars->weapon_config.pistol.smooth;
				g_vars->aim.target_bone = g_vars->weapon_config.pistol.target_bone;
			}

			else if ( g_prediction->is_sniper( ctx ) && g_vars->weapon_config.snipers.enabled )
			{
				g_vars->aim.fov_c = g_vars->weapon_config.snipers.weapon_fov;
				g_vars->aim.smooth = g_vars->weapon_config.snipers.smooth;
				g_vars->aim.target_bone = g_vars->weapon_config.snipers.target_bone;
			}
		}

		if ( g_vars->visuals.radar )
		{
			math::vector2 mouse_position = g_engine->get_cursor( );
			bool left_mouse_down = ( GetAsyncKeyState( VK_LBUTTON ) & 0x8000 );

			bool is_hovered = g_engine->is_hovered( math::vector2( g_vars->radar.radar_width, g_vars->radar.radar_height ), math::vector2( g_vars->radar.radar_size, g_vars->radar.radar_size ) );

			if ( is_hovered && left_mouse_down )
			{
				if ( g_vars->misc.menu )
				{
					g_vars->radar.radar_width = mouse_position.x - g_vars->radar.radar_size / 2;
					g_vars->radar.radar_height = mouse_position.y - g_vars->radar.radar_size / 2;
				}
			}

			ImVec2 center(
				g_vars->radar.radar_width + g_vars->radar.radar_size / 2,
				g_vars->radar.radar_height + g_vars->radar.radar_size / 2
			);

			auto radius = g_vars->radar.radar_size / 2.0f;

			ImGui::GetBackgroundDrawList( )->AddCircleFilled(
				center,
				radius,
				ImColor( 0, 0, 0, static_cast< int >( g_vars->radar.radar_solid_fill_opacity * 255.f ) )
			);

			ImGui::GetBackgroundDrawList( )->AddCircle(
				center,
				radius,
				ImColor( 0, 0, 0, static_cast< int >( g_vars->radar.radar_match_outline_opacity * 255.f ) ),
				0,
				1.5f
			);

			ImGui::GetBackgroundDrawList( )->AddCircle(
				center,
				radius,
				ImColor( g_vars->radar.radar_match_color [ 0 ], g_vars->radar.radar_match_color [ 1 ], g_vars->radar.radar_match_color [ 2 ], g_vars->radar.radar_match_opacity )
			);

			if ( g_vars->radar.radar_lines )
			{
				auto LINE_FADE_LENGTH = g_vars->radar.radar_match_fade_out;
				auto LINE_SIZE = g_vars->radar.radar_match_size;

				auto TICK_SPACING = 15.0f;
				auto TICK_LENGTH = 4.0f;

				for ( float x = 0; x <= radius; x += 1.0f ) {

					auto alpha = 1.0f;
					if ( x > radius * ( 1.0f - LINE_FADE_LENGTH ) ) {
						alpha = ( radius - x ) / ( radius * LINE_FADE_LENGTH );
					}

					ImColor lineColor = ImColor( g_vars->radar.lines_color [ 0 ], g_vars->radar.lines_color [ 1 ], g_vars->radar.lines_color [ 2 ], ( float ) ( 255 * alpha ) );

					ImGui::GetBackgroundDrawList( )->AddLine(
						ImVec2( center.x - x, center.y ),
						ImVec2( center.x - x - 1, center.y ),
						lineColor,
						LINE_SIZE
					);
					ImGui::GetBackgroundDrawList( )->AddLine(
						ImVec2( center.x + x, center.y ),
						ImVec2( center.x + x + 1, center.y ),
						lineColor,
						LINE_SIZE
					);

					if ( fmod( x, TICK_SPACING ) < 1.0f && x < radius * 0.9f ) {
						ImGui::GetBackgroundDrawList( )->AddLine(
							ImVec2( center.x + x, center.y - TICK_LENGTH ),
							ImVec2( center.x + x, center.y + TICK_LENGTH ),
							lineColor,
							LINE_SIZE
						);
						ImGui::GetBackgroundDrawList( )->AddLine(
							ImVec2( center.x - x, center.y - TICK_LENGTH ),
							ImVec2( center.x - x, center.y + TICK_LENGTH ),
							lineColor,
							LINE_SIZE
						);
					}
				}

				for ( float y = 0; y <= radius; y += 1.0f ) {

					auto alpha = 1.0f;
					if ( y > radius * ( 1.0f - LINE_FADE_LENGTH ) ) {
						alpha = ( radius - y ) / ( radius * LINE_FADE_LENGTH );
					}

					ImColor lineColor = ImColor( g_vars->radar.lines_color [ 0 ], g_vars->radar.lines_color [ 1 ], g_vars->radar.lines_color [ 2 ], ( float ) ( 255 * alpha ) );

					ImGui::GetBackgroundDrawList( )->AddLine(
						ImVec2( center.x, center.y - y ),
						ImVec2( center.x, center.y - y - 1 ),
						lineColor,
						LINE_SIZE
					);
					ImGui::GetBackgroundDrawList( )->AddLine(
						ImVec2( center.x, center.y + y ),
						ImVec2( center.x, center.y + y + 1 ),
						lineColor,
						LINE_SIZE
					);

					if ( fmod( y, TICK_SPACING ) < 1.0f && y < radius * 0.9f ) {
						ImGui::GetBackgroundDrawList( )->AddLine(
							ImVec2( center.x - TICK_LENGTH, center.y + y ),
							ImVec2( center.x + TICK_LENGTH, center.y + y ),
							lineColor,
							LINE_SIZE
						);
						ImGui::GetBackgroundDrawList( )->AddLine(
							ImVec2( center.x - TICK_LENGTH, center.y - y ),
							ImVec2( center.x + TICK_LENGTH, center.y - y ),
							lineColor,
							LINE_SIZE
						);
					}
				}
			}

			if ( g_vars->radar.display_fov )
			{
				auto LINE_FADE_LENGTH = g_vars->radar.radar_fov_fade_out;
				auto LINE_SIZE = g_vars->radar.radar_fov_match_size;

				auto FOV_ANGLE = g_engine->field_of_view;
				std::clamp( FOV_ANGLE, 0.00f, 90.00f );

				auto FOV_LENGTH = 0.7f;

				auto fovRadians = ( FOV_ANGLE * M_PI / 180.0f ) / 2.0f;
				auto fovMaxDist = radius * FOV_LENGTH;

				ImVec2 fovPoints [ 3 ] = {
					center,
					ImVec2(
						center.x - sinf( fovRadians ) * fovMaxDist,
						center.y - cosf( fovRadians ) * fovMaxDist
					),
					ImVec2(
						center.x + sinf( fovRadians ) * fovMaxDist,
						center.y - cosf( fovRadians ) * fovMaxDist
					)
				};

				ImGui::GetBackgroundDrawList( )->AddTriangleFilled(
					fovPoints [ 0 ],
					fovPoints [ 1 ],
					fovPoints [ 2 ],
					ImColor( 0, 0, 0, static_cast< int >( g_vars->radar.radar_fov_opacity * 255.f ) )
				);

				for ( float dist = 0; dist <= fovMaxDist; dist += 1.0f ) {

					auto alpha = 1.0f;
					if ( dist > fovMaxDist * ( 1.0f - LINE_FADE_LENGTH ) ) {
						alpha = ( fovMaxDist - dist ) / ( fovMaxDist * LINE_FADE_LENGTH );
					}

					ImColor fovColor = ImColor( g_vars->radar.fov_color [ 0 ], g_vars->radar.fov_color [ 1 ], g_vars->radar.fov_color [ 2 ], ( float ) ( 255 * alpha ) );

					auto x = dist * sin( fovRadians );
					auto y = -dist * cos( fovRadians );

					ImGui::GetBackgroundDrawList( )->AddLine(
						ImVec2( center.x - x, center.y + y ),
						ImVec2( center.x - x - 1, center.y + y - 1 ),
						fovColor,
						LINE_SIZE
					);
					ImGui::GetBackgroundDrawList( )->AddLine(
						ImVec2( center.x + x, center.y + y ),
						ImVec2( center.x + x + 1, center.y + y - 1 ),
						fovColor,
						LINE_SIZE
					);
				}
			}

			auto ARROW_SIZE = 8.0f;

			ImVec2 arrowPoints [ 3 ] = {
				ImVec2( center.x, center.y - ARROW_SIZE ),
				ImVec2( center.x - ARROW_SIZE / 2, center.y ),
				ImVec2( center.x + ARROW_SIZE / 2, center.y )
			};

			ImGui::GetBackgroundDrawList( )->AddTriangle(
				arrowPoints [ 0 ],
				arrowPoints [ 1 ],
				arrowPoints [ 2 ],
				ImColor( 0, 0, 0 ),
				4.0f
			);

			ImGui::GetBackgroundDrawList( )->AddTriangleFilled(
				arrowPoints [ 0 ],
				arrowPoints [ 1 ],
				arrowPoints [ 2 ],
				ImColor( 255, 255, 255 )
			);
		}

		if ( g_vars->visuals.targetline )
		{
			object::c_closest closest_player = g_aimbot->closest_actor;

			if ( closest_player.m_mesh && closest_player.crosshair_space < ( g_vars->aim.fov_c / g_engine->field_of_view ) * 90 ) {

				g_framework->line(
					ImVec2( g_engine->width_center, g_engine->height_center ),
					ImVec2( closest_player.m_head_screen.x, closest_player.m_head_screen.y ),
					ImColor( g_vars->colors.targetline_color [ 0 ], g_vars->colors.targetline_color [ 1 ], g_vars->colors.targetline_color [ 2 ] ),
					1.5f
				);
			}
		}

		if ( g_vars->visuals.show_target )
		{
			object::c_closest closest_player = g_aimbot->closest_actor;

			if ( closest_player.m_mesh && closest_player.crosshair_space < ( g_vars->aim.fov_c / g_engine->field_of_view ) * 90 ) {

				std::string target = hash_str( "Targeting " ) + ( !closest_player.m_username.empty( ) ? closest_player.m_username : hash_str( "usernmae" ) );

				ImVec2 text_size = ImGui::CalcTextSize(
					target.c_str( )
				);

				float center_padding = 10.00f;

				ImVec2 center = ImVec2( g_engine->width_center, g_engine->height_center );
				ImVec2 text_position( center.x - ( text_size.x / 2 ), ( center.y + center_padding ) );

				g_framework->text(
					target,
					text_position,
					ImColor( g_vars->colors.targeted_color [ 0 ], g_vars->colors.targeted_color [ 1 ], g_vars->colors.targeted_color [ 2 ] ),
					g_vars->font.size,
					g_framework->esp_font
				);
			}
		}

		if ( g_vars->aim.prediction_indicator )
		{
			object::c_closest closest_player = g_aimbot->closest_actor;

			if ( closest_player.m_mesh && closest_player.crosshair_space < ( g_vars->aim.fov_c / g_engine->field_of_view ) * 90 ) {

				g_framework->text(
					hash_str( "X" ),
					ImVec2( g_aimbot->predicted_ctx.x, g_aimbot->predicted_ctx.y ),
					ImColor( g_vars->colors.prediction_color [ 0 ], g_vars->colors.prediction_color [ 1 ], g_vars->colors.prediction_color [ 2 ] ),
					g_vars->font.size,
					g_framework->esp_font
				);
			}
		}

		if ( g_vars->misc.show_keybinds )
		{
			std::vector<keybinds::Key> keybinds;

			g_keybinds->AddKeybind( keybinds, g_vars->aim.enabled&& GetAsyncKeyState( g_vars->aim.aim_keycode ), hash_str( "aim assist" ), false, true );
			g_keybinds->AddKeybind( keybinds, g_vars->aim.enabled&& GetAsyncKeyState( g_vars->aim.second_aim_keycode ), hash_str( "aim assist #2" ), false, true );
			g_keybinds->AddKeybind( keybinds, g_vars->trigger.triggerbot&& GetAsyncKeyState( g_vars->trigger.trigger_keycode ), hash_str( "triggerbot" ), false, true );

			if ( g_vars->misc.keybinds == 0 )
			{
				ImVec2 draw_position = g_vars->moveable.keybinds_position;

				ImVec2 rect_size = ImVec2( 200, 4 );
				auto background_size = 20.00f;

				ImVec2 top_left_rect = ImVec2( draw_position.x - rect_size.x / 2, draw_position.y );
				ImVec2 bottom_right_rect = ImVec2( draw_position.x + rect_size.x / 2, draw_position.y + rect_size.y );

				g_framework->filled_rect( top_left_rect.x, top_left_rect.y, bottom_right_rect.x, bottom_right_rect.y, theme );

				g_framework->filled_rect( top_left_rect.x, bottom_right_rect.y, top_left_rect.x + rect_size.x, bottom_right_rect.y + background_size, ImColor( 0, 0, 0, ( 0.3 * 255 ) ) );

				std::string text = hash_str( "keybinds" );
				ImVec2 text_size = ImGui::CalcTextSize( text.c_str( ) );

				ImVec2 text_pos = ImVec2( top_left_rect.x + ( rect_size.x / 2 ) - ( text_size.x / 2 ), bottom_right_rect.y + ( background_size / 2 ) - ( text_size.y / 2 ) );
				g_framework->text( text, text_pos, ImColor( 255, 255, 255 ), g_vars->font.size, g_framework->esp_font, true );

				this->handle_drag( g_vars->moveable.keybinds_position, top_left_rect, ImVec2( rect_size.x, rect_size.y + background_size ), g_vars->misc.menu, KeybindsDragState );

				auto padding_t = 5.00f;
				auto offset_y = background_size + padding_t;

				for ( const auto& bind : keybinds ) {

					std::string keybind_text = bind.Name;
					std::string status = bind.Toggled ? hash_str( "[toggled]" ) : ( bind.Holding ? hash_str( "[holding]" ) : hash_str( "[off]" ) );

					ImVec2 keybind_text_size = ImGui::CalcTextSize( keybind_text.c_str( ) );
					ImVec2 keybind_text_pos = ImVec2( top_left_rect.x + padding_t, bottom_right_rect.y + offset_y );

					g_framework->text( keybind_text, keybind_text_pos, ImColor( 255, 255, 255 ), g_vars->font.size, g_framework->esp_font, true );

					ImVec2 keybind_status_size = ImGui::CalcTextSize( status.c_str( ) );
					ImVec2 keybind_status_pos = ImVec2( top_left_rect.x + rect_size.x - keybind_status_size.x - padding_t, bottom_right_rect.y + offset_y );

					g_framework->text( status, keybind_status_pos, ImColor( 255, 255, 255 ), g_vars->font.size, g_framework->esp_font, true );

					offset_y += keybind_text_size.y + padding_t;
				}
			}
			else if ( g_vars->misc.keybinds == 1 )
			{
				ImVec2 center = ImVec2( g_render->width_center, g_render->height_center );

				auto text_padding = 3.00f;

				for ( const auto& bind : keybinds ) {

					std::string keybind_text = bind.Name;
					std::string keybind_state = ( bind.Toggled ? hash_str( " [toggled]" ) : ( bind.Holding ? hash_str( " [holding]" ) : hash_str( " [off]" ) ) );

					ImVec2 keybind_text_size = ImGui::CalcTextSize( keybind_text.c_str( ) );
					ImVec2 keybind_state_size = ImGui::CalcTextSize( keybind_state.c_str( ) );

					float padding_state = 2.5f;

					ImVec2 keybind_text_pos = ImVec2( center.x - ( keybind_text_size.x / 2 + keybind_state_size.x / 2 + padding_state / 2 ), center.y + center_padding );
					ImVec2 keybind_state_pos = ImVec2( keybind_text_pos.x + keybind_text_size.x + padding_state, center.y + center_padding );

					g_framework->text( keybind_text, keybind_text_pos, ImColor( 255, 255, 255 ), g_vars->font.size, g_framework->esp_font );
					g_framework->text( keybind_state, keybind_state_pos, ImColor( 252, 72, 72 ), g_vars->font.size, g_framework->esp_font );

					center_padding += keybind_text_size.y + text_padding;
				}
			}
		}

		if ( g_vars->visuals.spectators )
		{
			auto do_spectators = [ & ] ( ) -> void
			{
				ImVec2 draw_position = g_vars->moveable.spectators_position;

				ImVec2 rect_size = ImVec2( 200, 4 );
				auto background_size = 20.00f;

				ImVec2 top_left_rect = ImVec2( draw_position.x - rect_size.x / 2, draw_position.y );
				ImVec2 bottom_right_rect = ImVec2( draw_position.x + rect_size.x / 2, draw_position.y + rect_size.y );

				g_framework->filled_rect( top_left_rect.x, top_left_rect.y, bottom_right_rect.x, bottom_right_rect.y, theme );

				g_framework->filled_rect( top_left_rect.x, bottom_right_rect.y, top_left_rect.x + rect_size.x, bottom_right_rect.y + background_size, ImColor( 0, 0, 0, ( 0.3 * 255 ) ) );

				std::string text = hash_str( "spectators" );
				ImVec2 text_size = ImGui::CalcTextSize( text.c_str( ) );

				ImVec2 text_pos = ImVec2( top_left_rect.x + ( rect_size.x / 2 ) - ( text_size.x / 2 ), bottom_right_rect.y + ( background_size / 2 ) - ( text_size.y / 2 ) );
				g_framework->text( text, text_pos, ImColor( 255, 255, 255 ), g_vars->font.size, g_framework->esp_font, true );

				this->handle_drag( g_vars->moveable.spectators_position, top_left_rect, ImVec2( rect_size.x, rect_size.y + background_size ), g_vars->misc.menu, SpectatorsDragState );

				auto padding_t = 5.00f;
				auto offset_y = background_size + padding_t;

				if ( g_ctx->size_spectators( ) < 1 ) return;

				for ( const auto& spectator : g_ctx->m_spectators ) {

					std::string username = spectator.name;
					std::string spectator_index = hash_str( "[" ) + std::to_string( spectator.index + 1 ) + hash_str( "]" );

					ImVec2 username_text_size = ImGui::CalcTextSize( username.c_str( ) );
					ImVec2 username_text_pos = ImVec2( top_left_rect.x + padding_t, bottom_right_rect.y + offset_y );

					g_framework->text( username, username_text_pos, ImColor( 255, 255, 255 ), g_vars->font.size, g_framework->esp_font, true );

					ImVec2 spectator_index_size = ImGui::CalcTextSize( spectator_index.c_str( ) );
					ImVec2 spectator_index_pos = ImVec2( top_left_rect.x + rect_size.x - spectator_index_size.x - padding_t, bottom_right_rect.y + offset_y );

					g_framework->text( spectator_index, spectator_index_pos, ImColor( 255, 255, 255 ), g_vars->font.size, g_framework->esp_font, true );

					offset_y += username_text_size.y + padding_t;
				}
			};

			do_spectators( );
		}
	}
	catch ( const std::exception& e ) {
		m_log->set_text_point( hash_str( "exception caught in entity render thread" ) );
		return;
	}
	catch ( ... ) {
		m_log->set_text_point( hash_str( "exception caught in entity render thread" ) );
		return;
	}
}

#endif