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

#[=======================================================================[.rst:
FindImageMagick
---------------

Finds ImageMagick, a software suite for displaying, converting, and manipulating
raster images:

.. code-block:: cmake

  find_package(ImageMagick [<version>] [COMPONENTS <components>...] [...])

.. versionadded:: 3.9
  Support for ImageMagick 7.

Components
^^^^^^^^^^

This module supports components and searches for a set of ImageMagick tools.
Typical components include the names of ImageMagick executables, but are not
limited to the following (future versions of ImageMagick may provide additional
components not listed here):

* ``animate``
* ``compare``
* ``composite``
* ``conjure``
* ``convert``
* ``display``
* ``identify``
* ``import``
* ``mogrify``
* ``montage``
* ``stream``

There are also components for the following ImageMagick APIs:

``Magick++``
  Finds the ImageMagick C++ API.
``MagickWand``
  Finds the ImageMagick MagickWand C API.
``MagickCore``
  Finds the ImageMagick MagickCore low-level C API.

Components can be specified using the :command:`find_package` command:

.. code-block:: cmake

  find_package(ImageMagick [COMPONENTS <components>...])

If no components are specified, the module only searches for the ImageMagick
executable directory.

Imported Targets
^^^^^^^^^^^^^^^^

This module provides the following :ref:`Imported Targets`:

``ImageMagick::Magick++``
  .. versionadded:: 3.26

  Target encapsulating the ImageMagick C++ API usage requirements, available if
  ImageMagick C++ is found.

``ImageMagick::MagickWand``
  .. versionadded:: 3.26

  Target encapsulating the ImageMagick MagickWand C API usage requirements,
  available if MagickWand is found.

``ImageMagick::MagickCore``
  .. versionadded:: 3.26

  Target encapsulating the ImageMagick MagickCore low-level C API usage
  requirements, available if MagickCore is found.

Result Variables
^^^^^^^^^^^^^^^^

This module defines the following variables:

``ImageMagick_FOUND``
  Boolean indicating whether (the requested version of) ImageMagick and all
  its requested components were found.

``ImageMagick_VERSION``
  .. versionadded:: 4.2

  The version of ImageMagick found in form of
  ``<major>.<minor>.<patch>-<addendum>`` (e.g., ``6.9.12-98``, where ``98``
  is the addendum release number).

  .. note::

    Version detection is available only for ImageMagick 6 and later.

``ImageMagick_INCLUDE_DIRS``
  All include directories needed to use ImageMagick.

``ImageMagick_LIBRARIES``
  Libraries needed to link against to use ImageMagick.

``ImageMagick_COMPILE_OPTIONS``
  .. versionadded:: 3.26

  Compile options of all libraries.

``ImageMagick_<component>_FOUND``
  Boolean indicating whether the ImageMagick ``<component>`` is found.

``ImageMagick_<component>_EXECUTABLE``
  The full path to ``<component>`` executable.

``ImageMagick_<component>_INCLUDE_DIRS``
  Include directories containing headers needed to use the ImageMagick
  ``<component>``.

``ImageMagick_<component>_COMPILE_OPTIONS``
  .. versionadded:: 3.26

  Compile options of the ImageMagick ``<component>``.

``ImageMagick_<component>_LIBRARIES``
  .. versionadded:: 3.31

  Libraries needed to link against to use the ImageMagick ``<component>``.

Cache Variables
^^^^^^^^^^^^^^^

The following cache variables may also be set:

``ImageMagick_EXECUTABLE_DIR``
  The full path to directory containing ImageMagick executables.

Deprecated Variables
^^^^^^^^^^^^^^^^^^^^

The following variables are provided for backward compatibility:

``ImageMagick_VERSION_STRING``
  .. deprecated:: 4.2
    Use ``ImageMagick_VERSION``, which has the same value.

  The version of ImageMagick found.

Examples
^^^^^^^^

Finding ImageMagick with its component ``Magick++``  and linking it to a project
target:

.. code-block:: cmake

  find_package(ImageMagick COMPONENTS Magick++)
  target_link_libraries(example PRIVATE ImageMagick::Magick++)
#]=======================================================================]

cmake_policy(PUSH)
cmake_policy(SET CMP0140 NEW)
cmake_policy(SET CMP0159 NEW) # file(STRINGS) with REGEX updates CMAKE_MATCH_<n>

find_package(PkgConfig QUIET)

#---------------------------------------------------------------------
# Helper functions
#---------------------------------------------------------------------
function(FIND_IMAGEMAGICK_API component header)
  set(ImageMagick_${component}_FOUND FALSE PARENT_SCOPE)

  if(PkgConfig_FOUND)
    pkg_check_modules(PC_${component} QUIET ${component})
  endif()

  find_path(ImageMagick_${component}_INCLUDE_DIR
    NAMES ${header}
    HINTS
      ${PC_${component}_INCLUDEDIR}
      ${PC_${component}_INCLUDE_DIRS}
    PATHS
      ${ImageMagick_INCLUDE_DIRS}
      "[HKEY_LOCAL_MACHINE\\SOFTWARE\\ImageMagick\\Current;BinPath]/include"
    PATH_SUFFIXES
      ImageMagick ImageMagick-6 ImageMagick-7
    DOC "Path to the ImageMagick arch-independent include dir."
    NO_DEFAULT_PATH
    )
  find_path(ImageMagick_${component}_ARCH_INCLUDE_DIR
    NAMES
      magick/magick-baseconfig.h
      MagickCore/magick-baseconfig.h
    HINTS
      ${PC_${component}_INCLUDEDIR}
      ${PC_${component}_INCLUDE_DIRS}
    PATHS
      ${ImageMagick_INCLUDE_DIRS}
      "[HKEY_LOCAL_MACHINE\\SOFTWARE\\ImageMagick\\Current;BinPath]/include"
    PATH_SUFFIXES
      ImageMagick ImageMagick-6 ImageMagick-7
    DOC "Path to the ImageMagick arch-specific include dir."
    NO_DEFAULT_PATH
    )
  find_library(ImageMagick_${component}_LIBRARY
    NAMES ${ARGN}
    HINTS
      ${PC_${component}_LIBDIR}
      ${PC_${component}_LIB_DIRS}
    PATHS
      "[HKEY_LOCAL_MACHINE\\SOFTWARE\\ImageMagick\\Current;BinPath]/lib"
    DOC "Path to the ImageMagick Magick++ library."
    NO_DEFAULT_PATH
    )

  # old version have only indep dir
  if(ImageMagick_${component}_INCLUDE_DIR AND ImageMagick_${component}_LIBRARY)
    set(ImageMagick_${component}_FOUND TRUE PARENT_SCOPE)

    # Construct per-component include directories.
    set(ImageMagick_${component}_INCLUDE_DIRS
      ${ImageMagick_${component}_INCLUDE_DIR}
      )
    if(ImageMagick_${component}_ARCH_INCLUDE_DIR)
      list(APPEND ImageMagick_${component}_INCLUDE_DIRS
        ${ImageMagick_${component}_ARCH_INCLUDE_DIR})
    endif()
    list(REMOVE_DUPLICATES ImageMagick_${component}_INCLUDE_DIRS)
    set(ImageMagick_${component}_INCLUDE_DIRS
      ${ImageMagick_${component}_INCLUDE_DIRS} PARENT_SCOPE)

    set(ImageMagick_${component}_LIBRARIES
      ${ImageMagick_${component}_LIBRARY}
      )
    set(ImageMagick_${component}_LIBRARIES
      ${ImageMagick_${component}_LIBRARIES} PARENT_SCOPE)

    set(ImageMagick_${component}_COMPILE_OPTIONS ${PC_${component}_CFLAGS_OTHER})

    # Add the per-component include directories to the full include dirs.
    list(APPEND ImageMagick_INCLUDE_DIRS ${ImageMagick_${component}_INCLUDE_DIRS})
    list(REMOVE_DUPLICATES ImageMagick_INCLUDE_DIRS)
    set(ImageMagick_INCLUDE_DIRS ${ImageMagick_INCLUDE_DIRS} PARENT_SCOPE)

    list(APPEND ImageMagick_LIBRARIES
      ${ImageMagick_${component}_LIBRARY}
      )
    set(ImageMagick_LIBRARIES ${ImageMagick_LIBRARIES} PARENT_SCOPE)

    list(APPEND ImageMagick_COMPILE_OPTIONS
      ${ImageMagick_${component}_COMPILE_OPTIONS}
      )
    set(ImageMagick_COMPILE_OPTIONS ${ImageMagick_COMPILE_OPTIONS} PARENT_SCOPE)

    if(NOT TARGET ImageMagick::${component})
      add_library(ImageMagick::${component} UNKNOWN IMPORTED)
      set_target_properties(ImageMagick::${component} PROPERTIES
        INTERFACE_INCLUDE_DIRECTORIES "${ImageMagick_${component}_INCLUDE_DIRS}"
        INTERFACE_COMPILE_OPTIONS "${ImageMagick_${component}_COMPILE_OPTIONS}"
        IMPORTED_LOCATION "${ImageMagick_${component}_LIBRARY}")
    endif()
  endif()
endfunction()

function(FIND_IMAGEMAGICK_EXE component)
  set(_IMAGEMAGICK_EXECUTABLE
    ${ImageMagick_EXECUTABLE_DIR}/${component}${CMAKE_EXECUTABLE_SUFFIX})
  if(EXISTS ${_IMAGEMAGICK_EXECUTABLE})
    set(ImageMagick_${component}_EXECUTABLE
      ${_IMAGEMAGICK_EXECUTABLE}
       PARENT_SCOPE
       )
    set(ImageMagick_${component}_FOUND TRUE PARENT_SCOPE)
  else()
    set(ImageMagick_${component}_FOUND FALSE PARENT_SCOPE)
  endif()
endfunction()

function(_ImageMagick_GetVersion)
  unset(version)

  if(ImageMagick_mogrify_EXECUTABLE)
    execute_process(
      COMMAND ${ImageMagick_mogrify_EXECUTABLE} -version
      OUTPUT_VARIABLE version
      ERROR_QUIET
      OUTPUT_STRIP_TRAILING_WHITESPACE
      RESULT_VARIABLE _version_result
    )

    if(version MATCHES "^Version: ImageMagick ([-0-9.]+)")
      set(version "${CMAKE_MATCH_1}")
    endif()
  elseif(ImageMagick_INCLUDE_DIRS)
    # MagickLibSubversion was used in ImageMagick <= 6.5.
    set(
      regex
      "^[\t ]*#[\t ]*define[\t ]+(MagickLibVersionText|MagickLibAddendum|MagickLibSubversion)[\t ]+\"([-0-9.]+)\""
    )

    foreach(dir IN LISTS ImageMagick_INCLUDE_DIRS)
      foreach(subdir IN ITEMS MagickCore magick)
        if(EXISTS ${dir}/${subdir}/version.h)
          file(STRINGS "${dir}/${subdir}/version.h" results REGEX "${regex}")

          foreach(line ${results})
            if(line MATCHES "${regex}")
              if(DEFINED version)
                string(APPEND version "${CMAKE_MATCH_2}")
              else()
                set(version "${CMAKE_MATCH_2}")
              endif()

              if(CMAKE_MATCH_1 STREQUAL "MagickLibAddendum")
                break()
              endif()
            endif()
          endforeach()
        endif()

        if(DEFINED version)
          break()
        endif()
      endforeach()

      if(DEFINED version)
        break()
      endif()
    endforeach()
  endif()

  if(DEFINED version)
    set(ImageMagick_VERSION "${version}")
    set(ImageMagick_VERSION_STRING "${ImageMagick_VERSION}")
  endif()

  return(PROPAGATE ImageMagick_VERSION ImageMagick_VERSION_STRING)
endfunction()

#---------------------------------------------------------------------
# Start Actual Work
#---------------------------------------------------------------------
# Try to find a ImageMagick installation binary path.
find_path(ImageMagick_EXECUTABLE_DIR
  NAMES mogrify${CMAKE_EXECUTABLE_SUFFIX}
  PATHS
    "[HKEY_LOCAL_MACHINE\\SOFTWARE\\ImageMagick\\Current;BinPath]"
  DOC "Path to the ImageMagick binary directory."
  NO_DEFAULT_PATH
  )
find_path(ImageMagick_EXECUTABLE_DIR
  NAMES mogrify${CMAKE_EXECUTABLE_SUFFIX}
  )

# Find each component. Search for all tools in same dir
# <ImageMagick_EXECUTABLE_DIR>; otherwise they should be found
# independently and not in a cohesive module such as this one.
unset(ImageMagick_REQUIRED_VARS)
unset(ImageMagick_DEFAULT_EXECUTABLES)
foreach(component ${ImageMagick_FIND_COMPONENTS}
    # DEPRECATED: forced components for backward compatibility
    convert mogrify import montage composite
    )
  if(component STREQUAL "Magick++")
    FIND_IMAGEMAGICK_API(Magick++ Magick++.h
      Magick++ CORE_RL_Magick++_
      Magick++-6 Magick++-7
      Magick++-Q8 Magick++-Q16 Magick++-Q16HDRI Magick++-Q8HDRI
      Magick++-6.Q64 Magick++-6.Q32 Magick++-6.Q64HDRI Magick++-6.Q32HDRI
      Magick++-6.Q16 Magick++-6.Q8 Magick++-6.Q16HDRI Magick++-6.Q8HDRI
      Magick++-7.Q64 Magick++-7.Q32 Magick++-7.Q64HDRI Magick++-7.Q32HDRI
      Magick++-7.Q16 Magick++-7.Q8 Magick++-7.Q16HDRI Magick++-7.Q8HDRI
      )
    list(APPEND ImageMagick_REQUIRED_VARS ImageMagick_Magick++_LIBRARY)
  elseif(component STREQUAL "MagickWand")
    FIND_IMAGEMAGICK_API(MagickWand "wand/MagickWand.h;MagickWand/MagickWand.h"
      Wand MagickWand CORE_RL_wand_ CORE_RL_MagickWand_
      MagickWand-6 MagickWand-7
      MagickWand-Q16 MagickWand-Q8 MagickWand-Q16HDRI MagickWand-Q8HDRI
      MagickWand-6.Q64 MagickWand-6.Q32 MagickWand-6.Q64HDRI MagickWand-6.Q32HDRI
      MagickWand-6.Q16 MagickWand-6.Q8 MagickWand-6.Q16HDRI MagickWand-6.Q8HDRI
      MagickWand-7.Q64 MagickWand-7.Q32 MagickWand-7.Q64HDRI MagickWand-7.Q32HDRI
      MagickWand-7.Q16 MagickWand-7.Q8 MagickWand-7.Q16HDRI MagickWand-7.Q8HDRI
      )
    list(APPEND ImageMagick_REQUIRED_VARS ImageMagick_MagickWand_LIBRARY)
  elseif(component STREQUAL "MagickCore")
    FIND_IMAGEMAGICK_API(MagickCore "magick/MagickCore.h;MagickCore/MagickCore.h"
      Magick MagickCore CORE_RL_magick_ CORE_RL_MagickCore_
      MagickCore-6 MagickCore-7
      MagickCore-Q16 MagickCore-Q8 MagickCore-Q16HDRI MagickCore-Q8HDRI
      MagickCore-6.Q64 MagickCore-6.Q32 MagickCore-6.Q64HDRI MagickCore-6.Q32HDRI
      MagickCore-6.Q16 MagickCore-6.Q8 MagickCore-6.Q16HDRI MagickCore-6.Q8HDRI
      MagickCore-7.Q64 MagickCore-7.Q32 MagickCore-7.Q64HDRI MagickCore-7.Q32HDRI
      MagickCore-7.Q16 MagickCore-7.Q8 MagickCore-7.Q16HDRI MagickCore-7.Q8HDRI
      )
    list(APPEND ImageMagick_REQUIRED_VARS ImageMagick_MagickCore_LIBRARY)
  else()
    if(ImageMagick_EXECUTABLE_DIR)
      FIND_IMAGEMAGICK_EXE(${component})
    endif()

    if(ImageMagick_FIND_COMPONENTS)
      list(FIND ImageMagick_FIND_COMPONENTS ${component} is_requested)
      if(is_requested GREATER -1)
        list(APPEND ImageMagick_REQUIRED_VARS ImageMagick_${component}_EXECUTABLE)
      endif()
    elseif(ImageMagick_${component}_EXECUTABLE)
      # if no components were requested explicitly put all (default) executables
      # in the list
      list(APPEND ImageMagick_DEFAULT_EXECUTABLES ImageMagick_${component}_EXECUTABLE)
    endif()
  endif()
endforeach()

if(NOT ImageMagick_FIND_COMPONENTS AND NOT ImageMagick_DEFAULT_EXECUTABLES)
  # No components were requested, and none of the default components were
  # found. Just insert mogrify into the list of the default components to
  # find so FPHSA below has something to check
  list(APPEND ImageMagick_REQUIRED_VARS ImageMagick_mogrify_EXECUTABLE)
elseif(ImageMagick_DEFAULT_EXECUTABLES)
  list(APPEND ImageMagick_REQUIRED_VARS ${ImageMagick_DEFAULT_EXECUTABLES})
endif()

set(ImageMagick_INCLUDE_DIRS ${ImageMagick_INCLUDE_DIRS})
set(ImageMagick_LIBRARIES ${ImageMagick_LIBRARIES})

_ImageMagick_GetVersion()

#---------------------------------------------------------------------
# Standard Package Output
#---------------------------------------------------------------------
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(ImageMagick
                                  REQUIRED_VARS ${ImageMagick_REQUIRED_VARS}
                                  VERSION_VAR ImageMagick_VERSION
  )

#---------------------------------------------------------------------
# DEPRECATED: Setting variables for backward compatibility.
#---------------------------------------------------------------------
set(IMAGEMAGICK_BINARY_PATH          ${ImageMagick_EXECUTABLE_DIR}
    CACHE PATH "Path to the ImageMagick binary directory.")
set(IMAGEMAGICK_CONVERT_EXECUTABLE   ${ImageMagick_convert_EXECUTABLE}
    CACHE FILEPATH "Path to ImageMagick's convert executable.")
set(IMAGEMAGICK_MOGRIFY_EXECUTABLE   ${ImageMagick_mogrify_EXECUTABLE}
    CACHE FILEPATH "Path to ImageMagick's mogrify executable.")
set(IMAGEMAGICK_IMPORT_EXECUTABLE    ${ImageMagick_import_EXECUTABLE}
    CACHE FILEPATH "Path to ImageMagick's import executable.")
set(IMAGEMAGICK_MONTAGE_EXECUTABLE   ${ImageMagick_montage_EXECUTABLE}
    CACHE FILEPATH "Path to ImageMagick's montage executable.")
set(IMAGEMAGICK_COMPOSITE_EXECUTABLE ${ImageMagick_composite_EXECUTABLE}
    CACHE FILEPATH "Path to ImageMagick's composite executable.")
mark_as_advanced(
  IMAGEMAGICK_BINARY_PATH
  IMAGEMAGICK_CONVERT_EXECUTABLE
  IMAGEMAGICK_MOGRIFY_EXECUTABLE
  IMAGEMAGICK_IMPORT_EXECUTABLE
  IMAGEMAGICK_MONTAGE_EXECUTABLE
  IMAGEMAGICK_COMPOSITE_EXECUTABLE
  )

cmake_policy(POP)
