cmake_minimum_required(VERSION 3.10.2)

project(daisykitsdk)

# Use Release build type if not specified
if (NOT EXISTS ${CMAKE_BINARY_DIR}/CMakeCache.txt)
  if (NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE "Release" CACHE STRING "" FORCE)
  endif()
endif()

if(CMAKE_TOOLCHAIN_FILE)
    set(LIBRARY_OUTPUT_PATH_ROOT ${CMAKE_BINARY_DIR} CACHE PATH "root for library output, set this to change where android libs are compiled to")
    # Get absolute path, but get_filename_component ABSOLUTE only refer with source dir, so find_file here.
    get_filename_component(CMAKE_TOOLCHAIN_FILE_NAME ${CMAKE_TOOLCHAIN_FILE} NAME)
    find_file(CMAKE_TOOLCHAIN_FILE ${CMAKE_TOOLCHAIN_FILE_NAME} PATHS ${CMAKE_SOURCE_DIR} NO_DEFAULT_PATH)
    message(STATUS "CMAKE_TOOLCHAIN_FILE = ${CMAKE_TOOLCHAIN_FILE}")
endif()

if(NOT DEFINED CMAKE_INSTALL_PREFIX)
    set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install" CACHE PATH "Installation Directory")
endif()
message(STATUS "CMAKE_INSTALL_PREFIX = ${CMAKE_INSTALL_PREFIX}")

if(NOT DEFINED DAISYKIT_VERSION)
    string(TIMESTAMP DAISYKIT_VERSION "%Y%m%d")
endif()

set(DAISYKIT_VERSION_MAJOR 0)
set(DAISYKIT_VERSION_MINOR 1)
# macos / ios only accepts a.b.c.d.e where a=24bit b/c/d/e=10bit
set(DAISYKIT_VERSION_PATCH_DARWIN 21.11.20)
# for other OSes
set(DAISYKIT_VERSION_PATCH_OTHERS 20211120)

if(APPLE OR IOS)
    set(DAISYKIT_VERSION_STRING ${DAISYKIT_VERSION_MAJOR}.${DAISYKIT_VERSION_MINOR}.${DAISYKIT_VERSION_PATCH_DARWIN})
else()
    set(DAISYKIT_VERSION_STRING ${DAISYKIT_VERSION_MAJOR}.${DAISYKIT_VERSION_MINOR}.${DAISYKIT_VERSION_PATCH_OTHERS})
endif()
message(STATUS "DAISYKIT_VERSION_STRING = ${DAISYKIT_VERSION_STRING}")

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_EXTENSIONS ON)
set(CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} -fexceptions -frtti -fPIC")

option(ncnn_FIND_PATH "Path to NCNN library" "~/Apps/ncnn-20210720-ubuntu-1804")
option(DAISYKIT_ENABLE_BARCODE_SCANNER "Enable barcode scanner" ON)
option(DAISYKIT_BUILD_EXAMPLES "Build examples" ON)
option(DAISYKIT_BUILD_PYTHON "Build Python packages" OFF)
option(DAISYKIT_BUILD_DOCS "Build documentation" OFF)
option(DAISYKIT_BUILD_SHARED_LIB "Build shared lib for dasiykitsdk. Set this value to OFF for static lib." OFF)
option(DAISYKIT_WITH_VULKAN "Build with Vulkan" ON)
option(DAISYKIT_COPY_ASSETS "Copy assets to bin folder" ON)

include_directories(include .)

if(ANDROID)
MESSAGE(STATUS "COMPILE_ANDROID")
    set(OpenCV_DIR ${CMAKE_SOURCE_DIR}/third_party/opencv-mobile-4.5.3-android/sdk/native/jni)
    set(ncnn_DIR ${CMAKE_SOURCE_DIR}/third_party/ncnn-20210720-android-vulkan/${ANDROID_ABI}/lib/cmake/ncnn)
    find_package(ncnn REQUIRED)
else()
    if (DAISYKIT_WITH_VULKAN)
        find_package(Vulkan)
        # If not found Vulkan, disable GPU support
        if(NOT Vulkan_FOUND)
            message("Vulkan is not found. Disabling GPU support.")
            set(DAISYKIT_WITH_VULKAN OFF)
        endif()
        option(NCNN_VULKAN "" ${DAISYKIT_WITH_VULKAN})
    endif()
    if (DAISYKIT_WITH_VULKAN)
        add_compile_definitions(DAISYKIT_WITH_VULKAN)
    endif()
    include_directories(${ncnn_FIND_PATH}/include/ncnn)

    message(${ncnn_FIND_PATH}/lib/cmake/ncnn)
    set(ncnn_DIR ${ncnn_FIND_PATH}/lib/cmake/ncnn)
    find_package(ncnn)
endif()

if(NOT ${ncnn_FOUND})
  message("Missing prebuilt ncnn. Building from source.")
  option(NCNN_BUILD_BENCHMARK "" OFF)
  option(NCNN_PYTHON "" OFF)
  option(NCNN_BUILD_TOOLS "" OFF)
  option(NCNN_BUILD_EXAMPLES "" OFF)
  option(NCNN_VULKAN "" ${DAISYKIT_WITH_VULKAN})
  add_subdirectory(third_party/ncnn ${CMAKE_BINARY_DIR}/bin_ncnn)
endif()

find_package(OpenCV REQUIRED PATHS ${OpenCV_DIR})

set(sources
    src/models/ncnn_model.cpp
    src/models/image_model.cpp
    src/models/body_detector.cpp
    src/models/pose_detector.cpp
    src/models/pose_detector_movenet.cpp
    src/models/action_classifier.cpp
    src/models/face_detector.cpp
    src/models/facial_landmark_detector.cpp
    src/models/background_matting.cpp
    src/models/yolox_utils.cpp
    src/models/hand_detector_yolox.cpp
    src/models/hand_pose_detector.cpp
    src/models/object_detector_yolox.cpp

    src/common/visualizers/base_visualizer.cpp
    src/common/profiler.cpp
    src/common/utils/timer.cpp
    src/common/io/data_reader.cpp

    src/processors/signal_processors/signal_smoothing.cpp
    src/processors/signal_processors/z_score_filter.cpp
    src/processors/image_processors/img_utils.cpp
    src/processors/fitness/pushup_analyzer.cpp

    src/graphs/core/node.cpp
    src/graphs/core/connection.cpp
    src/graphs/core/graph.cpp
    src/graphs/core/packet.cpp
    src/graphs/core/transmission_profile.cpp


    src/flows/object_detector_flow.cpp
    src/flows/pushup_counter_flow.cpp
    src/flows/face_detector_flow.cpp
    src/flows/background_matting_flow.cpp
    src/flows/human_pose_movenet_flow.cpp
    src/flows/hand_pose_detector_flow.cpp

)

# Add platform specific source files
if (ANDROID)
set(sources ${sources} 
    src/common/io/android_assets_stream.cpp)
endif()

# Add barcode scanner
if (DAISYKIT_ENABLE_BARCODE_SCANNER)
    add_subdirectory(third_party/zxing-cpp)
    include_directories(third_party/zxing-cpp/core/src)
    include_directories(third_party/zxing-cpp/opencv/src)
    set(sources ${sources} 
        src/flows/barcode_scanner_flow.cpp)
endif()

if (DAISYKIT_BUILD_SHARED_LIB)
    add_library(daisykitsdk SHARED ${sources})
else()
    add_library(daisykitsdk STATIC ${sources})
endif()

target_link_libraries(daisykitsdk ncnn ${OpenCV_LIBS})

if (DAISYKIT_ENABLE_BARCODE_SCANNER)
    target_link_libraries(daisykitsdk ZXing::ZXing)
endif()


if (WIN32)
# Copy OpenCV library along with daisykit
get_target_property(__dll_dbg opencv_world IMPORTED_LOCATION_DEBUG)
get_target_property(__dll_release opencv_world  IMPORTED_LOCATION_RELEASE)
add_custom_command(TARGET daisykitsdk POST_BUILD        # Adds a post-build event the TARGET
COMMAND ${CMAKE_COMMAND} -E copy_if_different           # which executes "cmake - E copy_if_different..."
    "$<$<CONFIG:debug>:${__dll_dbg}>$<$<CONFIG:release>:${__dll_release}>"      # <--this is in-file
    "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}"
    COMMENT "Copy opencv_world")
endif()

# ==================================================
# Build examples
# ==================================================
if ((NOT ANDROID) AND DAISYKIT_BUILD_EXAMPLES)
    add_subdirectory(src/examples)
endif()


# ==================================================
# Copy asset folders
# ==================================================
if (DAISYKIT_COPY_ASSETS)
    add_custom_target(configs ALL
        COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/assets/configs ${CMAKE_BINARY_DIR}/configs)
    add_custom_target(models ALL
        COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/assets/models ${CMAKE_BINARY_DIR}/models)
    add_custom_target(images ALL
        COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/assets/images ${CMAKE_BINARY_DIR}/images)
endif()

# ==================================================
# Build Python package
# ==================================================
if(DAISYKIT_BUILD_PYTHON)
    add_subdirectory(python)
endif()
