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

#[=======================================================================[.rst:
FindTCL
-------

Finds the Tcl (Tool Command Language), dynamic programming language:

.. code-block:: cmake

  find_package(TCL [...])

This module locates a Tcl installation, including its include directories and
libraries, and determines the appropriate Tcl library name for linking.  As part
of the Tcl ecosystem, it also finds Tk, a GUI toolkit that provides a library of
basic widgets for building graphical user interfaces.

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

This module defines the following variables:

``TCL_FOUND``
  Boolean indicating whether Tcl was found.
``TK_FOUND``
  Boolean indicating whether Tk was found.
``TCLTK_FOUND``
  Boolean indicating whether both Tcl and Tk were found.

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

The following cache variables may also be set:

``TCL_LIBRARY``
  The path to the Tcl library (e.g., ``tcl``, etc.).
``TCL_INCLUDE_PATH``
  The directory containing ``tcl.h`` and other Tcl-related headers needed to use
  Tcl.
``TCL_TCLSH``
  The path to the ``tclsh`` command-line executable.
``TK_LIBRARY``
  The path to the Tk library (e.g., ``tk``, etc.).
``TK_INCLUDE_PATH``
  The directory containing ``tk.h`` and other Tk-related headers needed to use
  Tk.
``TK_WISH``
  The path to the ``wish`` windowing shell command-line executable.

Other Libraries
^^^^^^^^^^^^^^^

The Tcl Stub Library can be found using the separate :module:`FindTclStub`
module.

Examples
^^^^^^^^

Finding Tcl:

.. code-block:: cmake

  find_package(TCL)

See Also
^^^^^^^^

* The :module:`FindTclsh` module to find the Tcl shell command-line executable.
* The :module:`FindTclStub` module to find the Tcl Stubs Library.
* The :module:`FindWish` module to find the ``wish`` windowing shell
  command-line executable .
#]=======================================================================]

block(SCOPE_FOR POLICIES)
  cmake_policy(SET CMP0173 OLD)
  include(${CMAKE_CURRENT_LIST_DIR}/CMakeFindFrameworks.cmake)
endblock()
include(${CMAKE_CURRENT_LIST_DIR}/FindTclsh.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/FindWish.cmake)

if(Tclsh_VERSION)
  set(TCL_TCLSH_VERSION "${Tclsh_VERSION}")
else()
  get_filename_component(TCL_TCLSH_PATH "${TCL_TCLSH}" PATH)
  get_filename_component(TCL_TCLSH_PATH_PARENT "${TCL_TCLSH_PATH}" PATH)
  string(REGEX REPLACE
    "^.*tclsh([0-9]\\.*[0-9]).*$" "\\1" TCL_TCLSH_VERSION "${TCL_TCLSH}")
endif()

get_filename_component(TK_WISH_PATH "${TK_WISH}" PATH)
get_filename_component(TK_WISH_PATH_PARENT "${TK_WISH_PATH}" PATH)
string(REGEX REPLACE
  "^.*wish([0-9]\\.*[0-9]).*$" "\\1" TK_WISH_VERSION "${TK_WISH}")

get_filename_component(TCL_INCLUDE_PATH_PARENT "${TCL_INCLUDE_PATH}" PATH)
get_filename_component(TK_INCLUDE_PATH_PARENT "${TK_INCLUDE_PATH}" PATH)

get_filename_component(TCL_LIBRARY_PATH "${TCL_LIBRARY}" PATH)
get_filename_component(TCL_LIBRARY_PATH_PARENT "${TCL_LIBRARY_PATH}" PATH)
string(REGEX REPLACE
  "^.*tcl([0-9]\\.*[0-9]).*$" "\\1" TCL_LIBRARY_VERSION "${TCL_LIBRARY}")

get_filename_component(TK_LIBRARY_PATH "${TK_LIBRARY}" PATH)
get_filename_component(TK_LIBRARY_PATH_PARENT "${TK_LIBRARY_PATH}" PATH)
string(REGEX REPLACE
  "^.*tk([0-9]\\.*[0-9]).*$" "\\1" TK_LIBRARY_VERSION "${TK_LIBRARY}")

set(TCLTK_POSSIBLE_LIB_PATHS
  "${TCL_INCLUDE_PATH_PARENT}/lib"
  "${TK_INCLUDE_PATH_PARENT}/lib"
  "${TCL_LIBRARY_PATH}"
  "${TK_LIBRARY_PATH}"
  "${TCL_TCLSH_PATH_PARENT}/lib"
  "${TK_WISH_PATH_PARENT}/lib"
)
# Entries built from a path not found yet are just /lib.
list(FILTER TCLTK_POSSIBLE_LIB_PATHS EXCLUDE REGEX "^/lib$")

set(TCLTK_POSSIBLE_LIB_PATH_SUFFIXES
  lib/tcl/tcl9.1
  lib/tcl/tk9.1
  lib/tcl/tcl9.0
  lib/tcl/tk9.0
  lib/tcl/tcl8.6
  lib/tcl/tk8.6
  lib/tcl/tcl8.5
  lib/tcl/tk8.5
  lib/tcl/tcl8.4
  lib/tcl/tk8.4
)

if(WIN32)
  get_filename_component(
    ActiveTcl_CurrentVersion
    "[HKEY_LOCAL_MACHINE\\SOFTWARE\\ActiveState\\ActiveTcl;CurrentVersion]"
    NAME)
  set(TCLTK_POSSIBLE_LIB_PATHS ${TCLTK_POSSIBLE_LIB_PATHS}
    "[HKEY_LOCAL_MACHINE\\SOFTWARE\\ActiveState\\ActiveTcl\\${ActiveTcl_CurrentVersion}]/lib"
    "$ENV{ProgramFiles}/Tcl/Lib"
    "C:/Program Files/Tcl/lib"
    "C:/Tcl/lib"
    )
endif()

find_library(TCL_LIBRARY
  NAMES
  tcl
  tcl${TCL_LIBRARY_VERSION} tcl${TCL_TCLSH_VERSION} tcl${TK_WISH_VERSION}
  tcl91 tcl9.1 tcl91t tcl9.1t
  tcl90 tcl9.0 tcl90t tcl9.0t
  tcl86 tcl8.6 tcl86t tcl8.6t
  tcl85 tcl8.5
  tcl84 tcl8.4
  tcl83 tcl8.3
  tcl82 tcl8.2
  tcl80 tcl8.0
  NAMES_PER_DIR
  PATHS ${TCLTK_POSSIBLE_LIB_PATHS}
  PATH_SUFFIXES ${TCLTK_POSSIBLE_LIB_PATH_SUFFIXES}
  )

find_library(TK_LIBRARY
  NAMES
  tk
  tk${TK_LIBRARY_VERSION} tk${TCL_TCLSH_VERSION} tk${TK_WISH_VERSION}
  tcl9tk91 tcl9tk9.1 tk91 tk9.1 tk91t tk9.1t
  tcl9tk90 tcl9tk9.0 tk90 tk9.0 tk90t tk9.0t
  tk86 tk8.6 tk86t tk8.6t
  tk85 tk8.5
  tk84 tk8.4
  tk83 tk8.3
  tk82 tk8.2
  tk80 tk8.0
  NAMES_PER_DIR
  PATHS ${TCLTK_POSSIBLE_LIB_PATHS}
  PATH_SUFFIXES ${TCLTK_POSSIBLE_LIB_PATH_SUFFIXES}
  )

CMAKE_FIND_FRAMEWORKS(Tcl)
CMAKE_FIND_FRAMEWORKS(Tk)

set(TCL_FRAMEWORK_INCLUDES)
if(Tcl_FRAMEWORKS)
  if(NOT TCL_INCLUDE_PATH)
    foreach(dir ${Tcl_FRAMEWORKS})
      set(TCL_FRAMEWORK_INCLUDES ${TCL_FRAMEWORK_INCLUDES} ${dir}/Headers)
    endforeach()
  endif()
endif()

set(TK_FRAMEWORK_INCLUDES)
if(Tk_FRAMEWORKS)
  if(NOT TK_INCLUDE_PATH)
    foreach(dir ${Tk_FRAMEWORKS})
      set(TK_FRAMEWORK_INCLUDES ${TK_FRAMEWORK_INCLUDES}
        ${dir}/Headers ${dir}/PrivateHeaders)
    endforeach()
  endif()
endif()

set(TCLTK_POSSIBLE_INCLUDE_PATHS
  "${TCL_LIBRARY_PATH_PARENT}/include"
  "${TK_LIBRARY_PATH_PARENT}/include"
  "${TCL_INCLUDE_PATH}"
  "${TK_INCLUDE_PATH}"
  ${TCL_FRAMEWORK_INCLUDES}
  ${TK_FRAMEWORK_INCLUDES}
  "${TCL_TCLSH_PATH_PARENT}/include"
  "${TK_WISH_PATH_PARENT}/include"
  )
list(FILTER TCLTK_POSSIBLE_INCLUDE_PATHS EXCLUDE REGEX "^/include$")

set(TCLTK_POSSIBLE_INCLUDE_PATH_SUFFIXES
  include/tcl${TK_LIBRARY_VERSION}
  include/tcl${TCL_LIBRARY_VERSION}
  include/tcl9.1
  include/tk9.1
  include/tcl9.0
  include/tk9.0
  include/tcl8.6
  include/tk8.6
  include/tcl8.5
  include/tk8.5
  include/tcl8.4
  include/tk8.4
  include/tcl8.3
  include/tcl8.2
  include/tcl8.0
  include/tcl-tk
  )

if(WIN32)
  set(TCLTK_POSSIBLE_INCLUDE_PATHS ${TCLTK_POSSIBLE_INCLUDE_PATHS}
    "[HKEY_LOCAL_MACHINE\\SOFTWARE\\ActiveState\\ActiveTcl\\${ActiveTcl_CurrentVersion}]/include"
    "$ENV{ProgramFiles}/Tcl/include"
    "C:/Program Files/Tcl/include"
    "C:/Tcl/include"
    )
endif()

find_path(TCL_INCLUDE_PATH
  NAMES tcl.h
  HINTS ${TCLTK_POSSIBLE_INCLUDE_PATHS}
  PATH_SUFFIXES ${TCLTK_POSSIBLE_INCLUDE_PATH_SUFFIXES}
  )

find_path(TK_INCLUDE_PATH
  NAMES tk.h
  HINTS ${TCLTK_POSSIBLE_INCLUDE_PATHS}
  PATH_SUFFIXES ${TCLTK_POSSIBLE_INCLUDE_PATH_SUFFIXES}
  )

include(FindPackageHandleStandardArgs)

if (CMAKE_FIND_PACKAGE_NAME STREQUAL "TclStub")
  # FindTclStub include()'s this module. It's an old pattern, but rather than
  # trying to suppress this from outside the module (which is then sensitive to
  # the contents, detect the case in this module and suppress it explicitly.
  set(FPHSA_NAME_MISMATCHED 1)
endif ()
find_package_handle_standard_args(TCL DEFAULT_MSG TCL_LIBRARY TCL_INCLUDE_PATH)
set(FPHSA_NAME_MISMATCHED 1)
set(TCLTK_FIND_REQUIRED ${TCL_FIND_REQUIRED})
set(TCLTK_FIND_QUIETLY  ${TCL_FIND_QUIETLY})
find_package_handle_standard_args(TCLTK DEFAULT_MSG TCL_LIBRARY TCL_INCLUDE_PATH TK_LIBRARY TK_INCLUDE_PATH)
set(TK_FIND_REQUIRED ${TCL_FIND_REQUIRED})
set(TK_FIND_QUIETLY  ${TCL_FIND_QUIETLY})
find_package_handle_standard_args(TK DEFAULT_MSG TK_LIBRARY TK_INCLUDE_PATH)
unset(FPHSA_NAME_MISMATCHED)

mark_as_advanced(
  TCL_INCLUDE_PATH
  TK_INCLUDE_PATH
  TCL_LIBRARY
  TK_LIBRARY
  )
