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

#[=======================================================================[.rst:
FindGLUT
--------

Finds the OpenGL Utility Toolkit (GLUT) library, which provides a simple API
for creating windows, handling input, and managing events in OpenGL
applications:

.. code-block:: cmake

  find_package(GLUT [...])

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

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

``GLUT::GLUT``
  .. versionadded:: 3.1

  Target encapsulating the GLUT usage requirements, available if GLUT is found.

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

This module defines the following variables:

``GLUT_FOUND``
  Boolean indicating whether GLUT is found.

``GLUT_INCLUDE_DIRS``
  .. versionadded:: 3.23

  Include directories needed to use GLUT.  Starting with CMake 3.23, this
  variable is intended to be used in target usage requirements instead of the
  cache variable ``GLUT_INCLUDE_DIR``, which is intended for finding GLUT.

``GLUT_LIBRARIES``
  List of libraries needed to link against for using GLUT.

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

This module may set the following cache variables depending on platform.
These variables may optionally be set to help this module find the
correct files, but should not be used as result variables:

``GLUT_INCLUDE_DIR``
  The full path to the directory containing ``GL/glut.h`` (without the ``GL/``).

``GLUT_glut_LIBRARY``
  The full path to the ``glut`` library.

``GLUT_Xi_LIBRARY``
  The full path to the dependent ``Xi`` (X Input Device Extension) library on
  some systems.

``GLUT_Xmu_LIBRARY``
  The full path to the dependent ``Xmu`` (X Miscellaneous Utilities) library on
  some systems.

Examples
^^^^^^^^

Finding GLUT and linking it to a project target:

.. code-block:: cmake

  find_package(GLUT)
  target_link_libraries(project_target PRIVATE GLUT::GLUT)
#]=======================================================================]

include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
include(FindPackageHandleStandardArgs)

find_package(PkgConfig QUIET)
if(PKG_CONFIG_FOUND)
  pkg_check_modules(PC_GLUT QUIET glut)
  if(NOT PC_GLUT_FOUND)
    pkg_check_modules(PC_GLUT QUIET freeglut)
  endif()
endif()

if(WIN32)
  find_path( GLUT_INCLUDE_DIR NAMES GL/glut.h
    PATHS  ${GLUT_ROOT_PATH}/include
    HINTS ${PC_GLUT_INCLUDE_DIRS})
  mark_as_advanced(GLUT_INCLUDE_DIR)
  find_library( GLUT_glut_LIBRARY_RELEASE NAMES freeglut glut glut32
    PATHS
    ${OPENGL_LIBRARY_DIR}
    ${GLUT_ROOT_PATH}/Release
    HINTS
    ${PC_GLUT_LIBRARY_DIRS}
    )
# N.B. As the pkg-config cannot distinguish between release and debug libraries,
# assume that their hint was the both Debug and Release library.
  find_library( GLUT_glut_LIBRARY_DEBUG NAMES freeglutd
    PATHS
    ${OPENGL_LIBRARY_DIR}
    ${GLUT_ROOT_PATH}/Debug
    HINTS
    ${PC_GLUT_LIBRARY_DIRS}
    )
  mark_as_advanced(GLUT_glut_LIBRARY_RELEASE GLUT_glut_LIBRARY_DEBUG)
  select_library_configurations(GLUT_glut)
elseif(APPLE)
  find_path(GLUT_INCLUDE_DIR glut.h PATHS ${OPENGL_LIBRARY_DIR} HINTS ${PC_GLUT_INCLUDE_DIRS})
  mark_as_advanced(GLUT_INCLUDE_DIR)
  find_library(GLUT_glut_LIBRARY GLUT HINTS ${PC_GLUT_LIBRARY_DIRS} DOC "GLUT library for OSX")
  find_library(GLUT_cocoa_LIBRARY Cocoa DOC "Cocoa framework for OSX")
  mark_as_advanced(GLUT_glut_LIBRARY GLUT_cocoa_LIBRARY)

  if(GLUT_cocoa_LIBRARY AND NOT TARGET GLUT::Cocoa)
    add_library(GLUT::Cocoa UNKNOWN IMPORTED)
    set_target_properties(GLUT::Cocoa PROPERTIES
      IMPORTED_LOCATION "${GLUT_cocoa_LIBRARY}")
  endif()
else()
  if(BEOS)
    set(_GLUT_INC_DIR /boot/develop/headers/os/opengl)
    set(_GLUT_glut_LIB_DIR /boot/develop/lib/x86)
  else()
    find_library( GLUT_Xi_LIBRARY Xi
      /usr/openwin/lib
      )
    mark_as_advanced(GLUT_Xi_LIBRARY)

    find_library( GLUT_Xmu_LIBRARY Xmu
      /usr/openwin/lib
      )
    mark_as_advanced(GLUT_Xmu_LIBRARY)

    if(GLUT_Xi_LIBRARY AND NOT TARGET GLUT::Xi)
      add_library(GLUT::Xi UNKNOWN IMPORTED)
      set_target_properties(GLUT::Xi PROPERTIES
        IMPORTED_LOCATION "${GLUT_Xi_LIBRARY}")
    endif()

    if(GLUT_Xmu_LIBRARY AND NOT TARGET GLUT::Xmu)
      add_library(GLUT::Xmu UNKNOWN IMPORTED)
      set_target_properties(GLUT::Xmu PROPERTIES
        IMPORTED_LOCATION "${GLUT_Xmu_LIBRARY}")
    endif()

  endif ()

  find_path( GLUT_INCLUDE_DIR GL/glut.h
    PATHS
    /usr/include/GL
    /usr/openwin/share/include
    /usr/openwin/include
    /opt/graphics/OpenGL/include
    /opt/graphics/OpenGL/contrib/libglut
    ${_GLUT_INC_DIR}
    HINTS
    ${PC_GLUT_INCLUDE_DIRS}
    )
  mark_as_advanced(GLUT_INCLUDE_DIR)

  find_library( GLUT_glut_LIBRARY glut
    PATHS
    /usr/openwin/lib
    ${_GLUT_glut_LIB_DIR}
    HINTS
    ${PC_GLUT_LIBRARY_DIRS}
    )
  mark_as_advanced(GLUT_glut_LIBRARY)

  unset(_GLUT_INC_DIR)
  unset(_GLUT_glut_LIB_DIR)
endif()

find_package_handle_standard_args(GLUT REQUIRED_VARS GLUT_glut_LIBRARY GLUT_INCLUDE_DIR)

if (GLUT_FOUND)
  # Is -lXi and -lXmu required on all platforms that have it?
  # If not, we need some way to figure out what platform we are on.
  set( GLUT_LIBRARIES
    ${GLUT_glut_LIBRARY}
    )
  set(GLUT_INCLUDE_DIRS
    ${GLUT_INCLUDE_DIR}
    )
  foreach(v GLUT_Xmu_LIBRARY GLUT_Xi_LIBRARY GLUT_cocoa_LIBRARY)
    if(${v})
      list(APPEND GLUT_LIBRARIES ${${v}})
    endif()
  endforeach()

  if(NOT TARGET GLUT::GLUT)
    add_library(GLUT::GLUT UNKNOWN IMPORTED)
    set_target_properties(GLUT::GLUT PROPERTIES
      INTERFACE_INCLUDE_DIRECTORIES "${GLUT_INCLUDE_DIRS}")
    if(GLUT_glut_LIBRARY_RELEASE)
      set_property(TARGET GLUT::GLUT APPEND PROPERTY
        IMPORTED_CONFIGURATIONS RELEASE)
      set_target_properties(GLUT::GLUT PROPERTIES
        IMPORTED_LOCATION_RELEASE "${GLUT_glut_LIBRARY_RELEASE}")
    endif()

    if(GLUT_glut_LIBRARY_DEBUG)
      set_property(TARGET GLUT::GLUT APPEND PROPERTY
        IMPORTED_CONFIGURATIONS DEBUG)
      set_target_properties(GLUT::GLUT PROPERTIES
        IMPORTED_LOCATION_DEBUG "${GLUT_glut_LIBRARY_DEBUG}")
    endif()

    if(NOT GLUT_glut_LIBRARY_RELEASE AND NOT GLUT_glut_LIBRARY_DEBUG)
      set_property(TARGET GLUT::GLUT APPEND PROPERTY
        IMPORTED_LOCATION "${GLUT_glut_LIBRARY}")
    endif()

    if(TARGET GLUT::Xmu)
      set_property(TARGET GLUT::GLUT APPEND
        PROPERTY INTERFACE_LINK_LIBRARIES GLUT::Xmu)
    endif()

    if(TARGET GLUT::Xi)
      set_property(TARGET GLUT::GLUT APPEND
        PROPERTY INTERFACE_LINK_LIBRARIES GLUT::Xi)
    endif()

    if(TARGET GLUT::Cocoa)
      set_property(TARGET GLUT::GLUT APPEND
        PROPERTY INTERFACE_LINK_LIBRARIES GLUT::Cocoa)
    endif()
  endif()
endif()
