
# la variable SOURCE_DIR apunta al directorio principal del código (trunk)
set(SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../..")

# directorio con archivos adicionales para el instalador
set(NSIS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/NSIS")
# módulo adicional para construir el instalados con NSIS
set(CMAKE_MODULE_PATH "${NSIS_DIR}" ${CMAKE_MODULE_PATH})

# => http://www.cmake.org/Wiki/CMake:CPackPackageGenerators

if(${TOL_PLATFORM} EQUAL "64")
  message(STATUS "Installer for TOL 64-bits")
  # la version de 64 bits se instala en el "program files" de 64
  # el instalador es sin embargo un ejecutable de 32 bits
  set(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES64")
  set(win_system_name win64)
  set(TOL_ENV_VAR TOLGNU_ROOT_64)
  set(CPACK_PACKAGE_NAME "TOL (GNU-64)")
else()
  message(STATUS "Installer for TOL 32-bits")
  set(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES32")
  set(win_system_name win32)
  set(TOL_ENV_VAR TOLGNU_ROOT)
  set(CPACK_PACKAGE_NAME "TOL (GNU)")
endif()

if(INCLUDE_TOLBASE)
  message(STATUS "Installer includes tolbase")
  set(CPACK_PACKAGE_NAMEV_INSTALL "tol-gnu-v${CPACK_PACKAGE_VERSION}")
  set(CPACK_PACKAGE_NAMEV "tol-gnu-v${CPACK_PACKAGE_VERSION}")
else()
  message(STATUS "Installer includes only tolsh")
  set(CPACK_PACKAGE_NAMEV_INSTALL "tol-gnu-v${CPACK_PACKAGE_VERSION}")  
  # se utiliza un nombre diferente para el instalador sin tolbase
  set(CPACK_PACKAGE_NAMEV "tolsh-gnu-v${CPACK_PACKAGE_VERSION}")
endif()

#! Debería comprobarse que fueron compilados e instalados en el Runtime_Base
#! los proyectos tol, toltcl y rtol, y también tolbase si corresponde.

set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CPACK_PACKAGE_VENDOR}\\\\${CPACK_PACKAGE_NAMEV_INSTALL}")
set(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "${CPACK_PACKAGE_NAMEV_INSTALL}")

# => http://www.cmake.org/Wiki/CMake:Component_Install_With_CPack

# BIN (APPLICATION)
file(TO_CMAKE_PATH "${TOL_RUNTIME_DIR}/bin/*.dll" dll_pattern)
file(GLOB RT_DLL  ${dll_pattern})
install(FILES ${RT_DLL} DESTINATION "bin" COMPONENT application)
# El puente con R, paso cuarto de la receta de construccion. tolRlink.dll cae
# en bin y por tanto viaja con el glob de arriba sin decir nada; lo que hace
# falta es AVISAR si no esta, porque un paquete sin ella instala el lado de R y
# muere en el primer tolInit() con un "LoadLibrary failure" que no menciona a
# TOL. Es el mismo aviso que da el instalador de Linux.
file(TO_CMAKE_PATH "${TOL_RUNTIME_DIR}/bin/tolRlink.dll" tolrlink_dll)
if(NOT EXISTS "${tolrlink_dll}")
  message(WARNING
    "tolRlink.dll is NOT in ${TOL_RUNTIME_DIR}/bin, so the R bridge will not "
    "travel in this installer. Build it with the fourth step of the recipe: "
    "cmake -S rtol -B <build>/rtol -DTOL_PREFIX_PATH=<runtime> && cmake --install. "
    "Everything else works without it; what breaks is calling TOL from R.")
else()
  message(STATUS "tolRlink.dll found, the R bridge will travel in the installer")
endif()

file(TO_CMAKE_PATH "${TOL_RUNTIME_DIR}/bin/*.exe" exe_pattern)
file(GLOB RT_EXE  ${exe_pattern})
install(FILES ${RT_EXE} DESTINATION "bin" COMPONENT application)
file(TO_CMAKE_PATH "${TOL_RUNTIME_DIR}/bin/stdlib" stdlib_dir)
install(DIRECTORY ${stdlib_dir} DESTINATION "bin" COMPONENT application 
  PATTERN ".svn" EXCLUDE)
file(TO_CMAKE_PATH "${TOL_RUNTIME_DIR}/bin/language.txt" language_txt)
file(GLOB RT_TXT  ${language_txt})
install(FILES ${RT_TXT} DESTINATION "bin" COMPONENT application)

# BIN (DEVELOPMENT)
file(TO_CMAKE_PATH "${TOL_RUNTIME_DIR}/bin/*.lib" lib_pattern)
file(GLOB RT_LIB  ${lib_pattern})
install(FILES ${RT_LIB} DESTINATION "bin" COMPONENT development)

# LIB (APPLICATION)
file(TO_CMAKE_PATH "${TOL_RUNTIME_DIR}/lib" lib_dir)
# Los *_noversion son las copias intactas de los iconos, antes de estamparles la
# marca de version: estan en el arbol para poder volver atras y no tienen nada
# que hacer en una instalacion. Viajaron dentro del instalador del 2026-08-20 y
# se excluyen aqui para que no dependa de acordarse de limpiar el arbol.
install(DIRECTORY ${lib_dir} DESTINATION "." COMPONENT application
  PATTERN "*.a" EXCLUDE PATTERN ".svn" EXCLUDE
  PATTERN "*_noversion.*" EXCLUDE)
  
# INCLUDE (DEVELOPMENT)
file(TO_CMAKE_PATH "${TOL_RUNTIME_DIR}/include" include_dir)
install(DIRECTORY ${include_dir} DESTINATION "." COMPONENT development)

#=== PACKAGES ================================================================
# Los paquetes de TOL viajan como los zips que construye TolPackage::Builder,
# no como un arbol desplegado: InstallZip hace mas que descomprimir --registra
# el paquete y resuelve las rutas de su parte binaria-- asi que es mas seguro
# que haga su trabajo en el momento de instalar.
#
# No se pueden instalar para toda la maquina, y esto no es una limitacion del
# instalador sino del diseno: el area de paquetes es TolAppDataPath +
# "TolPackage.<n>", y en Windows TolAppDataPath es %USERPROFILE%\TolBase. El
# instalador corre elevado, luego todo lo que instalara caeria en el perfil del
# administrador. tol-install-packages.cmd lo materializa para quien lo ejecute.
#
# El directorio de zips ha de ser uno preparado para Windows: los puros de TOL,
# los "#GNU" y los "#Win64GNU". Los "#Win64GNU" los produce el tolsh de Windows,
# no este, porque el sello de plataforma lo pone el TOL que compila el paquete
# --_.autodoc.platform es ObtainPlatform("OWN","OWN","OWN")--; esta escrito en
# doc/rescue/compilar-windows.md.
# Sin ruta por defecto, a proposito. En Linux el .deb puede caer en
# $HOME/.tol/TolPackage.5/Builder porque la maquina que construye es la misma
# clase de maquina que la que instala; cruzando a Windows no lo es, y adivinar
# aqui una ruta acabaria en un instalador sin paquetes y sin que nadie se diera
# cuenta. Se pasa con -DTOL_PACKAGE_ZIPS_DIR=<dir> o por el entorno.
if(NOT TOL_PACKAGE_ZIPS_DIR AND DEFINED ENV{TOL_PACKAGE_ZIPS_DIR})
  set(TOL_PACKAGE_ZIPS_DIR "$ENV{TOL_PACKAGE_ZIPS_DIR}")
endif()

if(TOL_PACKAGE_ZIPS_DIR)
  include("${CMAKE_CURRENT_SOURCE_DIR}/../cmake/TolPackageZips.cmake")
  # Se rechaza "#Linux": un .so de Linux dentro del instalador de Windows es
  # peso muerto en el mejor caso, y en el peor un "paquete instalado que no
  # carga".
  #
  # Y se rechazan los "PubDat*", que son series de datos publicadas --la EPA
  # del INE, meteorologia de Espana, Chile y Andorra, contabilidad nacional--
  # y no libreria. Son doce paquetes y 28,9 MB, mas de la mitad de lo que pesan
  # los 105 juntos, y Victor el 2026-10-06: "sirven para ejemplos mas que
  # nada". Se instalan en el perfil de CADA usuario la primera vez que abre
  # TOL, asi que son 29 MB por persona y varios segundos de su primer arranque
  # para unos datos que solo usa quien los pide. Quien los necesite los tiene a
  # un #Require de distancia, que es de donde salen igualmente.
  #
  # Con -DTOL_PACKAGE_ZIPS_REJECT=<regex> se cambia el criterio; una cadena
  # vacia no rechaza nada.
  if(NOT DEFINED TOL_PACKAGE_ZIPS_REJECT)
    set(TOL_PACKAGE_ZIPS_REJECT "#Linux|^PubDat")
  endif()
  tol_select_package_zips(tol_package_zips "${TOL_PACKAGE_ZIPS_DIR}"
    "${TOL_PACKAGE_ZIPS_REJECT}")
  # A bin/stdlib/DefaultPackages y no a un packages/ aparte, y este es el punto
  # entero: TOL ya sabe hacerlo solo. Client::Initialize, en client.tol, recorre
  # ESE directorio al arrancar, coge todo lo que sea *.zip y no este ya en el
  # catalogo, y lo instala en el area del usuario que arranca:
  #
  #   Set localZips = Select(GetDir(_.defaultPackageDir)[1], ... "*.zip");
  #   ... If(catalog::FindRecord(packageName), 0, { InstallZip(...) })
  #
  # DefaultPackages.tol solo decide cuales se CARGAN, no cuales se instalan.
  # Asi que con los zips aqui cada usuario los tiene la primera vez que abre TOL,
  # sin ejecutar nada y sin que nadie tenga que acordarse. Es una vez por perfil y
  # cuesta unos segundos.
  #
  # Esto no contradice lo de que el area es por usuario: sigue siendolo, y sigue
  # siendo cierto que el instalador no puede escribir en ella --corre elevado y
  # escribiria en el perfil del administrador--. Lo que se hace es dejar los zips
  # donde el motor los va a buscar en el arranque de cada uno.
  install(FILES ${tol_package_zips}
    DESTINATION "bin/stdlib/DefaultPackages" COMPONENT packages)
else()
  message(STATUS
    "TOL packages: none will travel in the installer. Set TOL_PACKAGE_ZIPS_DIR "
    "to a directory holding the zips built for Windows (pure TOL, #GNU and "
    "#Win64GNU).")
endif()

install(PROGRAMS
  "${CMAKE_CURRENT_SOURCE_DIR}/tol-install-packages.cmd"
  "${CMAKE_CURRENT_SOURCE_DIR}/tol-setup-r.cmd"
  DESTINATION "bin" COMPONENT packages)

# Los lanzadores. Van en la componente application y no en packages porque son
# el punto de entrada normal a TOL: los accesos directos apuntan a ellos y no a
# los .exe, que es lo que permite que cada instalacion use su propia R sin una
# variable de maquina. El porque, en tol-env.cmd.
install(PROGRAMS
  "${CMAKE_CURRENT_SOURCE_DIR}/tol-env.cmd"
  "${CMAKE_CURRENT_SOURCE_DIR}/tolbase.cmd"
  "${CMAKE_CURRENT_SOURCE_DIR}/tolsh.cmd"
  "${CMAKE_CURRENT_SOURCE_DIR}/tolcon.cmd"
  DESTINATION "bin" COMPONENT application)

# ===========================================================================
# THE R VERSION. Measured, not assumed, and the three things that have to say
# the same number all come out of this one measurement: r-required.txt, the
# CRAN download URL and the text of the messages.
#
# What rules is the R whose R.dll TolRInside was linked against, because
# TolRInside imports R.dll and only loads with that series. TolRInside is built
# natively against the R installed on the machine that compiles -- that is what
# doc/rescue/compilar-windows.md prescribes -- so that installation is the
# measurement, and it is read from the registry.
#
# The FULL version is needed (4.6.1, not 4.6) because the download URL carries
# it. When the package zips were built on another machine, impose it with
# -DTOL_REQUIRED_R_VERSION=x.y.z.
#
# If there is nothing to measure and nothing was given, it is NOT guessed: the
# installer comes out without the automatic download and behaves like the old
# ones, warning loudly here. A wrong URL would install an R that TolRInside
# cannot load, with a symptom that never mentions R, and that is worse than
# having no download at all.
# ===========================================================================
if(TOL_REQUIRED_R_SERIES AND NOT TOL_REQUIRED_R_VERSION)
  message(WARNING
    "TOL_REQUIRED_R_SERIES is no longer read: it held only a series (4.6) and "
    "the CRAN URL needs the full version. Pass -DTOL_REQUIRED_R_VERSION=x.y.z "
    "instead. Ignoring TOL_REQUIRED_R_SERIES=${TOL_REQUIRED_R_SERIES}.")
endif()

if(TOL_REQUIRED_R_VERSION)
  set(TOL_R_VERSION_ORIGIN "given with -DTOL_REQUIRED_R_VERSION")
elseif(CMAKE_HOST_WIN32)
  # Only on a Windows host. Cross-building from Linux, the R on the machine
  # that builds is a Linux R and has nothing to do with the R.dll TolRInside
  # was linked against, so reading it there would measure the wrong thing.
  cmake_host_system_information(RESULT TOL_REQUIRED_R_VERSION
    QUERY WINDOWS_REGISTRY "HKLM/SOFTWARE/R-core/R64" VALUE "Current Version"
    ERROR_VARIABLE tol_r_registry_error)
  if(TOL_REQUIRED_R_VERSION)
    set(TOL_R_VERSION_ORIGIN
        "measured in HKLM/SOFTWARE/R-core/R64 of the machine that builds")
  endif()
endif()

if(TOL_REQUIRED_R_VERSION AND
   NOT TOL_REQUIRED_R_VERSION MATCHES "^[0-9]+[.][0-9]+[.][0-9]+$")
  message(FATAL_ERROR
    "TOL_REQUIRED_R_VERSION is '${TOL_REQUIRED_R_VERSION}' and the full x.y.z "
    "is needed, because the CRAN download URL carries it inside.")
endif()

if(TOL_REQUIRED_R_VERSION)
  string(REGEX MATCH "^[0-9]+[.][0-9]+" TOL_REQUIRED_R_SERIES
         "${TOL_REQUIRED_R_VERSION}")
  message(STATUS
    "R this installer requires: ${TOL_REQUIRED_R_VERSION} "
    "(${TOL_R_VERSION_ORIGIN})")
  # r-required.txt carries the FULL version. tol-setup-r.cmd derives the series
  # from it for the compatibility warning -- TolRInside loads with any 4.6.x --
  # and uses the full version for the download URL. One file and one number, so
  # the two cannot drift apart.
  file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/r-required.txt"
       "${TOL_REQUIRED_R_VERSION}\n")
  install(FILES "${CMAKE_CURRENT_BINARY_DIR}/r-required.txt"
    DESTINATION "bin" COMPONENT packages)
else()
  message(WARNING
    "The R version could not be measured and was not given, so this installer "
    "will NOT install R by itself: it will only warn and offer the CRAN page, "
    "as the ones before it did. Pass -DTOL_REQUIRED_R_VERSION=x.y.z, the full "
    "version of the R whose R.dll TolRInside was linked against.")
endif()

install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/tol-install-r-packages.R"
  DESTINATION "share" COMPONENT packages)

# Los dos paquetes de R de TOL viajan como ARBOLES DE FUENTES, igual que en el
# .deb: son R puro, ninguno declara NeedsCompilation, asi que el destino no
# necesita Rtools. tol-setup-r.cmd los instala con R CMD INSTALL, tolBasis
# primero porque tolRlink lo importa. No estan en CRAN ni lo estaran: son los
# paquetes de R del propio TOL.
file(TO_CMAKE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../rtol/Rpackages" rpkg_dir)
if(EXISTS "${rpkg_dir}")
  install(DIRECTORY "${rpkg_dir}/tolBasis" "${rpkg_dir}/tolRlink"
    DESTINATION "share/Rpackages" COMPONENT packages
    PATTERN ".git*" EXCLUDE)
  message(STATUS "TOL R packages will travel in share/Rpackages")
else()
  message(WARNING
    "rtol/Rpackages not found at ${rpkg_dir}: the two R packages of TOL will "
    "not travel, and tol-setup-r.cmd will have nothing to install.")
endif()

# El parrafo de R de SIGUIENTE-PASO.txt. Se genera aqui, y no se escribe en la
# plantilla, porque dice cosas distintas segun el instalador instale R o no, y
# un fichero que promete lo que el instalador no hace es peor que no tenerlo.
# Los saltos de linea estan puestos contando con el valor ya sustituido, que
# son cinco caracteres (4.6.1) y tres (4.6).
if(TOL_REQUIRED_R_VERSION)
  set(TOL_NEXTSTEPS_R
"ESTE INSTALADOR INSTALA R SOLO. Si al instalar TOL no habia ninguna R en la
maquina, descarga de CRAN la @TOL_REQUIRED_R_VERSION@ y la instala. No vale cualquiera:
TolRInside importa R.dll y solo carga con la serie contra la que se compilo,
que es la @TOL_REQUIRED_R_SERIES@.

Si se dijo que no, o si no habia red, no se ha perdido nada. Ejecute una vez,
como administrador:

    bin\\tol-setup-r.cmd

que tambien esta en el menu de inicio como \"Preparar R para TOL\". Descarga e
instala R @TOL_REQUIRED_R_VERSION@ si falta, deja puesta R_HOME y baja de CRAN los paquetes de
R que TOL necesita. Se puede repetir las veces que haga falta.

SI LA MAQUINA YA TENIA R DE OTRA SERIE no se instala otra encima: se avisa y se
deja como esta. Quitar o sustituir una R instalada es una decision de quien
administra la maquina, no de este instalador.")
else()
  set(TOL_NEXTSTEPS_R
"ESTE INSTALADOR NO INSTALA R, porque al construirlo no se pudo averiguar contra
que version de R se compilo TolRInside. Solo la busca. Si la encuentra, deja
puesta la variable R_HOME. Si no la encuentra, lo dice al terminar y ofrece
abrir la pagina de descarga:

    https://cran.r-project.org/bin/windows/base/

Despues de instalar R, ejecute una vez, como administrador:

    bin\\tol-setup-r.cmd

que tambien esta en el menu de inicio como \"Preparar R para TOL\", y que baja
de CRAN los paquetes de R que TOL necesita.")
endif()
string(CONFIGURE "${TOL_NEXTSTEPS_R}" TOL_NEXTSTEPS_R @ONLY)

# Un fichero de texto y no un MessageBox. El dialogo no se puede seleccionar ni
# copiar, asi que obligaba a teclear rutas a mano, que es justo lo que no debe
# pasar. Esto se puede abrir, leer y copiar, y ademas queda instalado para
# consultarlo cuando haga falta.
list(LENGTH tol_package_zips NEXTSTEPS_PACKAGE_COUNT)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/SIGUIENTE-PASO.txt.in"
  "${CMAKE_CURRENT_BINARY_DIR}/SIGUIENTE-PASO.txt" @ONLY)
# NEWLINE_STYLE de configure_file no sirve aqui: normaliza los saltos que vienen
# de la plantilla, pero no los que trae dentro una variable sustituida, y el
# parrafo de R es una variable. Saldria un .txt con saltos mezclados. Asi que se
# normaliza el fichero entero despues, a LF, y file(WRITE) lo escribe con los
# saltos nativos de la maquina que construye -- CRLF en Windows, que es donde se
# construye este instalador.
file(READ "${CMAKE_CURRENT_BINARY_DIR}/SIGUIENTE-PASO.txt" tol_nextsteps_text)
string(REGEX REPLACE "\r\n" "\n" tol_nextsteps_text "${tol_nextsteps_text}")
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/SIGUIENTE-PASO.txt"
     "${tol_nextsteps_text}")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/SIGUIENTE-PASO.txt"
  DESTINATION "." COMPONENT packages)

# Components
set(CPACK_COMPONENTS_GROUPING "ALL_COMPONENTS_IN_ONE")
set(CPACK_COMPONENTS_ALL application development packages)
set(CPACK_COMPONENT_APPLICATION_REQUIRED 1)
set(CPACK_COMPONENT_DEVELOPMENT_DISABLED 1)
set(CPACK_COMPONENT_APPLICATION_DISPLAY_NAME "TOL Application")
set(CPACK_COMPONENT_DEVELOPMENT_DISPLAY_NAME "C++ Headers & Libraries")
set(CPACK_COMPONENT_APPLICATION_DESCRIPTION "Main components of TOL Application")
set(CPACK_COMPONENT_DEVELOPMENT_DESCRIPTION "C/C++ header files and libraries for development purposes")
set(CPACK_COMPONENT_PACKAGES_DISPLAY_NAME "TOL Packages")
set(CPACK_COMPONENT_PACKAGES_DESCRIPTION "TOL packages, installed per user with tol-install-packages")

# => http://stackoverflow.com/questions/21144655/customizing-nsis-installer-using-cpack
configure_file(${SOURCE_DIR}/CPackOptions.cmake.in ${PROJECT_BINARY_DIR}/CPackOptions.cmake)

set(CPACK_PROPERTIES_FILE "${PROJECT_BINARY_DIR}/CPackOptions.cmake")

set(CPACK_RESOURCE_FILE_LICENSE "${SOURCE_DIR}/tol/COPYING")
# Las contrabarras solo cuando se compila DESDE Windows. Estas cuatro rutas son
# ficheros de la maquina que construye --la licencia, el mapa de bits y los dos
# iconos-- y CPack tiene que abrirlos: cruzando desde Linux, con contrabarras no
# los encuentra y aborta con "could not be found". WIN32 no sirve para decidirlo
# porque se refiere al objetivo; lo que importa aqui es el anfitrion, que es
# CMAKE_HOST_WIN32. La conversion de CPACK_NSIS_INSTALLED_ICON_NAME, mas abajo,
# se queda sin guarda: esa es una ruta de la maquina donde se instala, escrita
# sobre la variable INSTDIR de NSIS, y ahi las contrabarras son obligatorias.
if(CMAKE_HOST_WIN32)
  string(REPLACE "/" "\\\\" CPACK_RESOURCE_FILE_LICENSE ${CPACK_RESOURCE_FILE_LICENSE})
endif()

# => http://www.mantidproject.org/NSIS_CPACK_Customisations
# => http://nsis.sourceforge.net/Environmental_Variables:_append,_prepend,_and_remove_entries
# => http://www.cmake.org/Wiki/CMake:CPackNSISAdvancedTips 

set(CPACK_PACKAGE_ICON "${NSIS_DIR}/nsis_tol.bmp") 
if(CMAKE_HOST_WIN32)
  string(REPLACE "/" "\\\\" CPACK_PACKAGE_ICON ${CPACK_PACKAGE_ICON})
endif()
set(CPACK_NSIS_MUI_ICON "${NSIS_DIR}/tolbase-install.ico")
if(CMAKE_HOST_WIN32)
  string(REPLACE "/" "\\\\" CPACK_NSIS_MUI_ICON ${CPACK_NSIS_MUI_ICON})
endif()
set(CPACK_NSIS_MUI_UNIICON "${NSIS_DIR}/tolbase-uninstall.ico")
if(CMAKE_HOST_WIN32)
  string(REPLACE "/" "\\\\" CPACK_NSIS_MUI_UNIICON ${CPACK_NSIS_MUI_UNIICON})
endif()
set(CPACK_NSIS_HELP_LINK "www.tol-project.org")

# nombre del paquete en el instalador
set(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_NAME} ${CPACK_PACKAGE_VERSION}")
# nombre del instalador:
set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAMEV}-${win_system_name}")
message(STATUS "Instaler Name: ${CPACK_PACKAGE_FILE_NAME}")


# Antes de copiar un solo fichero: comprobar que no hay ningun TOL abierto.
#
# Windows no deja sobrescribir un fichero que un proceso tiene cargado, asi que
# con TOLBase abierto el instalador se para en la primera DLL que toca --por
# orden alfabetico, libamd.dll-- con un dialogo de NSIS que solo dice el nombre
# del fichero. Le paso a un usuario el 2026-10-06. Peor: ese dialogo ofrece
# "Omitir", y omitir libtol.dll deja el motor viejo con los paquetes nuevos, que
# es una instalacion rota que no se queja hasta mucho despues.
#
# Se mira el BLOQUEO del fichero, no si hay un proceso con tal nombre. Es la
# condicion que de verdad va a fallar, y asi cubre tambien lo que una lista de
# nombres no cubriria: una sesion de R con tolRlink.dll cargada, por ejemplo,
# que arrastra libtol.dll igual que TOLBase.
#
# libtol.dll es el centinela porque la carga TODO proceso de TOL. El
# IfFileExists de delante no es decorativo: en una instalacion nueva no existe,
# y un FileOpen en modo "a" sobre un fichero que no hay LO CREA, o sea que sin
# esa guarda dejariamos un libtol.dll vacio de cero bytes.
#
# Y, con el camino libre, se borran los zips de paquetes por defecto de la
# version anterior. El instalador copia encima pero no quita nada, asi que
# bin\stdlib\DefaultPackages iba acumulando: medido el 2026-10-06 sobre una
# instalacion real, 100 zips donde el instalador trae 87, con ONCE paquetes en
# dos versiones a la vez -- AlgLib 3.702 junto a 13.702, BysSampler 8.1 junto a
# 18.1, TolRInside en tres-- y la numeracion de TOL 3.4 mezclada con la de 4.1.
#
# No es solo peso muerto: Client::Initialize instala del directorio todo zip que
# no este en el catalogo, asi que cada usuario acababa instalando tambien los
# obsoletos, y pagandolos en el primer arranque.
#
# Se borran solo los *.zip; DefaultPackages.tol viaja en la componente
# application y se reinstala a continuacion.
set(CPACK_NSIS_TOL_PREFLIGHT "
  tol_mirar_abierto:
  IfFileExists \\\"\\\$INSTDIR\\\\bin\\\\libtol.dll\\\" 0 tol_no_abierto
  ClearErrors
  FileOpen \\\$R9 \\\"\\\$INSTDIR\\\\bin\\\\libtol.dll\\\" a
  IfErrors tol_abierto 0
  FileClose \\\$R9
  Goto tol_no_abierto
  tol_abierto:
  IfSilent tol_abierto_silencioso 0
  MessageBox MB_RETRYCANCEL|MB_ICONEXCLAMATION \\\"HAY UN TOL ABIERTO EN ESTA MAQUINA, y por eso no se puede continuar: Windows no deja sobrescribir los ficheros que un programa tiene cargados.\\\$\\\\r\\\$\\\\n\\\$\\\\r\\\$\\\\nCierre TOLBase, y tambien cualquier ventana de tolsh o de tolcon. Despues pulse Reintentar.\\\$\\\\r\\\$\\\\n\\\$\\\\r\\\$\\\\nSi no ve ninguna, mirelo en el Administrador de tareas: tolbase.exe, tolsh.exe, tolcon.exe y tclsh86.exe. El propio instalador abre TOLBase al terminar, asi que es facil que quede una ventana minimizada de la vez anterior.\\\" IDRETRY tol_mirar_abierto
  Abort \\\"Hay un TOL abierto. Cierrelo y vuelva a ejecutar el instalador.\\\"
  tol_abierto_silencioso:
  DetailPrint \\\"Hay un TOL abierto en esta maquina: no se puede sobrescribir bin\\\\libtol.dll. Instalacion abortada.\\\"
  SetErrorLevel 2
  Abort \\\"Hay un TOL abierto.\\\"
  tol_no_abierto:
  DetailPrint \\\"Quitando los paquetes por defecto de la version anterior...\\\"
  Delete \\\"\\\$INSTDIR\\\\bin\\\\stdlib\\\\DefaultPackages\\\\*.zip\\\"
")
# Lo que el instalador hace al terminar. Tres cosas, y la separacion importa:
#
#   * R_HOME. TolRInside se niega a arrancar sin ella, y ese mensaje --"ha de
#     existir la variable de entorno R_HOME"-- es la forma mas comun de que una
#     instalacion de TOL parezca rota en Windows. Se delega en tol-setup-r.cmd
#     /envonly en vez de leer el registro aqui porque la ruta hay que pasarla
#     con barras normales: TolRInside la comprueba con DirExist, y una forma 8.3
#     como C:\Progra~1\R\R-4.1.0 la rechaza. Sustituir contrabarras en NSIS es
#     incomodo y en cmd es "%VAR:\\=/%", asi que la implementacion vive donde es
#     una linea. /envonly no toca la red --ni para los paquetes de CRAN ni para
#     la propia R--: es un sondeo, y lo que decide es su codigo de salida.
#
#   * R, cuando no hay ninguna. El sondeo sale con 2, y entonces se llama a
#     tol-setup-r.cmd entero, que descarga de CRAN la R contra la que se enlazo
#     TolRInside y la instala sin que haya que tocar nada a mano. Antes aqui se
#     abria la pagina de CRAN y se le pedia al usuario que la instalara el y
#     que luego volviera a ejecutar el guion; Joan Estevez se encontro con eso
#     en una maquina sin R. En Ubuntu nunca hizo falta, porque el .deb declara
#     r-base-core como dependencia y apt la trae.
#
#   * El aviso de lo que falta. Los paquetes de TOL NO los puede instalar el
#     instalador, porque el area es por usuario y esto corre elevado; lo mismo
#     que hace el postinst del .deb, que solo imprime instrucciones.
#
# nsExec y no ExecWait para que no aparezca una consola negra a media
# instalacion.

# El ramal de "no hay R" se arma aparte porque es lo unico que cambia segun se
# haya podido medir la version de R o no: con medida, el instalador la instala;
# sin ella se comporta como los anteriores y solo avisa. Asi no hay que repetir
# entero el bloque de ordenes de NSIS.
if(TOL_REQUIRED_R_VERSION)
  set(TOL_NSIS_NO_R "
  tol_sin_r:
  IfSilent tol_sin_r_hazlo 0
  MessageBox MB_YESNO|MB_ICONQUESTION \\\"TOL ${CPACK_PACKAGE_VERSION} queda instalado, pero EN ESTA MAQUINA NO HAY R.\\\$\\\\r\\\$\\\\n\\\$\\\\r\\\$\\\\nTOL funciona sin R. Lo que no funciona sin R es TolExcel, TolRInside y los diagnosticos de BysInfDiag, que son los paquetes que hablan con R.\\\$\\\\r\\\$\\\\n\\\$\\\\r\\\$\\\\nEste instalador puede descargar R ${TOL_REQUIRED_R_VERSION} de CRAN e instalarla ahora, sin que usted tenga que hacer nada a mano. Son unos 90 MB y tarda varios minutos.\\\$\\\\r\\\$\\\\n\\\$\\\\r\\\$\\\\nHacerlo ahora?\\\" IDNO tol_sin_r_luego
  tol_sin_r_hazlo:
  DetailPrint \\\"Descargando R ${TOL_REQUIRED_R_VERSION} de CRAN e instalandola; tarda varios minutos...\\\"
  nsExec::ExecToLog '\\\"\\\$INSTDIR\\\\bin\\\\tol-setup-r.cmd\\\"'
  Pop \\\$0
  StrCmp \\\$0 \\\"0\\\" tol_no_preguntar 0
  IfSilent tol_no_preguntar 0
  MessageBox MB_OK|MB_ICONEXCLAMATION \\\"TOL ${CPACK_PACKAGE_VERSION} queda instalado y funciona, pero NO SE PUDO DEJAR R LISTA. Lo normal es que no haya red o que CRAN no responda.\\\$\\\\r\\\$\\\\n\\\$\\\\r\\\$\\\\nCuando haya red, ejecute una vez, como administrador:\\\$\\\\r\\\$\\\\n\\\$\\\\r\\\$\\\\n    \\\$INSTDIR\\\\bin\\\\tol-setup-r.cmd\\\$\\\\r\\\$\\\\n\\\$\\\\r\\\$\\\\nque vuelve a intentarlo entero. Tambien esta en el menu de inicio, como Preparar R para TOL.\\\"
  Goto tol_no_preguntar
  tol_sin_r_luego:
  MessageBox MB_OK \\\"TOL ${CPACK_PACKAGE_VERSION} queda instalado y funciona.\\\$\\\\r\\\$\\\\n\\\$\\\\r\\\$\\\\nSin R no funcionan TolExcel, TolRInside ni los diagnosticos de BysInfDiag. Cuando quiera dejarlo resuelto, ejecute una vez, como administrador:\\\$\\\\r\\\$\\\\n\\\$\\\\r\\\$\\\\n    \\\$INSTDIR\\\\bin\\\\tol-setup-r.cmd\\\$\\\\r\\\$\\\\n\\\$\\\\r\\\$\\\\nque descarga R ${TOL_REQUIRED_R_VERSION} de CRAN, la instala y prepara los paquetes. Tambien esta en el menu de inicio, como Preparar R para TOL.\\\"
  Goto tol_no_preguntar
")
else()
  set(TOL_NSIS_NO_R "
  tol_sin_r:
  IfSilent tol_no_preguntar 0
  MessageBox MB_YESNO|MB_ICONEXCLAMATION \\\"TOL ${CPACK_PACKAGE_VERSION} queda instalado, pero EN ESTA MAQUINA NO HAY R.\\\$\\\\r\\\$\\\\n\\\$\\\\r\\\$\\\\nTOL funciona sin R. Lo que no funciona sin R es TolExcel, TolRInside y los diagnosticos de BysInfDiag, que son los paquetes que hablan con R.\\\$\\\\r\\\$\\\\n\\\$\\\\r\\\$\\\\nHace falta R para Windows de 64 bits. Despues de instalarla, ejecute una vez, como administrador:\\\$\\\\r\\\$\\\\n\\\$\\\\r\\\$\\\\n    \\\$INSTDIR\\\\bin\\\\tol-setup-r.cmd\\\$\\\\r\\\$\\\\n\\\$\\\\r\\\$\\\\nAbrir ahora la pagina de descarga de R?\\\" IDNO tol_no_preguntar
  ExecShell \\\"open\\\" \\\"https://cran.r-project.org/bin/windows/base/\\\"
  Goto tol_no_preguntar
")
endif()

set(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "
  DeleteRegValue HKCU \\\"Environment\\\" ${TOL_ENV_VAR}
  WriteRegExpandStr HKLM \\\"SYSTEM\\\\CurrentControlSet\\\\Control\\\\Session Manager\\\\Environment\\\" ${TOL_ENV_VAR} \\\$INSTDIR
  SendMessage \\\${HWND_BROADCAST} \\\${WM_WININICHANGE} 0 \\\"STR:Environment\\\" /TIMEOUT=5000
  nsExec::ExecToLog '\\\"\\\$INSTDIR\\\\bin\\\\tol-setup-r.cmd\\\" /envonly'
  Pop \\\$0
  FileOpen \\\$1 \\\"\\\$INSTDIR\\\\SIGUIENTE-PASO.txt\\\" a
  FileSeek \\\$1 0 END
  FileWrite \\\$1 \\\"\\\$\\\\r\\\$\\\\nRUTAS COMPLETAS DE ESTA INSTALACION\\\$\\\\r\\\$\\\\n\\\"
  FileWrite \\\$1 \\\"-----------------------------------\\\$\\\\r\\\$\\\\n\\\$\\\\r\\\$\\\\n\\\"
  FileWrite \\\$1 \\\"    \\\$INSTDIR\\\\bin\\\\tol-install-packages.cmd\\\$\\\\r\\\$\\\\n\\\"
  FileWrite \\\$1 \\\"    \\\$INSTDIR\\\\bin\\\\tol-setup-r.cmd\\\$\\\\r\\\$\\\\n\\\"
  FileClose \\\$1
  StrCmp \\\$0 \\\"2\\\" tol_sin_r 0
  StrCmp \\\$0 \\\"3\\\" 0 tol_r_completo
  IfSilent tol_no_preguntar 0
  MessageBox MB_YESNO|MB_ICONQUESTION \\\"Los paquetes de TOL se instalan solos la primera vez que cada usuario abra TOL.\\\$\\\\r\\\$\\\\nSi esta maquina YA TENIA TOL ${CPACK_PACKAGE_VERSION}, ejecute una vez bin\\\\tol-install-packages.cmd: el arranque solo instala lo que falta y no sustituye lo que ya este, aunque sea mas viejo. Lo explica SIGUIENTE-PASO.txt.\\\$\\\\r\\\$\\\\n\\\$\\\\r\\\$\\\\nA R LE FALTAN PAQUETES que TOL necesita --RInside entre ellos-- y sin ellos no funcionan TolExcel, TolRInside ni los diagnosticos de BysInfDiag. Se bajan de CRAN y tarda unos minutos.\\\$\\\\r\\\$\\\\n\\\$\\\\r\\\$\\\\nInstalarlos ahora?\\\" IDNO tol_no_preguntar
  DetailPrint \\\"Instalando los paquetes de R desde CRAN...\\\"
  nsExec::ExecToLog '\\\"\\\$INSTDIR\\\\bin\\\\tol-setup-r.cmd\\\"'
  Pop \\\$0
  Goto tol_no_preguntar
  tol_r_completo:
  IfSilent tol_no_preguntar 0
  MessageBox MB_OK \\\"TOL ${CPACK_PACKAGE_VERSION} queda instalado y no falta nada mas.\\\$\\\\r\\\$\\\\n\\\$\\\\nLos paquetes de TOL se instalan solos la primera vez que cada usuario abra TOL, y R ya tiene todo lo que hace falta.\\\$\\\\r\\\$\\\\n\\\$\\\\nSi esta maquina YA TENIA TOL ${CPACK_PACKAGE_VERSION}, ejecute una vez bin\\\\tol-install-packages.cmd, porque el arranque solo instala lo que falta y no sustituye lo que ya este. Lo explica SIGUIENTE-PASO.txt.\\\"
  Goto tol_no_preguntar
${TOL_NSIS_NO_R}
  tol_no_preguntar:
") 
# Accesos directos, para que no haya que teclear ninguna ruta. Van aqui y no en
# CPACK_PACKAGE_EXECUTABLES porque eso solo admite ejecutables, no .cmd ni .txt.
set(CPACK_NSIS_CREATE_ICONS_EXTRA "
  CreateShortCut '\\\$SMPROGRAMS\\\\\\\$STARTMENU_FOLDER\\\\Preparar R para TOL.lnk' '\\\$INSTDIR\\\\bin\\\\tol-setup-r.cmd'
  CreateShortCut '\\\$SMPROGRAMS\\\\\\\$STARTMENU_FOLDER\\\\Reinstalar los paquetes de TOL.lnk' '\\\$INSTDIR\\\\bin\\\\tol-install-packages.cmd'
  CreateShortCut '\\\$SMPROGRAMS\\\\\\\$STARTMENU_FOLDER\\\\Leeme de TOL.lnk' '\\\$INSTDIR\\\\SIGUIENTE-PASO.txt'
")
set(CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS "
  DeleteRegValue HKLM \\\"SYSTEM\\\\CurrentControlSet\\\\Control\\\\Session Manager\\\\Environment\\\" ${TOL_ENV_VAR}
  SendMessage \\\${HWND_BROADCAST} \\\${WM_WININICHANGE} 0 \\\"STR:Environment\\\" /TIMEOUT=5000
") 

if(INCLUDE_TOLBASE) 
  # añade el icono en el panel para desinstalar programas
  set(CPACK_NSIS_INSTALLED_ICON_NAME "${INSTDIR}/lib/TolbaseApp${CPACK_PACKAGE_VERSION}/toltk/images/tolbase-gnu.ico")
    string(REPLACE "/" "\\\\" CPACK_NSIS_INSTALLED_ICON_NAME ${CPACK_NSIS_INSTALLED_ICON_NAME})
  
  # Pregunta tras instalar si abrir tolbase, y apunta al LANZADOR, no al .exe.
  # Arrancar aqui tolbase.exe dejaba la primera sesion de TOL sin R_HOME --solo
  # la pone tol-env.cmd, que solo llaman los .cmd-- y por tanto sin TolRInside.
  # Esta linea venia del commit original del instalador y se quedo atras cuando
  # en agosto se metieron los lanzadores. Medido el 2026-10-05: el Exec de NSIS
  # si sabe arrancar un .cmd, y no deja ventana de consola visible.
  set(CPACK_NSIS_MUI_FINISHPAGE_RUN "tolbase.cmd")

  # Los accesos directos se crean a mano y apuntan al LANZADOR, tolbase.cmd, no
  # al .exe. Es lo que pone R_HOME en el proceso y por tanto lo que permite que
  # dos instalaciones de TOL enlazadas contra R distintas convivan; el motivo
  # completo esta en tol-env.cmd. Por eso no se usa CPACK_PACKAGE_EXECUTABLES,
  # que solo sabe crear accesos a .exe y sin icono propio.
  #
  # SW_SHOWMINIMIZED para que la ventana de consola del .cmd no se quede delante,
  # y el .ico explicito porque un .cmd no lleva icono dentro: sin el, Windows
  # pinta una hoja en blanco.
  set(TOL_LAUNCHER_ICON
      "$INSTDIR\\\\lib\\\\TolbaseApp${CPACK_PACKAGE_VERSION}\\\\toltk\\\\images\\\\tolbase-gnu.ico")
  set(CPACK_NSIS_CREATE_ICONS_EXTRA "
    CreateShortCut '\\\$SMPROGRAMS\\\\\\\$STARTMENU_FOLDER\\\\tolbase-gnu-v${CPACK_PACKAGE_VERSION}.lnk' \\\
      '\\\$INSTDIR\\\\bin\\\\tolbase.cmd' '' '${TOL_LAUNCHER_ICON}' 0 SW_SHOWMINIMIZED
    CreateShortCut '\\\$DESKTOP\\\\tolbase-gnu-v${CPACK_PACKAGE_VERSION}.lnk' \\\
      '\\\$INSTDIR\\\\bin\\\\tolbase.cmd' '' '${TOL_LAUNCHER_ICON}' 0 SW_SHOWMINIMIZED
  ")
  set(CPACK_NSIS_DELETE_ICONS_EXTRA "
    Delete '\\\$SMPROGRAMS\\\\\\\$MUI_TEMP\\\\tolbase-gnu-v${CPACK_PACKAGE_VERSION}.lnk'
    Delete '\\\$DESKTOP\\\\tolbase-gnu-v${CPACK_PACKAGE_VERSION}.lnk'
  ")
endif()

# crea otros accesos directos
set(CPACK_NSIS_MENU_LINKS "http://www.tol-project.org" "Tol-Project Site")

# include(CPack) ha de hacerse en este mismo archivo para que funcione adecuadamente
include(CPack)
