cmake_minimum_required (VERSION 3.2.2)
project (H4H5Examples C CXX)

#-----------------------------------------------------------------------------
# Instructions for use : Normal Build
#
# For standard build of H4H5 examples.
#-----------------------------------------------------------------------------
set (CMAKE_NO_SYSTEM_FROM_IMPORTED 1)

#-----------------------------------------------------------------------------
# Allow Visual Studio solution directories
#-----------------------------------------------------------------------------
# Provide a way for Visual Studio Express users to turn OFF the new FOLDER
# organization feature. Default to ON for non-Express users. Express users must
# explicitly turn off this option to build H4H5 in the Express IDE...
#
option (HDF_USE_FOLDERS "Enable folder grouping of projects in IDEs." ON)
mark_as_advanced (HDF_USE_FOLDERS)
if (HDF_USE_FOLDERS)
  set_property (GLOBAL PROPERTY USE_FOLDERS ON)
endif ()

#-----------------------------------------------------------------------------
# Define some CMake variables for use later in the project
#-----------------------------------------------------------------------------
set (H4H5EX_RESOURCES_DIR      ${PROJECT_SOURCE_DIR}/config/cmake)
set (H4H5EX_LIB_SRC_DIR        ${PROJECT_SOURCE_DIR}/lib)
set (H4H5EX_UTIL_SRC_DIR       ${PROJECT_SOURCE_DIR}/utils)

#-----------------------------------------------------------------------------
# Include some macros for reusable code
#-----------------------------------------------------------------------------
include (${H4H5EX_RESOURCES_DIR}/HDFMacros.cmake)
include (${H4H5EX_RESOURCES_DIR}/HDF45Macros.cmake)
include (${H4H5EX_RESOURCES_DIR}/H4H5Macros.cmake)

#-----------------------------------------------------------------------------
# Setup output Directories
#-----------------------------------------------------------------------------
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY
    ${PROJECT_BINARY_DIR}/bin CACHE PATH "Single Directory for all Executables."
)
set (CMAKE_LIBRARY_OUTPUT_DIRECTORY
    ${PROJECT_BINARY_DIR}/bin CACHE PATH "Single Directory for all Libraries"
)
set (CMAKE_ARCHIVE_OUTPUT_DIRECTORY
    ${PROJECT_BINARY_DIR}/bin CACHE PATH "Single Directory for all static libraries."
)
set (CMAKE_Fortran_MODULE_DIRECTORY
    ${PROJECT_BINARY_DIR}/bin CACHE PATH "Single Directory for all fortran modules."
)

#-----------------------------------------------------------------------------
# When building utility executables that generate other (source) files :
# we make use of the following variables defined in the root CMakeLists.
# Certain systems may add /Debug or /Release to output paths
# and we need to call the executable from inside the CMake configuration
#-----------------------------------------------------------------------------
set (EXE_EXT "")
if (WIN32)
  set (EXE_EXT ".exe")
  add_definitions (-D_BIND_TO_CURRENT_VCLIBS_VERSION=1)
  add_definitions (-D_CRT_SECURE_NO_WARNINGS)
  add_definitions (-D_CONSOLE)
endif ()

if (MSVC)
  set (CMAKE_MFC_FLAG 0)
endif ()

set (MAKE_SYSTEM)
if (CMAKE_BUILD_TOOL MATCHES "make")
  set (MAKE_SYSTEM 1)
endif ()

set (CFG_INIT "/${CMAKE_CFG_INTDIR}")
if (MAKE_SYSTEM)
  set (CFG_INIT "")
endif ()

#-----------------------------------------------------------------------------
# Compiler specific flags : Shouldn't there be compiler tests for these
#-----------------------------------------------------------------------------
if (CMAKE_COMPILER_IS_GNUCC)
  set (CMAKE_C_FLAGS "${CMAKE_ANSI_CFLAGS} ${CMAKE_C_FLAGS} -std=c99 -fomit-frame-pointer -finline-functions -fno-common")
endif ()
if (CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_LOADED)
  set (CMAKE_CXX_FLAGS "${CMAKE_ANSI_CFLAGS} ${CMAKE_CXX_FLAGS} -fomit-frame-pointer -finline-functions -fno-common")
endif ()

#-----------------------------------------------------------------------------
# H4H5 support
#-----------------------------------------------------------------------------
set (CMAKE_MODULE_PATH ${H4H5EX_RESOURCES_DIR} ${CMAKE_MODULE_PATH})

if (NOT H4H5_H4H5_HEADER)
  if (BUILD_SHARED_LIBS)
    set (FIND_HDF_COMPONENTS C shared static)
  else ()
    set (FIND_HDF_COMPONENTS C static)
  endif ()
  message (STATUS "H4H5 find comps: ${FIND_HDF_COMPONENTS}")
  set (SEARCH_PACKAGE_NAME ${H4H5_PACKAGE_NAME})

  find_package (H4H5 NAMES ${SEARCH_PACKAGE_NAME} COMPONENTS ${FIND_HDF_COMPONENTS})
  message (STATUS "H4H5 C libs:${H4H5_FOUND} static:${H4H5_static_C_FOUND} and shared:${H4H5_shared_C_FOUND}")
  if (H4H5_FOUND)
    if (NOT TARGET h4h5::h4toh5convert)
        add_executable (h4h5::h4toh5convert IMPORTED)
    endif()
    if (NOT TARGET h4h5::h5toh4convert)
        add_executable (h4h5::h5toh4convert IMPORTED)
    endif()
    if (NOT H4H5_static_C_FOUND AND NOT H4H5_shared_C_FOUND)
      set (FIND_HDF_COMPONENTS C)
      message (STATUS "H4H5 find comps: ${FIND_HDF_COMPONENTS}")

      find_package (H4H5 NAMES ${SEARCH_PACKAGE_NAME} COMPONENTS ${FIND_HDF_COMPONENTS})
      message (STATUS "H4H5 libs:${H4H5_FOUND} C:${H4H5_C_FOUND}")
      set (LINK_LIBS ${LINK_LIBS} ${H4H5_LIBRARIES})
      if (H4H5_BUILD_SHARED_LIBS)
        add_definitions (-DH4H5_BUILT_AS_DYNAMIC_LIB)
      else ()
        add_definitions (-DH4H5_BUILT_AS_STATIC_LIB)
      endif ()
      set_property (TARGET h4h5::h4toh5convert PROPERTY IMPORTED_LOCATION "${H4H5_TOOLS_DIR}/h4toh5convert")
      set_property (TARGET h4h5::h5toh4convert PROPERTY IMPORTED_LOCATION "${H4H5_TOOLS_DIR}/h5toh4convert")
    else ()
      if (BUILD_SHARED_LIBS AND H4H5_shared_C_FOUND)
        set (LINK_SHLIBS ${LINK_SHLIBS} ${H4H5_C_SHARED_LIBRARY})
      endif ()
      if (H4H5_static_C_FOUND)
        set (LINK_LIBS ${LINK_LIBS} ${H4H5_C_STATIC_LIBRARY})
      endif ()
    endif ()
    set (H4H5_45CONVERT_EXECUTABLE $<TARGET_FILE:h4h5::h4toh5convert>)
    set (H4H5_54CONVERT_EXECUTABLE $<TARGET_FILE:h4h5::h5toh4convert>)

    set (H4H5_HAVE_H4H5_H 1)
    set (H4H5_HAVE_H4H5 1)
    set (H4H5_H4H5_HEADER "h4toh5.h")
    set (H4H5_INCLUDE_DIR_GEN ${H4H5_INCLUDE_DIR})
    message (STATUS "H4H5-${H4H5_VERSION_STRING} found: INC=${H4H5_INCLUDE_DIR} TOOLS=${H4H5_TOOLS_DIR}")
  else ()
    message (FATAL_ERROR " H4H5 is Required for H4H5 Examples")
  endif ()
  set (H4H5_PACKAGE_NAME ${SEARCH_PACKAGE_NAME})
else ()
  # This project is being called from within another and HDF4 is already configured
  set (H4H5_HAVE_H4H5_H 1)
  set (H4H5_HAVE_H4H5 1)
endif ()

INCLUDE_DIRECTORIES (${H4H5_INCLUDE_DIR})
message (STATUS "H4H5 link libs: ${LINK_LIBS}")
if (BUILD_SHARED_LIBS)
  message (STATUS "H4H5 shared link libs: ${LINK_SHLIBS}")
endif ()

if (WIN32)
  set(CMAKE_TEST_LIB_DIRECTORY "${H4H5_TOOLS_DIR}")
else ()
  set(CMAKE_TEST_LIB_DIRECTORY "${H4H5_LIBRARY_PATH}")
endif ()

set (CMAKE_POSITION_INDEPENDENT_CODE ON)

HDF4_SUPPORT(true)
HDF5_SUPPORT(true)

set (LINK_LIBS ${LINK_LIBS} ${HDF5_LINK_LIBS} ${HDF4_LINK_LIBS})
set (LINK_SHLIBS ${LINK_SHLIBS} ${HDF5_LINK_SHLIBS} ${HDF4_LINK_SHLIBS})

#-----------------------------------------------------------------------------
# Option to allow the user to disable compiler warnings
#-----------------------------------------------------------------------------
option (HDF_DISABLE_COMPILER_WARNINGS "Disable compiler warnings" OFF)
if (HDF_DISABLE_COMPILER_WARNINGS)
  # MSVC uses /w to suppress warnings.  It also complains if another
  # warning level is given, so remove it.
  if (MSVC)
    set (HDF_WARNINGS_BLOCKED 1)
    string (REGEX REPLACE "(^| )([/-])W[0-9]( |$)" " " CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
    set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /w")
    string (REGEX REPLACE "(^| )([/-])W[0-9]( |$)" " " CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /w")
  endif ()
  if (WIN32)
    add_definitions (-D_CRT_SECURE_NO_WARNINGS)
  endif ()
  # Borland uses -w- to suppress warnings.
  if (BORLAND)
    set (HDF_WARNINGS_BLOCKED 1)
    set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w-")
  endif ()

  # Most compilers use -w to suppress warnings.
  if (NOT HDF_WARNINGS_BLOCKED)
    set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w")
    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -w")
  endif ()
endif ()

#-----------------------------------------------------------------------------
# This is in here to help some of the GCC based IDES like Eclipse
# and code blocks parse the compiler errors and warnings better.
#-----------------------------------------------------------------------------
if (CMAKE_COMPILER_IS_GNUCC)
  set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fmessage-length=0")
endif ()
if (CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_LOADED)
  set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fmessage-length=0")
endif ()

#-----------------------------------------------------------------------------
# All examples need the main include directories
#-----------------------------------------------------------------------------
INCLUDE_DIRECTORIES (${PROJECT_BINARY_DIR})

#-----------------------------------------------------------------------------
# Dashboard and Testing Settings
#-----------------------------------------------------------------------------
option (BUILD_TESTING "Build H4H5 Example Testing" OFF)
if (BUILD_TESTING)
  set (DART_TESTING_TIMEOUT 1200
      CACHE INTEGER
      "Timeout in seconds for each test (default 1200=20minutes)"
  )
  enable_testing ()
  include (CTest)
  include (${PROJECT_SOURCE_DIR}/CTestConfig.cmake)
  configure_file (${H4H5EX_RESOURCES_DIR}/CTestCustom.cmake ${PROJECT_BINARY_DIR}/CTestCustom.ctest @ONLY)

  #-----------------------------------------------------------------------------
  # Test examples
  #-----------------------------------------------------------------------------
  add_subdirectory (${PROJECT_SOURCE_DIR}/lib ${PROJECT_BINARY_DIR}/lib)
  add_subdirectory (${PROJECT_SOURCE_DIR}/utils ${PROJECT_BINARY_DIR}/utils)
endif ()
