cmake_minimum_required (VERSION 3.2.2)
PROJECT (HDFJAVA_JNI C)

message (STATUS "JAVA: JAVA_HOME=$ENV{JAVA_HOME} JAVA_ROOT=$ENV{JAVA_ROOT}")
find_package (JNI)

INCLUDE_DIRECTORIES ( ${JNI_INCLUDE_DIRS} )

#-----------------------------------------------------------------------------
# Option to Build Shared/Static libs, default is static
#-----------------------------------------------------------------------------
option (BUILD_SHARED_LIBS "Build Shared Libraries" OFF)
set (LIB_TYPE STATIC)
if (BUILD_SHARED_LIBS)
  set (LIB_TYPE SHARED)
  add_definitions (-DHDFJAVA_BUILT_AS_DYNAMIC_LIB)
else ()
  add_definitions (-DHDFJAVA_BUILT_AS_STATIC_LIB)
endif ()
set (LIB_TYPE ${LIB_TYPE} PARENT_SCOPE)
set (CMAKE_POSITION_INDEPENDENT_CODE ON)

#-----------------------------------------------------------------------------
# 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")
  if (NOT CYGWIN)
    add_definitions (-D_BIND_TO_CURRENT_VCLIBS_VERSION=1)
    add_definitions (-D_CRT_SECURE_NO_WARNINGS)
  endif ()
endif ()

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

#-----------------------------------------------------------------------------
# Add some definitions for Debug Builds
#-----------------------------------------------------------------------------
if (CMAKE_BUILD_TYPE MATCHES Debug)
  add_definitions (-DDEBUG)
  #-- NMake Makefiles will overwhelm the console with warnings if -Wall is used.
  if (NOT WIN32)
    add_definitions (-Wall)
  endif ()
else ()
  add_definitions (-UH4_DEBUG_API -DNDEBUG)
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 ()

#-----------------------------------------------------------------------------
# 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 ()

set (EXTERNAL_HEADER_LIST "")
set (EXTERNAL_LIBRARY_LIST "")
set (EXTERNAL_LIBRARYDLL_LIST "")

#-----------------------------------------------------------------------------
# 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)
  set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fmessage-length=0")
endif ()

include (ExternalProject)
set (HDF_ALLOW_EXTERNAL_SUPPORT "NO" CACHE STRING "Allow External Library Building (NO GIT TGZ)")
set_property (CACHE HDF_ALLOW_EXTERNAL_SUPPORT PROPERTY STRINGS NO GIT TGZ)
option (HDF4_USE_EXTERNAL "Use External Library Building for HDF4" 0)
option (HDF5_USE_EXTERNAL "Use External Library Building for HDF5" 0)
if (HDF_ALLOW_EXTERNAL_SUPPORT MATCHES "GIT" OR HDF_ALLOW_EXTERNAL_SUPPORT MATCHES "TGZ")
  set (HDF4_USE_EXTERNAL 1 CACHE BOOL "Use External Library Building for HDF4" FORCE)
  set (HDF5_USE_EXTERNAL 1 CACHE BOOL "Use External Library Building for HDF5" FORCE)
  if (HDF_ALLOW_EXTERNAL_SUPPORT MATCHES "GIT")
    set (HDF4_URL ${HDF4_GIT_URL})
    set (HDF4_BRANCHL ${HDF4_GIT_BRANCH})
    set (HDF5_URL ${HDF5_GIT_URL})
    set (HDF5_BRANCH ${HDF5_GIT_BRANCH})
  elseif (HDF_ALLOW_EXTERNAL_SUPPORT MATCHES "TGZ")
    if (NOT TGZPATH)
      set (TGZPATH ${HDFJAVA_SOURCE_DIR})
    endif ()
    set (HDF4_URL ${TGZPATH}/${HDF4_TGZ_NAME})
    set (HDF5_URL ${TGZPATH}/${HDF5_TGZ_NAME})
  endif ()
endif ()

set (HDF4_LINK_LIBS ${LINK_LIBS})
set (HDF5_LINK_LIBS ${LINK_LIBS})

#-----------------------------------------------------------------------------
# HDF4 support
#-----------------------------------------------------------------------------
if (NOT BUILD_SHARED_LIBS)
  set (HDF4_USE_STATIC_LIBRARIES 1)
endif ()

if (NOT HJAVA_HDF4_HEADER)
  if (NOT HDF4_USE_EXTERNAL)
    if (USE_SHARED_LIBS)
      set (FIND_HDF_COMPONENTS C shared)
    else ()
      set (FIND_HDF_COMPONENTS C static)
    endif ()
    message (STATUS "HDF4 find comps: ${FIND_HDF_COMPONENTS}")
    set (SEARCH_PACKAGE_NAME ${HDF4_PACKAGE_NAME})

    find_package (HDF4 NAMES ${SEARCH_PACKAGE_NAME} COMPONENTS ${FIND_HDF_COMPONENTS})
    message (STATUS "HDF4 C libs:${HDF4_FOUND} static:${HDF4_static_C_FOUND} and shared:${HDF4_shared_C_FOUND}")
  endif ()
  if (HDF4_FOUND)
    if (NOT HDF4_static_C_FOUND AND NOT HDF4_shared_C_FOUND)
      set (FIND_HDF_COMPONENTS C)

      find_package (HDF4 NAMES ${SEARCH_PACKAGE_NAME} COMPONENTS ${FIND_HDF_COMPONENTS})
      message (STATUS "HDF4 libs:${HDF4_FOUND} C:${HDF4_C_FOUND}")
      set (HDF4_LINK_LIBS ${HDF4_LINK_LIBS} ${HDF4_LIBRARIES})
      if (HDF4_BUILD_SHARED_LIBS)
        add_definitions (-DH4_BUILT_AS_DYNAMIC_LIB)
      else ()
        add_definitions (-DH4_BUILT_AS_STATIC_LIB)
      endif ()
    else ()
      if (USE_SHARED_LIBS AND HDF4_shared_C_FOUND)
        set (HDF4_LINK_LIBS ${HDF4_LINK_LIBS} ${HDF4_C_SHARED_LIBRARY})
        add_definitions (-DH4_BUILT_AS_DYNAMIC_LIB)
      else ()
        set (HDF4_LINK_LIBS ${HDF4_LINK_LIBS} ${HDF4_C_STATIC_LIBRARY})
        add_definitions (-DH4_BUILT_AS_STATIC_LIB)
      endif ()
    endif ()
  endif ()
  if (HDF4_FOUND)
    message (STATUS "HDF4 found: INC=${HDF4_INCLUDE_DIR}")
    if (USE_SHARED_LIBS AND NOT HDF4_BUILD_SHARED_LIBS)
      message (STATUS "HDF4 build type does match requested type")
    endif ()
    set (HJAVA_HAVE_HDF_H 1)
    set (HJAVA_HAVE_HDF4 1)
    set (HJAVA_HDF4_HEADER "hdf.h")
    set (HDF4_INCLUDE_DIR_GEN ${HDF4_INCLUDE_DIR})
    set (HDF4_INCLUDE_DIRS ${HDF4_INCLUDE_DIR})
  else ()
    if (HDF_ALLOW_EXTERNAL_SUPPORT MATCHES "GIT" OR HDF_ALLOW_EXTERNAL_SUPPORT MATCHES "TGZ")
      # May need to build JPEG with PIC on x64 machines with gcc
      # Need to use CMAKE_ANSI_CFLAGS define so that compiler test works
      if (NOT CMAKE_ANSI_CFLAGS)
        set (CMAKE_ANSI_CFLAGS " ")
      endif ()
      if (BUILD_JPEG_WITH_PIC)
        set (CMAKE_ANSI_CFLAGS "${CMAKE_ANSI_CFLAGS} -fPIC")
      endif ()

      EXTERNAL_HDF4_LIBRARY (${HDF_ALLOW_EXTERNAL_SUPPORT} ${LIB_TYPE})
      set (HJAVA_HAVE_HDF_H 1)
      set (HJAVA_HAVE_HDF4 1)
      set (HJAVA_HDF4_HEADER "hdf.h")
      message (STATUS "HDF4 is built")
      if (USE_SHARED_LIBS)
        set (HDF4_LINK_LIBS ${HDF4_LINK_LIBS} ${HDF4_SHARED_LIBRARY})
        add_definitions (-DH4_BUILT_AS_DYNAMIC_LIB)
      else ()
        set (HDF4_LINK_LIBS ${HDF4_LINK_LIBS} ${HDF4_STATIC_LIBRARY})
        add_definitions (-DH4_BUILT_AS_STATIC_LIB)
      endif ()
    else ()
      message (FATAL_ERROR " HDF4 is Required for  HDFJava")
    endif ()
  endif ()
else ()
  # This project is being called from within another and HDF4 is already configured
  set (HJAVA_HAVE_HDF_H 1)
  set (HJAVA_HAVE_HDF4 1)
endif ()
message (STATUS "HDF4 link libs: ${HDF4_LINK_LIBS}")

if (NOT HDF4_LIBRARY)
  set (HDF4_LIBRARY ${HDF4_LIBRARIES})
endif ()
INCLUDE_DIRECTORIES (${HDF4_INCLUDE_DIRS})
set (HDF4_FOUND 1 PARENT_SCOPE)
set (HDF4_INCLUDE_DIR_GEN ${HDF4_INCLUDE_DIR_GEN} PARENT_SCOPE)
set (HDF4_VERSION_STRING ${HDF4_VERSION_STRING} PARENT_SCOPE)

#-----------------------------------------------------------------------------
# HDF5 support
#-----------------------------------------------------------------------------
if (NOT BUILD_SHARED_LIBS)
  set (HDF5_USE_STATIC_LIBRARIES 1)
endif ()

if (NOT HJAVA_HDF5_HEADER)
  if (NOT HDF5_USE_EXTERNAL)
    if (USE_SHARED_LIBS)
      set (FIND_HDF_COMPONENTS C shared)
    else ()
      set (FIND_HDF_COMPONENTS C static)
    endif ()
    message (STATUS "HDF5 find comps: ${FIND_HDF_COMPONENTS}")
    set (SEARCH_PACKAGE_NAME ${HDF5_PACKAGE_NAME})

    find_package (HDF5 NAMES ${SEARCH_PACKAGE_NAME} COMPONENTS ${FIND_HDF_COMPONENTS})
    message (STATUS "HDF5 C libs:${HDF5_FOUND} static:${HDF5_static_C_FOUND} and shared:${HDF5_shared_C_FOUND}")
    if (HDF5_FOUND)
      if (NOT HDF5_static_C_FOUND AND NOT HDF5_shared_C_FOUND)
        #find library from non-dual-binary package
        set (FIND_HDF_COMPONENTS C)

        find_package (HDF5 NAMES ${SEARCH_PACKAGE_NAME} COMPONENTS ${FIND_HDF_COMPONENTS})
        message (STATUS "HDF5 libs:${HDF5_FOUND} C:${HDF5_C_FOUND}")
        set (HDF5_LINK_LIBS ${HDF5_LINK_LIBS} ${HDF5_LIBRARIES})
        if (HDF5_BUILD_SHARED_LIBS)
          add_definitions (-DH5_BUILT_AS_DYNAMIC_LIB)
        else ()
          add_definitions (-DH5_BUILT_AS_STATIC_LIB)
        endif ()
      else ()
        if (USE_SHARED_LIBS AND HDF5_shared_C_FOUND)
          set (HDF5_LINK_LIBS ${HDF5_LINK_LIBS} ${HDF5_C_SHARED_LIBRARY})
          add_definitions (-DH5_BUILT_AS_DYNAMIC_LIB)
        else ()
          set (HDF5_LINK_LIBS ${HDF5_LINK_LIBS} ${HDF5_C_STATIC_LIBRARY})
          add_definitions (-DH5_BUILT_AS_STATIC_LIB)
        endif ()
      endif ()
    else ()
      find_package (HDF5) # Legacy find
      #Legacy find_package does not set HDF5_BUILD_SHARED_LIBS, so we set it here
      if (USE_SHARED_LIBS AND EXISTS "${HDF5_LIBRARY_DIRS}/libhdf5.so")
        set (HDF5_BUILD_SHARED_LIBS 1)
      else ()
        set (HDF5_BUILD_SHARED_LIBS 0)
      endif ()
      set (HDF5_LINK_LIBS ${HDF5_LINK_LIBS} ${HDF5_LIBRARIES})
      set (LINK_LIBS ${LINK_LIBS} ${HDF5_LIBRARIES})
    endif ()
  endif ()
  if (HDF5_FOUND)
    message (STATUS "HDF5 found: INC=${HDF5_INCLUDE_DIR}")
    if (USE_SHARED_LIBS AND NOT HDF5_BUILD_SHARED_LIBS)
      message (STATUS "HDF5 build type does match requested type")
    endif ()
    set (HJAVA_HAVE_H5PUBCONF_H 1)
    set (HJAVA_HAVE_HDF5 1)
    set (HJAVA_HDF5_HEADER "h5pubconf.h")
    set (HDF5_INCLUDE_DIR_GEN ${HDF5_INCLUDE_DIR})
    set (HDF5_INCLUDE_DIRS ${HDF5_INCLUDE_DIR})
  else ()
    if (HDF_ALLOW_EXTERNAL_SUPPORT MATCHES "GIT" OR HDF_ALLOW_EXTERNAL_SUPPORT MATCHES "TGZ")
      EXTERNAL_HDF5_LIBRARY (${HDF_ALLOW_EXTERNAL_SUPPORT} ${LIB_TYPE})
      set (HJAVA_HAVE_H5PUBCONF_H 1)
      set (HJAVA_HAVE_HDF5 1)
      set (HJAVA_HDF5_HEADER "h5pubconf.h")
      message (STATUS "HDF5 is built")
      if (USE_SHARED_LIBS)
          set (HDF5_LINK_LIBS ${HDF5_LINK_LIBS} ${HDF5_SHARED_LIBRARY})
        add_definitions (-DH5_BUILT_AS_DYNAMIC_LIB)
      else ()
          set (HDF5_LINK_LIBS ${HDF5_LINK_LIBS} ${HDF5_STATIC_LIBRARY})
        add_definitions (-DH5_BUILT_AS_STATIC_LIB)
      endif ()
    else ()
      message (FATAL_ERROR " HDF5 is Required for  HDFJava")
    endif ()
  endif ()
else ()
  # This project is being called from within another and HDF5 is already configured
  set (HJAVA_HAVE_H5PUBCONF_H 1)
  set (HJAVA_HAVE_HDF5 1)
endif ()
message (STATUS "HDF5 link libs: ${HDF5_LINK_LIBS}")

if (NOT HDF5_LIBRARY)
  set (HDF5_LIBRARY ${HDF5_LIBRARIES})
endif ()
INCLUDE_DIRECTORIES (${HDF5_INCLUDE_DIRS})
set (HDF5_FOUND 1 PARENT_SCOPE)
set (HDF5_INCLUDE_DIR_GEN ${HDF5_INCLUDE_DIR_GEN} PARENT_SCOPE)
set (HDF5_VERSION_STRING ${HDF5_VERSION_STRING} PARENT_SCOPE)

add_subdirectory (${HDFJAVA_JNI_SOURCE_DIR}/hdflib      hdflib)
add_subdirectory (${HDFJAVA_JNI_SOURCE_DIR}/hdf5lib     hdf5lib)

if (HDF_ALLOW_EXTERNAL_SUPPORT MATCHES "GIT" OR HDF_ALLOW_EXTERNAL_SUPPORT MATCHES "TGZ")
  if (JPEG_FOUND)
    add_dependencies (${HDFJAVA_JNI_HDF_LIB_TARGET} JPEG)
    if (HDF4_FOUND AND HDF4_USE_EXTERNAL)
      add_dependencies (HDF4 JPEG)
    endif ()
  endif ()
  if (ZLIB_FOUND)
    add_dependencies (${HDFJAVA_JNI_HDF_LIB_TARGET} ZLIB)
    if (HDF4_FOUND AND HDF4_USE_EXTERNAL)
      add_dependencies (HDF4 ZLIB)
    endif ()
    if (HDF5_FOUND AND HDF5_USE_EXTERNAL)
      add_dependencies (HDF5 ZLIB)
    endif ()
  endif ()
  if (SZIP_FOUND)
    add_dependencies (${HDFJAVA_JNI_HDF_LIB_TARGET} SZIP)
    if (HDF4_FOUND AND HDF4_USE_EXTERNAL)
      add_dependencies (HDF4 SZIP)
    endif ()
    if (HDF5_FOUND AND HDF5_USE_EXTERNAL)
      add_dependencies (HDF5 SZIP)
    endif ()
  endif ()
  if (HDF4_FOUND AND HDF4_USE_EXTERNAL)
    add_dependencies (${HDFJAVA_JNI_HDF_LIB_TARGET} HDF4)
  endif ()
  if (HDF5_FOUND AND HDF5_USE_EXTERNAL)
    add_dependencies (${HDFJAVA_JNI_HDF5_LIB_TARGET} HDF5)
  endif ()
endif ()
