#!
#! @ingroup group_sdk_cmake_camitk
#!
#! camitk_install_all_headers is a macro that install all header files of a project at build and install time
#!
#! Duplicate headers installation:
#! - one is used at compiled time and puts everything in
#!   ${CMAKE_BINARY_DIR}/include/${CAMITK_SHORT_VERSION_STRING}/${GroupName}/${ComponentName}/...
#! - the other one is used at installation time and puts everything in
#!   ${CMAKE_INSTALL_PREFIX}/include/${CAMITK_SHORT_VERSION_STRING}/${GroupName}/${ComponentName}/...
#!
#! This macro keeps header files directories tree structure at installation. In other words, if your extension
#! has its header files located in subdirectories, this tree structure will be kept the same at installation.
#!
#! Note that only file matching regex "*.h" in the source dir and subdir are considered headers.
#! If you need to add other files, you need to use the HEADERS_TO_INSTALL option.
#!
#! Usage:
#! \code
#! camitk_install_all_headers(  COMPONENT ComponentName
#!                              [GROUP GroupName]
#!                           )
#! \endcode
#!
#! \param COMPONENT (required)       Name of the component to use. This is also the include subdirectory name
#!                                   used for copying the file
#! \param GROUP (optional)           Name of the group this install should be using group will be
#!                                   prepend to the component name. This is either actions, components, viewers or libraries.
#!
#! Example invocation:
#!
#! \code
#!
#! #--------------
#! # installation
#! #--------------
#! camitk_install_headers( COMPONENT ${MYPROJECT_NAME}
#!                         GROUP libraries
#! )
#! \endcode
#!
#! Here, in this example, we will install all the header files, in the ${CAMITK_INCLUDE_DIR}/include/libraries/${MYPROJECT_NAME} directories (at build and installation times)
#! If my header files are located in some subdirectories, this structure will be kept the same at build and installation times.
#!
macro(camitk_install_all_headers)

    set(options "")
    set(oneValueArgs COMPONENT GROUP)
    set(multiValueArgs "")
    cmake_parse_arguments(CAMITK_INSTALL_ALL_HEADERS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )

    #
    # 1. Create the build-time directory tree
    #

    # The base include directories
    set(CAMITK_INSTALL_ALL_HEADERS_BUILD_BASE_DIR ${CMAKE_BINARY_DIR}/include/${CAMITK_SHORT_VERSION_STRING})

    # Get action, component or library name without its prefix
    set(CAMITK_INSTALL_ALL_HEADERS_TARGET_NAME ${CAMITK_INSTALL_ALL_HEADERS_COMPONENT})
    string(REGEX REPLACE "^component-|^component_|^action-|^action_|^viewer-|^viewer_|^library_|^library-" "" CAMITK_INSTALL_ALL_HEADERS_COMPONENT "${CAMITK_INSTALL_ALL_HEADERS_COMPONENT}")

    # Check group directory
    if(CAMITK_INSTALL_ALL_HEADERS_GROUP)
        # Create group directory if not already existing
        if (NOT EXISTS "${CAMITK_INSTALL_ALL_HEADERS_BUILD_BASE_DIR}/${CAMITK_INSTALL_ALL_HEADERS_GROUP}" AND NOT CAMITK_INSTALL_ALL_HEADERS_DIRECTORY)
            add_custom_command( TARGET ${CAMITK_INSTALL_ALL_HEADERS_TARGET_NAME}
                                POST_BUILD
                                COMMAND ${CMAKE_COMMAND} -E make_directory ${CAMITK_INSTALL_ALL_HEADERS_BUILD_BASE_DIR}/${CAMITK_INSTALL_ALL_HEADERS_GROUP}
                                COMMENT "Creating build-time group include dir ${CAMITK_INSTALL_ALL_HEADERS_BUILD_BASE_DIR}/${CAMITK_INSTALL_ALL_HEADERS_GROUP}"
                                VERBATIM
                              )
        endif()
        # Update base dirs
        set(CAMITK_INSTALL_ALL_HEADERS_BUILD_BASE_DIR ${CAMITK_INSTALL_ALL_HEADERS_BUILD_BASE_DIR}/${CAMITK_INSTALL_ALL_HEADERS_GROUP})
    endif()

    # Create component directory if not already existing
    if (NOT EXISTS "${CAMITK_INSTALL_ALL_HEADERS_BUILD_BASE_DIR}/${CAMITK_INSTALL_ALL_HEADERS_COMPONENT}" AND NOT CAMITK_INSTALL_ALL_HEADERS_DIRECTORY)
        add_custom_command( TARGET ${CAMITK_INSTALL_ALL_HEADERS_TARGET_NAME}
                            POST_BUILD
                            COMMAND ${CMAKE_COMMAND} -E make_directory ${CAMITK_INSTALL_ALL_HEADERS_BUILD_BASE_DIR}/${CAMITK_INSTALL_ALL_HEADERS_COMPONENT}
                            COMMENT "Creating build-time include dir ${CAMITK_INSTALL_ALL_HEADERS_BUILD_BASE_DIR}/${CAMITK_INSTALL_ALL_HEADERS_COMPONENT}"
                            VERBATIM
                          )
    endif()
    # Update base dirs
    set(CAMITK_INSTALL_ALL_HEADERS_BUILD_BASE_DIR ${CAMITK_INSTALL_ALL_HEADERS_BUILD_BASE_DIR}/${CAMITK_INSTALL_ALL_HEADERS_COMPONENT})

    #
    # 2. Install the file (build-time and install-time)
    #

    # get the list of headers
    file(GLOB_RECURSE HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/ *.h)

    # Build time installation
    foreach(HEADER ${HEADERS})
        # Get the subdirectory name of the header
        string(REGEX MATCH ".*/" SUBDIR ${HEADER})

        # Create subdirectory if not already existing
        if(NOT EXISTS "${CAMITK_INSTALL_ALL_HEADERS_BUILD_BASE_DIR}/${SUBDIR}" AND NOT CAMITK_INSTALL_ALL_HEADERS_${SUBDIR})
            # Create directory at build time
            add_custom_command( TARGET ${CAMITK_INSTALL_ALL_HEADERS_TARGET_NAME}
                                POST_BUILD
                                COMMAND ${CMAKE_COMMAND} -E make_directory ${CAMITK_INSTALL_ALL_HEADERS_BUILD_BASE_DIR}/${SUBDIR}
                                COMMENT "Creating build-time include dir ${CAMITK_INSTALL_ALL_HEADERS_COMPONENT}/${SUBDIR}"
                                VERBATIM
                            )
            set(CAMITK_INSTALL_ALL_HEADERS_${SUBDIR} "CREATED") # To avoid creating the directory another time
        endif()

        # Install header at build time
        add_custom_command( TARGET ${CAMITK_INSTALL_ALL_HEADERS_TARGET_NAME}
                            POST_BUILD
                            COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/${HEADER} ${CAMITK_INSTALL_ALL_HEADERS_BUILD_BASE_DIR}/${SUBDIR}
                            COMMENT "Installing build-time header ${CAMITK_INSTALL_ALL_HEADERS_COMPONENT}/${HEADER}"
                            VERBATIM
                          )
    endforeach()

    # Install time, copy all the .h directories structure
    foreach(HEADER ${HEADERS})
        # Get the subdirectory name of the header
        string(REGEX MATCH ".*/" SUBDIR ${HEADER})

        install(FILES ${HEADER}
                DESTINATION include/${CAMITK_SHORT_VERSION_STRING}/${CAMITK_INSTALL_ALL_HEADERS_GROUP}/${CAMITK_INSTALL_ALL_HEADERS_COMPONENT}/${SUBDIR}
                COMPONENT ${CAMITK_INSTALL_ALL_HEADERS_COMPONENT}
        )
    endforeach()
endmacro()
