set(DEPENDENCY_PREFIX ${CMAKE_BINARY_DIR}/thirdparty CACHE STRING "Location where external dependencies will be installed." FORCE)
set(DEPENDENCY_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/dependencies CACHE STRING "Location where external dependencies will be installed." FORCE)

include(ExternalProject)

if(NOT ALLOW_EXTERNAL_PROJECTS)
    message(STATUS "ALLOW_EXTERNAL_PROJECTS not specified assuming allowing downloading and installing dependent external projects.")
    set(ALLOW_EXTERNAL_PROJECTS True CACHE BOOL "Choose whether to allow downloading and installing dependent external projects." FORCE)
endif()

function(FIND_PACKAGE_EXTERNAL)
    set(options REQUIRED)
    set(oneValueArgs VERSION PACKAGE)
    set(multiValueArgs COMPONENTS)
    cmake_parse_arguments(FIND_PACKAGE_EXTERNAL "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

    set(FIND_PACKAGE_EXTERNAL_COMMAND ${FIND_PACKAGE_EXTERNAL_PACKAGE})
    if(FIND_PACKAGE_EXTERNAL_VERSION)
        set(FIND_PACKAGE_EXTERNAL_COMMAND ${FIND_PACKAGE_EXTERNAL_COMMAND} " ${FIND_PACKAGE_EXTERNAL_VERSION}")
    endif()
    if(FIND_PACKAGE_EXTERNAL_REQUIRED AND NOT ALLOW_EXTERNAL_PROJECTS)
        set(FIND_PACKAGE_EXTERNAL_COMMAND ${FIND_PACKAGE_EXTERNAL_COMMAND} " REQUIRED")
    endif()
    if(FIND_PACKAGE_EXTERNAL_COMPONENTS)
        set(FIND_PACKAGE_EXTERNAL_COMMAND ${FIND_PACKAGE_EXTERNAL_COMMAND} " COMPONENTS ${FIND_PACKAGE_EXTERNAL_COMPONENTS}")
    endif()

    string(TOUPPER ${FIND_PACKAGE_EXTERNAL_PACKAGE} FIND_PACKAGE_EXTERNAL_PACKAGE_UPPERCASE)
    if(NOT FORCE_EXTERNAL_PROJECTS)
        find_package(${FIND_PACKAGE_EXTERNAL_COMMAND})
    endif()
    if(ALLOW_EXTERNAL_PROJECTS AND NOT ${FIND_PACKAGE_EXTERNAL_PACKAGE_UPPERCASE}_FOUND OR FORCE_EXTERNAL_PROJECTS)
        message(STATUS "Going to download and install \"${FIND_PACKAGE_EXTERNAL_PACKAGE}\"")
        include(External_${FIND_PACKAGE_EXTERNAL_PACKAGE})
        set(${FIND_PACKAGE_EXTERNAL_PACKAGE_UPPERCASE}_EXTERNAL True CACHE BOOL "" FORCE)
    endif()
endfunction()

function(ADD_DEPENDENCY_EXTERNAL)
    set(options)
    set(oneValueArgs TARGET PACKAGE)
    set(multiValueArgs)
    cmake_parse_arguments(ADD_DEPENDENCY_EXTERNAL "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

    string(TOUPPER ${ADD_DEPENDENCY_EXTERNAL_PACKAGE} ADD_DEPENDENCY_EXTERNAL_PACKAGE_UPPERCASE)
    if(ALLOW_EXTERNAL_PROJECTS AND ${ADD_DEPENDENCY_EXTERNAL_PACKAGE_UPPERCASE}_EXTERNAL)
        add_dependencies(${ADD_DEPENDENCY_EXTERNAL_TARGET} ${ADD_DEPENDENCY_EXTERNAL_PACKAGE})
    endif()
endfunction()
