#include "Game.h"
#include "squirrel/SquirrelEx.h"
#include "EngineFrame/Component/Sprite.h"
#include "EngineFrame/Actor/Actor.h"
#include "EngineFrame/Component/Text.h"

Game::Game()
{
}

Game::~Game()
{
    Clear();
}

void Game::Init(std::function<void()> CallBack)
{

    SDL_InitSubSystem(SDL_INIT_JOYSTICK);
    SDL_JoystickEventState(SDL_ENABLE);
    SDL_JoystickOpen(0);

    // 设置OpenGL ES 3.2上下文属性
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); // 双缓冲

    // 启用多重采样（关键步骤）
    SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); // 启用多重采样缓冲
    SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 8); // 4x 采样（可改为 8 等）

    if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
    {
        SDL_LogError(SDL_LOG_CATEGORY_ERROR, "SDL could not initialize! Error: %s\n", SDL_GetError());
        m_isRunning = false;
    }
    m_window = SDL_CreateWindow("Game", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, Screen_W, Screen_H, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);
    if (m_window == nullptr)
    {
        SDL_LogError(SDL_LOG_CATEGORY_ERROR, "SDL could not Create Window! Error: %s\n", SDL_GetError());
        m_isRunning = false;
    }
    // 关闭原生鼠标
    SDL_ShowCursor(0);

    // 打开所有检测到的控制器
    int numControllers = SDL_NumJoysticks();
    for (int i = 0; i < numControllers; i++)
    {
        if (SDL_IsGameController(i))
        {
            SDL_GameController *controller = SDL_GameControllerOpen(i);
            if (controller)
            {
                SDL_Log("成功打开控制器: %s", SDL_GameControllerName(controller));
            }
            else
            {
                SDL_Log("无法打开控制器 %d! SDL错误: %s", i, SDL_GetError());
            }
        }
    }
    // 创建OpenGL渲染器
    m_renderer = new RenderManager(m_window);

    IMG_Init(IMG_INIT_PNG);

    // 初始化SDL_mixer，支持OGG格式
    // 44100: 采样率, MIX_DEFAULT_FORMAT: 音频格式, 2: 声道数(立体声), 4096: 缓冲区大小
    if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 4096) < 0)
    {
        SDL_LogError(SDL_LOG_CATEGORY_ERROR, "SDL_mixer初始化失败! Mix_Error: %s\n", Mix_GetError());
        m_isRunning = false;
    }

    // 初始化 TTF
    if (TTF_Init() == -1)
    {
        SDL_LogError(SDL_LOG_CATEGORY_ERROR, "TTF 初始化失败！TTF_Error: %s\n", TTF_GetError());
        m_isRunning = false;
    }
    // SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0");
    CallBack();
}

void Game::Run()
{
    // 计算帧时间
    m_frameTime = 1000.0 / m_Settingfps;

    while (m_isRunning)
    {
        // 帧开始时间
        Uint64 frameStart = SDL_GetTicks64();
        SDL_Event m_event;
        HandleEvents(&m_event);
        Update(m_deltaTime);
        Render();

        // 帧率统计 每一秒钟的时候记录一次帧率
        m_frameCounter++;
        Uint64 currentTime = SDL_GetTicks64();
        if (currentTime - m_lastFpsPrintTime >= 1000)
        {
            m_fps = m_frameCounter;
            m_lastFpsPrintTime = currentTime;
            m_frameCounter = 0;
        }

        // 计算实际总帧时间（关键修改）
        Uint64 diff = SDL_GetTicks64() - frameStart; // 处理耗时
        if (diff < m_frameTime)
        {
            SDL_Delay(m_frameTime - diff); // 尝试延迟补全
        }
        // 延迟后，重新计算从帧开始到现在的总时间（包含可能的延迟误差）
        Uint64 actualFrameTime = SDL_GetTicks64() - frameStart;
        m_deltaTime = actualFrameTime / 1000.0f; // 用实际总时间更新deltaTime
        m_frameTime_ms = actualFrameTime;
    }
}

void Game::HandleEvents(SDL_Event *e)
{
    while (SDL_PollEvent(e))
    {
        if (e->type == SDL_QUIT)
        {
            m_isRunning = false;
            SDL_Log("Game Exit1");
        }
        else if (e->type == SDL_JOYBUTTONDOWN)
        {
            if (e->jbutton.button == JOY_PLUS)
            {
                m_isRunning = false;
                SDL_Log("Game Exit2");
            }
        }
        // 处理屏幕按下事件
        else if (e->type == SDL_FINGERDOWN)
        {
            // 触发双击事件
            SDL_Log("退出程序");
            m_isRunning = false;
            SDL_Log("Game Exit3");
        }

        if (m_scene != nullptr)
            m_scene->HandleEvents(e);
        if (m_uiScene != nullptr)
            m_uiScene->HandleEvents(e);
    }
}

void Game::Update(float deltaTime)
{
    //调用松鼠的更新
    SquirrelEx::GetInstance().Update(deltaTime);
     if (m_scene != nullptr)
        m_scene->Update(deltaTime);
    if (m_uiScene != nullptr)
        m_uiScene->Update(deltaTime);
}

void Game::Render()
{
    // 调用预渲染
    if (m_scene != nullptr)
        m_scene->PreRender();
    if (m_uiScene != nullptr)
        m_uiScene->PreRender();
        
    // 清空渲染器后渲染
    m_renderer->ClearScreen();
    if (m_scene != nullptr)
    {
        m_renderer->SetOrthoMatrixType(0);
        m_scene->Render();
    }
    if (m_uiScene != nullptr)
    {
        m_renderer->SetOrthoMatrixType(1);
        m_uiScene->Render();
    }
    m_renderer->SwapBuffer();
}

void Game::Clear()
{
    if (m_scene != nullptr)
    {
        m_scene->Exit();
    }
    m_scene = nullptr;
    if (m_uiScene != nullptr)
    {
        m_uiScene->Exit();
    }
    m_uiScene = nullptr;
    IMG_Quit();
    SDL_DestroyWindow(m_window);
    SDL_Quit();
}

void Game::ChangeScene(RefPtr<Scene> scene)
{
    if (m_scene != nullptr)
    {
        m_scene->Exit();
    }
    m_scene = scene;
    m_scene->Enter();
}

void Game::ChangeUIScene(RefPtr<Scene> scene)
{
    if (m_uiScene != nullptr)
    {
        m_uiScene->Exit();
    }
    m_uiScene = scene;
    m_uiScene->Enter();
}

RenderManager *Game::GetRenderer()
{
    return m_renderer;
}
