include(ExternalProject)

# The TEA configure scripts of these extensions are POSIX shell scripts, and on
# Windows they cannot be executed directly: ExternalProject spawns its commands
# through cmd.exe, which has no notion of a #! line and answers
#   "...\configure" no se reconoce como un comando interno o externo
# So a shell has to go in front. TEA_SHELL is empty on Unix, where the shebang does
# the job; on Windows it is the POSIX shell to run them with -- pass it as
# -DTEA_SHELL=C:/msys64/usr/bin/sh.exe, or leave the default and have sh on the PATH.
#
# TEA_PATCH goes with it. The TEA of these extensions is from 2009 and recognises
# Windows by matching "uname -s" against *MINGW32_*, which does not match the
# MINGW64_NT that MSYS2 answers, so it decides the platform is unix and then looks for
# the private Tcl and Tk headers under .../unix instead of .../win. rbc stops dead at
# "rbcTkInt.h:16:10: fatal error: tkWinInt.h: No such file or directory".
#
# So THIS, and not cross compilation, is why rbc and Tktable never built for Windows:
# their configure predates 64-bit MinGW and fails the same way natively. The patch
# runs on the extracted copy and never touches the tarballs in the repository.
if( WIN32 )
  set( TEA_SHELL "sh" CACHE FILEPATH
       "POSIX shell used to run the TEA configure scripts of the third party extensions" )
  set( TEA_PATCH ${CMAKE_COMMAND} -P
       "${CMAKE_CURRENT_SOURCE_DIR}/tea-patch-third-party.cmake" )
else( WIN32 )
  set( TEA_SHELL "" )
  set( TEA_PATCH "" )
endif( WIN32 )

# These extensions are K&R-era C and need to be told so. rbcInt.h declares
#   typedef int (*Rbc_Op)();
# an unprototyped function pointer, and calls it with four arguments. In C23 an empty
# parameter list means (void), so that call is no longer a warning but an error:
#   rbcBusy.c:1192:15: error: too many arguments to function 'proc'; expected 0, have 4
# GCC 15 and later default to -std=gnu23, so the dialect has to be pinned. Not guarded
# by platform, because this is about the compiler's age and not the system's: the same
# GCC breaks these sources on Linux just as readily.
#
# The -Wno-error list is the second half of the same story. GCC 14 promoted a set of
# long standing C warnings to errors, and these sources trip one of them:
#   rbcCanvEps.c:1727:26: error: assignment to 'int (*)(..., char *, ...)' from
#   incompatible pointer type 'int (*)(..., const char *, ...)'
#     [-Wincompatible-pointer-types]
# which is Tk having added const to a callback signature since 2009.
#
# -fpermissive does the same job in one word and was what this used to say, but the
# Ubuntu machine measured the cost on 2026-08-24: GCC 13 does not accept it for C and
# emits "command-line option '-fpermissive' is valid for C++/ObjC++ but not for C" once
# per translation unit. Harmless, and noise that hides real warnings. Naming the
# specific diagnostics instead is understood by both, and says what is being tolerated
# rather than tolerating everything.
include(CheckCCompilerFlag)

# Each flag is offered to the compiler before being used, because a -Wno-error= whose
# warning the compiler does not know is NOT ignored: it is a hard error, and one that
# arrives disguised. GCC 14 named -Wreturn-mismatch and GCC 13.3 answers
#   cc1: error: '-Wno-error=return-mismatch': no option '-Wreturn-mismatch'
# to every compilation, so the TEA configure of rbc and Tktable concludes "C compiler
# cannot create executables" and the whole build of tolbase stops without ever
# mentioning a flag. Measured on Ubuntu 24.04 with GCC 13.3 the 2026-09-16.
set( TEA_CFLAGS_CANDIDATES
     -std=gnu17
     -Wno-error=incompatible-pointer-types
     -Wno-error=implicit-function-declaration
     -Wno-error=int-conversion
     -Wno-error=implicit-int
     -Wno-error=return-mismatch )
set( TEA_CFLAGS_SUPPORTED "" )
foreach( tea_flag IN LISTS TEA_CFLAGS_CANDIDATES )
  string( MAKE_C_IDENTIFIER "TEA_CFLAG_${tea_flag}" tea_flag_var )
  check_c_compiler_flag( "${tea_flag}" ${tea_flag_var} )
  if( ${tea_flag_var} )
    string( APPEND TEA_CFLAGS_SUPPORTED " ${tea_flag}" )
  endif( ${tea_flag_var} )
endforeach( tea_flag )
string( STRIP "${TEA_CFLAGS_SUPPORTED}" TEA_CFLAGS_SUPPORTED )

set( TEA_CFLAGS
     "${TEA_CFLAGS_SUPPORTED}"
     CACHE STRING
     "C dialect for the third party Tcl extensions, whose sources predate C99 prototypes" )

get_filename_component( TCL_LIB_DIR ${TCL_LIBRARY} DIRECTORY )
get_filename_component( TK_LIB_DIR ${TK_LIBRARY} DIRECTORY )

if( NOT TCLODBC_VERSION )
  set( TCLODBC_VERSION 2.5 )
endif( )

if( BUILD_TCLODBC )
  message( STATUS "Third party tclodbc${TCLODBC_VERSION} will be built." )
  find_library( ODBC_LIBRARY 
    NAMES iodbc unixodbc odbc
    )

  if( ODBC_LIBRARY )
    message( STATUS "ODBC_LIBRARY = ${ODBC_LIBRARY}" )
  else( ODBC_LIBRARY )
    message( ERROR "Could not find ODBC library" )
  endif( ODBC_LIBRARY )

  get_filename_component( ODBC_LIB_DIR ${ODBC_LIBRARY} DIRECTORY )

  ExternalProject_Add( tclodbc
    URL ${CMAKE_CURRENT_SOURCE_DIR}/tclodbc${TCLODBC_VERSION}_bayes.tar.gz
    PREFIX ${CMAKE_CURRENT_BINARY_DIR}
    PATCH_COMMAND ${TEA_PATCH}
    CONFIGURE_COMMAND ${TEA_SHELL} ${CMAKE_CURRENT_BINARY_DIR}/src/tclodbc/configure 
    CC=g++ --prefix=${CMAKE_CURRENT_BINARY_DIR}
    --exec-prefix=${CMAKE_CURRENT_BINARY_DIR}
    --with-tcl=${TCL_LIB_DIR}
    --enable-gxx
    --with-odbclibrary=${ODBC_LIB_DIR}
    )
  install( DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib/tclodbc${TCLODBC_VERSION} COMPONENT RUNTIME DESTINATION lib )    
endif( BUILD_TCLODBC )

if( NOT TKTABLE_VERSION )
  set( TKTABLE_VERSION 2.10 )
endif( )

if( BUILD_TKTABLE )
  message( STATUS "Third party Tktable${TKTABLE_VERSION} will be built." )
  ExternalProject_Add( tktable
    URL ${CMAKE_CURRENT_SOURCE_DIR}/Tktable${TKTABLE_VERSION}.tar.gz
    PREFIX ${CMAKE_CURRENT_BINARY_DIR}
    PATCH_COMMAND ${TEA_PATCH}
    CONFIGURE_COMMAND ${TEA_SHELL} ${CMAKE_CURRENT_BINARY_DIR}/src/tktable/configure
    CFLAGS=${TEA_CFLAGS}
    --prefix=${CMAKE_CURRENT_BINARY_DIR}
    --exec-prefix=${CMAKE_CURRENT_BINARY_DIR}
    --with-tcl=${TCL_LIB_DIR}
    --with-tk=${TK_LIB_DIR}
    )
  install( DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib/Tktable${TKTABLE_VERSION} COMPONENT RUNTIME DESTINATION lib )
endif( BUILD_TKTABLE )

if( NOT IMG_VERSION )
  set( IMG_VERSION 1.4.6 )
endif( )

if( BUILD_IMG )
  message( STATUS "Third party Img${IMG_VERSION} will be built." )
  ExternalProject_Add( img
    URL ${CMAKE_CURRENT_SOURCE_DIR}/Img-Source-${IMG_VERSION}.tar.gz
    PREFIX ${CMAKE_CURRENT_BINARY_DIR}
    PATCH_COMMAND ${TEA_PATCH}
    CONFIGURE_COMMAND ${TEA_SHELL} ${CMAKE_CURRENT_BINARY_DIR}/src/img/configure
    CFLAGS=${TEA_CFLAGS}
    --prefix=${CMAKE_CURRENT_BINARY_DIR}
    --exec-prefix=${CMAKE_CURRENT_BINARY_DIR}
    --with-tcl=${TCL_LIB_DIR}
    --with-tk=${TK_LIB_DIR}
    )
  install( DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib/Img${IMG_VERSION} COMPONENT RUNTIME DESTINATION lib )
endif( BUILD_IMG )

if( NOT RBC_VERSION )
  set( RBC_VERSION 0.1 )
endif( )

if( BUILD_RBC )
  message( STATUS "Third party rbc${RBC_VERSION} will be built." )
  ExternalProject_Add( rbc
    URL ${CMAKE_CURRENT_SOURCE_DIR}/rbc${RBC_VERSION}.zip
    PREFIX ${CMAKE_CURRENT_BINARY_DIR}
    PATCH_COMMAND ${TEA_PATCH}
    CONFIGURE_COMMAND ${TEA_SHELL} ${CMAKE_CURRENT_BINARY_DIR}/src/rbc/configure
    CFLAGS=${TEA_CFLAGS}
    --prefix=${CMAKE_CURRENT_BINARY_DIR}
    --exec-prefix=${CMAKE_CURRENT_BINARY_DIR}
    --with-tcl=${TCL_LIB_DIR}
    --with-tk=${TK_LIB_DIR}
    )
  install( DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib/rbc${RBC_VERSION} COMPONENT RUNTIME DESTINATION lib )
endif( BUILD_RBC )

if(NOT TREECTRL_VERSION)
  set(TREECTRL_VERSION 2.4.1)
endif(NOT TREECTRL_VERSION)

if(BUILD_TREECTRL)
  message( STATUS "Third party tktreectrl-${RBC_VERSION} will be built." )
  ExternalProject_Add( treectrl
    URL ${CMAKE_CURRENT_SOURCE_DIR}/tktreectrl-${TREECTRL_VERSION}.tar.gz
    PREFIX ${CMAKE_CURRENT_BINARY_DIR}
    PATCH_COMMAND ${TEA_PATCH}
    CONFIGURE_COMMAND ${TEA_SHELL} ${CMAKE_CURRENT_BINARY_DIR}/src/treectrl/configure
    CFLAGS=${TEA_CFLAGS}
    --prefix=${CMAKE_CURRENT_BINARY_DIR}
    --exec-prefix=${CMAKE_CURRENT_BINARY_DIR}
    --with-tcl=${TCL_LIB_DIR}
    --with-tk=${TK_LIB_DIR}
    )
  install( DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib/treectrl${TREECTRL_VERSION} COMPONENT RUNTIME DESTINATION lib )
endif(BUILD_TREECTRL)
