include_directories(
    ${CMAKE_CURRENT_SOURCE_DIR}
    ${CMAKE_CURRENT_BINARY_DIR}
    ${TOP_SOURCE_DIR}/windows/getopt
    ${GRAPHVIZ_LIB_DIR}/cdt
    ${GRAPHVIZ_LIB_DIR}/cgraph
    ${GRAPHVIZ_LIB_DIR}/common
    ${GRAPHVIZ_LIB_DIR}/gvc
    ${GRAPHVIZ_LIB_DIR}/ingraphs
    ${GRAPHVIZ_LIB_DIR}/neatogen
    ${GRAPHVIZ_LIB_DIR}/pack
    ${GRAPHVIZ_LIB_DIR}/pathplan
    ${GRAPHVIZ_LIB_DIR}/sparse
    ${EXPAT_INCLUDE_DIRS}
)

# This function sets some default values that every tools shares:
# - linking to getopt if REQUIRED
# - installation of executable
# - installation of manpage
function(tool_defaults name)
    if(NOT HAVE_GETOPT_H)
        target_link_libraries(${name} getopt)
    endif(NOT HAVE_GETOPT_H)

    install(
        TARGETS ${name}
        RUNTIME DESTINATION ${BINARY_INSTALL_DIR}
    )

    install(
        FILES ${name}.1
        DESTINATION ${MAN_INSTALL_DIR}
    )
endfunction(tool_defaults)

# ================================ simple tools ================================
# These tools have a single source file and share linked libraries, etc.

# This function adds a simple tool using only it's name
function(add_simple_tool name)
    add_executable(${name} ${name}.c)

    target_link_libraries(${name}
        cgraph
        ingraphs
    )

    tool_defaults(${name})
endfunction(add_simple_tool)

add_simple_tool(acyclic)
add_simple_tool(bcomps)
add_simple_tool(ccomps)
add_simple_tool(gc)
add_simple_tool(nop)
add_simple_tool(tred)
target_link_libraries(tred common) # e.g. for start_timer
add_simple_tool(unflatten)

# ================================ complex tools ===============================
# These tools have multiple source files, different dependencies or other
# differences from the simple tools above

# ================================== dijkstra ==================================
add_executable(dijkstra
    # Source files
    dijkstra.c
)

target_link_libraries(dijkstra
    cdt
    cgraph
    ingraphs
)

tool_defaults(dijkstra)

# =================================== gml2gv ===================================
BISON_TARGET(Gmlparse gmlparse.y ${CMAKE_CURRENT_BINARY_DIR}/gmlparse.c)
FLEX_TARGET(Gmlscan gmlscan.l  ${CMAKE_CURRENT_BINARY_DIR}/gmlscan.c)
ADD_FLEX_BISON_DEPENDENCY(Gmlscan Gmlparse)

# Modify files generated by Bison and Flex, to match the Autotools build.
# - Replace "yy" with "gml" in all three files
# - Replace "unsigned long int" with "uint64_t" in gmlparse.h and gmlparse.c
# - Replace "unsigned long" with "uint64_t" in gmlparse.h and gmlparse.c
configure_file(
    "${TOP_SOURCE_DIR}/cmake/modify_gml2gv_gmlparse.cmake.in"
    "${CMAKE_CURRENT_BINARY_DIR}/modify_gml2gv_gmlparse.cmake"
    @ONLY
)
configure_file(
    "${TOP_SOURCE_DIR}/cmake/modify_gml2gv_gmlscan.cmake.in"
    "${CMAKE_CURRENT_BINARY_DIR}/modify_gml2gv_gmlscan.cmake"
    @ONLY
)
add_custom_command(
    OUTPUT ${BISON_Gmlparse_OUTPUTS}
    COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/modify_gml2gv_gmlparse.cmake
    APPEND
)
add_custom_command(
    OUTPUT ${FLEX_Gmlscan_OUTPUTS}
    COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/modify_gml2gv_gmlscan.cmake
    APPEND
)

add_executable(gml2gv
    # Source files
    gml2gv.c

    # Generated files
    ${BISON_Gmlparse_OUTPUTS}
    ${FLEX_Gmlscan_OUTPUTS}
)

target_link_libraries(gml2gv
    cgraph
    ingraphs
)

tool_defaults(gml2gv)

# ================================= graphml2gv =================================
if(EXPAT_FOUND)

add_executable(graphml2gv
    # Source files
    graphml2gv.c
)

target_link_libraries(graphml2gv
    cdt
    cgraph
    ingraphs
    ${EXPAT_LIBRARIES}
)

tool_defaults(graphml2gv)

endif(EXPAT_FOUND)

# ================================== gvcolor ===================================
add_executable(gvcolor
    # Header files
    colortbl.h

    # Source files
    colxlate.c
    gvcolor.c
)

target_link_libraries(gvcolor
    cgraph
    ingraphs
)

tool_defaults(gvcolor)

# ==================================== gvgen ===================================
add_executable(gvgen
    # Source files
    graph_generator.c
    gvgen.c
)

target_link_libraries(gvgen cgraph)

# Link to math library
if (UNIX)
    target_link_libraries(gvgen m)
endif (UNIX)

tool_defaults(gvgen)

# =================================== gvpack ===================================
# TODO add gvpack_static

add_definitions(-DDEMAND_LOADING=0)

add_executable(gvpack
    # Source files
    gvpack.c
)

target_link_libraries(gvpack
    cdt
    cgraph
    gvc
    gvplugin_neato_layout
    ingraphs
)

# Link to math library
if (UNIX)
    target_link_libraries(gvpack m)
endif (UNIX)

tool_defaults(gvpack)

# =================================== gxl2gv ===================================
if(EXPAT_FOUND)

add_executable(gxl2gv
    # Source files
    cvtgxl.c
    gv2gxl.c
    gxl2gv.c
)

target_link_libraries(gxl2gv
    cdt
    cgraph
    ingraphs
    ${EXPAT_LIBRARIES}
)

tool_defaults(gxl2gv)

endif(EXPAT_FOUND)

# ==================================== mm2gv ===================================
add_executable(mm2gv
    # Source files
    matrix_market.c
    mm2gv.c
    mmio.c
)

target_link_libraries(mm2gv
    cgraph
    common
    gvc
    pathplan
    sparse
)

# Link to math library
if (UNIX)
    target_link_libraries(mm2gv m)
endif (UNIX)

tool_defaults(mm2gv)

# =================================== sccmap ===================================
if(EXPAT_FOUND)

add_executable(sccmap
    # Source files
    sccmap.c
)

target_link_libraries(sccmap
    cgraph
    ingraphs
    ${EXPAT_LIBRARIES}
)

tool_defaults(sccmap)

endif(EXPAT_FOUND)

# ===================== Install third party DLLs on Windows ====================

if (WIN32 AND EXPAT_FOUND)
    install(
        FILES ${EXPAT_RUNTIME_LIBRARIES}
        DESTINATION ${BINARY_INSTALL_DIR}
    )
endif(WIN32 AND EXPAT_FOUND)
