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

#[=======================================================================[.rst:
FindFLTK
--------

Find the FLTK library

Input Variables
^^^^^^^^^^^^^^^

By default this module will search for all of the FLTK components and
add them to the FLTK_LIBRARIES variable.  You can limit the components
which get placed in FLTK_LIBRARIES by defining one or more of the
following three options:

``FLTK_SKIP_OPENGL``
  Set to true to disable searching for the FLTK GL library

``FLTK_SKIP_FORMS``
  Set to true to disable searching for the FLTK Forms library

``FLTK_SKIP_IMAGES``
  Set to true to disable searching for the FLTK Images library

FLTK is composed also by a binary tool. You can set the following option:

``FLTK_SKIP_FLUID``
  Set to true to not look for the FLUID binary

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

The following variables will be defined:

``FLTK_FOUND``
  True if all components not skipped were found

``FLTK_INCLUDE_DIR``
  Path to the include directory for FLTK header files

``FLTK_LIBRARIES``
  List of the FLTK libraries found

``FLTK_FLUID_EXECUTABLE``
  Path to the FLUID binary tool

``FLTK_WRAP_UI``
  True if FLUID is found, used to enable the FLTK_WRAP_UI command

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

The following cache variables are also available to set or use:

``FLTK_BASE_LIBRARY_RELEASE``
  The FLTK base library (optimized)

``FLTK_BASE_LIBRARY_DEBUG``
  The FLTK base library (debug)

``FLTK_GL_LIBRARY_RELEASE``
  The FLTK GL library (optimized)

``FLTK_GL_LIBRARY_DEBUG``
  The FLTK GL library (debug)

``FLTK_FORMS_LIBRARY_RELEASE``
  The FLTK Forms library (optimized)

``FLTK_FORMS_LIBRARY_DEBUG``
  The FLTK Forms library (debug)

``FLTK_IMAGES_LIBRARY_RELEASE``
  The FLTK Images protobuf library (optimized)

``FLTK_IMAGES_LIBRARY_DEBUG``
  The FLTK Images library (debug)
#]=======================================================================]

if(NOT FLTK_SKIP_OPENGL)
  find_package(OpenGL)
endif()

#  Platform dependent libraries required by FLTK
if(WIN32)
  if(NOT CYGWIN)
    if(BORLAND)
      set( FLTK_PLATFORM_DEPENDENT_LIBS import32 )
    else()
      set( FLTK_PLATFORM_DEPENDENT_LIBS wsock32 comctl32 )
    endif()
  endif()
endif()

if(UNIX)
  include(${CMAKE_CURRENT_LIST_DIR}/FindX11.cmake)
  find_library(FLTK_MATH_LIBRARY m)
  set( FLTK_PLATFORM_DEPENDENT_LIBS ${X11_LIBRARIES} ${FLTK_MATH_LIBRARY})
endif()

if(APPLE)
  set( FLTK_PLATFORM_DEPENDENT_LIBS  "-framework Carbon -framework Cocoa -framework ApplicationServices -lz")
endif()

# If FLTK_INCLUDE_DIR is already defined we assigne its value to FLTK_DIR
if(FLTK_INCLUDE_DIR)
  set(FLTK_DIR ${FLTK_INCLUDE_DIR})
endif()


# If FLTK has been built using CMake we try to find everything directly
set(FLTK_DIR_STRING "directory containing FLTKConfig.cmake.  This is either the root of the build tree, or PREFIX/lib/fltk for an installation.")

# Search only if the location is not already known.
if(NOT FLTK_DIR)
  # Get the system search path as a list.
  file(TO_CMAKE_PATH "$ENV{PATH}" FLTK_DIR_SEARCH2)

  # Construct a set of paths relative to the system search path.
  set(FLTK_DIR_SEARCH "")
  foreach(dir ${FLTK_DIR_SEARCH2})
    set(FLTK_DIR_SEARCH ${FLTK_DIR_SEARCH} "${dir}/../lib/fltk")
  endforeach()
  string(REPLACE "//" "/" FLTK_DIR_SEARCH "${FLTK_DIR_SEARCH}")

  #
  # Look for an installation or build tree.
  #
  find_path(FLTK_DIR FLTKConfig.cmake
    # Look for an environment variable FLTK_DIR.
    HINTS
      ENV FLTK_DIR

    # Look in places relative to the system executable search path.
    ${FLTK_DIR_SEARCH}

    PATH_SUFFIXES
    fltk
    fltk/include
    lib/fltk
    lib/fltk/include

    # Help the user find it if we cannot.
    DOC "The ${FLTK_DIR_STRING}"
    )
endif()

# Check if FLTK was built using CMake
if(EXISTS ${FLTK_DIR}/FLTKConfig.cmake)
  set(FLTK_BUILT_WITH_CMAKE 1)
endif()

if(FLTK_BUILT_WITH_CMAKE)
  set(FLTK_FOUND 1)
  include(${FLTK_DIR}/FLTKConfig.cmake)

  # Fluid
  if(FLUID_COMMAND)
    set(FLTK_FLUID_EXECUTABLE ${FLUID_COMMAND} CACHE FILEPATH "Fluid executable")
  else()
    find_program(FLTK_FLUID_EXECUTABLE fluid PATHS
      ${FLTK_EXECUTABLE_DIRS}
      ${FLTK_EXECUTABLE_DIRS}/RelWithDebInfo
      ${FLTK_EXECUTABLE_DIRS}/Debug
      ${FLTK_EXECUTABLE_DIRS}/Release
      NO_SYSTEM_PATH)
  endif()
  # mark_as_advanced(FLTK_FLUID_EXECUTABLE)

  set(FLTK_INCLUDE_DIR ${FLTK_DIR})
  link_directories(${FLTK_LIBRARY_DIRS})

  set(FLTK_BASE_LIBRARY fltk)
  set(FLTK_GL_LIBRARY fltk_gl)
  set(FLTK_FORMS_LIBRARY fltk_forms)
  set(FLTK_IMAGES_LIBRARY fltk_images)

  # Add the extra libraries
  load_cache(${FLTK_DIR}
    READ_WITH_PREFIX
    FL FLTK_USE_SYSTEM_JPEG
    FL FLTK_USE_SYSTEM_PNG
    FL FLTK_USE_SYSTEM_ZLIB
    )

  set(FLTK_IMAGES_LIBS "")
  if(FLFLTK_USE_SYSTEM_JPEG)
    set(FLTK_IMAGES_LIBS ${FLTK_IMAGES_LIBS} fltk_jpeg)
  endif()
  if(FLFLTK_USE_SYSTEM_PNG)
    set(FLTK_IMAGES_LIBS ${FLTK_IMAGES_LIBS} fltk_png)
  endif()
  if(FLFLTK_USE_SYSTEM_ZLIB)
    set(FLTK_IMAGES_LIBS ${FLTK_IMAGES_LIBS} fltk_zlib)
  endif()
  set(FLTK_IMAGES_LIBS "${FLTK_IMAGES_LIBS}" CACHE INTERNAL
    "Extra libraries for fltk_images library.")

else()

  # if FLTK was not built using CMake
  # Find fluid executable.
  find_program(FLTK_FLUID_EXECUTABLE fluid ${FLTK_INCLUDE_DIR}/fluid)

  # Use location of fluid to help find everything else.
  set(FLTK_INCLUDE_SEARCH_PATH "")
  set(FLTK_LIBRARY_SEARCH_PATH "")
  if(FLTK_FLUID_EXECUTABLE)
    get_filename_component(FLTK_BIN_DIR "${FLTK_FLUID_EXECUTABLE}" PATH)
    set(FLTK_INCLUDE_SEARCH_PATH ${FLTK_INCLUDE_SEARCH_PATH}
      ${FLTK_BIN_DIR}/../include ${FLTK_BIN_DIR}/..)
    set(FLTK_LIBRARY_SEARCH_PATH ${FLTK_LIBRARY_SEARCH_PATH}
      ${FLTK_BIN_DIR}/../lib)
    set(FLTK_WRAP_UI 1)
  endif()

  #
  # Try to find FLTK include dir using fltk-config
  #
  if(UNIX)
    # Use fltk-config to generate a list of possible include directories
    find_program(FLTK_CONFIG_SCRIPT fltk-config PATHS ${FLTK_BIN_DIR})
    if(FLTK_CONFIG_SCRIPT)
      if(NOT FLTK_INCLUDE_DIR)
        exec_program(${FLTK_CONFIG_SCRIPT} ARGS --cxxflags OUTPUT_VARIABLE FLTK_CXXFLAGS)
        if(FLTK_CXXFLAGS)
          string(REGEX MATCHALL "-I[^ ]*" _fltk_temp_dirs ${FLTK_CXXFLAGS})
          string(REPLACE "-I" "" _fltk_temp_dirs "${_fltk_temp_dirs}")
          foreach(_dir ${_fltk_temp_dirs})
            string(STRIP ${_dir} _output)
            list(APPEND _FLTK_POSSIBLE_INCLUDE_DIRS ${_output})
          endforeach()
        endif()
      endif()
    endif()
  endif()

  list(APPEND FLTK_INCLUDE_SEARCH_PATH ${_FLTK_POSSIBLE_INCLUDE_DIRS})

  find_path(FLTK_INCLUDE_DIR
      NAMES FL/Fl.h FL/Fl.H    # fltk 1.1.9 has Fl.H (#8376)
      PATH_SUFFIXES fltk fltk/include
      PATHS ${FLTK_INCLUDE_SEARCH_PATH})

  #
  # Try to find FLTK library
  if(UNIX)
    if(FLTK_CONFIG_SCRIPT)
      exec_program(${FLTK_CONFIG_SCRIPT} ARGS --libs OUTPUT_VARIABLE _FLTK_POSSIBLE_LIBS)
      if(_FLTK_POSSIBLE_LIBS)
        get_filename_component(_FLTK_POSSIBLE_LIBRARY_DIR ${_FLTK_POSSIBLE_LIBS} PATH)
      endif()
    endif()
  endif()

  list(APPEND FLTK_LIBRARY_SEARCH_PATH ${FLTK_INCLUDE_DIR}/lib ${_FLTK_POSSIBLE_LIBRARY_DIR})

  include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)

  # Allow libraries to be set manually
  if(NOT FLTK_BASE_LIBRARY)
      find_library(FLTK_BASE_LIBRARY_RELEASE NAMES fltk PATHS ${FLTK_LIBRARY_SEARCH_PATH} PATH_SUFFIXES fltk fltk/lib)
      find_library(FLTK_BASE_LIBRARY_DEBUG NAMES fltkd PATHS ${FLTK_LIBRARY_SEARCH_PATH} PATH_SUFFIXES fltk fltk/lib)
      select_library_configurations(FLTK_BASE)
  endif()
  if(NOT FLTK_GL_LIBRARY)
      find_library(FLTK_GL_LIBRARY_RELEASE NAMES fltkgl fltk_gl PATHS ${FLTK_LIBRARY_SEARCH_PATH} PATH_SUFFIXES fltk fltk/lib)
      find_library(FLTK_GL_LIBRARY_DEBUG NAMES fltkgld fltk_gld PATHS ${FLTK_LIBRARY_SEARCH_PATH} PATH_SUFFIXES fltk fltk/lib)
      select_library_configurations(FLTK_GL)
  endif()
  if(NOT FLTK_FORMS_LIBRARY)
      find_library(FLTK_FORMS_LIBRARY_RELEASE NAMES fltkforms fltk_forms PATHS ${FLTK_LIBRARY_SEARCH_PATH} PATH_SUFFIXES fltk fltk/lib)
      find_library(FLTK_FORMS_LIBRARY_DEBUG NAMES fltkformsd fltk_formsd PATHS ${FLTK_LIBRARY_SEARCH_PATH} PATH_SUFFIXES fltk fltk/lib)
      select_library_configurations(FLTK_FORMS)
  endif()
  if(NOT FLTK_IMAGES_LIBRARY)
      find_library(FLTK_IMAGES_LIBRARY_RELEASE NAMES fltkimages fltk_images PATHS ${FLTK_LIBRARY_SEARCH_PATH} PATH_SUFFIXES fltk fltk/lib)
      find_library(FLTK_IMAGES_LIBRARY_DEBUG NAMES fltkimagesd fltk_imagesd PATHS ${FLTK_LIBRARY_SEARCH_PATH} PATH_SUFFIXES fltk fltk/lib)
      select_library_configurations(FLTK_IMAGES)
  endif()

  # Find the extra libraries needed for the fltk_images library.
  if(UNIX)
    if(FLTK_CONFIG_SCRIPT)
      exec_program(${FLTK_CONFIG_SCRIPT} ARGS --use-images --ldflags
        OUTPUT_VARIABLE FLTK_IMAGES_LDFLAGS)
      set(FLTK_LIBS_EXTRACT_REGEX ".*-lfltk_images (.*) -lfltk.*")
      if("${FLTK_IMAGES_LDFLAGS}" MATCHES "${FLTK_LIBS_EXTRACT_REGEX}")
        string(REGEX REPLACE " +" ";" FLTK_IMAGES_LIBS "${CMAKE_MATCH_1}")
        # The EXEC_PROGRAM will not be inherited into subdirectories from
        # the file that originally included this module.  Save the answer.
        set(FLTK_IMAGES_LIBS "${FLTK_IMAGES_LIBS}" CACHE INTERNAL
          "Extra libraries for fltk_images library.")
      endif()
    endif()
  endif()

endif()

# Append all of the required libraries together (by default, everything)
set(FLTK_LIBRARIES)
if(NOT FLTK_SKIP_IMAGES)
  list(APPEND FLTK_LIBRARIES ${FLTK_IMAGES_LIBRARY})
endif()
if(NOT FLTK_SKIP_FORMS)
  list(APPEND FLTK_LIBRARIES ${FLTK_FORMS_LIBRARY})
endif()
if(NOT FLTK_SKIP_OPENGL)
  list(APPEND FLTK_LIBRARIES ${FLTK_GL_LIBRARY} ${OPENGL_gl_LIBRARY})
  list(APPEND FLTK_INCLUDE_DIR ${OPENGL_INCLUDE_DIR})
  list(REMOVE_DUPLICATES FLTK_INCLUDE_DIR)
endif()
list(APPEND FLTK_LIBRARIES ${FLTK_BASE_LIBRARY})

include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
if(FLTK_SKIP_FLUID)
  FIND_PACKAGE_HANDLE_STANDARD_ARGS(FLTK DEFAULT_MSG FLTK_LIBRARIES FLTK_INCLUDE_DIR)
else()
  FIND_PACKAGE_HANDLE_STANDARD_ARGS(FLTK DEFAULT_MSG FLTK_LIBRARIES FLTK_INCLUDE_DIR FLTK_FLUID_EXECUTABLE)
endif()

if(FLTK_FOUND)
  if(APPLE)
    set(FLTK_LIBRARIES ${FLTK_PLATFORM_DEPENDENT_LIBS} ${FLTK_LIBRARIES})
  else()
    set(FLTK_LIBRARIES ${FLTK_LIBRARIES} ${FLTK_PLATFORM_DEPENDENT_LIBS})
  endif()

  # The following deprecated settings are for compatibility with CMake 1.4
  set (HAS_FLTK ${FLTK_FOUND})
  set (FLTK_INCLUDE_PATH ${FLTK_INCLUDE_DIR})
  set (FLTK_FLUID_EXE ${FLTK_FLUID_EXECUTABLE})
  set (FLTK_LIBRARY ${FLTK_LIBRARIES})
endif()
