#!
#! @ingroup group_sdk_cmake_camitk
#!
#! macro camitk_extension_project creates an optional (disabled by default) CEP (CamiTK Extension Project)
#! subdirectory the build.
#!
#! Usage:
#! \code
#! camitk_extension_project(CONTACT
#!                          [ENABLED]
#!                          [NAME cepName]
#!                          [DESCRIPTION longDescription]
#!                          [DEFAULT_APPLICATION exeName]
#!                          [NEEDS_CEP cep1 cep2...]
#!                          [LICENSE licenseName]
#!                          [ENABLE_TESTING]
#!                          [ENABLE_TEST_COVERAGE]
#! )
#! \endcode
#! 
#! \param CONTACT               Mandatory, this is the person(s) to contact to get more information about the CEP
#! \param ENABLED               If used, this CEP is forced by default (otherwise the user as to tick the option
#!                              in CMake GUI or defined a -DCEP_<cepName>:BOOL=TRUE on the command line
#! \param NAME                  By default the name of a CEP is given automatically by the name of the top level source directory
#!                              If you specify a name here, the directory name will be ignored
#! \param DESCRIPTION           A (not so) small description of this CEP (objective, content, implementation information)
#! \param DEFAULT_APPLICATION   The default application to run (for MSVC launchers), default is camitk-imp
#! \param LICENSE               The name of the license for this CEP, default is LGPL-v3
#! \param ENABLE_TESTING        Enable the testing framework ("make test" will run all the test)
#! \param ENABLE_TEST_COVERAGE  Enable the test coverage report ("make camitk-ce-test-coverage" will run all the test and generate
#!                              a report in the camitk-ce-test-coverage subdirectory. Only works with the g++ compiler.
#! \param NEEDS_CEP (TODO)      Dependencies to other CEP
#!
macro(camitk_extension_project)

    get_directory_name(${CMAKE_CURRENT_SOURCE_DIR} CEP_DIR_NAME)
    
    set(options ENABLED ENABLE_TESTING ENABLE_TEST_COVERAGE)
    set(oneValueArgs DEFAULT_APPLICATION DESCRIPTION CONTACT NAME LICENSE)
    set(multiValueArgs NEEDS_CEP)
    cmake_parse_arguments(${CEP_DIR_NAME}_CMAKE "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )

    # get the proper name
    if(NOT DEFINED ${CEP_DIR_NAME}_CMAKE_NAME)
        set(CEP_NAME ${CEP_DIR_NAME})
    else()
        set(CEP_NAME ${${CEP_DIR_NAME}_CMAKE_NAME})
    endif()
    string(TOUPPER ${CEP_NAME} CEP_NAME_CMAKE)
    
    # if it is the first cmake run, create the internal variable with a correct initial value (false is default)
    if(NOT CEP_${CEP_NAME_CMAKE}_INTERNAL)
        # add option to enable/disable this CEP
        if(${CEP_DIR_NAME}_CMAKE_ENABLED)
            set(CEP_${CEP_NAME_CMAKE}_ENABLED TRUE)
        else()
            set(CEP_${CEP_NAME_CMAKE}_ENABLED FALSE)
        endif()
        set(CEP_${CEP_NAME_CMAKE} ${CEP_${CEP_NAME_CMAKE}_ENABLED} CACHE BOOL "Build CEP ${CEP_NAME}")
        set(CEP_${CEP_NAME_CMAKE}_INTERNAL TRUE CACHE INTERNAL "Is variable CAMITK_CEP_${CEP_NAME_CMAKE} already created?")
    endif()
    
    if(CEP_${CEP_NAME_CMAKE})        
        message(STATUS "Building CEP ${CEP_NAME}")
        
        if (${CEP_DIR_NAME}_CMAKE_ENABLE_TESTING OR ${CEP_DIR_NAME}_CMAKE_ENABLE_TEST_COVERAGE)
            include(CTest)
            enable_testing()
            message(STATUS "Testing framework enabled")
        endif()
        
        if (${CEP_DIR_NAME}_CMAKE_ENABLE_TEST_COVERAGE)
            set(${CEP_DIR_NAME}_CMAKE_ENABLE_TESTING ON)
            # to create specific target: camitk-ce-test-coverage
            option(CAMITK_TEST_COVERAGE "Code coverage" ON)
            include(macros/camitk/test/CamiTKTestCoverage)
        endif()
        
        project(${CEP_NAME})

        if(NOT DEFINED ${CEP_DIR_NAME}_CMAKE_CONTACT)
            message(FATAL_ERROR "In camitk_extension_project(...) for CEP \"${CEP_NAME}\": CONTACT argument is mandatory\n   Should give the email address of the person(s) to contact for more information about the CEP \"${CEP_NAME}\"")
        endif()

        if(NOT DEFINED ${CEP_DIR_NAME}_CMAKE_LICENSE)
            set(${CEP_NAME}_LICENSE "LGPL-v3")
        else()
            set(${CEP_NAME}_LICENSE ${${CEP_DIR_NAME}_CMAKE_LICENSE})
        endif()
        
        # update module path
        set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR})

        # init cep sub project
        camitk_init_manifest_data()
        
        # packaging macro must be called before parsing extensions CMakeList files.
        camitk_cep_packaging(NAME ${CEP_NAME}
                             CONTACT ${${CEP_DIR_NAME}_CMAKE_CONTACT}
                             DESCRIPTION ${${CEP_DIR_NAME}_CMAKE_DESCRIPTION}
                             LICENSE ${${CEP_NAME}_LICENSE}
        )

        # add all subprojects
        camitk_add_subdirectory(libraries)
        camitk_add_subdirectory(components)
        camitk_add_subdirectory(actions)
        camitk_add_subdirectory(viewers)
        camitk_add_subdirectory(applications)

        # CEP packaging (only works if this is a stand-alone CEP
        camitk_write_manifest_data()

        # For Microsoft Visual C++, sets the default application for the "ALL_BUILD" project
        # (i.e. launches imp when we you click on "Debug" or "Start Without Debugging" button on Visual)
        # In addition, but not the least, sets the environment to the debug dll directory for VTK (and ITK)
        # to solve the dll incompatibility between debug and relase version of QVTK.dll and ITKCommon.dll
        # is there a specifi application to run by default
        if(${CEP_NAME_CMAKE}_CMAKE_DEFAULT_APPLICATION)
            set(CEP_DEFAULT_APPLICATION ${${CEP_NAME_CMAKE}_CMAKE_DEFAULT_APPLICATION})
        else()
            set(CEP_DEFAULT_APPLICATION "camitk-imp")
        endif()
        
        # simply target name so that the custom target name does not contains any space
        string(REGEX REPLACE " " "" ESCAPED_PROJECT_NAME "${CEP_NAME}")        
        string(TOLOWER "${ESCAPED_PROJECT_NAME}" SIMPLIFIED_CEP_NAME)
        
        # if this is a single CEP, provides the installation facilities
        # otherwise, just add include(CamiTKInstall) to get the installation facilities
        if (NOT CAMITK_EXTENSION_PROJECT_SET)
            #-- camitk-global-install == install in CAMITK_DIR
            if (CAMITK_COMMUNITY_EDITION_BUILD)
                # if the SDK is currently being build => install in CMAKE_INSTALL_PREFIX
                add_custom_target(camitk-${SIMPLIFIED_CEP_NAME}-global-install
                    # Second cmake to install
                    COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target install --config ${CMAKE_CFG_INTDIR}
                    COMMENT "Global Installation in ${CMAKE_INSTALL_PREFIX}"
                )

            else()
                # this is called from a normal CEP build => install in CAMITK_DIR
                add_custom_target(camitk-${SIMPLIFIED_CEP_NAME}-global-install
                    # First cmake to redefine install prefix
                    COMMAND ${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX:PATH=${CAMITK_DIR} ${CMAKE_BINARY_DIR}
                    # Second cmake to install
                    COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target install --config ${CMAKE_CFG_INTDIR}
                    COMMENT "Global Installation in ${CAMITK_DIR}"
                )
            endif()

            # camitk-local-install == install in User Config directory
            add_custom_target(camitk-${SIMPLIFIED_CEP_NAME}-local-install
                # First cmake to redefine install prefix
                COMMAND ${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX:PATH=${CAMITK_USER_DIR} ${CMAKE_BINARY_DIR}
                COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target install --config ${CMAKE_CFG_INTDIR}
                COMMENT "Local Installation in ${CAMITK_USER_DIR}"
            )

            # Add an update-translate target to configure all the .qrc files for the different extensions of this CEP on demand.
            # .qrc files consider up to date .ts resources files for translation
            add_custom_target(camitk-${SIMPLIFIED_CEP_NAME}-update-translate
                COMMAND ${CMAKE_COMMAND} -E echo "Updating translation for ${CEP_NAME}"
                COMMAND ${CMAKE_COMMAND} -DCAMITK_TRANSLATE=TRUE ${CMAKE_BINARY_DIR}
                COMMAND ${CMAKE_COMMAND} -DCAMITK_TRANSLATE=FALSE ${CMAKE_BINARY_DIR}
                COMMAND ${CMAKE_COMMAND} -E echo "Translation updated for ${CEP_NAME}"
                COMMENT "Translation updated for ${CEP_NAME}"
            )

            # Add a package source target using unified names
            add_custom_target(camitk-${SIMPLIFIED_CEP_NAME}-package-source
                COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target package_source --config ${CMAKE_CFG_INTDIR}
                COMMENT "Building package source ${CEP_NAME}"
            )
            
        endif()

    endif()
endmacro()
