#
# cmake package for autotools support
#
# @Author Ralf Habacker
# 

#
# load autotools configure file into an internal list named _configure_ac
#
macro(autoinit config)
    set(_configure_ac_name ${config})
    file(READ ${config} _configure_ac_raw)
    # Convert file contents into a CMake list (where each element in the list
    # is one line of the file)
    STRING(REGEX REPLACE ";" "\\\\;" _configure_ac "${_configure_ac_raw}")
    STRING(REGEX REPLACE "\n" ";" _configure_ac "${_configure_ac}")
endmacro()

# extracts version information from autoconf config file
# and set related cmake variables
# 
# returns  
#   ${prefix}_VERSION
#   ${prefix}_VERSION_STRING
#   ${prefix}_MAJOR_VERSION
#   ${prefix}_MINOR_VERSION
#   ${prefix}_MICRO_VERSION
#   ${prefix}_LIBRARY_AGE
#   ${prefix}_LIBRARY_REVISION
#   ${prefix}_LIBRARY_CURRENT
# 
macro(autoversion prefix)
    string(TOUPPER ${prefix} prefix_upper)
    string (REGEX REPLACE ".*${prefix}_major_version], .([0-9]+).*" "\\1" ${prefix_upper}_MAJOR_VERSION ${_configure_ac_raw})
    string (REGEX REPLACE ".*${prefix}_minor_version], .([0-9]+).*" "\\1" ${prefix_upper}_MINOR_VERSION ${_configure_ac_raw})
    string (REGEX REPLACE ".*${prefix}_micro_version], .([0-9]+).*" "\\1" ${prefix_upper}_MICRO_VERSION ${_configure_ac_raw})
    set (${prefix_upper}_VERSION ${${prefix_upper}_MAJOR_VERSION}.${${prefix_upper}_MINOR_VERSION}.${${prefix_upper}_MICRO_VERSION})
    set (${prefix_upper}_VERSION_STRING "${${prefix_upper}_VERSION}")
    string (REGEX REPLACE ".*LT_AGE=([0-9]+).*" "\\1" ${prefix_upper}_LIBRARY_AGE ${_configure_ac_raw})
    string (REGEX REPLACE ".*LT_CURRENT=([0-9]+).*" "\\1" ${prefix_upper}_LIBRARY_CURRENT ${_configure_ac_raw})
    string (REGEX REPLACE ".*LT_REVISION=([0-9]+).*" "\\1" ${prefix_upper}_LIBRARY_REVISION ${_configure_ac_raw})
endmacro()

#
# Defines package related variables (PACKAGE_..., PACKAGE and VERSION)
# as done by autotools.
#
# Additional it defines a cmake variable named PACKAGE_CONFIG_H_TEMPLATE
# which could be placed in config.h templates to have those variables
# defined at code level like shown below:
#
# config.h.template
#   ...
#   @AUTOPACKAGE_CONFIG_H_TEMPLATE@
#   ...
#
macro(autopackage name version url support_url)
    # Define to the full name of this package.
    set(PACKAGE_NAME ${name})

    # Define to the version of this package.
    set(PACKAGE_VERSION ${version})

    # Define to the home page for this package.
    set(PACKAGE_URL ${url})

    # Define to the address where bug reports for this package should be sent.
    set(PACKAGE_BUGREPORT ${support_url})

    # Define to the full name and version of this package.
    set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")

    # Define to the one symbol short name of this package.
    set(PACKAGE_TARNAME ${PACKAGE_NAME})

    set(PACKAGE ${name})
    set(VERSION ${DBUS_VERSION_STRING})

    string(CONFIGURE "/* generated by cmake macro autopackage */\n
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT \"@PACKAGE_BUGREPORT@\"

/* Define to the full name of this package. */
#define PACKAGE_NAME \"@PACKAGE_NAME@\"

/* Define to the full name and version of this package. */
#define PACKAGE_STRING \"@PACKAGE_STRING@\"

/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME \"@PACKAGE_TARNAME@\"

/* Define to the home page for this package. */
#define PACKAGE_URL \"@PACKAGE_URL@\"

/* Define to the version of this package. */
#define PACKAGE_VERSION \"@PACKAGE_VERSION@\"

/* defined by autotools package */
#define PACKAGE \"@PACKAGE@\"
#define VERSION \"@VERSION@\"
" AUTOPACKAGE_CONFIG_H_TEMPLATE)
endmacro(autopackage)

#
# define a cmake variable from autotools AC_DEFINE statement
#
macro(autodefine name)
    foreach(line ${_configure_ac})
        if(line MATCHES ".*AC_DEFINE(.*${name}.*).*")
            string (REGEX REPLACE ".*AC_DEFINE(.*).*" "\\1" value ${line})
            string (REGEX REPLACE ".*,(.*),.*" "\\1" value2 ${value})
            string (REPLACE "[" "" value3 ${value2})
            string (REPLACE "]" "" value4 ${value3})
            set(${name} ${value4})
        endif()
    endforeach()
endmacro()

macro(autoheaderchecks config_h_in configure_checks_file config_h_cmake)
    file(READ ${configure_checks_file} configure_checks_file_raw)
    file(READ ${config_h_in} _config_h_in_raw)
    file(READ ${config_h_cmake} _config_h_cmake_raw)
    STRING(REGEX REPLACE ";" "\\\\;" _config_h_in "${_config_h_in_raw}")
    STRING(REGEX REPLACE "\n" ";" _config_h_in "${_config_h_in}")
    foreach(line ${_config_h_in})
        #message(STATUS ${line})
        if(line MATCHES ".*HAVE_.*_H.*")
            string (REGEX REPLACE ".*HAVE_(.*)_H.*" "\\1" key ${line})
            set(full_key "HAVE_${key}_H")
            if(key MATCHES ".*_.*")
                string(REGEX MATCH "^[A-Z0-9]+" dir ${key})
                string(REGEX MATCH "[A-Z0-9]+$" file ${key})
                string(TOLOWER ${dir} dirname)
                string(TOLOWER ${file} filename)
                set(check "check_include_file(${dirname}/${filename}.h     ${full_key})")
                set(config_define "#cmakedefine ${full_key}")
            else()
                set(file ${key})
                string(TOLOWER ${file} filename)
                set(check "check_include_file(${filename}.h     ${full_key})")
                set(config_define "#cmakedefine ${full_key}")
            endif()
            if(NOT configure_checks_file_raw MATCHES ".*${full_key}.*")
                message("${check}")
            endif()
            if(NOT _config_h_cmake_raw MATCHES "${full_key}")
                message("${config_define}")
            endif()
        endif()
    endforeach()
endmacro(autoheaderchecks)

#
# parses config.h template and create cmake equivalent 
# not implemented yet
# 
macro(autoconfig template output)
	file(READ ${template} contents)
	# Convert file contents into a CMake list (where each element in the list
	# is one line of the file)
	STRING(REGEX REPLACE ";" "\\\\;" contents "${contents}")
	STRING(REGEX REPLACE "\n" ";" contents "${contents}")
	foreach(line contents)
		message(STATUS ${line})
		# find #undef lines
		# append to config.h #define <variable-name> <variable-content>
	endforeach()
endmacro()
