// ============================================================================
// GAME LAUNCHER IMPLEMENTATION
// ============================================================================
// Menu system for selecting and launching games

#include "game_launcher.h"
#include "input_manager.h"
#include "display/low_level_render.h"
#include "display/low_level_gui.h"
#include <stdio.h>

GameLauncher::GameLauncher(uint16_t width, uint16_t height, 
                          LowLevelRenderer* renderer, LowLevelGUI* gui, InputManager* input_manager)
    : width(width), height(height), renderer(renderer), gui(gui), input_manager(input_manager),
      selected_index(0), selected_game(nullptr), current_page(0) {
}

void GameLauncher::register_game(const char* name, const char* description,
                                 std::function<Game*(uint16_t, uint16_t, LowLevelRenderer*, LowLevelGUI*, InputManager*)> factory) {
    GameEntry entry;
    entry.name = name;
    entry.description = description;
    entry.factory = factory;
    games.push_back(entry);
    
    printf("Registered game: %s - %s\n", name, description);
}

void GameLauncher::draw() {
    // Draw main window
    LowLevelWindow* window = gui->draw_new_window(10, 10, width - 20, height - 20, "Game Launcher");

    renderer->set_font(&font_5x5_obj);
    
    // Draw title with page indicator
    int total_pages = get_total_pages();
    char title[64];
    snprintf(title, sizeof(title), "Select a Game: (Page %d/%d)", current_page + 1, total_pages);
    renderer->draw_string_scaled(30, 40, title, 2);
    
    // Get games for current page
    int page_start = get_page_start_index();
    int page_end = get_page_end_index();
    
    // Draw game list with GUI buttons for current page only
    for (int i = page_start; i < page_end && i < (int)games.size(); i++) {
        int item_index = i - page_start;
        int y = MENU_Y_START + (item_index * MENU_ITEM_HEIGHT);
        
        // Draw button (pressed/highlighted if selected)
        bool is_selected = (i == selected_index);
        gui->draw_button(window, 20, y, games[i].name, is_selected, true);
        
        // Draw description below button
        renderer->set_font(&font_5x5_obj);  // Restore small font for description
        renderer->set_text_color(true);     // Normal text color
        renderer->draw_string_scaled(50, y + 36, games[i].description, 1);
    }
    
    // Draw navigation buttons at bottom (only if multiple pages)
    if (total_pages > 1) {
        int button_y = height - 65;
        
        // Previous page button
        bool has_prev = (current_page > 0);
        gui->draw_button(window, 30, button_y, "< PREV", false, true);
        
        // Next page button
        bool has_next = (current_page + 1 < total_pages);
        gui->draw_button(window, 200, button_y, "NEXT >", false, true);
        
        // Draw instructions
        renderer->set_font(&font_5x5_obj);
        renderer->draw_string_scaled(30, height - 25, "Touch buttons or KEY0/KEY1", 1);
    } else {
        // Single page - just show select instruction
        renderer->set_font(&font_5x5_obj);
        renderer->draw_string_scaled(30, height - 35, "KEY0: Navigate | KEY1: Select | Touch to play", 1);
    }
}


bool GameLauncher::update(const InputEvent& event) {
    bool needs_refresh = false;
    int total_pages = get_total_pages();
    
    switch (event.type) {
        case INPUT_TOUCH_DOWN: {
            printf("Touch at (%d,%d) in launcher\n", event.x, event.y);
            
            // Check if touch is on navigation buttons (if multiple pages)
            if (total_pages > 1) {
                // Previous button: x [30-180], y [235-275]
                if (event.x >= PREV_BUTTON_X && event.x < PREV_BUTTON_X + BUTTON_WIDTH &&
                    event.y >= NAV_BUTTON_Y && event.y < NAV_BUTTON_Y + BUTTON_HEIGHT) {
                    if (current_page > 0) {
                        current_page--;
                        selected_index = get_page_start_index();
                        needs_refresh = true;
                        printf("Navigated to previous page: %d\n", current_page);
                    }
                    break;
                }
                
                // Next button: x [200-350], y [235-275]
                if (event.x >= NEXT_BUTTON_X && event.x < NEXT_BUTTON_X + BUTTON_WIDTH &&
                    event.y >= NAV_BUTTON_Y && event.y < NAV_BUTTON_Y + BUTTON_HEIGHT) {
                    if (current_page + 1 < total_pages) {
                        current_page++;
                        selected_index = get_page_start_index();
                        needs_refresh = true;
                        printf("Navigated to next page: %d\n", current_page);
                    }
                    break;
                }
            }
            
            // Check if touch is on a game entry for current page
            int page_start = get_page_start_index();
            int page_end = get_page_end_index();
            
            for (int i = page_start; i < page_end && i < (int)games.size(); i++) {
                int item_index = i - page_start;
                int y = MENU_Y_START + (item_index * MENU_ITEM_HEIGHT);
                
                // Touch area is the entire menu item
                if (event.y >= y - 5 && event.y < y + MENU_ITEM_HEIGHT - 5) {
                    // Game selected - create instance
                    printf("Selected game: %s\n", games[i].name);
                    selected_game = games[i].factory(width, height, renderer, gui, input_manager);
                    if (selected_game) {
                        selected_game->init();
                        return true;  // Signal game selected
                    }
                    break;
                }
            }
            break;
        }
        
        case INPUT_BUTTON_0: {
            // Navigate within current page or switch pages
            int page_start = get_page_start_index();
            int page_end = get_page_end_index();
            
            // If multiple games on current page, navigate within page first
            if (page_end - page_start > 1) {
                // Move within current page
                int old_index = selected_index;
                selected_index++;
                if (selected_index >= page_end) {
                    // Moving to next page
                    if (current_page + 1 < total_pages) {
                        current_page++;
                        selected_index = get_page_start_index();
                    } else {
                        // Wrap to first page
                        current_page = 0;
                        selected_index = 0;
                    }
                } else if (selected_index < page_start) {
                    selected_index = page_start;
                }
            } else {
                // Single game on page, move to next page
                if (current_page + 1 < total_pages) {
                    current_page++;
                    selected_index = get_page_start_index();
                } else {
                    // Wrap to first page
                    current_page = 0;
                    selected_index = 0;
                }
            }
            needs_refresh = true;
            printf("Menu selection: %d (%s), Page: %d\n", selected_index, games[selected_index].name, current_page);
            break;
        }
        
        case INPUT_BUTTON_1: {
            // Select current game
            if (selected_index >= 0 && selected_index < (int)games.size()) {
                printf("Selected game: %s\n", games[selected_index].name);
                selected_game = games[selected_index].factory(width, height, renderer, gui, input_manager);
                if (selected_game) {
                    selected_game->init();
                    return true;  // Signal game selected
                }
            }
            break;
        }
        
        default:
            break;
    }
    
    return needs_refresh;
}

Game* GameLauncher::get_selected_game() {
    return selected_game;
}

void GameLauncher::reset() {
    // Clean up current game if any
    if (selected_game) {
        delete selected_game;
        selected_game = nullptr;
    }
    selected_index = 0;
    current_page = 0;
    printf("Launcher reset - returning to menu\n");
}

int GameLauncher::get_total_pages() const {
    if (games.empty()) return 1;
    return (games.size() + GAMES_PER_PAGE - 1) / GAMES_PER_PAGE;
}

int GameLauncher::get_page_start_index() const {
    return current_page * GAMES_PER_PAGE;
}

int GameLauncher::get_page_end_index() const {
    return (current_page + 1) * GAMES_PER_PAGE;
}
