cmake_minimum_required(VERSION 3.20)
project(vibe3_physics)

# Establecer el estándar de C++
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Opciones comunes de compilación
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Os -ffunction-sections -fdata-sections")

# Buscar SDL3 automáticamente
find_package(SDL3 REQUIRED)

# Buscar SDL3_ttf
find_package(SDL3_ttf REQUIRED)

# ---- Shader compilation (non-Apple only: Vulkan/SPIRV) ----
if(NOT APPLE)
    find_program(GLSLC glslc HINTS "$ENV{VULKAN_SDK}/bin" "$ENV{VULKAN_SDK}/Bin")
    if(NOT GLSLC)
        message(STATUS "glslc not found — using precompiled SPIR-V headers from shaders/precompiled/")
        set(SHADER_GEN_DIR "${CMAKE_SOURCE_DIR}/shaders/precompiled")
    else()
        set(SHADER_SRC_DIR "${CMAKE_SOURCE_DIR}/shaders")
        set(SHADER_GEN_DIR "${CMAKE_BINARY_DIR}/generated_shaders")
        file(MAKE_DIRECTORY "${SHADER_GEN_DIR}")

        set(SPIRV_HEADERS)
        foreach(SHADER sprite_vert sprite_frag postfx_vert postfx_frag ball_vert)
            if(SHADER MATCHES "_vert$")
                set(STAGE_FLAG "-fshader-stage=vertex")
            else()
                set(STAGE_FLAG "-fshader-stage=fragment")
            endif()
            string(REGEX REPLACE "_vert$" ".vert" GLSL_NAME "${SHADER}")
            string(REGEX REPLACE "_frag$" ".frag" GLSL_NAME "${GLSL_NAME}")

            set(GLSL_FILE "${SHADER_SRC_DIR}/${GLSL_NAME}")
            set(SPV_FILE  "${SHADER_GEN_DIR}/${SHADER}.spv")
            set(H_FILE    "${SHADER_GEN_DIR}/${SHADER}_spv.h")

            add_custom_command(
                OUTPUT "${H_FILE}"
                COMMAND "${GLSLC}" ${STAGE_FLAG} -o "${SPV_FILE}" "${GLSL_FILE}"
                COMMAND "${CMAKE_COMMAND}"
                        -DINPUT="${SPV_FILE}"
                        -DOUTPUT="${H_FILE}"
                        -DVAR_NAME="k${SHADER}_spv"
                        -P "${CMAKE_SOURCE_DIR}/cmake/spv_to_header.cmake"
                DEPENDS "${GLSL_FILE}"
                COMMENT "Compiling ${GLSL_NAME} to SPIRV"
            )
            list(APPEND SPIRV_HEADERS "${H_FILE}")
        endforeach()

        add_custom_target(shaders ALL DEPENDS ${SPIRV_HEADERS})
    endif()
endif()

# Archivos fuente (excluir main_old.cpp)
file(GLOB SOURCE_FILES source/*.cpp source/external/*.cpp source/boids_mgr/*.cpp source/gpu/*.cpp source/input/*.cpp source/scene/*.cpp source/shapes/*.cpp source/shapes_mgr/*.cpp source/state/*.cpp source/themes/*.cpp source/text/*.cpp source/ui/*.cpp)
list(REMOVE_ITEM SOURCE_FILES "${CMAKE_SOURCE_DIR}/source/main_old.cpp")

# Suprimir falso positivo de GCC en stb_image.h (externo)
set_source_files_properties(source/external/texture.cpp PROPERTIES COMPILE_FLAGS "-Wno-stringop-overflow")

# Comprobar si se encontraron archivos fuente
if(NOT SOURCE_FILES)
    message(FATAL_ERROR "No se encontraron archivos fuente en el directorio 'source/'. Verifica la ruta.")
endif()

# Detectar la plataforma y configuraciones específicas
if(WIN32)
    set(LINK_LIBS SDL3::SDL3 SDL3_ttf::SDL3_ttf mingw32 ws2_32)
elseif(UNIX AND NOT APPLE)
    set(LINK_LIBS SDL3::SDL3 SDL3_ttf::SDL3_ttf)
elseif(APPLE)
    set(LINK_LIBS SDL3::SDL3 SDL3_ttf::SDL3_ttf)
endif()

# Incluir directorios de SDL3 y SDL3_ttf
include_directories(${SDL3_INCLUDE_DIRS} ${SDL3_ttf_INCLUDE_DIRS})

# Incluir directorio source/ para poder usar includes desde la raíz del proyecto
include_directories(${CMAKE_SOURCE_DIR}/source)

# Añadir el ejecutable reutilizando el nombre del proyecto
add_executable(${PROJECT_NAME} ${SOURCE_FILES})

# Especificar la ubicación del ejecutable (en la raíz del proyecto)
set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR})

# Enlazar las bibliotecas necesarias
target_link_libraries(${PROJECT_NAME} ${LINK_LIBS})

if(NOT APPLE)
    if(GLSLC)
        add_dependencies(${PROJECT_NAME} shaders)
    endif()
    target_include_directories(${PROJECT_NAME} PRIVATE "${SHADER_GEN_DIR}")
endif()

# Tool: pack_resources
add_executable(pack_resources tools/pack_resources.cpp source/resource_pack.cpp)
target_include_directories(pack_resources PRIVATE ${CMAKE_SOURCE_DIR}/source)
set_target_properties(pack_resources PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/tools")
