# CMake file for building simple Open Inventor example programs.
#
# This "generic" CMakeLists.txt file can be used to quickly create project
# files for almost any Open Inventor example program, including most (but
# not all) example programs that depend on Qt. The resulting project files
# build the executable in a sub-directory below the project directory and
# do not modify any files provided with the SDK.
#
# We call it the "generic" CMakeLists.txt because, by default it pulls in all
# the source files in the same directory and creates a project with the generic
# name "OIV_Example".  This generic behavior is very convenient for modifying
# and rebuilding multiple example programs. You can simply copy the files for
# an Open Inventor example into a directory, replace the specific CMakeLists.txt
# with the generic one, re-run CMake and build the resulting project.
#
# The generic CMakeLists.txt file is also useful as an example for adding Open
# Inventor support to your own CMake files or as a starting point for creating
# CMake files for an Open Inventor project. This file shows how to compile with
# the Open Inventor header files and link with the Open Inventor libraries using
# the CMake command _find_package_.  It also shows how to (optionally) combine
# Open Inventor with Qt.
#
# Requires these environment variables be set:
#   - OpenInventor_DIR : where the OpenInventor.config file is, i.e. OIVHOME/source/cmake/config
#
#     and if using Qt
#   - Qt<N>_DIR : where the Qt<N>Config.cmake (with N is either 5 or 6) file is
#               or
#   - QTDIR   : where the bin, include and lib directories are
#
# To build an Open Inventor example program:
#   1. Copy the source, header (and if necessary) data files.
#   2. Run cmake (or on Windows run cmake-gui).
#   3. Load the resulting project or make file.
#
# Qt:
#   By default we ask CMake to find and link against Qt.
#   This is "just in case". Most Open Inventor examples do _not_ require Qt.
#   If you do not need Qt, do one of the following:
#     - Change the default value for NEED_QT below.
#     - Command line: Run CMake with "-DNEED_QT=OFF".
#     - Cmake-gui: Check the NEED_QT box under "Ungrouped Entries".

# CMake options
cmake_minimum_required(VERSION "3.10" FATAL_ERROR)
set(CMAKE_INCLUDE_CURRENT_DIR ON) # In case include files are in the project src directory.

# Set default and create gui option for (not) using Qt.
set(NEED_QT ON CACHE BOOL "Find and link Qt")
option(NEED_QT "Set this option to find and link Qt" ON)

# Declare project name
# NOTE: This must come before almost everything else!
#       Else CMake will fail with error "ADD_LIBRARY was called with SHARED option
#       but the target platform does not support dynamic linking".
# Automatically sets variable PROJECT_NAME (used later)
Project(OIV_Example)

# Look for Open Inventor includes and libraries

# OpenInventor_DIR cache value is needed by the function 'find_package(OpenInventor...). If OIVHOME
# environment variable is set, this cache value is forced to be defined according to this environment
# variable.
if(EXISTS "$ENV{OIVHOME}")
  set(OpenInventor_DIR "$ENV{OIVHOME}/source/cmake/config" CACHE PATH "Open Inventor CMake path" FORCE)
endif()

# find_package(OpenInventor)
#   - Sets an OpenInventor_FOUND variable. :-)
#   - Sets a target for every component of Open Inventor, e.g. OIV::fei_inventor
#     - also sets a variable with the legacy nema. e.g. OpenInventor_LIBRARIES
#     When linking against these targets, the include dir is automatically set
#        and dependencies are linked against (e.g. linking against OIV::fei_volumeViz
#        will link against OIV::fei_inventor, among others)
#   - Sets the OIV_INCLUDE_DIR variable, for legacy purposes.
#
# Note: You can specify a list of COMPONENTS to be found (e.g. volumeViz)
# but its dependencies are not automatically resolved yet, and you will have to
# specify them
find_package(OpenInventor REQUIRED)

# Display the Open Inventor version number (not required).
file(STRINGS ${OIV_INCLUDE_DIR}/SoVersion.h TEMP REGEX "\"[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\"")
string(REGEX MATCH "[0-9]+\.[0-9]+\.[0-9]+" OIV_Version ${TEMP})
message(STATUS "OIV_Version: ${OIV_Version}")

# Look for Qt includes and libraries (if needed)
#   - Set 'NEED_QT' to OFF to avoid cluttering project with Qt.
#     Most OIV example programs do not require Qt.
#   - Only the 'Widgets' component is required for simple OIV example programs.
#     Add additional components as needed!
if(NEED_QT)
  # Qt6 is supported for Visual Studio >= 2022, and Qt5 for any other platform.
  set(TARGETED_QT_VERSION Qt5)
  if(NOT OIV_FORCE_QT5 AND CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
    if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 19.30)
      set(TARGETED_QT_VERSION Qt6)
    endif()
  endif()
  # Qt5_DIR/Qt6_DIR cache value is needed by the function 'find_package(Qt${QT_VERSION_MAJOR}...). If QTDIR environment
  # variable is set, this cache value is forced to be defined according to this environment
  # variable.
  if(EXISTS "$ENV{QTDIR}")
    set(${TARGETED_QT_VERSION}_DIR $ENV{QTDIR}/lib/cmake/${TARGETED_QT_VERSION})
  endif()
  find_package(QT NAMES ${TARGETED_QT_VERSION} COMPONENTS Widgets QUIET)

  if(NOT QT_VERSION_MAJOR)
    set(QT_VERSION_MAJOR 5)
    if(TARGETED_QT_VERSION STREQUAL Qt6)
      set(QT_VERSION_MAJOR 6)
    endif()
  endif()
  find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Widgets QUIET)

  if(Qt${QT_VERSION_MAJOR}_FOUND)
    set(CMAKE_AUTOMOC ON)
    set(CMAKE_AUTOUIC ON)
  endif()
endif()

# Set per-platform output directories local to the project.
# Note: None of these lines are required! Just convenient for multiple platforms.
if(APPLE)
  SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib/macos/)
  SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib/macos/)
  SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin/macos/)
elseif(UNIX)
  SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib/linux/)
  SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib/linux/)
  SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin/linux/)
elseif(WIN32)
  SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib/win/)
  SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib/win/)
  SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin/win/)
endif()

if(MSVC_IDE)
  # If using Visual Studio, make the real project the 'startup' project
  # instead of ALL_BUILD.  Much more convenient for starting the debugger.
  set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME}) 
endif()

# -----------------------------------------------------------------------------
# The actual project

# Source files
# "GLOB" allows you to drop any example program into the directory and build it.
# --> A real project should explicitly define its source files like this:
# set(SOURCES
#   file1.cxx
#   file2.cxx
# )
file(GLOB SOURCES *.cxx)

# This is not mandatory.
# But it is useful to see the header files in the Visual Studio IDE.
# See previous comment about file GLOB versus explicit names.
# set(HEADERS
#   header1.h
# )
file(GLOB HEADERS *.h)

# Define the project target and required files.
# NOTE: Do NOT use the old add_oiv_executable macro.
#       It sets the output directory to the SDK demo executable directory!
add_executable( ${PROJECT_NAME} ${SOURCES} ${HEADERS} )
message(STATUS "${PROJECT_NAME} ${SOURCES} ${HEADERS}")

# Open Inventor includes
target_include_directories(${PROJECT_NAME} PUBLIC ${OIV_INCLUDE_DIR} )

# Open Inventor libraries as needed.
# Here we request most of the OIV component libraries for convenience.
# --> You will need to modify this if you use other OIV components.
target_link_libraries(${PROJECT_NAME}
    #OIV::fei_inventor_base #not necessary, as it is a dependency of inventor
    #OIV::fei_inventor #not necessary, as it is a dependency of volumeViz
    OIV::fei_inventor_ViewerComponents
    OIV::fei_inventor_QtViewerComponents
    OIV::fei_ivTune

    OIV::fei_inventor_medical
    OIV::fei_volumeViz
    #OIV::fei_ldm #not necessary, as it is a dependency of volumeViz
    OIV::fei_inventor_ui
    OIV::fei_dialogViz
)

# Qt libraries if needed.
# --> Examples with an actual Qt GUI may need additional Qt components.
if(Qt${QT_VERSION_MAJOR}_FOUND)
  message(STATUS "Qt${QT_VERSION_MAJOR} found")
  target_link_libraries(${PROJECT_NAME} Qt::Widgets)
endif()

message(STATUS "ProjectName = " ${PROJECT_NAME})
