# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.

#.rst:
# CMakeFindPackageMode
# --------------------
#
#
#
# This file is executed by cmake when invoked with --find-package.  It
# expects that the following variables are set using -D:
#
# ``NAME``
#   name of the package
# ``COMPILER_ID``
#   the CMake compiler ID for which the result is,
#   i.e. GNU/Intel/Clang/MSVC, etc.
# ``LANGUAGE``
#   language for which the result will be used,
#   i.e. C/CXX/Fortran/ASM
# ``MODE``
#   ``EXIST``
#     only check for existence of the given package
#   ``COMPILE``
#     print the flags needed for compiling an object file which uses
#     the given package
#   ``LINK``
#     print the flags needed for linking when using the given package
# ``QUIET``
#   if TRUE, don't print anything

if(NOT NAME)
  message(FATAL_ERROR "Name of the package to be searched not specified. Set the CMake variable NAME, e.g. -DNAME=JPEG .")
endif()

if(NOT COMPILER_ID)
  message(FATAL_ERROR "COMPILER_ID argument not specified. In doubt, use GNU.")
endif()

if(NOT LANGUAGE)
  message(FATAL_ERROR "LANGUAGE argument not specified. Use C, CXX or Fortran.")
endif()

if(NOT MODE)
  message(FATAL_ERROR "MODE argument not specified. Use either EXIST, COMPILE or LINK.")
endif()

# require the current version. If we don't do this, Platforms/CYGWIN.cmake complains because
# it doesn't know whether it should set WIN32 or not:
cmake_minimum_required(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION} )

macro(ENABLE_LANGUAGE)
  # disable the enable_language() command, otherwise --find-package breaks on Windows.
  # On Windows, enable_language(RC) is called in the platform files unconditionally.
  # But in --find-package mode, we don't want (and can't) enable any language.
endmacro()

set(CMAKE_PLATFORM_INFO_DIR ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY})

include(CMakeDetermineSystem)

# short-cut some tests on Darwin, see Darwin-GNU.cmake:
if("${CMAKE_SYSTEM_NAME}" MATCHES Darwin  AND  "${COMPILER_ID}" MATCHES GNU)
  set(CMAKE_${LANGUAGE}_SYSROOT_FLAG "")
  set(CMAKE_${LANGUAGE}_OSX_DEPLOYMENT_TARGET_FLAG "")
endif()

include(CMakeSystemSpecificInitialize)

# Also load the system specific file, which sets up e.g. the search paths.
# This makes the FIND_XXX() calls work much better
include(CMakeSystemSpecificInformation)

if(UNIX)

  # try to guess whether we have a 64bit system, if it has not been set
  # from the outside
  if(NOT CMAKE_SIZEOF_VOID_P)
    set(CMAKE_SIZEOF_VOID_P 4)
    if(EXISTS /usr/lib64)
      set(CMAKE_SIZEOF_VOID_P 8)
    else()
      # use the file utility to check whether itself is 64 bit:
      find_program(FILE_EXECUTABLE file)
      if(FILE_EXECUTABLE)
        get_filename_component(FILE_ABSPATH "${FILE_EXECUTABLE}" ABSOLUTE)
        execute_process(COMMAND "${FILE_ABSPATH}" "${FILE_ABSPATH}" OUTPUT_VARIABLE fileOutput ERROR_QUIET)
        if("${fileOutput}" MATCHES "64-bit")
          set(CMAKE_SIZEOF_VOID_P 8)
        endif()
      endif()
    endif()
  endif()

  # guess Debian multiarch if it has not been set:
  if(EXISTS /etc/debian_version)
    if(NOT CMAKE_${LANGUAGE}_LIBRARY_ARCHITECTURE )
      file(GLOB filesInLib RELATIVE /lib /lib/*-linux-gnu* )
      foreach(file ${filesInLib})
        if("${file}" MATCHES "${CMAKE_LIBRARY_ARCHITECTURE_REGEX}")
          set(CMAKE_${LANGUAGE}_LIBRARY_ARCHITECTURE ${file})
          break()
        endif()
      endforeach()
    endif()
    if(NOT CMAKE_LIBRARY_ARCHITECTURE)
      set(CMAKE_LIBRARY_ARCHITECTURE ${CMAKE_${LANGUAGE}_LIBRARY_ARCHITECTURE})
    endif()
  endif()

endif()

set(CMAKE_${LANGUAGE}_COMPILER "dummy")
set(CMAKE_${LANGUAGE}_COMPILER_ID "${COMPILER_ID}")
include(CMake${LANGUAGE}Information)


function(set_compile_flags_var _packageName)
  string(TOUPPER "${_packageName}" PACKAGE_NAME)
  # Check the following variables:
  # FOO_INCLUDE_DIRS
  # Foo_INCLUDE_DIRS
  # FOO_INCLUDES
  # Foo_INCLUDES
  # FOO_INCLUDE_DIR
  # Foo_INCLUDE_DIR
  set(includes)
  if(DEFINED ${_packageName}_INCLUDE_DIRS)
    set(includes ${_packageName}_INCLUDE_DIRS)
  elseif(DEFINED ${PACKAGE_NAME}_INCLUDE_DIRS)
    set(includes ${PACKAGE_NAME}_INCLUDE_DIRS)
  elseif(DEFINED ${_packageName}_INCLUDES)
    set(includes ${_packageName}_INCLUDES)
  elseif(DEFINED ${PACKAGE_NAME}_INCLUDES)
    set(includes ${PACKAGE_NAME}_INCLUDES)
  elseif(DEFINED ${_packageName}_INCLUDE_DIR)
    set(includes ${_packageName}_INCLUDE_DIR)
  elseif(DEFINED ${PACKAGE_NAME}_INCLUDE_DIR)
    set(includes ${PACKAGE_NAME}_INCLUDE_DIR)
  endif()

  set(PACKAGE_INCLUDE_DIRS "${${includes}}" PARENT_SCOPE)

  # Check the following variables:
  # FOO_DEFINITIONS
  # Foo_DEFINITIONS
  set(definitions)
  if(DEFINED ${_packageName}_DEFINITIONS)
    set(definitions ${_packageName}_DEFINITIONS)
  elseif(DEFINED ${PACKAGE_NAME}_DEFINITIONS)
    set(definitions ${PACKAGE_NAME}_DEFINITIONS)
  endif()

  set(PACKAGE_DEFINITIONS  "${${definitions}}" )

endfunction()


function(set_link_flags_var _packageName)
  string(TOUPPER "${_packageName}" PACKAGE_NAME)
  # Check the following variables:
  # FOO_LIBRARIES
  # Foo_LIBRARIES
  # FOO_LIBS
  # Foo_LIBS
  set(libs)
  if(DEFINED ${_packageName}_LIBRARIES)
    set(libs ${_packageName}_LIBRARIES)
  elseif(DEFINED ${PACKAGE_NAME}_LIBRARIES)
    set(libs ${PACKAGE_NAME}_LIBRARIES)
  elseif(DEFINED ${_packageName}_LIBS)
    set(libs ${_packageName}_LIBS)
  elseif(DEFINED ${PACKAGE_NAME}_LIBS)
    set(libs ${PACKAGE_NAME}_LIBS)
  endif()

  set(PACKAGE_LIBRARIES "${${libs}}" PARENT_SCOPE )

endfunction()


find_package("${NAME}" QUIET)

set(PACKAGE_FOUND FALSE)

string(TOUPPER "${NAME}" UPPERCASE_NAME)

if(${NAME}_FOUND  OR  ${UPPERCASE_NAME}_FOUND)
  set(PACKAGE_FOUND TRUE)

  if("${MODE}" STREQUAL "EXIST")
    # do nothing
  elseif("${MODE}" STREQUAL "COMPILE")
    set_compile_flags_var(${NAME})
  elseif("${MODE}" STREQUAL "LINK")
    set_link_flags_var(${NAME})
  else()
    message(FATAL_ERROR "Invalid mode argument ${MODE} given.")
  endif()

endif()

set(PACKAGE_QUIET ${SILENT} )
