include_guard(GLOBAL)

function (ixm_cmake_project_version name)
  if (DEFINED PROJECT_VERSION)
    return()
  endif()
  set(VERSION 0.1.0)
  set(MAJOR 0)
  set(MINOR 1)
  set(PATCH 0)
  set(TWEAK)
  set(${name}_VERSION ${VERSION} PARENT_SCOPE)
  set(PROJECT_VERSION ${VERSION} PARENT_SCOPE)
  foreach (var IN ITEMS MAJOR MINOR PATCH TWEAK)
    set(${name}_VERSION_${var} ${${var}} PARENT_SCOPE)
    set(PROJECT_VERSION_${var} ${${var}} PARENT_SCOPE)
  endforeach()
endfunction()

# TODO: Rename standalone concept to top-level
function (ixm_cmake_project_standalone name)
  set(standalone OFF)
  if (CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
    set(standalone ON)
  endif()
  set_property(GLOBAL PROPERTY ${name}::standalone ${standalone})
  set(PROJECT_STANDALONE ${standalone} PARENT_SCOPE)
  set(${name}_STANDALONE ${standalone} CACHE BOOL "Whether ${name} is the top level CMake project")
endfunction()

function (ixm_cmake_project_build_types)
  list(APPEND build-types ${CMAKE_CONFIGURATION_TYPES})
  list(APPEND build-types "Debug" "Release" "RelWithDebInfo" "MinSizeRel")
  list(REMOVE_DUPLICATES build-types)
  set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS ${build-types})
endfunction()

# TODO: Rename to prologue
function (ixm_cmake_project_prepare)
  if (NOT CMAKE_BUILD_TYPE)
    log(WARN "CMAKE_BUILD_TYPE not set. Using 'Debug'")
    set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Choose the type of build")
  endif()
  set(single VERSION DESCRIPTION HOMEPAGE_URL)
  cmake_parse_arguments("" "" "${single};BLUEPRINT" "LANGUAGES" ${ARGN})
  set_property(GLOBAL PROPERTY ixm::blueprint::name ${_BLUEPRINT})
  foreach (arg IN LISTS single)
    if (DEFINED _${arg})
      list(APPEND args ${arg} "${_${arg}}")
    endif()
  endforeach()
  # The for-loop doesn't NEED to be inside the if(), but it helps with
  # understanding what we're doing here :)
  if (_LANGUAGES)
    list(APPEND args LANGUAGES)
    foreach (language IN LISTS _LANGUAGES)
      string(REGEX MATCH "^([^0-9]*)([0-9]*)$" matched ${language})
      if (DEFINED CMAKE_MATCH_2 AND NOT DEFINED CMAKE_${CMAKE_MATCH_1}_STANDARD)
        set(CMAKE_${CMAKE_MATCH_1}_STANDARD ${CMAKE_MATCH_2} PARENT_SCOPE)
      endif()
      list(APPEND args ${CMAKE_MATCH_1})
    endforeach()
  endif()
  set(cmake-sanitized-args ${args} PARENT_SCOPE)
endfunction()

# TODO: Rename to epilogue
function (ixm_cmake_project_blueprint)
  get_property(name GLOBAL PROPERTY ixm::blueprint::name)
  if (NOT name)
    return()
  endif()
  # Construct all possible path names to search for
  string(TOLOWER "${name}" lower)
  foreach (dir IN LISTS CMAKE_MODULE_PATH IXM_ROOT)
    list(APPEND paths "${dir}/Blueprints/${name}/Init.cmake")
    list(APPEND paths "${dir}/blueprints/${lower}/init.cmake")
    list(APPEND paths "${dir}/Blueprints/${name}.cmake")
    list(APPEND paths "${dir}/blueprints/${lower}.cmake")
  endforeach()
  foreach (path IN LISTS paths)
    if (EXISTS "${path}")
      set_property(GLOBAL PROPERTY ixm::blueprint::file "${path}")
      break()
    endif()
  endforeach()
  get_property(filename GLOBAL PROPERTY ixm::blueprint::file)
  if (NOT filename)
    log(FATAL "Could not discover blueprint '${name}'")
  endif()
  include(${filename})
  set_property(DIRECTORY PROPERTY ixm::blueprint::file ${filename})
  set_property(DIRECTORY PROPERTY ixm::blueprint::name ${name})
endfunction()
