#  Copyright 2014-2019, Parker Owan
#  PhD Dissertation, University of Washington
#
#  CMake Lists for hole cleaning application
#
#  Dependencies:
#  Eigen, Boost, OpenCV, CoreRobotics, CHAI3d, and GTest (optional)
#  If these are in non-standard locations (i.e. not /usr/local), 
#  then you need to set the paths so CMake can find these packages:
#  Windows: >> set CMAKE_PREFIX_PATH=...
#  Unix: >> set CMAKE_PREFIX_PATH=...
#
#  On Mac, this is easy:
#  >> cmake -G "Xcode" -DHEBI_DIR="~/Documents/hebi" ..
#
#  

# Output each path in the CMAKE_PREFIX_PATH
foreach(path ${CMAKE_PREFIX_PATH})
    message("Path: " ${path})
endforeach(path)

cmake_minimum_required (VERSION 3.5)
project (app-brush)

# Set variables
SET (ROBOT_TARGET_NAME "app-brush")
SET (TEST_TARGET_NAME "app-tests")
SET (HEBINAME "hebi")

# Set compiler parameters
SET (CMAKE_CXX_STANDARD 11)
SET (CMAKE_CXX_STANDARD_REQUIRED ON)


# DEPENDENCIES

# Find external dependencies
find_package (OpenGL REQUIRED)
find_package (CoreRobotics 2.0.0 REQUIRED)
find_package (OpenCV REQUIRED)
find_package (CHAI3D REQUIRED)
find_package (tinyxml2 REQUIRED)
find_package (GTest)

# include the hebi cmake
if (NOT HEBI_DIR)
    message(FATAL_ERROR "HEBI_DIR not specified")
endif()
include(${HEBI_DIR}/cmake/hebi_platform.cmake)

# set the hebi library subdirectories
if(HEBI_HOST_LINUX)
  set(HEBI_C_LIB_SUBDIR "lib/linux_${HEBI_TARGET_ARCH}")
elseif(HEBI_HOST_WINDOWS)
  set(HEBI_C_LIB_SUBDIR "lib/win_${HEBI_TARGET_ARCH}")
elseif(HEBI_HOST_OSX)
  set(HEBI_C_LIB_SUBDIR "lib/osx_${HEBI_TARGET_ARCH}")
else()
  message(FATAL_ERROR "Unknown host platform")
endif()

# Windows global build options - for CHAI3d
message(STATUS ${CMAKE_SYSTEM_NAME})
if (CMAKE_SYSTEM_NAME MATCHES Windows)
    # VisualStudio compiler
    if (MSVC)
        add_definitions (-D_T_SECURE_NO_DEPRECATE)
        if (CMAKE_CL_64)
            add_definitions (-DWIN64)
        else ()
            add_definitions (-DWIN32)
        endif ()
    endif()
# Linux global build options
elseif (CMAKE_SYSTEM_NAME MATCHES Linux)
    add_definitions (-DLINUX)
# Mac OS X global build options
elseif (CMAKE_SYSTEM_NAME MATCHES Darwin)
    add_definitions (-DMACOSX)
endif ()

# Find GLUT/GL
if (CMAKE_SYSTEM_NAME MATCHES Windows)
	find_package (FreeGLUT REQUIRED)
elseif (CMAKE_SYSTEM_NAME MATCHES Darwin)
	find_package (GLUT REQUIRED)
endif ()

# header search paths
include_directories(
	${CMAKE_CURRENT_SOURCE_DIR}/src
    ${CMAKE_CURRENT_SOURCE_DIR}/lib
    ${CMAKE_CURRENT_SOURCE_DIR}/include
	${HEBI_DIR}/src
	${HEBI_DIR}/include
	${OpenCV_INCLUDE_DIRS}
    ${CHAI3D_INCLUDE_DIRS}
    ${OPENGL_INCLUDE_DIRS}
    ${GLUT_INCLUDE_DIRS} #mac
	${FREEGLUT_INCLUDE_DIRS} #windows
    ${CR_INCLUDE_DIRS}
)

# linker directories
link_directories(
    ${CR_LIBRARY_DIRS}
    ${CHAI3D_LIBRARY_DIRS}
	${HEBI_DIR}/${HEBI_C_LIB_SUBDIR}
)


# HEBI SETUP

# Add HEBI source files
# These are all of the source files required to
# build the C++ wrapper for the C API.
add_library(HEBI_CPP_FILES OBJECT
    ${HEBI_DIR}/src/command.cpp
    ${HEBI_DIR}/src/feedback.cpp
    ${HEBI_DIR}/src/group_command.cpp
    ${HEBI_DIR}/src/group.cpp
    ${HEBI_DIR}/src/group_feedback.cpp
    ${HEBI_DIR}/src/group_info.cpp
    ${HEBI_DIR}/src/info.cpp
    ${HEBI_DIR}/src/kinematics.cpp
    ${HEBI_DIR}/src/lookup.cpp
    ${HEBI_DIR}/src/mac_address.cpp
    ${HEBI_DIR}/src/trajectory.cpp
    ${HEBI_DIR}/src/log_file.cpp
)

# include the source code to build:
file(GLOB SOURCE_FILES
	${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp
	${CMAKE_CURRENT_SOURCE_DIR}/src/*.h
	${CMAKE_CURRENT_SOURCE_DIR}/src/*.hpp
)

# inlude the lib files to build
file(GLOB LIB_FILES
    ${CMAKE_CURRENT_SOURCE_DIR}/lib/*.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/lib/*.h
    ${CMAKE_CURRENT_SOURCE_DIR}/lib/*.hpp
    ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h
    ${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp
)

# HEBI turns off the exceptions, boost needs them enabled
IF(MSVC)
    ADD_DEFINITIONS("/EHsc")
ENDIF(MSVC)


# BUILD

# Set the exectuable target
add_executable(${ROBOT_TARGET_NAME} ${SOURCE_FILES} ${LIB_FILES}
    $<TARGET_OBJECTS:HEBI_CPP_FILES>)
target_link_libraries(${ROBOT_TARGET_NAME} ${OpenCV_LIBS}
    ${CHAI3D_LIBRARIES} ${OPENGL_LIBRARIES} ${GLUT_LIBRARY}
    ${FREEGLUT_LIBRARIES} ${CR_LIBRARIES} tinyxml2)

# hebi target links
if (WIN32)
    target_link_libraries( ${ROBOT_TARGET_NAME} "hebi" kernel32 )
else()
    target_link_libraries( ${ROBOT_TARGET_NAME} "hebi" m pthread )
endif()

# put the files into some groups
source_group("\\src" FILES ${SOURCE_FILES})
source_group("\\lib" FILES ${LIB_FILES})


# COPY DYNAMIC LIBRARIES

# Copy over any missing dlls we need to the target directory
# Copy the Hebi .dll
if (WIN32)
    add_custom_command( TARGET ${ROBOT_TARGET_NAME} POST_BUILD
        COMMAND ${CMAKE_COMMAND} -E copy_if_different
        "${HEBI_DIR}/${HEBI_C_LIB_SUBDIR}/${HEBINAME}.dll"
        $<TARGET_FILE_DIR:${ROBOT_TARGET_NAME}>)

	# Glob the opencv .dlls
	file(GLOB OPENCV_DLLS src/core/*.hpp )

	# and generate a new copy for each
	add_custom_command( TARGET ${ROBOT_TARGET_NAME} POST_BUILD
        COMMAND ${CMAKE_COMMAND} -E copy_if_different
        "${HEBI_DIR}/${HEBI_C_LIB_SUBDIR}/${HEBINAME}.dll"
        $<TARGET_FILE_DIR:${ROBOT_TARGET_NAME}>)
endif()

# copy over dylib
if (APPLE)
    add_custom_command( TARGET ${ROBOT_TARGET_NAME} POST_BUILD
        COMMAND ${CMAKE_COMMAND} -E copy_if_different
        "${HEBI_DIR}/${HEBI_C_LIB_SUBDIR}/libhebi.1.0.dylib"
        "${HEBI_DIR}/${HEBI_C_LIB_SUBDIR}/libhebi.1.dylib"
        "${HEBI_DIR}/${HEBI_C_LIB_SUBDIR}/libhebi.dylib"
        $<TARGET_FILE_DIR:${ROBOT_TARGET_NAME}>)
endif()


# BUILD TESTS

# Get the test files
file(GLOB TESTS tests/*.cpp)

# Check for GTest
if(NOT GTEST_FOUND)
    message(STATUS "GTEST not found, not building the test suite")

else()
    message(STATUS "GTEST found, building the test suite")

    # add the gtest includes
    include_directories(${GTEST_INCLUDE_DIRS})

    # Add an executable for the tests
    add_executable(${TEST_TARGET_NAME} ${TESTS} ${LIB_FILES})

    # Link the library binary
    target_link_libraries(${TEST_TARGET_NAME}
        ${GTEST_LIBRARIES} ${OpenCV_LIBS}
        ${CHAI3D_LIBRARIES} ${OPENGL_LIBRARIES} ${GLUT_LIBRARY}
        ${FREEGLUT_LIBRARIES} ${CR_LIBRARIES})

endif()

