cmake_minimum_required(VERSION 3.21)

project(Motherload LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")

option(MOTHERLOAD_USE_BUNDLED_WINDOWS_SDL "Use the bundled prebuilt SDL packages on Windows" ON)
option(MOTHERLOAD_ENABLE_WARNINGS "Enable compiler warnings" ON)

if(WIN32 AND MOTHERLOAD_USE_BUNDLED_WINDOWS_SDL)
    list(PREPEND CMAKE_PREFIX_PATH
        "${CMAKE_SOURCE_DIR}/Libraries/SDLMain/SDL2-2.26.3/cmake"
        "${CMAKE_SOURCE_DIR}/Libraries/SDLImage/SDL2_image-2.6.3/cmake"
        "${CMAKE_SOURCE_DIR}/Libraries/SDLMixer/SDL2_mixer-2.6.3/cmake"
        "${CMAKE_SOURCE_DIR}/Libraries/SDLTtf/SDL2_ttf-2.20.2/cmake"
    )
endif()

find_package(OpenGL REQUIRED)

function(motherload_import_pkgconfig_target imported_target pkg_name pkg_prefix)
    if(TARGET "${imported_target}")
        return()
    endif()

    find_package(PkgConfig REQUIRED)
    pkg_check_modules(${pkg_prefix} REQUIRED IMPORTED_TARGET "${pkg_name}")

    add_library("${imported_target}" INTERFACE IMPORTED)
    target_link_libraries("${imported_target}" INTERFACE "PkgConfig::${pkg_prefix}")
endfunction()

function(motherload_enable_warnings target_name)
    if(NOT MOTHERLOAD_ENABLE_WARNINGS)
        return()
    endif()

    if(MSVC)
        target_compile_options(${target_name} PRIVATE /W4 /permissive-)
    else()
        target_compile_options(${target_name} PRIVATE -Wall -Wextra -Wpedantic)
    endif()
endfunction()

find_package(SDL2 QUIET CONFIG)
find_package(SDL2_image QUIET CONFIG)
find_package(SDL2_mixer QUIET CONFIG)
find_package(SDL2_ttf QUIET CONFIG)

motherload_import_pkgconfig_target(SDL2::SDL2 sdl2 SDL2_PC)
motherload_import_pkgconfig_target(SDL2_image::SDL2_image SDL2_image SDL2_IMAGE_PC)
motherload_import_pkgconfig_target(SDL2_mixer::SDL2_mixer SDL2_mixer SDL2_MIXER_PC)
motherload_import_pkgconfig_target(SDL2_ttf::SDL2_ttf SDL2_ttf SDL2_TTF_PC)

if(NOT TARGET SDL2::SDL2main)
    find_library(SDL2MAIN_LIBRARY NAMES SDL2main)
    if(SDL2MAIN_LIBRARY)
        add_library(SDL2::SDL2main UNKNOWN IMPORTED)
        set_target_properties(SDL2::SDL2main PROPERTIES IMPORTED_LOCATION "${SDL2MAIN_LIBRARY}")
    endif()
endif()

set(ENGINE_SOURCES
    Engine/BaseGame.cpp
    Engine/Collision.cpp
    Engine/Matrix2x3.cpp
    Engine/SVGParser.cpp
    Engine/SoundEffect.cpp
    Engine/SoundStream.cpp
    Engine/Text.cpp
    Engine/Texture.cpp
    Engine/Vector2f.cpp
    Engine/structs.cpp
    Engine/utils.cpp
)

set(GAME_SOURCES
    Game/Animations/Animation.cpp
    Game/Camera.cpp
    Game/Game.cpp
    Game/GameManager.cpp
    Game/GridSystem/GroundTileTypeManager.cpp
    Game/GridSystem/WorldGridManager.cpp
    Game/GridSystem/WorldTile.cpp
    Game/Gui/GuiButton.cpp
    Game/Gui/GuiElement.cpp
    Game/Gui/GuiMeter.cpp
    Game/Gui/GuiText.cpp
    Game/Gui/Screen.cpp
    Game/Gui/Screens/FuelScreen/FuelScreen.cpp
    Game/Gui/Screens/GameOver/GameOverScreen.cpp
    Game/Gui/Screens/MainScreen.cpp
    Game/Gui/Screens/ScreenManager.cpp
    Game/Gui/Screens/SellScreen/SellScreen.cpp
    Game/Gui/Screens/SellScreen/SellSreenRow.cpp
    Game/Inventory/PlayerInventory.cpp
    Game/Levels/Level.cpp
    Game/Levels/MainMenu/MainMenuLevel.cpp
    Game/Levels/World/Building.cpp
    Game/Levels/World/OrbitingObject.cpp
    Game/Levels/World/WorldLevel.cpp
    Game/Particle/Particle.cpp
    Game/Player.cpp
    Game/TextureManager.cpp
    Game/main.cpp
    Game/pch.cpp
)

add_library(Engine STATIC ${ENGINE_SOURCES})
target_include_directories(Engine
    PUBLIC
        "${CMAKE_SOURCE_DIR}/Engine"
)
target_compile_definitions(Engine
    PUBLIC
        MOTHERLOAD_DISABLE_MSVC_LINK_PRAGMAS=1
)
target_link_libraries(Engine
    PUBLIC
        OpenGL::GL
        SDL2::SDL2
        SDL2_image::SDL2_image
        SDL2_mixer::SDL2_mixer
        SDL2_ttf::SDL2_ttf
)
motherload_enable_warnings(Engine)

add_executable(Motherload ${GAME_SOURCES})
target_include_directories(Motherload
    PRIVATE
        "${CMAKE_SOURCE_DIR}/Game"
        "${CMAKE_SOURCE_DIR}/Engine"
)
target_link_libraries(Motherload
    PRIVATE
        Engine
        OpenGL::GL
        SDL2::SDL2
        SDL2_image::SDL2_image
        SDL2_mixer::SDL2_mixer
        SDL2_ttf::SDL2_ttf
)

if(TARGET SDL2::SDL2main)
    target_link_libraries(Motherload PRIVATE SDL2::SDL2main)
endif()
motherload_enable_warnings(Motherload)

source_group(TREE "${CMAKE_SOURCE_DIR}" FILES ${ENGINE_SOURCES} ${GAME_SOURCES})
set_property(DIRECTORY PROPERTY VS_STARTUP_PROJECT Motherload)
set_property(TARGET Motherload PROPERTY VS_DEBUGGER_WORKING_DIRECTORY "$<TARGET_FILE_DIR:Motherload>")

add_custom_command(TARGET Motherload POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E copy_directory
            "${CMAKE_SOURCE_DIR}/Resources"
            "$<TARGET_FILE_DIR:Motherload>"
)

if(WIN32)
    add_custom_command(TARGET Motherload POST_BUILD
        COMMAND ${CMAKE_COMMAND} -E copy_if_different
                $<TARGET_RUNTIME_DLLS:Motherload>
                $<TARGET_FILE_DIR:Motherload>
        COMMAND_EXPAND_LISTS
    )
endif()
