# This is a CMake version file for the Config-mode of find_package().
#
# The version constraint is compatible with the current package under the
# following conditions:
# - If a version range is specified, the package version falls within the
#   range up to the supplied version components.
# - If a single version is specified, the current package version matches
#   only the requested version components.
#
# Examples:
# - 3...5 matches 3.0.0.0 to <6.0.0.0
# - 3...<5 matches 3.0.0.0 to <5.0.0.0
# - 3...<5.1 matches 3.0.0.0 to <5.1.0.0
# - 3 matches 3.0.0.0 to <4.0.0.0
# - 3.4 matches 3.4.0.0 to <4.0.0.0 due to semantic versioning
# - 3.4 EXACT matches 3.4.0.0 to <3.5.0.0

set(PACKAGE_VERSION "@CVF_VERSION@")

# Extract version components.
if ("${PACKAGE_VERSION}" MATCHES "^([0-9]+)(\\.([0-9]+))?(\\.([0-9]+))?(\\.([0-9]+))?$")
  set(_PACKAGE_VERSION_MAJOR "${CMAKE_MATCH_1}")
  if (DEFINED CMAKE_MATCH_3)
    set(_PACKAGE_VERSION_MINOR "${CMAKE_MATCH_3}")
  else()
    set(_PACKAGE_VERSION_MINOR "0")
  endif()
  if (DEFINED CMAKE_MATCH_5)
    set(_PACKAGE_VERSION_PATCH "${CMAKE_MATCH_5}")
  else()
    set(_PACKAGE_VERSION_PATCH "0")
  endif()
  if (DEFINED CMAKE_MATCH_7)
    set(_PACKAGE_VERSION_TWEAK "${CMAKE_MATCH_7}")
  else()
    set(_PACKAGE_VERSION_TWEAK "0")
  endif()
  set(_PACKAGE_VERSION_FULL "${_PACKAGE_VERSION_MAJOR}.${_PACKAGE_VERSION_MINOR}.${_PACKAGE_VERSION_PATCH}.${_PACKAGE_VERSION_TWEAK}")
endif()

if (PACKAGE_FIND_VERSION_RANGE)
  # Create exclusive bound for the range maximum.
  if (PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE")
    set(_PACKAGE_FIND_VERSION_UPPER "${PACKAGE_FIND_VERSION_MAX_MAJOR}.${PACKAGE_FIND_VERSION_MAX_MINOR}.${PACKAGE_FIND_VERSION_MAX_PATCH}.${PACKAGE_FIND_VERSION_MAX_TWEAK}")
  else()
    # Increment the last supplied version number.
    if (PACKAGE_FIND_VERSION_MAX_COUNT EQUAL 1)
      math(EXPR _PACKAGE_FIND_VERSION_MAX_MAJOR "${PACKAGE_FIND_VERSION_MAX_MAJOR}+1")
      set(_PACKAGE_FIND_VERSION_UPPER "${_PACKAGE_FIND_VERSION_MAX_MAJOR}.0.0.0")
    elseif (PACKAGE_FIND_VERSION_MAX_COUNT EQUAL 2)
      math(EXPR _PACKAGE_FIND_VERSION_MAX_MINOR "${PACKAGE_FIND_VERSION_MAX_MINOR}+1")
      set(_PACKAGE_FIND_VERSION_UPPER "${PACKAGE_FIND_VERSION_MAX_MAJOR}.${_PACKAGE_FIND_VERSION_MAX_MINOR}.0.0")
    elseif (PACKAGE_FIND_VERSION_MAX_COUNT EQUAL 3)
      math(EXPR _PACKAGE_FIND_VERSION_MAX_PATCH "${PACKAGE_FIND_VERSION_MAX_PATCH}+1")
      set(_PACKAGE_FIND_VERSION_UPPER "${PACKAGE_FIND_VERSION_MAX_MAJOR}.${PACKAGE_FIND_VERSION_MAX_MINOR}.${_PACKAGE_FIND_VERSION_MAX_PATCH}.0")
    elseif (PACKAGE_FIND_VERSION_MAX_COUNT EQUAL 4)
      math(EXPR _PACKAGE_FIND_VERSION_MAX_TWEAK "${PACKAGE_FIND_VERSION_MAX_TWEAK}+1")
      set(_PACKAGE_FIND_VERSION_UPPER "${PACKAGE_FIND_VERSION_MAX_MAJOR}.${PACKAGE_FIND_VERSION_MAX_MINOR}.${PACKAGE_FIND_VERSION_MAX_PATCH}.${_PACKAGE_FIND_VERSION_MAX_TWEAK}")
    endif()
  endif()

  if ((_PACKAGE_VERSION_FULL VERSION_LESS PACKAGE_FIND_VERSION_MIN)
        OR (_PACKAGE_VERSION_FULL VERSION_GREATER_EQUAL _PACKAGE_FIND_VERSION_UPPER))
    set(PACKAGE_VERSION_COMPATIBLE FALSE)
  else()
    set(PACKAGE_VERSION_COMPATIBLE TRUE)
  endif()
else()

  # Semantic versioning upper bound.
  math(EXPR _PACKAGE_FIND_VERSION_MAJOR "${PACKAGE_FIND_VERSION_MAJOR}+1")
  set(_PACKAGE_FIND_VERSION_SEMVER_UPPER "${_PACKAGE_FIND_VERSION_MAJOR}.0.0.0")

  # Create exclusive upper bound for exact match.
  if (PACKAGE_FIND_VERSION_COUNT EQUAL 1)
    set(_PACKAGE_FIND_VERSION_EXACT_UPPER "${_PACKAGE_FIND_VERSION_SEMVER_UPPER}")
  elseif (PACKAGE_FIND_VERSION_COUNT EQUAL 2)
    math(EXPR _PACKAGE_FIND_VERSION_MINOR "${PACKAGE_FIND_VERSION_MINOR}+1")
    set(_PACKAGE_FIND_VERSION_EXACT_UPPER "${PACKAGE_FIND_VERSION_MAJOR}.${_PACKAGE_FIND_VERSION_MINOR}.0.0")
  elseif (PACKAGE_FIND_VERSION_COUNT EQUAL 3)
    math(EXPR _PACKAGE_FIND_VERSION_PATCH "${PACKAGE_FIND_VERSION_PATCH}+1")
    set(_PACKAGE_FIND_VERSION_EXACT_UPPER "${PACKAGE_FIND_VERSION_MAJOR}.${PACKAGE_FIND_VERSION_MINOR}.${_PACKAGE_FIND_VERSION_PATCH}.0")
  elseif (PACKAGE_FIND_VERSION_COUNT EQUAL 4)
    math(EXPR _PACKAGE_FIND_VERSION_TWEAK "${PACKAGE_FIND_VERSION_TWEAK}+1")
    set(_PACKAGE_FIND_VERSION_EXACT_UPPER "${PACKAGE_FIND_VERSION_MAJOR}.${PACKAGE_FIND_VERSION_MINOR}.${PACKAGE_FIND_VERSION_PATCH}.${_PACKAGE_FIND_VERSION_TWEAK}")
  endif()

  if((_PACKAGE_VERSION_FULL VERSION_LESS PACKAGE_FIND_VERSION) OR (_PACKAGE_VERSION_FULL VERSION_GREATER_EQUAL _PACKAGE_FIND_VERSION_SEMVER_UPPER))
    set(PACKAGE_VERSION_COMPATIBLE FALSE)
  else()
    set(PACKAGE_VERSION_COMPATIBLE TRUE)
    if(_PACKAGE_VERSION_FULL VERSION_LESS _PACKAGE_FIND_VERSION_EXACT_UPPER)
      set(PACKAGE_VERSION_EXACT TRUE)
    endif()
  endif()
endif()
