# -*- cmake -*-
# Copyright 2021 Jean Pierre Cimalando
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#

if(NOT YSFX_PORTABLE AND MSVC AND MSVC_C_ARCHITECTURE_ID STREQUAL "x64")
    if(NOT NASM_PROGRAM)
        message(FATAL_ERROR "Cannot find nasm, required in a MSVC x64 configuration")
    endif()
endif()

# wdl-base
# ------------------------------------------------------------------------------
add_library(wdl-base OBJECT "thirdparty/WDL/source/WDL/fft.c")
if(WIN32)
    target_sources(wdl-base PRIVATE "thirdparty/WDL/source/WDL/win32_utf8.c")
endif()
target_compile_definitions(wdl-base PUBLIC "WDL_FFT_REALSIZE=8")
target_compile_definitions(wdl-base PUBLIC "WDL_LINEPARSE_ATOF=ysfx_wdl_atof")
target_compile_definitions(wdl-base PRIVATE "${YSFX_FILE_OFFSET_BITS_GENEXP}")
if(MSVC)
    target_compile_definitions(wdl-base PRIVATE "_CRT_NONSTDC_NO_WARNINGS")
endif()
target_include_directories(wdl-base PUBLIC "thirdparty/WDL/source")

if(NOT MSVC)
    # wdltypes wants char to be signed; ARM has it unsigned by default
    target_compile_options(wdl-base PUBLIC "-fsigned-char")
endif()

# lice
# ------------------------------------------------------------------------------
if(YSFX_GFX)
    add_library(lice
        OBJECT
            "thirdparty/WDL/source/WDL/lice/lice.cpp"
            "thirdparty/WDL/source/WDL/lice/lice_arc.cpp"
            "thirdparty/WDL/source/WDL/lice/lice_colorspace.cpp"
            "thirdparty/WDL/source/WDL/lice/lice_image.cpp"
            "thirdparty/WDL/source/WDL/lice/lice_line.cpp"
            "thirdparty/WDL/source/WDL/lice/lice_palette.cpp"
            "thirdparty/WDL/source/WDL/lice/lice_texgen.cpp"
            "thirdparty/WDL/source/WDL/lice/lice_text.cpp"
            "thirdparty/WDL/source/WDL/lice/lice_textnew.cpp")
    target_compile_definitions(lice PRIVATE "${YSFX_FILE_OFFSET_BITS_GENEXP}")
    target_link_libraries(lice
        PUBLIC
            wdl-base
        PRIVATE
            ${CMAKE_DL_LIBS}
            Threads::Threads)

    # custom image loaders
    target_sources(lice
        PRIVATE
            "sources/lice_stb/lice_stb_generic.hpp"
            "sources/lice_stb/lice_stb_loaders.cpp"
            "sources/lice_stb/lice_stb_loaders.hpp"
            "sources/lice_stb/lice_stb_bmp.cpp"
            "sources/lice_stb/lice_stb_gif.cpp"
            "sources/lice_stb/lice_stb_jpg.cpp"
            "sources/lice_stb/lice_stb_png.cpp"
            "sources/lice_stb/lice_stb_write.cpp")
    target_link_libraries(lice PRIVATE stb)

    # SWELL
    if(NOT WIN32)
        target_sources(lice
            PRIVATE
                "thirdparty/WDL/source/WDL/swell/swell-ini.cpp"
                "thirdparty/WDL/source/WDL/swell/swell.cpp")
        if(NOT APPLE)
            target_sources(lice
                PRIVATE
                    "thirdparty/WDL/source/WDL/swell/swell-appstub-generic.cpp"
                    "thirdparty/WDL/source/WDL/swell/swell-dlg-generic.cpp"
                    "thirdparty/WDL/source/WDL/swell/swell-gdi-generic.cpp"
                    "thirdparty/WDL/source/WDL/swell/swell-gdi-lice.cpp"
                    "thirdparty/WDL/source/WDL/swell/swell-generic-gdk.cpp"
                    "thirdparty/WDL/source/WDL/swell/swell-generic-headless.cpp"
                    "thirdparty/WDL/source/WDL/swell/swell-kb-generic.cpp"
                    "thirdparty/WDL/source/WDL/swell/swell-menu-generic.cpp"
                    "thirdparty/WDL/source/WDL/swell/swell-misc-generic.cpp"
                    "thirdparty/WDL/source/WDL/swell/swell-miscdlg-generic.cpp"
                    "thirdparty/WDL/source/WDL/swell/swell-modstub-generic.cpp"
                    "thirdparty/WDL/source/WDL/swell/swell-wnd-generic.cpp")
                target_compile_definitions(lice PUBLIC "SWELL_LICE_GDI")
                if(TARGET Fontconfig::Fontconfig)
                    target_compile_definitions(lice PUBLIC "SWELL_FONTCONFIG")
                    target_link_libraries(lice PRIVATE Fontconfig::Fontconfig)
                endif()
                if(TARGET Freetype::Freetype)
                    target_compile_definitions(lice PUBLIC "SWELL_FREETYPE")
                    target_link_libraries(lice PRIVATE Freetype::Freetype)
                endif()
        else()
            target_sources(lice
                PRIVATE
                    "thirdparty/WDL/source/WDL/swell/swell-appstub.mm"
                    "thirdparty/WDL/source/WDL/swell/swell-dlg.mm"
                    "thirdparty/WDL/source/WDL/swell/swell-gdi.mm"
                    "thirdparty/WDL/source/WDL/swell/swell-kb.mm"
                    "thirdparty/WDL/source/WDL/swell/swell-menu.mm"
                    "thirdparty/WDL/source/WDL/swell/swell-misc.mm"
                    "thirdparty/WDL/source/WDL/swell/swell-miscdlg.mm"
                    "thirdparty/WDL/source/WDL/swell/swell-modstub.mm"
                    "thirdparty/WDL/source/WDL/swell/swell-wnd.mm")
            target_link_libraries(lice
                PRIVATE
                    Apple::Cocoa
                    Apple::Carbon
                    Apple::Foundation
                    Apple::Metal)
        endif()
    endif()
endif()

# eel2
# ------------------------------------------------------------------------------
add_library(eel2
    OBJECT
        "thirdparty/WDL/source/WDL/eel2/nseel-caltab.c"
        "thirdparty/WDL/source/WDL/eel2/nseel-cfunc.c"
        "thirdparty/WDL/source/WDL/eel2/nseel-compiler.c"
        "thirdparty/WDL/source/WDL/eel2/nseel-eval.c"
        "thirdparty/WDL/source/WDL/eel2/nseel-lextab.c"
        "thirdparty/WDL/source/WDL/eel2/nseel-ram.c"
        "thirdparty/WDL/source/WDL/eel2/nseel-yylex.c")
add_library(eel2nasm OBJECT IMPORTED)
if(YSFX_PORTABLE)
    target_compile_definitions(eel2 PUBLIC "EEL_TARGET_PORTABLE")
else()
    if(NOT MSVC)
        target_sources(eel2 PRIVATE "sources/eel2-gas/sources/asm-nseel-x64-sse.S")
    elseif(MSVC_C_ARCHITECTURE_ID STREQUAL "x64")
        set_property(TARGET eel2nasm PROPERTY IMPORTED_OBJECTS "${CMAKE_CURRENT_BINARY_DIR}/asm-nseel-x64-sse.obj")
        add_custom_command(
            OUTPUT "asm-nseel-x64-sse.obj"
            COMMAND "${NASM_PROGRAM}" "-f" "win64" "-o" "${CMAKE_CURRENT_BINARY_DIR}/asm-nseel-x64-sse.obj" "${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/WDL/source/WDL/eel2/asm-nseel-x64-sse.asm"
            DEPENDS "thirdparty/WDL/source/WDL/eel2/asm-nseel-x64-sse.asm")
    endif()
endif()
target_compile_definitions(eel2
    PRIVATE
        "NSEEL_ATOF=ysfx_wdl_atof")

target_compile_definitions(eel2 PRIVATE "${YSFX_FILE_OFFSET_BITS_GENEXP}")
if(MSVC)
    target_compile_definitions(eel2 PRIVATE "_CRT_NONSTDC_NO_WARNINGS")
endif()
target_link_libraries(eel2
    PUBLIC
        wdl-base
    PRIVATE
        Threads::Threads)

if(NOT YSFX_SKIP_CHECKSUM)
    # Verify if the reference ASM file has been modified.
    # It tells that the GAS source requires updating to match upstream.
    add_custom_command(
        OUTPUT
            "eel2-gas-validate-stamp.txt"
        COMMAND
            "${CMAKE_COMMAND}"
            "-DSOURCE_FILE=${CMAKE_SOURCE_DIR}/thirdparty/WDL/source/WDL/eel2/asm-nseel-x64-sse.asm"
            "-DCHECKSUM_FILE=${CMAKE_SOURCE_DIR}/sources/eel2-gas/sources/ref-hash-sha512.txt"
            "-DTEXT_MODE=ON"
            "-P" "${PROJECT_SOURCE_DIR}/cmake/ValidateSHA512.cmake"
        COMMAND
            "${CMAKE_COMMAND}" "-E" "touch" "${CMAKE_CURRENT_BINARY_DIR}/eel2-gas-validate-stamp.txt"
        DEPENDS
            "thirdparty/WDL/source/WDL/eel2/asm-nseel-x64-sse.asm"
            "sources/eel2-gas/sources/ref-hash-sha512.txt")
    add_custom_target(eel2-gas-validate DEPENDS "eel2-gas-validate-stamp.txt")
    add_dependencies(eel2 eel2-gas-validate)
endif()
