# ______ _           _ _____                    _   _             _______  _____  _
# |  ___(_)         | |_   _|                  | | (_)           | | ___ \/  __ \| |
# | |_   _ _ __   __| | | | __ _ _ __ __ _  ___| |_ _ _______  __| | |_/ /| /  \/| |
# |  _| | | '_ \ / _` | | |/ _` | '__/ _` |/ _ \ __| |_  / _ \/ _` |  __/ | |    | |
# | |   | | | | | (_| | | | (_| | | | (_| |  __/ |_| |/ /  __/ (_| | |    | \__/\| |____
# \_|   |_|_| |_|\__,_| \_/\__,_|_|  \__, |\___|\__|_/___\___|\__,_\_|     \____/\_____/
# zhengrr                             __/ |
# 2021-10-21 – 2021-10-21            |___/
# Unlicense

cmake_minimum_required(VERSION 3.12)
cmake_policy(VERSION 3.12)

include_guard()  # 3.10

if(NOT COMMAND rr_add_library)
  include("${CMAKE_CURRENT_LIST_DIR}/rrCMake/rrAddLibrary.cmake")
endif()

#[=======================================================================[.rst:
FindTargetizedPCL
-----------------

Find the `Point Cloud Library <https://pointclouds.org/>`_ and wrap with targets if version 1.11.1.

IMPORTED Targets
^^^^^^^^^^^^^^^^

This module defines the following :prop_tgt:`IMPORTED` targets:

``PCL::PCL``
  The Point Cloud Library, if found and wrapped.

Result Variables
^^^^^^^^^^^^^^^^

This module defines the following variables:

``TargetizedPCL_FOUND``
  Found the Point Cloud Library.
#]=======================================================================]

if(TargetizedPCL_FOUND)
  return()
endif()

if(TargetizedPCL_FIND_REQUIRED)
  set(oRequired REQUIRED)
else()
  set(oRequired)
endif()

set(zRequiredComponents)
set(zOptionalComponents)
foreach(sComponent IN LISTS TargetizedPCL_FIND_COMPONENTS)
  if("TargetizedPCL_FIND_REQUIRED_${sComponent}")
    list(APPEND zRequiredComponents "${sComponent}")
  else()
    list(APPEND zOptionalComponents "${sComponent}")
  endif()
endforeach()
if(NOT zRequiredComponents STREQUAL "")
  set(oRequiredComponents COMPONENTS ${zRequiredComponents})
else()
  set(oRequiredComponents)
endif()
if(NOT zOptionalComponents STREQUAL "")
  set(oOptionalComponents OPTIONAL_COMPONENTS ${zOptionalComponents})
else()
  set(oOptionalComponents)
endif()

# PCL
set(sTmp "${CMAKE_MESSAGE_LOG_LEVEL}")
set(CMAKE_MESSAGE_LOG_LEVEL "ERROR")
find_package(
  PCL CONFIG
  ${oRequired}
  ${oRequiredComponents}
  ${oOptionalComponents})
set(CMAKE_MESSAGE_LOG_LEVEL "${sTmp}")

set(TargetizedPCL_FOUND "${PCL_FOUND}")
if(NOT PCL_FOUND)
  return()
endif()

if(PCL_VERSION VERSION_EQUAL "1.11.1" AND WIN32)
  # PCL::<shared-components>
  if(PCL_FOUND)
    set(zPclSharedComponents ${pcl_all_components})
    list(REMOVE_ITEM zPclSharedComponents "2d" "geometry")
    foreach(sPclComponent IN LISTS zPclSharedComponents)
      rr_add_library(
        "PCL::${sPclComponent}" SHARED                  IMPORTED
        PROPERTIES              IMPORTED_IMPLIB_DEBUG   "${PCL_ROOT}/lib/pcl_${sPclComponent}d.lib"
                                IMPORTED_LOCATION_DEBUG "${PCL_ROOT}/bin/pcl_${sPclComponent}d.dll"
                                IMPORTED_IMPLIB         "${PCL_ROOT}/lib/pcl_${sPclComponent}.lib"
                                IMPORTED_LOCATION       "${PCL_ROOT}/bin/pcl_${sPclComponent}.dll")
      if(TARGET "pcl_${sPclComponent}")
        target_link_libraries("pcl_${sPclComponent}" INTERFACE "PCL::${sPclComponent}")
      endif()
    endforeach()
  endif()

  # PCL::io_ply
  if(PCL_FOUND)
    rr_add_library(
      PCL::io_ply SHARED                  IMPORTED
      PROPERTIES  IMPORTED_IMPLIB_DEBUG   "${PCL_ROOT}/lib/pcl_io_plyd.lib"
                  IMPORTED_LOCATION_DEBUG "${PCL_ROOT}/bin/pcl_io_plyd.dll"
                  IMPORTED_IMPLIB         "${PCL_ROOT}/lib/pcl_io_ply.lib"
                  IMPORTED_LOCATION       "${PCL_ROOT}/bin/pcl_io_ply.dll")
    if(TARGET pcl_io)
      target_link_libraries(pcl_io INTERFACE PCL::io_ply)
    endif()
  endif()

  # PCL::FLANN
  if(FLANN_FOUND)
    rr_add_library(
      PCL::FLANN          SHARED            IMPORTED
      PROPERTIES          IMPORTED_IMPLIB   "${FLANN_ROOT}/lib/flann.lib"
                          IMPORTED_LOCATION "${FLANN_ROOT}/bin/flann.dll"
      INCLUDE_DIRECTORIES INTERFACE         "${FLANN_ROOT}/include")
    if(TARGET pcl_kdtree)
      target_link_libraries(pcl_kdtree INTERFACE PCL::FLANN)
    endif()
    if(TARGET pcl_search)
      target_link_libraries(pcl_search INTERFACE PCL::FLANN)
    endif()
  endif()

  # PCL::OpenNI2
  if(OPENNI2_FOUND)
    rr_add_library(
      PCL::OpenNI2        SHARED            IMPORTED
      PROPERTIES          IMPORTED_IMPLIB   "${OPENNI2_LIBRARY}"
                          IMPORTED_LOCATION "${OPENNI2_LIBRARY}/../../Redist/OpenNI2.dll"
      INCLUDE_DIRECTORIES INTERFACE         "${OPENNI2_INCLUDE_DIR}")
    if(TARGET pcl_io)
      target_link_libraries(pcl_io INTERFACE PCL::OpenNI2)
    endif()
    if(TARGET pcl_visualization)
      target_link_libraries(pcl_visualization INTERFACE PCL::OpenNI2)
    endif()
  endif()

  # PCL::PCL
  if(NOT TARGET PCL::PCL)
    rr_add_library(
      PCL::PCL            INTERFACE IMPORTED
      COMPILE_DEFINITIONS INTERFACE ${PCL_DEFINITIONS}
      INCLUDE_DIRECTORIES INTERFACE ${PCL_INCLUDE_DIRS}
      LINK_DIRECTORIES    INTERFACE ${PCL_LIBRARY_DIRS}
      LINK_LIBRARIES      INTERFACE ${PCL_LIBRARIES})
  endif()
endif()
