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

#[=======================================================================[.rst:
FindOpenSceneGraph
------------------

Find OpenSceneGraph (3D graphics application programming interface)

This module searches for the OpenSceneGraph core "osg" library as well
as :module:`FindOpenThreads`, and whatever additional ``COMPONENTS``
(nodekits) that you specify.

::

    See http://www.openscenegraph.org



NOTE: To use this module effectively you must either require ``CMake >=
2.6.3`` with  :command:`cmake_minimum_required(VERSION 2.6.3)` or download
and place :module:`FindOpenThreads`, :module:`Findosg` functions,
:module:`Findosg` and ``Find<etc>.cmake`` files into your
:variable:`CMAKE_MODULE_PATH`.

==================================

This module accepts the following variables (note mixed case)

::

    OpenSceneGraph_DEBUG - Enable debugging output



::

    OpenSceneGraph_MARK_AS_ADVANCED - Mark cache variables as advanced
                                      automatically



The following environment variables are also respected for finding the
OSG and it's various components.  :variable:`CMAKE_PREFIX_PATH` can also be
used for this (see :command:`find_library` CMake documentation).

``<MODULE>_DIR``
  (where ``MODULE`` is of the form "OSGVOLUME" and there is
  a :module:`FindosgVolume`.cmake` file)
``OSG_DIR``
  ..
``OSGDIR``
  ..
``OSG_ROOT``
  ..


[CMake 2.8.10]: The CMake variable ``OSG_DIR`` can now be used as well to
influence detection, instead of needing to specify an environment
variable.

This module defines the following output variables:

::

    OPENSCENEGRAPH_FOUND - Was the OSG and all of the specified components found?



::

    OPENSCENEGRAPH_VERSION - The version of the OSG which was found



::

    OPENSCENEGRAPH_INCLUDE_DIRS - Where to find the headers



::

    OPENSCENEGRAPH_LIBRARIES - The OSG libraries



================================== Example Usage:

.. code-block:: cmake

  find_package(OpenSceneGraph 2.0.0 REQUIRED osgDB osgUtil)
      # libOpenThreads & libosg automatically searched
  include_directories(${OPENSCENEGRAPH_INCLUDE_DIRS})



.. code-block:: cmake

  add_executable(foo foo.cc)
  target_link_libraries(foo ${OPENSCENEGRAPH_LIBRARIES})
#]=======================================================================]

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

#
# Naming convention:
#  Local variables of the form _osg_foo
#  Input variables of the form OpenSceneGraph_FOO
#  Output variables of the form OPENSCENEGRAPH_FOO
#

include(${CMAKE_CURRENT_LIST_DIR}/Findosg_functions.cmake)

set(_osg_modules_to_process)
foreach(_osg_component ${OpenSceneGraph_FIND_COMPONENTS})
    list(APPEND _osg_modules_to_process ${_osg_component})
endforeach()
list(APPEND _osg_modules_to_process "osg" "OpenThreads")
list(REMOVE_DUPLICATES _osg_modules_to_process)

if(OpenSceneGraph_DEBUG)
    message(STATUS "[ FindOpenSceneGraph.cmake:${CMAKE_CURRENT_LIST_LINE} ] "
        "Components = ${_osg_modules_to_process}")
endif()

#
# First we need to find and parse osg/Version
#
OSG_FIND_PATH(OSG osg/Version)
if(OpenSceneGraph_MARK_AS_ADVANCED)
    OSG_MARK_AS_ADVANCED(OSG)
endif()

# Try to ascertain the version...
if(OSG_INCLUDE_DIR)
    if(OpenSceneGraph_DEBUG)
        message(STATUS "[ FindOpenSceneGraph.cmake:${CMAKE_CURRENT_LIST_LINE} ] "
            "Detected OSG_INCLUDE_DIR = ${OSG_INCLUDE_DIR}")
    endif()

    set(_osg_Version_file "${OSG_INCLUDE_DIR}/osg/Version")
    if("${OSG_INCLUDE_DIR}" MATCHES "\\.framework$" AND NOT EXISTS "${_osg_Version_file}")
        set(_osg_Version_file "${OSG_INCLUDE_DIR}/Headers/Version")
    endif()

    if(EXISTS "${_osg_Version_file}")
      file(STRINGS "${_osg_Version_file}" _osg_Version_contents
           REGEX "#define (OSG_VERSION_[A-Z]+|OPENSCENEGRAPH_[A-Z]+_VERSION)[ \t]+[0-9]+")
    else()
      set(_osg_Version_contents "unknown")
    endif()

    string(REGEX MATCH ".*#define OSG_VERSION_MAJOR[ \t]+[0-9]+.*"
        _osg_old_defines "${_osg_Version_contents}")
    string(REGEX MATCH ".*#define OPENSCENEGRAPH_MAJOR_VERSION[ \t]+[0-9]+.*"
        _osg_new_defines "${_osg_Version_contents}")
    if(_osg_old_defines)
        string(REGEX REPLACE ".*#define OSG_VERSION_MAJOR[ \t]+([0-9]+).*"
            "\\1" _osg_VERSION_MAJOR ${_osg_Version_contents})
        string(REGEX REPLACE ".*#define OSG_VERSION_MINOR[ \t]+([0-9]+).*"
            "\\1" _osg_VERSION_MINOR ${_osg_Version_contents})
        string(REGEX REPLACE ".*#define OSG_VERSION_PATCH[ \t]+([0-9]+).*"
            "\\1" _osg_VERSION_PATCH ${_osg_Version_contents})
    elseif(_osg_new_defines)
        string(REGEX REPLACE ".*#define OPENSCENEGRAPH_MAJOR_VERSION[ \t]+([0-9]+).*"
            "\\1" _osg_VERSION_MAJOR ${_osg_Version_contents})
        string(REGEX REPLACE ".*#define OPENSCENEGRAPH_MINOR_VERSION[ \t]+([0-9]+).*"
            "\\1" _osg_VERSION_MINOR ${_osg_Version_contents})
        string(REGEX REPLACE ".*#define OPENSCENEGRAPH_PATCH_VERSION[ \t]+([0-9]+).*"
            "\\1" _osg_VERSION_PATCH ${_osg_Version_contents})
    else()
        message(WARNING "[ FindOpenSceneGraph.cmake:${CMAKE_CURRENT_LIST_LINE} ] "
            "Failed to parse version number, please report this as a bug")
    endif()
    unset(_osg_Version_contents)

    set(OPENSCENEGRAPH_VERSION "${_osg_VERSION_MAJOR}.${_osg_VERSION_MINOR}.${_osg_VERSION_PATCH}"
                                CACHE INTERNAL "The version of OSG which was detected")
    if(OpenSceneGraph_DEBUG)
        message(STATUS "[ FindOpenSceneGraph.cmake:${CMAKE_CURRENT_LIST_LINE} ] "
            "Detected version ${OPENSCENEGRAPH_VERSION}")
    endif()
endif()

set(_osg_quiet)
if(OpenSceneGraph_FIND_QUIETLY)
    set(_osg_quiet "QUIET")
endif()
#
# Here we call find_package() on all of the components
#
foreach(_osg_module ${_osg_modules_to_process})
    if(OpenSceneGraph_DEBUG)
        message(STATUS "[ FindOpenSceneGraph.cmake:${CMAKE_CURRENT_LIST_LINE} ] "
            "Calling find_package(${_osg_module} ${_osg_required} ${_osg_quiet})")
    endif()
    find_package(${_osg_module} ${_osg_quiet})

    string(TOUPPER ${_osg_module} _osg_module_UC)
    # append to list if module was found OR is required
    if( ${_osg_module_UC}_FOUND OR OpenSceneGraph_FIND_REQUIRED )
      list(APPEND OPENSCENEGRAPH_INCLUDE_DIR ${${_osg_module_UC}_INCLUDE_DIR})
      list(APPEND OPENSCENEGRAPH_LIBRARIES ${${_osg_module_UC}_LIBRARIES})
    endif()

    if(OpenSceneGraph_MARK_AS_ADVANCED)
        OSG_MARK_AS_ADVANCED(${_osg_module})
    endif()
endforeach()

if(OPENSCENEGRAPH_INCLUDE_DIR)
    list(REMOVE_DUPLICATES OPENSCENEGRAPH_INCLUDE_DIR)
endif()

#
# Check each module to see if it's found
#
set(_osg_component_founds)
if(OpenSceneGraph_FIND_REQUIRED)
    foreach(_osg_module ${_osg_modules_to_process})
        string(TOUPPER ${_osg_module} _osg_module_UC)
        list(APPEND _osg_component_founds ${_osg_module_UC}_FOUND)
    endforeach()
endif()

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(OpenSceneGraph
                                  REQUIRED_VARS OPENSCENEGRAPH_LIBRARIES OPENSCENEGRAPH_INCLUDE_DIR ${_osg_component_founds}
                                  VERSION_VAR OPENSCENEGRAPH_VERSION)

unset(_osg_component_founds)

set(OPENSCENEGRAPH_INCLUDE_DIRS ${OPENSCENEGRAPH_INCLUDE_DIR})

cmake_policy(POP)
