if (NOT ENABLE_DOCGEN)
   message(FATAL_ERROR "Documentation generation is disabled")
endif()

set(ASY_TEX_BUILD_ROOT ${CMAKE_CURRENT_BINARY_DIR}/docbuild)
file(MAKE_DIRECTORY ${ASY_TEX_BUILD_ROOT})
configure_file(${ASY_RESOURCE_DIR}/version.texi.in ${ASY_TEX_BUILD_ROOT}/version.texi)

set(LATEX_ARTIFRACT_EXTENSIONS aux hd idx ins log out toc)

set(PDFLATEX_BASE_ARGUMENTS ${PDFLATEX_COMPILER}
       -output-directory=${ASY_TEX_BUILD_ROOT}
)

find_package(LATEX COMPONENTS PDFLATEX REQUIRED)
list(
       TRANSFORM LATEX_ARTIFRACT_EXTENSIONS
       PREPEND ${ASY_TEX_BUILD_ROOT}/asy-latex.
       OUTPUT_VARIABLE ASY_LATEX_DTX_ARTIFACTS
)

add_custom_command(
       OUTPUT ${ASY_TEX_BUILD_ROOT}/asy-latex.pdf ${ASY_TEX_BUILD_ROOT}/asymptote.sty
       DEPENDS ${ASY_DOC_DIR}/asy-latex.dtx
       COMMAND ${PDFLATEX_BASE_ARGUMENTS} ${ASY_DOC_DIR}/asy-latex.dtx
       WORKING_DIRECTORY ${ASY_DOC_DIR}
       BYPRODUCTS ${ASY_LATEX_DTX_ARTIFACTS}
)

add_custom_command(
       OUTPUT ${ASY_TEX_BUILD_ROOT}/latexusage.pdf
       DEPENDS
           ${ASY_DOC_DIR}/latexusage.tex
           ${ASY_TEX_BUILD_ROOT}/asymptote.sty
           asy ${ASY_OUTPUT_BASE_FILES}
       COMMAND ${PY3_INTERPRETER} ${ASY_DOC_DIR}/build-latexusage-pdf.py
           --build-dir=${ASY_TEX_BUILD_ROOT}
           --latexusage-source-dir=${ASY_DOC_DIR}
           --pdflatex-executable=${PDFLATEX_COMPILER}
           --asy-executable=$<TARGET_FILE:asy>
           --asy-base-dir=${ASY_BUILD_BASE_DIR}
       WORKING_DIRECTORY ${ASY_DOC_DIR}
       BYPRODUCTS ${ASY_TEX_BUILD_ROOT}/latexusage.log
)

set(CMAKE_COPY_ASY_FILE_TO_DOCBUILD_BASE_ARGS ${CMAKE_COMMAND} -E copy -t ${ASY_TEX_BUILD_ROOT})
set(CMAKE_RM_BASE_ARGUMENTS ${CMAKE_COMMAND} -E rm)
set(ASY_BASE_ARGUMENTS asy -dir ${ASY_BUILD_BASE_DIR} -config '' -render=0 -noprc -noV)

macro(add_additional_pdf_outputs filename_base num_times_to_call_pdflatex compiler)
   # ARGN can be used to specify additional dependencies
   foreach (DUMMY_VAR RANGE 1 ${num_times_to_call_pdflatex})
       list(APPEND COMMAND_ARGS COMMAND ${compiler} ${ASY_DOC_DIR}/${filename_base}.tex)
   endforeach()

   set(PDFLATEX_OUTPUT_PREFIX ${ASY_TEX_BUILD_ROOT}/${filename_base})

   # there are unfortunately still some issues with out-of-source builds
   # with pdflatex, hence we have to copy the files to the build root first
   add_custom_command(
           OUTPUT ${PDFLATEX_OUTPUT_PREFIX}.tex
           DEPENDS ${ASY_DOC_DIR}/${filename_base}.tex
           COMMAND ${CMAKE_COPY_ASY_FILE_TO_DOCBUILD_BASE_ARGS} ${ASY_DOC_DIR}/${filename_base}.tex
   )

   add_custom_command(
           OUTPUT ${PDFLATEX_OUTPUT_PREFIX}.pdf
           DEPENDS ${PDFLATEX_OUTPUT_PREFIX}.tex
           ${ARGN}
           ${COMMAND_ARGS}
           COMMAND ${CMAKE_RM_BASE_ARGUMENTS} -f ${PDFLATEX_OUTPUT_PREFIX}.dvi
           WORKING_DIRECTORY ${ASY_TEX_BUILD_ROOT}
           BYPRODUCTS
               ${PDFLATEX_OUTPUT_PREFIX}.aux
               ${PDFLATEX_OUTPUT_PREFIX}.log
               ${PDFLATEX_OUTPUT_PREFIX}.toc
   )
endmacro()

# asy -> pdf file generation

set(ASY_DOC_PDF_FILES "")

macro(add_asy_pdf_dependency_basic asyfile)
   set(ASY_DOC_FILE_OUTPUT ${ASY_TEX_BUILD_ROOT}/${asyfile}.pdf)
   # asymptote has some problems (currently as writing this) with asy files involving tex
   # and output directory not matching, so a workaround is to copy to the doc build root
   add_custom_command(
           OUTPUT ${ASY_DOC_FILE_OUTPUT}
           DEPENDS ${ASY_DOC_DIR}/${asyfile}.asy asy ${ASY_OUTPUT_BASE_FILES}
           # copy <docroot>/file.asy -> <buildroot>/file.asy
           COMMAND ${CMAKE_COPY_ASY_FILE_TO_DOCBUILD_BASE_ARGS} ${ASY_DOC_DIR}/${asyfile}.asy
           COMMAND ${ASY_BASE_ARGUMENTS} -fpdf ${asyfile}.asy
           # cleanup <buildroot>/file.asy
           COMMAND ${CMAKE_RM_BASE_ARGUMENTS}
           ${ASY_TEX_BUILD_ROOT}/${asyfile}.asy
           # cleanup tex artifacts, if exist
           COMMAND ${CMAKE_RM_BASE_ARGUMENTS} -f
           ${ASY_TEX_BUILD_ROOT}/${asyfile}_.tex
           WORKING_DIRECTORY ${ASY_TEX_BUILD_ROOT}
   )
   list(APPEND ASY_DOC_PDF_FILES ${ASY_DOC_FILE_OUTPUT})
endmacro()

# CAD1 is here because it is needed for CAD.pdf.
add_asy_pdf_dependency_basic(CAD1)

# additional asymptote file outputs
add_additional_pdf_outputs(asyRefCard 1 ${PDFTEX_EXEC})
add_additional_pdf_outputs(TeXShopAndAsymptote 2 ${PDFLATEX_COMPILER})
add_additional_pdf_outputs(
       CAD
       3
       ${PDFLATEX_COMPILER}
       DEPENDS ${ASY_TEX_BUILD_ROOT}/CAD1.pdf
)

set(
       BASE_ASYMPTOTE_DOC_AND_TEX_FILES
       ${ASY_TEX_BUILD_ROOT}/asymptote.sty
       ${ASY_TEX_BUILD_ROOT}/asy-latex.pdf
       ${ASY_TEX_BUILD_ROOT}/CAD.pdf
       ${ASY_TEX_BUILD_ROOT}/TeXShopAndAsymptote.pdf
       ${ASY_TEX_BUILD_ROOT}/asyRefCard.pdf
)

add_custom_target(docgen DEPENDS ${BASE_ASYMPTOTE_DOC_AND_TEX_FILES})


# the following files are only used with docgen, hence they are not added if
# ENABLE_ASYMPTOTE_PDF_DOCGEN is not used
if (ENABLE_ASYMPTOTE_PDF_DOCGEN)
# asy files
set(ASY_DOC_FILE_PREFIXES
       axis3 basealign bezier bigdiagonal binarytreetest Bode brokenaxis
       colons colors cube cylinderskeleton datagraph diagonal dots
       eetomumu elliptic errorbars exp  fillcontour flow flowchartdemo
       GaussianSurface generalaxis generalaxis3 graphmarkers graphwithderiv grid3xyz
       hatch helix HermiteSpline histogram Hobbycontrol Hobbydir icon image imagecontour
       irregularcontour join join3 knots labelsquare legend lineargraph lineargraph0
       linetype log2graph loggraph loggrid logimage logticks makepen markers1 markers2 mexicanhat
       monthaxis multicontour onecontour parametricgraph penfunctionimage penimage planes quartercircle
       saddle scaledgraph shadedtiling slopefield1 square subpictures superpath tile
       triangulate unitcircle3 vectorfield
)

# independent asymptote files that can be generated with any other files
foreach(ASY_DOC_FILE_PREFIX ${ASY_DOC_FILE_PREFIXES})
   add_asy_pdf_dependency_basic(${ASY_DOC_FILE_PREFIX})
endforeach()

macro(add_asy_file_with_extension asy_file extra_ext)
   set(ASY_DOC_FILE_OUTPUT ${ASY_TEX_BUILD_ROOT}/${asy_file}.pdf)
   set(ASY_AUX_FILE_NAME ${asy_file}.${extra_ext})
   # asymptote has some problems (currently as writing this) with asy files involving tex
   # and output directory not matching, so a workaround is to copy to the doc build root
   add_custom_command(
           OUTPUT ${ASY_DOC_FILE_OUTPUT}
           DEPENDS
               ${ASY_DOC_DIR}/${asy_file}.asy
               ${ASY_DOC_DIR}/${ASY_AUX_FILE_NAME}
               asy ${ASY_OUTPUT_BASE_FILES}
           COMMAND ${CMAKE_COPY_ASY_FILE_TO_DOCBUILD_BASE_ARGS}
               ${ASY_DOC_DIR}/${asy_file}.asy
               ${ASY_DOC_DIR}/${ASY_AUX_FILE_NAME}
           COMMAND ${ASY_BASE_ARGUMENTS} -fpdf ${ASY_DOC_FILE_PREFIX}.asy
           COMMAND ${CMAKE_RM_BASE_ARGUMENTS}
               ${ASY_TEX_BUILD_ROOT}/${asy_file}.asy
               ${ASY_TEX_BUILD_ROOT}/${ASY_AUX_FILE_NAME}
           COMMAND ${CMAKE_RM_BASE_ARGUMENTS} -f
               ${ASY_TEX_BUILD_ROOT}/${asy_file}_.tex
           WORKING_DIRECTORY ${ASY_TEX_BUILD_ROOT}
   )
   list(APPEND ASY_DOC_PDF_FILES ${ASY_DOC_FILE_OUTPUT})
endmacro()

# asy + csv Files
foreach(ASY_DOC_FILE_PREFIX diatom secondaryaxis westnile)
   add_asy_file_with_extension(${ASY_DOC_FILE_PREFIX} csv)
endforeach()

# asy + dat files
foreach(ASY_DOC_FILE_PREFIX filegraph leastsquares)
   add_asy_file_with_extension(${ASY_DOC_FILE_PREFIX} dat)
endforeach()


# handle CDlabel and logo separately
macro(copy_doc_asy_file_to_docbuild_root asyfile)
   add_custom_command(
           OUTPUT ${ASY_TEX_BUILD_ROOT}/${asyfile}.asy
           COMMAND ${CMAKE_COPY_ASY_FILE_TO_DOCBUILD_BASE_ARGS}
           ${ASY_DOC_DIR}/${asyfile}.asy
           DEPENDS ${ASY_DOC_DIR}/${asyfile}.asy
   )
endmacro()

function(add_asy_file_with_asy_dependency asyfile) # <asydep1> [asydep2] ...
   list(
           TRANSFORM ARGN
           PREPEND ${ASY_TEX_BUILD_ROOT}/
           OUTPUT_VARIABLE ASY_REQUIRED_DEPS
   )
   list(
           TRANSFORM ASY_REQUIRED_DEPS
           APPEND .asy
   )

   add_custom_command(
           OUTPUT ${ASY_TEX_BUILD_ROOT}/${asyfile}.pdf
           DEPENDS ${ASY_DOC_DIR}/${asyfile}.asy asy ${ASY_OUTPUT_BASE_FILES} ${ASY_REQUIRED_DEPS}
           # copy <docroot>/file.asy -> <buildroot>/file.asy
           COMMAND ${CMAKE_COPY_ASY_FILE_TO_DOCBUILD_BASE_ARGS} ${ASY_DOC_DIR}/${asyfile}.asy
           COMMAND ${ASY_BASE_ARGUMENTS} -fpdf ${asyfile}.asy
           # cleanup <buildroot>/file.asy
           COMMAND ${CMAKE_RM_BASE_ARGUMENTS} ${ASY_TEX_BUILD_ROOT}/${asyfile}.asy
           # cleanup tex artifacts, if exist
           COMMAND ${CMAKE_RM_BASE_ARGUMENTS} -f ${ASY_TEX_BUILD_ROOT}/${asyfile}_.tex
           WORKING_DIRECTORY ${ASY_TEX_BUILD_ROOT}
   )
endfunction()

macro(add_asy_file_from_docbuild_root asyfile)
   # does not copy from doc root to docbuild root; have to do manually
   add_custom_command(
           OUTPUT ${ASY_TEX_BUILD_ROOT}/${asyfile}.pdf
           COMMAND ${ASY_BASE_ARGUMENTS} -fpdf ${asyfile}.asy
           DEPENDS ${ASY_TEX_BUILD_ROOT}/${asyfile}.asy
           BYPRODUCTS ${ASY_TEX_BUILD_ROOT}/${asyfile}_.tex ${ASY_TEX_BUILD_ROOT}/${asyfile}_.eps
           WORKING_DIRECTORY ${ASY_TEX_BUILD_ROOT}
   )
endmacro()

# CDlabel + logo
copy_doc_asy_file_to_docbuild_root(logo)
add_asy_file_from_docbuild_root(logo)
add_asy_file_with_asy_dependency(CDlabel logo)

# bezier2 & beziercurve
copy_doc_asy_file_to_docbuild_root(beziercurve)
add_asy_file_from_docbuild_root(beziercurve)
add_asy_file_with_asy_dependency(bezier2 beziercurve)

list(APPEND ASY_DOC_PDF_FILES
       ${ASY_TEX_BUILD_ROOT}/logo.pdf
       ${ASY_TEX_BUILD_ROOT}/CDlabel.pdf
       ${ASY_TEX_BUILD_ROOT}/beziercurve.pdf
       ${ASY_TEX_BUILD_ROOT}/bezier2.pdf
)

# options file
add_custom_command(
       OUTPUT ${ASY_TEX_BUILD_ROOT}/options
       DEPENDS asy ${ASY_DOC_DIR}/gen-asy-options-file.py
       COMMAND ${PY3_INTERPRETER} ${ASY_DOC_DIR}/gen-asy-options-file.py
       --asy-executable=$<TARGET_FILE:asy>
       --output-file=${ASY_TEX_BUILD_ROOT}/options
)

# asymptote.pdf

set(TEXI_ARTIFACT_EXTENSIONS log tmp cp toc cps aux)
list(
       TRANSFORM TEXI_ARTIFACT_EXTENSIONS
       PREPEND ${ASY_TEX_BUILD_ROOT}/asymptote.
       OUTPUT_VARIABLE ASYMPTOTE_PDF_EXTRA_ARTIFACTS
   )

if (WIN32)
if (WIN32_TEXINDEX STREQUAL WSL)
   set(TEXINDEX_WRAPPER ${CMAKE_CURRENT_SOURCE_DIR}/windows/texindex-wsl.cmd)
else()
   set(TEXINDEX_WRAPPER ${WIN32_TEXINDEX})
endif()
add_custom_command(
       OUTPUT ${ASY_TEX_BUILD_ROOT}/asymptote.pdf
       DEPENDS
           ${ASY_TEX_BUILD_ROOT}/options
           ${ASY_TEX_BUILD_ROOT}/latexusage.pdf
           ${ASY_DOC_DIR}/asymptote.texi
           ${ASY_DOC_PDF_FILES}
       COMMAND ${PY3_INTERPRETER}
           ${ASY_DOC_DIR}/build-asymptote-pdf-win.py
           --texify-loc=${TEXIFY}
           --texindex-loc=${TEXINDEX_WRAPPER}
           --texi-file=${ASY_DOC_DIR}/asymptote.texi
       WORKING_DIRECTORY ${ASY_TEX_BUILD_ROOT}
       BYPRODUCTS ${ASYMPTOTE_PDF_EXTRA_ARTIFACTS}
)
else()
add_custom_command(
       OUTPUT ${ASY_TEX_BUILD_ROOT}/asymptote.pdf
       DEPENDS
       ${ASY_TEX_BUILD_ROOT}/options
       ${ASY_TEX_BUILD_ROOT}/latexusage.pdf
       ${ASY_DOC_DIR}/asymptote.texi
       ${ASY_DOC_PDF_FILES}
       COMMAND ${TEXI2DVI} --pdf ${ASY_DOC_DIR}/asymptote.texi
       WORKING_DIRECTORY ${ASY_TEX_BUILD_ROOT}
       BYPRODUCTS ${ASYMPTOTE_PDF_EXTRA_ARTIFACTS}
)
endif()
add_custom_target(asymptote_pdf_file DEPENDS ${ASY_TEX_BUILD_ROOT}/asymptote.pdf)
add_dependencies(docgen asymptote_pdf_file)

# manual page
add_custom_command(
       OUTPUT ${ASY_TEX_BUILD_ROOT}/asy.1
       DEPENDS
           ${ASY_DOC_DIR}/asy.1.begin
           ${ASY_DOC_DIR}/asy.1.end
           ${ASY_TEX_BUILD_ROOT}/options
           ${ASY_DOC_DIR}/build-asy-1-file.py
       COMMAND ${PY3_INTERPRETER} ${ASY_DOC_DIR}/build-asy-1-file.py
           --options-file=${ASY_TEX_BUILD_ROOT}/options
           --asy-1-begin-file=${ASY_DOC_DIR}/asy.1.begin
           --asy-1-end-file=${ASY_DOC_DIR}/asy.1.end
           --out-file=${ASY_TEX_BUILD_ROOT}/asy.1
       WORKING_DIRECTORY ${ASY_TEX_BUILD_ROOT}
)

   add_custom_target(manpage DEPENDS ${ASY_TEX_BUILD_ROOT}/asy.1)

if (UNIX)
   add_dependencies(docgen manpage)
endif()

endif() # ENABLE_ASYMPTOTE_PDF_DOCGEN