#========================================================================
#
# cmake-config.txt
#
# CMake script to do misc cmake config and platform-specific config.
#
# Copyright 2021 Glyph & Cog, LLC
#
#========================================================================

if (POLICY CMP0074)
  cmake_policy(SET CMP0074 NEW)
endif ()

if (APPLE)
  set(CMAKE_MACOSX_RPATH 1)
endif ()

include(CheckFunctionExists)
include(CheckCXXSourceCompiles)
include(GNUInstallDirs)

enable_language(CXX)
set(CMAKE_CXX_STANDARD 11)

#--- add a 'Profiling' build mode
if (CMAKE_GENERATOR STREQUAL "Unix Makefiles")
  set(CMAKE_C_FLAGS_PROFILING "-g -pg -O -Wall"
      CACHE STRING "C compiler flags for profiling mode"
      FORCE)
  set(CMAKE_CXX_FLAGS_PROFILING "-g -pg -O -Wall"
      CACHE STRING "C++ compiler flags for profiling mode"
      FORCE)
  set(CMAKE_EXE_LINKER_FLAGS_PROFILING "-g -pg -O -Wall"
      CACHE STRING "linker flags for profiling mode"
      FORCE)
  set(CMAKE_SHARED_LINKER_FLAGS_PROFILING "-g -pg -O -Wall"
      CACHE STRING "shared linker flags for profiling mode"
      FORCE)
  mark_as_advanced(
    CMAKE_C_FLAGS_PROFILING
    CMAKE_CXX_FLAGS_PROFILING
    CMAKE_EXE_LINKER_FLAGS_PROFILING
    CMAKE_SHARED_LINKER_FLAGS_PROFILING)
  set(CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING
      "Choose build mode - options are: None Debug Release RelWithDebInfo MinSizeRel Profiling"
      FORCE)
endif ()

#--- set default C/C++ compiler flags for Windows
if (MSVC)
  option(USE_MT_IN_DEBUG "use /MT instead of /MTd in debug builds" OFF)
  foreach (var CMAKE_C_FLAGS_DEBUG CMAKE_CXX_FLAGS_DEBUG
               CMAKE_C_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELEASE
               CMAKE_C_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_MINSIZEREL
               CMAKE_C_FLAGS_RELWITHDEBINFO CMAKE_CXX_FLAGS_RELWITHDEBINFO)
    # note: this converts /MD to /MT and /MDd to /MTd
    string(REGEX REPLACE "/MD" "/MT" ${var} "${${var}}")
  endforeach ()
  if (USE_MT_IN_DEBUG)
    string(REPLACE "/MTd" "/MT" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}")
    string(REPLACE "/MTd" "/MT" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
  else ()
    set(CMAKE_EXE_LINKER_FLAGS_DEBUG "/NODEFAULTLIB:libcmt ${CMAKE_EXE_LINKER_FLAGS_DEBUG}")
    set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "/NODEFAULTLIB:libcmt ${CMAKE_SHARED_LINKER_FLAGS_DEBUG}")
  endif ()
  foreach (var CMAKE_C_FLAGS_DEBUG
               CMAKE_C_FLAGS_RELEASE
               CMAKE_C_FLAGS_MINSIZEREL
               CMAKE_C_FLAGS_RELWITHDEBINFO)
    set(${var} "${${var}} /D_CRT_SECURE_NO_WARNINGS /wd4290 /wd4996")
  endforeach ()
  foreach (var CMAKE_CXX_FLAGS_DEBUG
               CMAKE_CXX_FLAGS_RELEASE
               CMAKE_CXX_FLAGS_MINSIZEREL
               CMAKE_CXX_FLAGS_RELWITHDEBINFO)
    set(${var} "${${var}} /D_CRT_SECURE_NO_WARNINGS /wd4290 /wd4996 /EHsc")
  endforeach ()
endif ()

#--- don't set an rpath
set(CMAKE_SKIP_RPATH FALSE)

#--- miscellaneous options
option(A4_PAPER "use A4 (instead of Letter) paper size by default for PostScript output" OFF)
option(NO_TEXT_SELECT "do not allow text selection" OFF)
option(OPI_SUPPORT "include support for OPI comments" OFF)
option(MULTITHREADED "include support for multithreading" ON)
option(USE_EXCEPTIONS "use C++ exceptions" ON)
option(USE_FIXEDPOINT "use fixed point (instead of floating point) arithmetic" OFF)
option(SPLASH_CMYK "include support for CMYK rasterization" OFF)
option(NO_FONTCONFIG "disable support for libfontconfig" OFF)
if (WIN32)
  option(XPDFWIDGET_PRINTING "include printing support in XpdfWidget" OFF)
else ()
  option(XPDFWIDGET_PRINTING "include printing support in XpdfWidget" ON)
endif ()
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
  option(USE_XDG "use XDG paths for config and state files" ON)
else ()
  option(USE_XDG "use XDG paths for config and state files" OFF)
endif ()

#--- paths
set(SYSTEM_XPDFRC "${SYSTEM_XPDFRC}" CACHE FILEPATH "full path for system-wide xpdfrc file")
set(XPDFRC_DATADIR "${XPDFRC_DATADIR}" CACHE PATH "directory to use for the DATADIR xpdfrc variable")
set(BASE14_FONT_DIR "${BASE14_FONT_DIR}" CACHE PATH "directory where the Base14 fonts are installed")

#--- check for various library functions
check_function_exists(mkstemp HAVE_MKSTEMP)
check_function_exists(mkstemps HAVE_MKSTEMPS)
check_function_exists(popen HAVE_POPEN)
check_cxx_source_compiles(
    "#include <algorithm>
    bool cmp(const int &x, const int &y) { return x < y; }
    int a[100];
    int main() { std::sort(a, a+100, &cmp); }"
  HAVE_STD_SORT)

#--- set up 64-bit file seeks
check_function_exists(fseeko HAVE_FSEEKO)
check_function_exists(fseek64 HAVE_FSEEK64)
check_function_exists(_fseeki64 HAVE_FSEEKI64)

#--- look for FreeType
# This could use cmake's FindFreetype, except that it would require
# a newer version of cmake -- because FreeType changed their include
# paths around.  Older versions of FreeType require two separate
# -I switches (typically ..../include and ..../include/freetype2);
# while newer versions require just one (typically ..../include/freetype2)
find_path(FREETYPE_INCLUDE_DIR_ft2build ft2build.h
  HINTS
  ${FREETYPE_DIR}
  PATHS
  /usr/local/include
  /usr/local/X11R6/include
  /usr/local/X11/include
  /usr/freeware/include
  PATH_SUFFIXES freetype2 include/freetype2 include
)
find_path(FREETYPE_INCLUDE_DIR_freetype freetype.h
  HINTS
  ${FREETYPE_DIR}
  PATHS
  /usr/local/include
  /usr/local/X11R6/include
  /usr/local/X11/include
  /usr/freeware/include
  PATH_SUFFIXES freetype2 include/freetype2 include
)
find_path(FREETYPE_INCLUDE_DIR_freetype_freetype freetype/freetype.h
  HINTS
  ${FREETYPE_DIR}
  PATHS
  /usr/local/include
  /usr/local/X11R6/include
  /usr/local/X11/include
  /usr/freeware/include
  PATH_SUFFIXES freetype2 include/freetype2 include
)
find_library(FREETYPE_LIBRARY
  NAMES freetype libfreetype freetype2 freetype219
  HINTS
  ${FREETYPE_DIR}
  PATH_SUFFIXES lib64 lib
  PATHS
  /usr/local
  /usr/local/X11R6
  /usr/local/X11
  /usr/freeware
)
if (FREETYPE_INCLUDE_DIR_ft2build
    AND FREETYPE_INCLUDE_DIR_freetype
    AND (FREETYPE_INCLUDE_DIR_ft2build STREQUAL FREETYPE_INCLUDE_DIR_freetype)
    AND FREETYPE_LIBRARY)
  set(FREETYPE_INCLUDE_DIRS "${FREETYPE_INCLUDE_DIR_ft2build}")
  set(HAVE_FREETYPE_H TRUE)
  message(STATUS "Found FreeType (new-style includes): ${FREETYPE_LIBRARY}")
elseif (FREETYPE_INCLUDE_DIR_ft2build
        AND FREETYPE_INCLUDE_DIR_freetype_freetype
        AND FREETYPE_LIBRARY)
  set(FREETYPE_INCLUDE_DIRS
      "${FREETYPE_INCLUDE_DIR_ft2build};${FREETYPE_INCLUDE_DIR_freetype_freetype}")
  set(HAVE_FREETYPE_H TRUE)
  message(STATUS "Found FreeType (old-style includes): ${FREETYPE_LIBRARY}")
else ()
  message(STATUS "FreeType not found")
endif ()
if (HAVE_FREETYPE_H)
  set(HAVE_SPLASH TRUE)
endif ()


#--- look for zlib
find_package(ZLIB)

#--- look for libpng
find_package(PNG)




#--- look for Qt
find_package(Qt6Widgets QUIET)
if (Qt6Widgets_FOUND)
  find_package(Qt6Network)
  find_package(Qt6Concurrent)
  find_package(Qt6PrintSupport)
else ()
  find_package(Qt5Widgets QUIET)
  if (Qt5Widgets_FOUND)
    find_package(Qt5Network)
    find_package(Qt5Concurrent)
    find_package(Qt5PrintSupport)
  endif ()
endif ()
if (Qt5Widgets_FOUND)
  message(STATUS "Qt5 found")
  if (XPDFWIDGET_PRINTING)
    set(QT_INCLUDES "${Qt5Widgets_INCLUDE_DIRS} ${Qt5Network_INCLUDE_DIRS} ${Qt5Concurrent_INCLUDE_DIRS} ${Qt5PrintSupport_INCLUDE_DIRS}")
    set(QT_DEFINITIONS "${Qt5Widgets_DEFINITIONS} ${Qt5Network_DEFINITIONS} ${Qt5Concurrent_DEFINITIONS} ${Qt5PrintSupport_DEFINITIONS}")
    set(QT_LIBRARIES Qt5::Widgets Qt5::Network Qt5::PrintSupport)
  else ()
    set(QT_INCLUDES "${Qt5Widgets_INCLUDE_DIRS} ${Qt5Network_INCLUDE_DIRS} ${Qt5Concurrent_INCLUDE_DIRS}")
    set(QT_DEFINITIONS "${Qt5Widgets_DEFINITIONS} ${Qt5Network_DEFINITIONS} ${Qt5Concurrent_DEFINITIONS}")
    set(QT_LIBRARIES Qt5::Widgets Qt5::Network)
  endif ()
  if (XPDFWIDGET_PRINTING)
    if (APPLE)
      set(EXTRA_QT_LIBRARIES "-framework ApplicationServices")
    elseif (UNIX)
      find_package(Cups)
      if (CUPS_FOUND)
        set(EXTRA_QT_LIBRARIES ${CUPS_LIBRARIES})
      else ()
        set (XPDFWIDGET_PRINTING OFF)
      endif ()
    else ()
      set(EXTRA_QT_LIBRARIES "")
    endif ()
  endif ()
  # remove "-fPIE" here because we added "-fPIC" above
  string(REPLACE "-fPIE" "" QT_CFLAGS "${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
elseif (Qt6Widgets_FOUND)
  message(STATUS "Qt6 found")
  if (XPDFWIDGET_PRINTING)
    set(QT_INCLUDES ${Qt6Widgets_INCLUDE_DIRS} ${Qt6Network_INCLUDE_DIRS} ${Qt6Concurrent_INCLUDE_DIRS} ${Qt6PrintSupport_INCLUDE_DIRS})
    set(QT_DEFINITIONS "${Qt6Widgets_DEFINITIONS} ${Qt6Network_DEFINITIONS} ${Qt6Concurrent_DEFINITIONS} ${Qt6PrintSupport_DEFINITIONS}")
    set(QT_LIBRARIES Qt6::Widgets Qt6::Network Qt6::Concurrent Qt6::PrintSupport)
  else ()
    set(QT_INCLUDES ${Qt6Widgets_INCLUDE_DIRS} ${Qt6Network_INCLUDE_DIRS} ${Qt6Concurrent_INCLUDE_DIRS})
    set(QT_DEFINITIONS "${Qt6Widgets_DEFINITIONS} ${Qt6Network_DEFINITIONS} ${Qt6Concurrent_DEFINITIONS}")
    set(QT_LIBRARIES Qt6::Widgets Qt6::Network Qt6::Concurrent)
  endif ()
  if (XPDFWIDGET_PRINTING)
    if (APPLE)
      set(EXTRA_QT_LIBRARIES "-framework ApplicationServices")
    elseif (UNIX)
      find_package(Cups)
      if (CUPS_FOUND)
        set(EXTRA_QT_LIBRARIES ${CUPS_LIBRARIES})
      else ()
        set (XPDFWIDGET_PRINTING OFF)
      endif ()
    else ()
      set(EXTRA_QT_LIBRARIES "")
    endif ()
  endif ()
  # remove "-fPIE" here because we added "-fPIC" above
  string(REPLACE "-fPIE" "" QT_CFLAGS "${Qt6Widgets_EXECUTABLE_COMPILE_FLAGS}")
else ()
  message(STATUS "No Qt library found")
endif ()

#--- look for libpaper
find_library(PAPER_LIBRARY
             NAMES paper libpaper
             PATH_SUFFIXES lib64 lib
)
if (PAPER_LIBRARY)
  set(HAVE_PAPER_H TRUE)
else ()
  set(HAVE_PAPER_H FALSE)
  set(PAPER_LIBRARY "")
endif ()

#--- look for fontconfig
if (NOT NO_FONTCONFIG)
  find_library(FONTCONFIG_LIBRARY
               NAMES fontconfig libfontconfig
               PATH_SUFFIXES lib64 lib
  )
  if (FONTCONFIG_LIBRARY)
    set(HAVE_FONTCONFIG TRUE)
    message(STATUS "Found fontconfig")
  else ()
    set(HAVE_FONTCONFIG FALSE)
    set(FONTCONFIG_LIBRARY "")
  endif ()
else ()
  set(HAVE_FONTCONFIG FALSE)
  set(FONTCONFIG_LIBRARY "")
endif ()

#--- look for pthreads
if (MULTITHREADED)
  find_package(Threads)
else ()
  set(CMAKE_THREAD_LIBS_INIT "")
endif ()

#--- create aconf.h
configure_file("aconf.h.in" "aconf.h")
