#pragma once #include // for SDL_Event #include // for SDL_Renderer #include // for Uint64 #include // for SDL_Window #include // for array #include // for unique_ptr, shared_ptr #include // for string #include // for vector #include "ball.h" // for Ball #include "boids_mgr/boid_manager.h" // for BoidManager #include "defines.h" // for GravityDirection, ColorTheme, ShapeType #include "external/texture.h" // for Texture #include "input/input_handler.h" // for InputHandler #include "scene/scene_manager.h" // for SceneManager #include "shapes/shape.h" // for Shape (interfaz polimórfica) #include "shapes_mgr/shape_manager.h" // for ShapeManager #include "state/state_manager.h" // for StateManager #include "theme_manager.h" // for ThemeManager #include "ui/ui_manager.h" // for UIManager class Engine { public: // Interfaz pública principal bool initialize(int width = 0, int height = 0, int zoom = 0, bool fullscreen = false); void run(); void shutdown(); // === Métodos públicos para InputHandler === // Gravedad y física void pushBallsAwayFromGravity(); void handleGravityToggle(); void handleGravityDirectionChange(GravityDirection direction, const char* notification_text); // Display y depuración void toggleVSync(); void toggleDebug(); // Figuras 3D void toggleShapeMode(); void activateShape(ShapeType type, const char* notification_text); void handleShapeScaleChange(bool increase); void resetShapeScale(); void toggleDepthZoom(); // Boids (comportamiento de enjambre) void toggleBoidsMode(); // Temas de colores void cycleTheme(bool forward); void switchThemeByNumpad(int numpad_key); void toggleThemePage(); void pauseDynamicTheme(); // Sprites/Texturas void switchTexture(); // Escenarios (número de pelotas) void changeScenario(int scenario_id, const char* notification_text); // Zoom y fullscreen void handleZoomIn(); void handleZoomOut(); void toggleFullscreen(); void toggleRealFullscreen(); void toggleIntegerScaling(); // Modos de aplicación (DEMO/LOGO) void toggleDemoMode(); void toggleDemoLiteMode(); void toggleLogoMode(); // === Métodos públicos para StateManager (callbacks) === // NOTA: StateManager coordina estados, Engine proporciona implementación // Estos callbacks permiten que StateManager ejecute acciones complejas que // requieren acceso a múltiples componentes (SceneManager, ThemeManager, ShapeManager, etc.) // Este enfoque es pragmático y mantiene la separación de responsabilidades limpia void performLogoAction(bool logo_waiting_for_flip); void executeDemoAction(bool is_lite); void executeRandomizeOnDemoStart(bool is_lite); void executeToggleGravityOnOff(); void executeEnterLogoMode(size_t ball_count); void executeExitLogoMode(); private: // === Componentes del sistema (Composición) === std::unique_ptr input_handler_; // Manejo de entradas SDL std::unique_ptr scene_manager_; // Gestión de bolas y física std::unique_ptr shape_manager_; // Gestión de figuras 3D std::unique_ptr boid_manager_; // Gestión de comportamiento boids std::unique_ptr state_manager_; // Gestión de estados (DEMO/LOGO) std::unique_ptr ui_manager_; // Gestión de UI (HUD, FPS, notificaciones) // Recursos SDL SDL_Window* window_ = nullptr; SDL_Renderer* renderer_ = nullptr; std::shared_ptr texture_ = nullptr; // Textura activa actual std::vector> textures_; // Todas las texturas disponibles std::vector texture_names_; // Nombres de texturas (sin extensión) size_t current_texture_index_ = 0; // Índice de textura activa int current_ball_size_ = 10; // Tamaño actual de pelotas (dinámico, se actualiza desde texture) // Estado del simulador bool should_exit_ = false; // Sistema de timing Uint64 last_frame_time_ = 0; float delta_time_ = 0.0f; // Sistema de zoom dinámico int current_window_zoom_ = DEFAULT_WINDOW_ZOOM; // V-Sync bool vsync_enabled_ = true; bool fullscreen_enabled_ = false; bool real_fullscreen_enabled_ = false; ScalingMode current_scaling_mode_ = ScalingMode::INTEGER; // Modo de escalado actual (F5) // Resolución base (configurada por CLI o default) int base_screen_width_ = DEFAULT_SCREEN_WIDTH; int base_screen_height_ = DEFAULT_SCREEN_HEIGHT; // Resolución dinámica actual (cambia en fullscreen real) int current_screen_width_ = DEFAULT_SCREEN_WIDTH; int current_screen_height_ = DEFAULT_SCREEN_HEIGHT; // Resolución física real de ventana/pantalla (para texto absoluto) int physical_window_width_ = DEFAULT_SCREEN_WIDTH; int physical_window_height_ = DEFAULT_SCREEN_HEIGHT; // Sistema de temas (delegado a ThemeManager) std::unique_ptr theme_manager_; int theme_page_ = 0; // Página actual de temas (0 o 1) para acceso por Numpad // Sistema de Figuras 3D (polimórfico) // NOTA: Engine mantiene implementación de figuras usada por callbacks DEMO/LOGO // ShapeManager tiene implementación paralela para controles manuales del usuario SimulationMode current_mode_ = SimulationMode::PHYSICS; ShapeType current_shape_type_ = ShapeType::SPHERE; // Tipo de figura actual ShapeType last_shape_type_ = ShapeType::SPHERE; // Última figura para toggle F std::unique_ptr active_shape_; // Puntero polimórfico a figura activa float shape_scale_factor_ = 1.0f; // Factor de escala manual (Numpad +/-) bool depth_zoom_enabled_ = true; // Zoom por profundidad Z activado // Sistema de Modo DEMO (auto-play) y LOGO // NOTA: Engine mantiene estado de implementación para callbacks performLogoAction() // StateManager coordina los triggers y timers, Engine ejecuta las acciones AppMode previous_app_mode_ = AppMode::SANDBOX; // Modo previo antes de entrar a LOGO float demo_timer_ = 0.0f; // Contador de tiempo para próxima acción float demo_next_action_time_ = 0.0f; // Tiempo aleatorio hasta próxima acción (segundos) // Sistema de convergencia para LOGO MODE (escala con resolución) // Usado por performLogoAction() para detectar cuando las bolas forman el logo float shape_convergence_ = 0.0f; // % de pelotas cerca del objetivo (0.0-1.0) float logo_convergence_threshold_ = 0.90f; // Threshold aleatorio (75-100%) float logo_min_time_ = 3.0f; // Tiempo mínimo escalado con resolución float logo_max_time_ = 5.0f; // Tiempo máximo escalado (backup) // Sistema de espera de flips en LOGO MODE (camino alternativo) // Permite que LOGO espere a que ocurran rotaciones antes de cambiar estado bool logo_waiting_for_flip_ = false; // true si eligió el camino "esperar flip" int logo_target_flip_number_ = 0; // En qué flip actuar (1, 2 o 3) float logo_target_flip_percentage_ = 0.0f; // % de flip a esperar (0.2-0.8) int logo_current_flip_count_ = 0; // Flips observados hasta ahora // Control de entrada manual vs automática a LOGO MODE // Determina si LOGO debe salir automáticamente o esperar input del usuario bool logo_entered_manually_ = false; // true si se activó con tecla K, false si automático desde DEMO // Estado previo antes de entrar a Logo Mode (para restaurar al salir) // Guardado por executeEnterLogoMode(), restaurado por executeExitLogoMode() int logo_previous_theme_ = 0; // Índice de tema (0-9) size_t logo_previous_texture_index_ = 0; float logo_previous_shape_scale_ = 1.0f; // Batch rendering std::vector batch_vertices_; std::vector batch_indices_; // Configuración del sistema de texto (constantes configurables) static constexpr const char* TEXT_FONT_PATH = "data/fonts/determination.ttf"; static constexpr int TEXT_BASE_SIZE = 24; // Tamaño base para 240p static constexpr bool TEXT_ANTIALIASING = true; // true = suavizado, false = píxeles nítidos // Métodos principales del loop void calculateDeltaTime(); void update(); void render(); // Métodos auxiliares privados (llamados por la interfaz pública) void showNotificationForAction(const std::string& text); // Mostrar notificación solo en modo MANUAL // Sistema de cambio de sprites dinámico - Métodos privados void switchTextureInternal(bool show_notification); // Implementación interna del cambio de textura // Sistema de zoom dinámico - Métodos privados int calculateMaxWindowZoom() const; void setWindowZoom(int new_zoom); void zoomIn(); void zoomOut(); void updatePhysicalWindowSize(); // Actualizar tamaño físico real de ventana // Rendering void addSpriteToBatch(float x, float y, float w, float h, int r, int g, int b, float scale = 1.0f); // Sistema de Figuras 3D - Métodos privados // NOTA FASE 7: Métodos DUPLICADOS con ShapeManager (Engine mantiene implementación para DEMO/LOGO) // TODO FASE 8: Convertir en wrappers puros cuando migremos DEMO/LOGO void toggleShapeModeInternal(bool force_gravity_on_exit = true); // Implementación interna del toggle void activateShapeInternal(ShapeType type); // Implementación interna de activación void updateShape(); // Actualizar figura activa void generateShape(); // Generar puntos de figura activa void clampShapeScale(); // Limitar escala para evitar clipping };