cmake_minimum_required(VERSION 3.0.2)
project(robot_base_local_planner VERSION 1.0.0 LANGUAGES CXX)

# ========================================================
# Detect Catkin or Standalone
# ========================================================
if(DEFINED CATKIN_DEVEL_PREFIX OR DEFINED CATKIN_TOPLEVEL)
  set(BUILDING_WITH_CATKIN TRUE)
  message(STATUS "Building robot_base_local_planner with Catkin")
else()
  set(BUILDING_WITH_CATKIN FALSE)
  message(STATUS "Building robot_base_local_planner with Standalone CMake")
endif()

# ========================================================
# C++ Standard
# ========================================================
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

add_compile_options(-Wall -Wextra -Wpedantic)

# ========================================================
# Dependencies
# ========================================================
find_package(Boost REQUIRED COMPONENTS thread)
find_package(Eigen3 REQUIRED)

# ========================================================
# Catkin configuration
# ========================================================
if(BUILDING_WITH_CATKIN)

  find_package(catkin REQUIRED COMPONENTS
    robot_angles
    robot_costmap_2d
    robot_std_msgs
    robot_geometry_msgs
    robot_sensor_msgs
    robot_nav_msgs
    robot_cpp
    tf3
    robot_tf3_geometry_msgs
    robot_voxel_grid
    data_convert
  )

  catkin_package(
    INCLUDE_DIRS include
    LIBRARIES ${PROJECT_NAME}
    CATKIN_DEPENDS
      robot_angles
      robot_costmap_2d
      robot_std_msgs
      robot_geometry_msgs
      robot_sensor_msgs
      robot_nav_msgs
      robot_cpp
      tf3
      robot_tf3_geometry_msgs
      robot_voxel_grid
      data_convert
    DEPENDS Boost Eigen3
  )

else()

# ========================================================
# Standalone configuration
# ========================================================

  set(CMAKE_POSITION_INDEPENDENT_CODE ON)

  set(CMAKE_BUILD_RPATH_USE_ORIGIN TRUE)
  set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
  set(CMAKE_BUILD_RPATH "${CMAKE_BINARY_DIR}")

  set(PACKAGES_DIR
    robot_angles
    robot_costmap_2d
    robot_std_msgs
    robot_geometry_msgs
    robot_sensor_msgs
    robot_nav_msgs
    robot_cpp
    tf3
    robot_tf3_geometry_msgs
    robot_voxel_grid
    data_convert
  )

endif()

# ========================================================
# Check headers
# ========================================================
include(CheckIncludeFile)

check_include_file(sys/time.h HAVE_SYS_TIME_H)

if(HAVE_SYS_TIME_H)
  add_definitions(-DHAVE_SYS_TIME_H)
endif()

# ========================================================
# Library
# ========================================================
add_library(${PROJECT_NAME} SHARED

  src/footprint_helper.cpp
  src/goal_functions.cpp
  src/map_cell.cpp
  src/map_grid.cpp
  src/map_grid_visualizer.cpp
  src/map_grid_cost_function.cpp
  src/obstacle_cost_function.cpp
  src/oscillation_cost_function.cpp
  src/prefer_forward_cost_function.cpp
  src/point_grid.cpp
  src/costmap_model.cpp
  src/simple_scored_sampling_planner.cpp
  src/simple_trajectory_generator.cpp
  src/trajectory.cpp
  src/twirling_cost_function.cpp
  src/voxel_grid_model.cpp
)

# ========================================================
# Include directories
# ========================================================
target_include_directories(${PROJECT_NAME}

  PUBLIC
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    $<INSTALL_INTERFACE:include>

)

# ========================================================
# Dependencies
# ========================================================
if(BUILDING_WITH_CATKIN)

  add_dependencies(${PROJECT_NAME}
    ${catkin_EXPORTED_TARGETS}
  )

  target_link_libraries(${PROJECT_NAME}

    PUBLIC
      ${catkin_LIBRARIES}

    PRIVATE
      Boost::thread
      Eigen3::Eigen
  )

else()

  target_link_libraries(${PROJECT_NAME}

    PUBLIC
      ${PACKAGES_DIR}

    PRIVATE
      Boost::thread
      Eigen3::Eigen
  )

  set_target_properties(${PROJECT_NAME} PROPERTIES
    LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}
    BUILD_RPATH "${CMAKE_BINARY_DIR}"
    INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib"
  )

endif()

# ========================================================
# Install
# ========================================================
if(BUILDING_WITH_CATKIN)

  install(TARGETS ${PROJECT_NAME}

    ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
    LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
    RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION}
  )

  install(DIRECTORY include/${PROJECT_NAME}/
    DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
  )

else()

  install(TARGETS ${PROJECT_NAME}
    EXPORT ${PROJECT_NAME}-targets
    LIBRARY DESTINATION lib
    ARCHIVE DESTINATION lib
  )

  install(EXPORT ${PROJECT_NAME}-targets
    FILE ${PROJECT_NAME}-targets.cmake
    NAMESPACE ${PROJECT_NAME}::
    DESTINATION lib/cmake/${PROJECT_NAME}
  )

  install(DIRECTORY include/${PROJECT_NAME}/
    DESTINATION include
  )

  message(STATUS "=================================")
  message(STATUS "Project: ${PROJECT_NAME}")
  message(STATUS "Version: ${PROJECT_VERSION}")
  message(STATUS "C++ Standard: ${CMAKE_CXX_STANDARD}")
  message(STATUS "Libraries: ${PROJECT_NAME}")
  message(STATUS "=================================")

endif()
