cmake_minimum_required(VERSION 3.20)

cmake_policy(SET CMP0091 NEW)

project(rem-essentials LANGUAGES CXX)

set(FLSHARP_DIR "${CMAKE_CURRENT_SOURCE_DIR}/third_party/flsharp")
set(FLSHARP_IMPORT_DIR "${CMAKE_CURRENT_BINARY_DIR}/third_party/flsharp")
set(FLSHARP_COMMON_LIB "${FLSHARP_IMPORT_DIR}/Common.lib")
set(FLSHARP_DALIB_LIB "${FLSHARP_IMPORT_DIR}/DALib.lib")
set(FLSHARP_DACOM_LIB "${FLSHARP_IMPORT_DIR}/Dacom.lib")

file(MAKE_DIRECTORY "${FLSHARP_IMPORT_DIR}")

add_custom_command(
    OUTPUT "${FLSHARP_COMMON_LIB}"
    COMMAND lib /NOLOGO /MACHINE:X86 /DEF:"${FLSHARP_DIR}/def/Common.def" /NAME:COMMON /OUT:"${FLSHARP_COMMON_LIB}"
    DEPENDS "${FLSHARP_DIR}/def/Common.def"
)

add_custom_command(
    OUTPUT "${FLSHARP_DALIB_LIB}"
    COMMAND lib /NOLOGO /MACHINE:X86 /DEF:"${FLSHARP_DIR}/def/DALib.def" /NAME:DALIB /OUT:"${FLSHARP_DALIB_LIB}"
    DEPENDS "${FLSHARP_DIR}/def/DALib.def"
)

add_custom_command(
    OUTPUT "${FLSHARP_DACOM_LIB}"
    COMMAND lib /NOLOGO /MACHINE:X86 /DEF:"${FLSHARP_DIR}/def/Dacom.def" /NAME:DACOM /OUT:"${FLSHARP_DACOM_LIB}"
    DEPENDS "${FLSHARP_DIR}/def/Dacom.def"
)

add_custom_target(flsharp_imports DEPENDS
    "${FLSHARP_COMMON_LIB}"
    "${FLSHARP_DALIB_LIB}"
    "${FLSHARP_DACOM_LIB}"
)

set(FLSHARP_SOURCES
    third_party/flsharp/src/Freelancer.cpp
    third_party/flsharp/src/alchemy_crash.cpp
    third_party/flsharp/src/base_info.cpp
    third_party/flsharp/src/blank_faction.cpp
    third_party/flsharp/src/cheat_detection.cpp
    third_party/flsharp/src/copy_paste.cpp
    third_party/flsharp/src/cursor_colors.cpp
    third_party/flsharp/src/dealer_fixes.cpp
    third_party/flsharp/src/dll_crash.cpp
    third_party/flsharp/src/exit.cpp
    third_party/flsharp/src/flash_particles.cpp
    third_party/flsharp/src/fl_math.cpp
    third_party/flsharp/src/group_members.cpp
    third_party/flsharp/src/infocards.cpp
    third_party/flsharp/src/logger.cpp
    third_party/flsharp/src/pilot_names.cpp
    third_party/flsharp/src/projectiles.cpp
    third_party/flsharp/src/rep_requirements.cpp
    third_party/flsharp/src/resolutions.cpp
    third_party/flsharp/src/resolutions_asm.cpp
    third_party/flsharp/src/save_crash.cpp
    third_party/flsharp/src/server_filter.cpp
    third_party/flsharp/src/shield_capacity.cpp
    third_party/flsharp/src/temp_fixes.cpp
    third_party/flsharp/src/test_sounds.cpp
    third_party/flsharp/src/trade_lane_lights.cpp
    third_party/flsharp/src/ui_anim.cpp
    third_party/flsharp/src/update.cpp
    third_party/flsharp/src/utils.cpp
    third_party/flsharp/src/waypoint.cpp
    third_party/flsharp/src/waypoint_names.cpp
    third_party/flsharp/src/weapon_anim.cpp
)

set(FLPLUSPLUS_SOURCES
    src/features/flplusplus.cpp
    src/features/flplusplus_common.cpp
    src/features/flplusplus_config.cpp
    third_party/flplusplus/src/codec.cpp
    third_party/flplusplus/src/consolewindow.cpp
    third_party/flplusplus/src/cursor.cpp
    third_party/flplusplus/src/fontresource.cpp
    third_party/flplusplus/src/Freelancer.cpp
    third_party/flplusplus/src/graphics.cpp
    third_party/flplusplus/src/log.cpp
    third_party/flplusplus/src/patch.cpp
    third_party/flplusplus/src/restart.cpp
    third_party/flplusplus/src/savegame.cpp
    third_party/flplusplus/src/screenshot.cpp
    third_party/flplusplus/src/shippreviewscroll.cpp
    third_party/flplusplus/src/startlocation.cpp
    third_party/flplusplus/src/startup.cpp
    third_party/flplusplus/src/thnplayer.cpp
    third_party/flplusplus/src/touchpad.cpp
)

add_library(rem-essentials SHARED
    src/main.cpp
    src/rem/config.cpp
    src/rem/feature_manager.cpp
    src/rem/log.cpp
    src/rem/patch.cpp
    src/rem/runtime.cpp
    src/rem/version_guard.cpp
    src/features/alchemy_crash.cpp
    src/features/jump_waypoint.cpp
    src/features/mouse.cpp
    src/features/quit_message.cpp
    src/features/ship_buy_kick.cpp
    ${FLSHARP_SOURCES}
    ${FLPLUSPLUS_SOURCES}
)

add_dependencies(rem-essentials flsharp_imports)

target_include_directories(rem-essentials PRIVATE "${FLSHARP_DIR}/include" include third_party/flplusplus/src third_party/flplusplus/include)
target_compile_features(rem-essentials PRIVATE cxx_std_17)
target_link_libraries(rem-essentials PRIVATE
    user32
    gdi32
    gdiplus
    shell32
    shlwapi
    version
    "${FLSHARP_COMMON_LIB}"
    "${FLSHARP_DALIB_LIB}"
    "${FLSHARP_DACOM_LIB}"
)

if(NOT WIN32)
    message(FATAL_ERROR "rem-essentials builds a Windows Freelancer DLL.")
endif()

if(NOT MSVC)
    message(FATAL_ERROR "The migrated hooks currently require 32-bit MSVC inline assembly.")
endif()

if(NOT CMAKE_SIZEOF_VOID_P EQUAL 4)
    message(FATAL_ERROR "Freelancer is 32-bit; configure this project with a Win32/x86 generator.")
endif()

target_compile_options(rem-essentials PRIVATE /W4 /WX /EHsc /O2 /Zc:threadSafeInit-)
set_source_files_properties(${FLSHARP_SOURCES} PROPERTIES COMPILE_OPTIONS "/wd4005;/wd4100;/wd4200;/wd4701;/wd4703")
set_source_files_properties(${FLPLUSPLUS_SOURCES} PROPERTIES COMPILE_OPTIONS "/wd4005;/wd4068;/wd4100;/wd4189;/wd4200;/wd4244;/wd4459;/wd4996")
target_compile_definitions(rem-essentials PRIVATE WIN32_LEAN_AND_MEAN NOMINMAX USE_ST6)
set_property(TARGET rem-essentials PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")

set_target_properties(rem-essentials PROPERTIES
    OUTPUT_NAME "rem-essentials"
    RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
)
