#!
#! @ingroup group_sdk_cmake_camitk
#!
#! Macro camitk_extension simplifies writing a camitk extension (component, action, viewer)
#!
#! The name of the extension is automatically the name of the directory from where this macro
#! is called, unless it is overriden by the TARGET_NAME parameter.
#!
#! \note
#! To be more precise, after the execution of this macro, the variable `type_TARGET_NAME` (i.e.,
#! `ACTION_TARGET_NAME`, `COMPONENT_TARGET_NAME`, or `VIEWER_TARGET_NAME`) holds the name
#! of the CMake target produced by this macro.
#! The target name itself is equal to either `action-name`, `component-name` 
#! or `viewer-name` (depending on the type of the extension), where `name` is 
#! the name of the current folder in lowercase, unless TARGET_NAME
#! is provided
#! On windows, the `-` (dash) is replaced by `_` (underscore)
#!
#!  usage:
#! \code
#!   camitk_extension( <type>
#!                     [DISABLED]
#!                     [CAMITK_FILE file]
#!                     [NEEDS_ITK]
#!                     [NEEDS_LIBXML2]
#!                     [NEEDS_OPENCV]
#!                     [NEEDS_IGSTK]
#!                     [NEEDS_XSD]
#!                     [NEEDS_GDCM]
#!                     [NEEDS_ACTION_EXTENSION action1 action2 ...]
#!                     [NEEDS_VIEWER_EXTENSION viewer1 viewer2 ...]
#!                     [NEEDS_COMPONENT_EXTENSION component1 component2 ...]
#!                     [NEEDS_CEP_LIBRARIES CEPLib1 CEPLib2 ...]
#!                     [INCLUDE_DIRECTORIES dir1 dir2 ...]
#!                     [DEFINES flag1 flag2 ...]
#!                     [CXX_FLAGS flag1 flag2 ...]
#!                     [EXTERNAL_SOURCES file1 file2 ...]
#!                     [EXTERNAL_LIBRARIES lib1 lib2 ...]
#!                     [HEADERS_TO_INSTALL header1.h header2.h ...]
#!                     [INSTALL_ALL_HEADERS]
#!                     [TARGET_NAME non-default-targetname]
#!                     [DESCRIPTION description]
#!                     [EXTRA_TRANSLATE_LANGUAGE]
#!                     [ENABLE_AUTO_TEST]
#!                     [TEST_FILES file1 file2 ...]
#!                     [AUTO_TEST_LEVEL 1]
#!                     [AUTO_TEST_LEVEL 2]
#!                     [ENABLE_INTEGRATION_TEST]
#!     )
#! \endcode
#!
#! \param <type>                    REQUIRED. The selected type of extension you wish to build.
#!                                    possible values : ACTION_EXTENSION, COMPONENT_EXTENSION
#!                                    or VIEWER_EXTENSION.
#! \param DISABLED                  means this is a not a default extension, it will not be compiled automatically
#! \param CAMITK_FILE               the .camitk file to generate action source code that uses user action class
#!                                  (if not present, this extension is a classic extension, and is not auto-generated)
#! \param NEEDS_ITK                 add this if your extension needs ITK.
#!                                    Do not forget to add the needed list of ITK libraries in the LIBRARIES parameter
#! \param NEEDS_LIBXML2             add this if your extension needs libxml2
#! \param NEEDS_XSD                 add this if your extension needs Codesynthesis xsd cxx (xml schema compiler)
#! \param NEEDS_OPENCV              add this if your extension needs OpenCV
#! \param NEEDS_IGSTK               add this if your extension needs IgsTK
#! \param NEEDS_XERCESC             add this if your extension needs XercesC library
#! \param NEEDS_GDCM                Add this if your extension requires GDCM library
#! \param NEEDS_CEP_LIBRARIES       list of needed CEP libraries (not external dependencies)
#! \param NEEDS_COMPONENT_EXTENSION list of needed component extensions
#! \param NEEDS_ACTION_EXTENSION    list of needed action extensions
#! \param NEEDS_VIEWER_EXTENSION    list of needed viewer extensions
#! \param INCLUDE_DIRECTORIES       additional include directories
#! \param DEFINES                   list of define flags to add at compilation time.
#! \param CXX_FLAGS                 list of compiler flags to add (such as warning levels (-Wall ...)).
#! \param EXTERNAL_SOURCES          list of extra source/headers files (external to the current directory)
#!                                    that needed to be added to the SOURCES variable.
#!                                    Note: EXTERNAL_SOURCES are not installed
#! \param EXTERNAL_LIBRARIES        external libraries to add to the link command
#! \param HEADERS_TO_INSTALL        list of headers to install, if present this will automatically
#!                                    create an "install-EXTENSION_NAME" target, that can be used
#!                                    anywhere else to manage dependencies to this extension.
#!                                    The headers are installed ${CAMITK_BUILD_INCLUDE_DIR}/EXTENSION_TYPE/EXTENSION_NAME
#!                                    when the target "install-EXTENSION_NAME" is called.
#! \param INSTALL_ALL_HEADERS       install all of the headers (this is the lazy solution, please consider
#!                                    making a list and using HEADERS_TO_INSTALL parameter instead.
#!                                    Only the files matching the regex *.h will be install. If you need to add
#!                                    other files, you need to use the HEADERS_TO_INSTALL option.
#! \param TARGET_NAME               specify a target name different than the default (default is the extension source code directory name)
#!                                    this can be very useful for example when you have an extension source code directory in
#!                                    your CEP that has the same name as one in the camitk community edition.
#! \param CEP_NAME                  specify the CEP_NAME, which is used to categorized the extension for packaging purpose
#!                                    No CEP_NAME provided will result in default categorization (generic extension).
#! \param DESCRIPTION               Simple description of the extension. Used for packaging presentation for instance.
#! \param EXTRA_TRANSLATE_LANGUAGE  Additionnal extra language to translate the application
#! \param ENABLE_AUTO_TEST          Create automatic test with either testactions or testcomponents.
#!                                    By default, auto test are run at the highlest level (level 3) unless AUTO_TEST_LEVEL is specified
#!                                    See also TEST_FILES and AUTO_TEST_LEVEL options
#! \param TEST_FILES                List of files to use for testing.
#!                                    If provided, only the filenames are required (not the absolute paths), each of them should be
#!                                    found in the testdata build dir.
#!                                    If no test files are provided:
#!                                        - for component extension auto test: all the files in the component
#!                                          testdata subdir are used by default
#!                                        - for action extension auto test: all the files available in the testdata build dir (i.e.,
#!                                          all the component testdata) are used by default (which might be too many!).
#! \param AUTO_TEST_LEVEL i         for automatic test of component extensions: set the highest level of automatic test to perform:
#!                                    - level 1: load the component extension, open and close a testdata component file
#!                                    - level 2: same as level 1, but save the component before closing it.
#!                                    - level 3 (default): same as level 2, but also compare the saved component to the input.
#! \param ENABLE_INTEGRATION_TEST   add a specific integration test (see camitk_add_integration_test) CamiTK CMake macro.
#!                                    Since CamiTK 4.1
#!                                    It does add an integration test using the action-state-machine to process a chain
#!                                    of actions (requires that subdirectory integration-testdata exists, and contains
#!                                    a file called "asm-input.scxml" and at least one file name "output-*.*")
#!                                    Check the wiki for more information about integration test
#!
#!
#!
#!
macro(camitk_extension)


    # Instruct CMake to run moc automatically when needed.
    set(CMAKE_AUTOMOC ON)


    #########################################################################
    #                                                                       #
    #   ARGUMENTS PARSING                                                   #
    #                                                                       #
    #   * Use a macro to create the CMAKE variables according to the        #
    #     provided options as input.                                        #
    #                                                                       #
    #########################################################################

    get_directory_name(${CMAKE_CURRENT_SOURCE_DIR} EXTENSION_NAME)

    set(options ACTION_EXTENSION COMPONENT_EXTENSION VIEWER_EXTENSION DISABLED NEEDS_XERCESC NEEDS_ITK NEEDS_LIBXML2 NEEDS_XSD NEEDS_OPENCV NEEDS_IGSTK INSTALL_ALL_HEADERS NEEDS_GDCM ENABLE_AUTO_TEST ENABLE_INTEGRATION_TEST)
    set(oneValueArgs TARGET_NAME CEP_NAME DESCRIPTION AUTO_TEST_LEVEL CAMITK_FILE)
    set(multiValueArgs NEEDS_TOOL NEEDS_CEP_LIBRARIES NEEDS_COMPONENT_EXTENSION NEEDS_ACTION_EXTENSION NEEDS_VIEWER_EXTENSION INCLUDE_DIRECTORIES EXTERNAL_LIBRARIES HEADERS_TO_INSTALL DEFINES CXX_FLAGS EXTERNAL_SOURCES EXTRA_TRANSLATE_LANGUAGE TEST_FILES)
    cmake_parse_arguments(${EXTENSION_NAME_CMAKE} "${options}" "${oneValueArgs}"
                          "${multiValueArgs}" ${ARGN} )

    #########################################################################
    #                                                                       #
    #   CREATE CMAKE VARIABLES                                              #
    #                                                                       #
    #   * Create required and useful CMake variables for the macro          #
    #                                                                       #
    #########################################################################

    # TYPE EXTENSION : ACTION or COMPONENT or VIEWER
    if (${EXTENSION_NAME_CMAKE}_ACTION_EXTENSION)
        set(TYPE_EXTENSION "action")
        string(TOUPPER ${TYPE_EXTENSION} TYPE_EXTENSION_CMAKE)
    elseif(${EXTENSION_NAME_CMAKE}_COMPONENT_EXTENSION)
        set(TYPE_EXTENSION "component")
        string(TOUPPER ${TYPE_EXTENSION} TYPE_EXTENSION_CMAKE)
    elseif(${EXTENSION_NAME_CMAKE}_VIEWER_EXTENSION)
        set(TYPE_EXTENSION "viewer")
        string(TOUPPER ${TYPE_EXTENSION} TYPE_EXTENSION_CMAKE)
    endif()

    # CMAKE CACHE VARIABLE
    # if it is the first cmake run, create the extension variable with a correct initial value
    if(NOT ${TYPE_EXTENSION_CMAKE}_${EXTENSION_NAME_CMAKE}_INTERNAL)
        # add option to enable/disable this extension and set it to true by default
        # Building the extension can be disabled by giving the argument DISABLED to the macro
        # or by passing the flag -D${TYPE_EXTENSION_CMAKE}_${EXTENSION_NAME_CMAKE}_DISABLED:BOOL=TRUE
        if(${EXTENSION_NAME_CMAKE}_DISABLED)
            set(${TYPE_EXTENSION_CMAKE}_${EXTENSION_NAME_CMAKE}_ENABLED FALSE)
        else()
            set(${TYPE_EXTENSION_CMAKE}_${EXTENSION_NAME_CMAKE}_ENABLED TRUE)
        endif()
        set(${TYPE_EXTENSION_CMAKE}_${EXTENSION_NAME_CMAKE} ${${TYPE_EXTENSION_CMAKE}_${EXTENSION_NAME_CMAKE}_ENABLED} CACHE BOOL "Build extension ${EXTENSION_NAME}")
        set(${TYPE_EXTENSION_CMAKE}_${EXTENSION_NAME_CMAKE}_INTERNAL TRUE CACHE INTERNAL "Is variable ${TYPE_EXTENSION_CMAKE}_${EXTENSION_NAME} already created?")
    endif()

    # if this extension is enabled, do everything needed
    # otherwise... do nothing
    if (${${TYPE_EXTENSION_CMAKE}_${EXTENSION_NAME_CMAKE}})

        # TARGET NAME
        # The target name is composed of the following: [action / component]-name
        # * action / component is the type of extension as prefix
        # * name is deduced from the input folder containing the calling CMakeLists.txt file of the extension.
        if (${EXTENSION_NAME_CMAKE}_TARGET_NAME)
            set(${TYPE_EXTENSION_CMAKE}_OUTPUT_NAME ${${EXTENSION_NAME_CMAKE}_TARGET_NAME})
        else()
            set(${TYPE_EXTENSION_CMAKE}_OUTPUT_NAME ${EXTENSION_NAME})
        endif()
        # replace "-" by "_" if the extension is being packaged with NSIS, the program to create a Windows installer.
        if (PACKAGING_NSIS)
            # NSIS requires that cpack component names do not feature space or "-" characters
            set(${TYPE_EXTENSION_CMAKE}_TARGET_NAME ${TYPE_EXTENSION}_${${TYPE_EXTENSION_CMAKE}_OUTPUT_NAME})
        else()
            set(${TYPE_EXTENSION_CMAKE}_TARGET_NAME ${TYPE_EXTENSION}-${${TYPE_EXTENSION_CMAKE}_OUTPUT_NAME})
        endif()

        message(STATUS "Building extension ${${TYPE_EXTENSION_CMAKE}_TARGET_NAME}")

        # EXTENSION_PLUGIN_FILE
        # determine the extension full file name depending on the plateform
        set(EXTENSION_PLUGIN_FILE "${CAMITK_BUILD_PRIVATE_LIB_DIR}/${TYPE_EXTENSION}s")
        if (MSVC)
            set(EXTENSION_PLUGIN_FILE $<TARGET_FILE:${${TYPE_EXTENSION_CMAKE}_TARGET_NAME}>)
        elseif(APPLE)
            set(EXTENSION_PLUGIN_FILE ${EXTENSION_PLUGIN_FILE}/lib${${TYPE_EXTENSION_CMAKE}_OUTPUT_NAME}.dylib)
        else()
            # Must be Linux
            set(EXTENSION_PLUGIN_FILE ${EXTENSION_PLUGIN_FILE}/lib${${TYPE_EXTENSION_CMAKE}_OUTPUT_NAME}.so)
        endif()

        #########################################################################
        #                                                                       #
        #   EXTENSION GENERATOR                                                 #
        #                                                                       #
        #########################################################################
        if (${EXTENSION_NAME_CMAKE}_CAMITK_FILE)
            camitk_extension_generator(CAMITK_FILE ${${EXTENSION_NAME_CMAKE}_CAMITK_FILE})
        endif()

        #########################################################################
        #                                                                       #
        #   INCLUDE DIRECTORIES                                                 #
        #                                                                       #
        #   * Include basic directories where to look header files              #
        #   * Include also additional user provided directories                 #
        #   * These directories are used for compilation step                   #
        #                                                                       #
        #########################################################################
        # BASIC DIRECTORIES

        include_directories(${CMAKE_CURRENT_SOURCE_DIR})
        include_directories(${CMAKE_CURRENT_BINARY_DIR})
        include_directories(${CAMITK_INCLUDE_DIRECTORIES})

        # USER INPUT DIRECTORIES
        include_directories(${${EXTENSION_NAME_CMAKE}_INCLUDE_DIRECTORIES})



        #########################################################################
        #                                                                       #
        #   GATHER RESOURCES                                                   #
        #                                                                       #
        #   * Get all the headers (.h) and source files (.cpp) of the project   #
        #   * Create the needed Qt files (using moc and uic)                    #
        #   * On Windows, Visual Studio, group .moc and .ui files               #
        #     in subdirectories                                                 #
        #                                                                       #
        #########################################################################

        # get all headers, sources and do what is needed for Qt
        # one need to do this just before the add_library so that all defines, include directories and link directories
        # are set properly (gather_headers_and_sources include the call to Qt moc and uic)
        gather_headers_and_sources(${EXTENSION_NAME_CMAKE})



        #########################################################################
        #                                                                       #
        #   ADDITIONAL KNOWN EXTERNAL LIBRARY DEPENDENCIES                      #
        #                                                                       #
        #   * Look for specific library needed                                  #
        #   * Specific libraries are specified as option with the               #
        #     NEEDS_LIBRARY syntax (see macro syntax for more options)          #
        #   * Backward compatibility : Warn user if using old NEEDS_TOOL syntax #
        #                                                                       #
        #########################################################################

        # Looking for ITK
        set(ITK_LIBRARIES "")
        if(${EXTENSION_NAME_CMAKE}_NEEDS_ITK)
            find_package(ITK REQUIRED)
            if(ITK_FOUND)
                include(${ITK_USE_FILE})
                set(ITK_VERSION ${ITK_VERSION_MAJOR}.${ITK_VERSION_MINOR}.${ITK_VERSION_PATCH}) #ITK_VERSION is not always set
                set(CAMITK_ITK_VERSION ${ITK_VERSION_MAJOR}.${ITK_VERSION_MINOR})
                message(STATUS "${${TYPE_EXTENSION_CMAKE}_TARGET_NAME}: Found ITK version ${ITK_VERSION}")
                set(CAMITK_ITK_LIBRARIES ${ITK_LIBRARIES})
            else()
                message(FATAL_ERROR "ITK not found but required by ${${TYPE_EXTENSION_CMAKE}_TARGET_NAME}")
            endif()
        endif()

        # LIBXML2
        set(LIBXML2_LIBRARY "")
        if(${EXTENSION_NAME_CMAKE}_NEEDS_LIBXML2)
            # LibXml2 is required
            find_package(Xml2)
            if (LIBXML2_FOUND)
                add_definitions(${LIBXML2_DEFINITIONS})
                include_directories(${LIBXML2_INCLUDE_DIR})
                set(LIBXML2_LIBRARY ${LIBXML2_LIBRARIES})
            else()
                # most probably win32 or crosscompiling
                message(STATUS "${EXTENSION_NAME}: libxml2 required")
            endif()
        endif()

        # OPENCV
        set(OpenCV_LIBRARIES "")
        if(${EXTENSION_NAME_CMAKE}_NEEDS_OPENCV)
            # OpenCV is required
            find_package(OpenCV REQUIRED )
        else ( )
            set(OpenCV_LIBRARIES "")
        endif()

        # IGSTK
        set(IGSTK_LIBRARIES "")
        if(${EXTENSION_NAME_CMAKE}_NEEDS_IGSTK)
            find_package(IGSTK REQUIRED)
            include(${IGSTK_USE_FILE})
        else()
            set(IGSTK_LIBRARIES "")
        endif()

        # XERCES-C
        set(XERCESC_LIBRARIES)
        if(${EXTENSION_NAME_CMAKE}_NEEDS_XERCESC)
            # XercesC is required
            if (NOT XERCESC_LIBRARY)
                find_package(XercesC REQUIRED)
            endif()
            if (XERCESC_FOUND)
                include_directories(${XERCESC_INCLUDE_DIR})
                set(XERCESC_LIBRARIES ${XERCESC_LIBRARY})
            else()
                # most probably win32 or crosscompiling
                message(FATAL_ERROR "${EXTENSION_NAME}: xerces-c required. Please provide Xerces-C path.")
            endif()
        endif()

        # XSD
        if(${EXTENSION_NAME_CMAKE}_NEEDS_XSD)
            # XercesC is required
            if (NOT XERCESC_LIBRARY)
                find_package(XercesC REQUIRED)
            endif()
            find_package(XercesC REQUIRED)
            if (XERCESC_FOUND)
                include_directories(${XERCESC_INCLUDE_DIR})
                set(XERCESC_LIBRARIES ${XERCESC_LIBRARY})
                find_package(XSD REQUIRED)
                include_directories(${XSD_INCLUDE_DIR})
            else()
                # most probably win32 or crosscompiling
                message(FATAL_ERROR "${EXTENSION_NAME}: xerces-c required because of XSD cxx, please set XERCESC_INCLUDE_DIR")
            endif()
            # with C++11 MSVC requires explicit XSD_CXX11 flag definition
            add_definitions(-DXSD_CXX11)
        endif()

        # GDCM 2.2.x
        set(GDCM_LIBRARIES)
        if(${EXTENSION_NAME_CMAKE}_NEEDS_GDCM)
            if(NOT GDCM_FOUND)
                # Look for GDCM library only if not found (for instance, ITK has already search for it)
                # Calling find_package(GDCM ..) more than once creates CMake errors.
                find_package(GDCM 2.0 REQUIRED)
            endif()
            if(GDCM_FOUND)
                include(${GDCM_USE_FILE})
                if (${VTK_VERSION} VERSION_GREATER 9)
                    message(STATUS "Detected VTK ${VTK_VERSION_MAJOR}.${VTK_VERSION_MINOR} in GDCM ${GDCM_VERSION_MAJOR}.${GDCM_VERSION_MINOR}: adding extra path for include ${GDCM_INCLUDE_DIRS}/vtk-${VTK_VERSION_MAJOR}.${VTK_VERSION_MINOR}")
                    include_directories(${GDCM_INCLUDE_DIRS}/vtk-${VTK_VERSION_MAJOR}.${VTK_VERSION_MINOR})
                    set(VTK_GDCM_LIB vtkgdcm-${VTK_VERSION_MAJOR}.${VTK_VERSION_MINOR})
                else()
                    set(VTK_GDCM_LIB vtkgdcm)
                endif()

                set(GDCM_LIBRARIES gdcmCommon gdcmDICT gdcmDSED gdcmMEXD gdcmMSFF ${VTK_GDCM_LIB})
                
                if (MSVC)
                    # List all available GDCM library files                    
                    unset(GDCM_LIBRARIES_MSVC)
                    foreach(GDCM_LIB_FILE ${GDCM_LIBRARIES})                        
                        # Add both debug and optimized version
                        list(APPEND GDCM_LIBRARIES_MSVC debug ${GDCM_LIB_FILE}${CAMITK_DEBUG_POSTFIX}.lib
                                                        optimized ${GDCM_LIB_FILE}.lib)
                    endforeach()
                    set(GDCM_LIBRARIES ${GDCM_LIBRARIES_MSVC})
                endif()
            else()
                message(FATAL_ERROR "${EXTENSION_NAME}: GDCM 2.x or above library required. Please install GDCM.")
            endif()
        endif()

        # EXTERNAL LIBRARIES
        set(EXTERNAL_LIBRARIES)
        if(${EXTENSION_NAME_CMAKE}_EXTERNAL_LIBRARIES)
            foreach(EXTERNAL_LIBRARY ${${EXTENSION_NAME_CMAKE}_EXTERNAL_LIBRARIES})
                if (MSVC)
                    list(APPEND EXTERNAL_LIBRARIES debug ${EXTERNAL_LIBRARY}${CAMITK_DEBUG_POSTFIX}.lib
                                                   optimized ${EXTERNAL_LIBRARY}.lib
                    )
                else()
                    list(APPEND EXTERNAL_LIBRARIES ${EXTERNAL_LIBRARY})
                endif()
            endforeach()
        endif()



        #########################################################################
        #                                                                       #
        #   LINK DIRECTORIES                                                    #
        #                                                                       #
        #   * Link directories are used to indicate the compiler where          #
        #     to look for folder containing libraries to link with.             #
        #   * Must be done BEFORE creating the CMake target with add_library    #
        #                                                                       #
        #########################################################################

        # CAMITK BASIC LIB DIRECTORIES
        link_directories(${CAMITK_LINK_DIRECTORIES})



        #########################################################################
        #                                                                       #
        #   TARGET COMPILATION DEFINITION                                       #
        #                                                                       #
        #   * Additional sources files to consider at compilation (.cpp)        #
        #   * CMake project target definition                                   #
        #                                                                       #
        #########################################################################
        # EXTERNAL SOURCES
        set(${EXTENSION_NAME_CMAKE}_SOURCES ${${EXTENSION_NAME_CMAKE}_SOURCES} ${${EXTENSION_NAME_CMAKE}_EXTERNAL_SOURCES})

        # CMAKE TARGET DEFINITION
        add_library(${${TYPE_EXTENSION_CMAKE}_TARGET_NAME} SHARED ${${EXTENSION_NAME_CMAKE}_SOURCES})



        #########################################################################
        #                                                                       #
        #   QT LINKING LIBRARIES                                                #
        #                                                                       #
        #   * Set at linking the Qt libraries                                  #
        #                                                                       #
        #########################################################################
        target_link_libraries(${${TYPE_EXTENSION_CMAKE}_TARGET_NAME} PRIVATE ${CAMITK_QT_LIBRARIES})

        #########################################################################
        #                                                                       #
        #   CAMITK ACTION / COMPONENT / LIBRARIES DEPENDENCIES                  #
        #                                                                       #
        #   * Look for action / component / libraries dependencies              #
        #   * Specific actions / components / libraries are specified as option #
        #     with the NEEDS_ACTION/COMPONENT_EXTENSION/CEP_LIBRARIES syntax    #
        #   * Add dependencies to library-camitkcore and the testing            #
        #     action/component if test are runned on it                         #
        #                                                                       #
        #########################################################################

        # 1st CAMITKCORE LIBRARY DEPENDENCY
        # add_dependencies(..) is only needed to enable parallel build during SDK build
        # but generates an error for external CEP, where this target does not
        # exists.
        # Using target_link_libraries(..) is enough to link the extension to the CamiTK core library
        if(CAMITK_COMMUNITY_EDITION_BUILD)
            add_dependencies(${${TYPE_EXTENSION_CMAKE}_TARGET_NAME} ${CAMITK_CORE_TARGET_LIB_NAME})
            # add the dependency to the core automoc target only if inside a SDK build
            set_property(TARGET ${${TYPE_EXTENSION_CMAKE}_TARGET_NAME} APPEND PROPERTY AUTOGEN_TARGET_DEPENDS ${CAMITK_CORE_TARGET_LIB_NAME})
        endif()


        # 2nd COMPONENTS DEPENDENCIES
        if(${EXTENSION_NAME_CMAKE}_NEEDS_COMPONENT_EXTENSION)
            set(COMPONENTS_DEPENDENCY_LIST "") #use for generating the project.xml file
            foreach(COMPONENT_NEEDED ${${EXTENSION_NAME_CMAKE}_NEEDS_COMPONENT_EXTENSION})
                 # include directories from build, camitk (local or global install).
                include_directories(${CAMITK_BUILD_INCLUDE_DIR}/components/${COMPONENT_NEEDED})
                include_directories(${CAMITK_INCLUDE_DIR}/components/${COMPONENT_NEEDED})
                # file dependency
                if (MSVC)
                    list(APPEND COMPONENT_EXTENSION_LIBRARIES debug ${CAMITK_BUILD_PRIVATE_LIB_DIR}/components/${COMPONENT_NEEDED}${CAMITK_DEBUG_POSTFIX}.lib
                                                              optimized ${COMPONENT_NEEDED}
                    )
                else()
                    list(APPEND COMPONENT_EXTENSION_LIBRARIES ${COMPONENT_NEEDED})
                endif()
                # CMake / CDash dependencies
                if(PACKAGING_NSIS)
                    # if the target is installed in the CAMITK_INCLUDE_DIR, import it before adding the dependencies
                    if(EXISTS ${CAMITK_INCLUDE_DIR}/components/${COMPONENT_NEEDED} AND NOT TARGET component_${COMPONENT_NEEDED})
                        message(STATUS "Importing target component_${COMPONENT_NEEDED}")
                        add_library(component_${COMPONENT_NEEDED} INTERFACE IMPORTED)
                    endif()
                    add_dependencies(${${TYPE_EXTENSION_CMAKE}_TARGET_NAME} component_${COMPONENT_NEEDED})
                else()
                    if(EXISTS ${CAMITK_INCLUDE_DIR}/components/${COMPONENT_NEEDED} AND NOT TARGET component-${COMPONENT_NEEDED})
                        message(STATUS "Importing target component-${COMPONENT_NEEDED}")
                        add_library(component-${COMPONENT_NEEDED} INTERFACE IMPORTED)
                    endif()
                    add_dependencies(${${TYPE_EXTENSION_CMAKE}_TARGET_NAME} component-${COMPONENT_NEEDED})
                    list(APPEND COMPONENTS_DEPENDENCY_LIST component-${COMPONENT_NEEDED})
                endif()
            endforeach()
        endif()

        # 3rd ACTIONS DEPENDENCIES
        if(${EXTENSION_NAME_CMAKE}_NEEDS_ACTION_EXTENSION)
            set(ACTIONS_DEPENDENCY_LIST "") #use for generating the project.xml file
            foreach(ACTION_NEEDED ${${EXTENSION_NAME_CMAKE}_NEEDS_ACTION_EXTENSION})
                # include directories from build, camitk (local or global install).
                include_directories(${CAMITK_BUILD_INCLUDE_DIR}/actions/${ACTION_NEEDED})
                include_directories(${CAMITK_INCLUDE_DIR}/actions/${ACTION_NEEDED})
                # file dependency
                if (MSVC)
                    list(APPEND ACTION_EXTENSION_LIBRARIES debug ${CAMITK_BUILD_PRIVATE_LIB_DIR}/actions/${ACTION_NEEDED}${CAMITK_DEBUG_POSTFIX}.lib
                                                           optimized ${ACTION_NEEDED}
                    )
                else()
                    list(APPEND ACTION_EXTENSION_LIBRARIES ${ACTION_NEEDED})
                endif()
                # CMake / CDash dependencies
                if (PACKAGING_NSIS)
                    # if the target is installed in the CAMITK_INCLUDE_DIR, import it before adding the dependencies
                    if(EXISTS ${CAMITK_INCLUDE_DIR}/actions/${ACTION_NEEDED} AND NOT TARGET action_${ACTION_NEEDED})
                        message(STATUS "Importing target action_${ACTION_NEEDED}")
                        add_library(action_${ACTION_NEEDED} INTERFACE IMPORTED)
                    endif()
                    add_dependencies(${${TYPE_EXTENSION_CMAKE}_TARGET_NAME} action_${ACTION_NEEDED})
                else()
                    # if the target is installed in the CAMITK_INCLUDE_DIR, import it before adding the dependencies
                    if(EXISTS ${CAMITK_INCLUDE_DIR}/actions/${ACTION_NEEDED} AND NOT TARGET action-${ACTION_NEEDED})
                        message(STATUS "Importing target action-${ACTION_NEEDED}")
                        add_library(action-${ACTION_NEEDED} INTERFACE IMPORTED)
                    endif()
                    add_dependencies(${${TYPE_EXTENSION_CMAKE}_TARGET_NAME} action-${ACTION_NEEDED})
                    list(APPEND ACTIONS_DEPENDENCY_LIST action-${ACTION_NEEDED})
                endif()
            endforeach()
        endif()

        # 4th VIEWERS DEPENDENCIES
        if(${EXTENSION_NAME_CMAKE}_NEEDS_VIEWER_EXTENSION)
            set(VIEWERS_DEPENDENCY_LIST "") #use for generating the project.xml file
            foreach(VIEWER_NEEDED ${${EXTENSION_NAME_CMAKE}_NEEDS_VIEWER_EXTENSION})
                # include directories from build, camitk (local or global install).
                include_directories(${CAMITK_BUILD_INCLUDE_DIR}/viewers/${VIEWER_NEEDED})
                include_directories(${CAMITK_INCLUDE_DIR}/viewers/${VIEWER_NEEDED})
                # file dependency
                if (MSVC)
                    list(APPEND VIEWER_EXTENSION_LIBRARIES debug ${CAMITK_BUILD_PRIVATE_LIB_DIR}/viewers/${VIEWER_NEEDED}${CAMITK_DEBUG_POSTFIX}.lib
                                                           optimized ${VIEWER_NEEDED}
                    )
                else()
                    list(APPEND VIEWER_EXTENSION_LIBRARIES ${VIEWER_NEEDED})
                endif()
                # CMake / CDash dependencies
                if (PACKAGING_NSIS)
                    if(EXISTS ${CAMITK_INCLUDE_DIR}/viewers/${VIEWER_NEEDED} AND NOT TARGET viewer_${VIEWER_NEEDED})
                        message(STATUS "Importing target viewer_${VIEWER_NEEDED}")
                        add_library(viewer_${VIEWER_NEEDED} INTERFACE IMPORTED)
                    endif()
                    # now add the dependency
                    add_dependencies(${${TYPE_EXTENSION_CMAKE}_TARGET_NAME} viewer_${VIEWER_NEEDED})
                else()
                    # if the target is installed in the CAMITK_INCLUDE_DIR, import it before adding the dependencies
                    if(EXISTS ${CAMITK_INCLUDE_DIR}/viewers/${VIEWER_NEEDED} AND NOT TARGET viewer-${VIEWER_NEEDED})
                        message(STATUS "Importing target viewer-${VIEWER_NEEDED}")
                        add_library(viewer-${VIEWER_NEEDED} INTERFACE IMPORTED)
                    endif()
                    add_dependencies(${${TYPE_EXTENSION_CMAKE}_TARGET_NAME} viewer-${VIEWER_NEEDED})
                    list(APPEND VIEWERS_DEPENDENCY_LIST viewer-${VIEWER_NEEDED})
                endif()
            endforeach()
        endif()

        # 5th CEP LIBRARIES DEPENDENCIES
        if(${EXTENSION_NAME_CMAKE}_NEEDS_CEP_LIBRARIES)
            set(CEP_LIBRARIES_DEPENDENCY_LIST "") #use for generating the project.xml file
            foreach(CEP_LIBRARY_NEEDED ${${EXTENSION_NAME_CMAKE}_NEEDS_CEP_LIBRARIES})
                 # include directories from build, camitk (local or global install).
                include_directories(${CAMITK_BUILD_INCLUDE_DIR}/libraries/${CEP_LIBRARY_NEEDED})
                include_directories(${CAMITK_INCLUDE_DIR}/libraries/${CEP_LIBRARY_NEEDED})
                # file dependency
                if (MSVC)
                    list(APPEND CEP_LIBRARIES debug ${CEP_LIBRARY_NEEDED}${CAMITK_DEBUG_POSTFIX}.lib
                                              optimized ${CEP_LIBRARY_NEEDED}
                    )
                else()
                    list(APPEND CEP_LIBRARIES ${CEP_LIBRARY_NEEDED})
                endif()
                # CMake / CDash dependencies
                if (PACKAGING_NSIS)
                    if (EXISTS ${CAMITK_INCLUDE_DIR}/libraries/${CEP_LIBRARY_NEEDED} AND NOT TARGET library_${CEP_LIBRARY_NEEDED})
                        message(STATUS "Importing target library_${CEP_LIBRARY_NEEDED}")
                        add_library(library_${CEP_LIBRARY_NEEDED} INTERFACE IMPORTED)
                    endif()
                    # now add the dependency
                    add_dependencies(${${TYPE_EXTENSION_CMAKE}_TARGET_NAME} library_${CEP_LIBRARY_NEEDED})
                    # add the dependency to the component automoc target only if compiling SDK
                    #if(CAMITK_COMMUNITY_EDITION_BUILD)
                        #set_property(TARGET ${${TYPE_EXTENSION_CMAKE}_TARGET_NAME} APPEND PROPERTY AUTOGEN_TARGET_DEPENDS library_${CEP_LIBRARY_NEEDED})
                    #endif()
                else()
                    # if the target is installed in the CAMITK_INCLUDE_DIR, import it before adding the dependencies
                    if (NOT TARGET library-${CEP_LIBRARY_NEEDED})
                        message(STATUS "Importing target library-${CEP_LIBRARY_NEEDED}")
                        add_library(library-${CEP_LIBRARY_NEEDED} INTERFACE IMPORTED)
                    endif()
                    add_dependencies(${${TYPE_EXTENSION_CMAKE}_TARGET_NAME} library-${CEP_LIBRARY_NEEDED})
                    list(APPEND CEP_LIBRARIES_DEPENDENCY_LIST ${CEP_LIBRARY_NEEDED} library-${CEP_LIBRARY_NEEDED})
                    ## add the dependency to the component automoc target only if compiling SDK
                    #if(CAMITK_COMMUNITY_EDITION_BUILD)
                        #set_property(TARGET ${${TYPE_EXTENSION_CMAKE}_TARGET_NAME} APPEND PROPERTY AUTOGEN_TARGET_DEPENDS library-${CEP_LIBRARY_NEEDED})
                    #endif()
                endif()
            endforeach()
        endif()

        #########################################################################
        #                                                                       #
        #   COMPILATION FLAG                                                    #
        #                                                                       #
        #   * Flags are options to give to the compiler                         #
        #   * Add user input flags                                              #
        #   * Add platform specific flags                                       #
        #                                                                       #
        #########################################################################

        # USER INPUT DEFINES COMPILER FLAG
        if(${EXTENSION_NAME_CMAKE}_DEFINES)
          foreach (FLAG ${${EXTENSION_NAME_CMAKE}_DEFINES})
            add_definitions(-D${FLAG})
          endforeach()
        endif()

        # USER INPUT CUSTOM COMPILER FLAG
        if(${EXTENSION_NAME_CMAKE}_CXX_FLAGS)
          foreach (FLAG ${${EXTENSION_NAME_CMAKE}_CXX_FLAGS})
            set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLAG}")
          endforeach()
        endif()

        # PLATFORM SPECIFIC COMPILER FLAG
        # 64bits and other platform with relocation needs -fPIC
        include(TestCXXAcceptsFlag)
        check_cxx_accepts_flag(-fPIC FPIC_FLAG_ACCEPTED)
        # no need to add -fPIC on mingw, otherwise it generates a warning: -fPIC ignored for target (all code is position independent) [enabled by default]
        # msvc is also accepting the flag, but then produce warning D9002 : ignoring unknown option '-fPIC'   cl
        if(FPIC_FLAG_ACCEPTED AND NOT WIN32)
            set_property(TARGET ${${TYPE_EXTENSION_CMAKE}_TARGET_NAME} APPEND PROPERTY COMPILE_FLAGS -fPIC)
        endif()



        #########################################################################
        #                                                                       #
        #   LINKING                                                             #
        #                                                                       #
        #   * Linking is the last stage of compilation                          #
        #   * Indicate what libraries to use for linking the target             #
        #                                                                       #
        #########################################################################
        # LINKING LIBRARIES
        # Any component or action has to be linked with ${CAMITK_CORE_LIBRARIES} and with all its dependencies
        target_link_libraries(${${TYPE_EXTENSION_CMAKE}_TARGET_NAME} PRIVATE ${CAMITK_CORE_LIBRARIES} ${CAMITK_LIBRARIES} ${COMPONENT_EXTENSION_LIBRARIES} ${ACTION_EXTENSION_LIBRARIES} ${VIEWER_EXTENSION_LIBRARIES} ${CEP_LIBRARIES} ${CAMITK_ITK_LIBRARIES} ${LIBXML2_LIBRARY} ${OpenCV_LIBRARIES} ${IGSTK_LIBRARIES} ${XERCESC_LIBRARIES} ${GDCM_LIBRARIES} ${EXTERNAL_LIBRARIES})

        # for VTK9, see https://docs.vtk.org/en/latest/advanced/migration_guides/ModuleMigration.html
        if("${VTK_VERSION}" VERSION_GREATER_EQUAL 9.0)
            vtk_module_autoinit(
                TARGETS ${${TYPE_EXTENSION_CMAKE}_TARGET_NAME}
                MODULES ${CAMITK_VTK_LIBRARIES})
        endif()

        #########################################################################
        #                                                                       #
        #   OUTPUT                                                              #
        #                                                                       #
        #   * Define the output directory (location and name)                   #
        #   * Define the output name of the library                             #
        #   * Add ${CAMITK_DEBUG_POSTFIX} suffix to Debug MSVC built libraries  #
        #   * Additional Linux .so files information                            #
        #                                                                       #
        #########################################################################

        # OUTPUT LIBRARY NAME
        set_target_properties(${${TYPE_EXTENSION_CMAKE}_TARGET_NAME}
                               PROPERTIES OUTPUT_NAME ${${TYPE_EXTENSION_CMAKE}_OUTPUT_NAME}
        )

        # OUTPUT DIRECTORY LOCATION AND NAME
        # Output directory (all extensions are private)
        set_target_properties(${${TYPE_EXTENSION_CMAKE}_TARGET_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CAMITK_BUILD_PRIVATE_LIB_DIR}/${TYPE_EXTENSION}s
                                                                                LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CAMITK_BUILD_PRIVATE_LIB_DIR}/${TYPE_EXTENSION}s
                                                                                LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CAMITK_BUILD_PRIVATE_LIB_DIR}/${TYPE_EXTENSION}s
        )
        # Output directory (for dll plateform, this is still the same, extensions are private)
        set_target_properties(${${TYPE_EXTENSION_CMAKE}_TARGET_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CAMITK_BUILD_PRIVATE_LIB_DIR}/${TYPE_EXTENSION}s
                                                                                RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CAMITK_BUILD_PRIVATE_LIB_DIR}/${TYPE_EXTENSION}s
                                                                                RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CAMITK_BUILD_PRIVATE_LIB_DIR}/${TYPE_EXTENSION}s
        )
        # Output directory (for dll plateform, this is still the same, extensions are private)
        set_target_properties(${${TYPE_EXTENSION_CMAKE}_TARGET_NAME} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${CAMITK_BUILD_PRIVATE_LIB_DIR}/${TYPE_EXTENSION}s
                                                                                ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CAMITK_BUILD_PRIVATE_LIB_DIR}/${TYPE_EXTENSION}s
                                                                                ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CAMITK_BUILD_PRIVATE_LIB_DIR}/${TYPE_EXTENSION}s
        )

        # OUTPUT LIBRARY NAME MSVC in DEBUG mode
        if (MSVC)
            set_target_properties(${${TYPE_EXTENSION_CMAKE}_TARGET_NAME} PROPERTIES DEBUG_POSTFIX ${CAMITK_DEBUG_POSTFIX})
        endif()

        # ADDITIONAL LINUX .so FILE INFORMATION
        set(${TYPE_EXTENSION_CMAKE}_LIBRARY_PROPERTIES ${${TYPE_EXTENSION_CMAKE}_LIBRARY_PROPERTIES}
            VERSION   "${CAMITK_VERSION_MAJOR}.${CAMITK_VERSION_MINOR}.${CAMITK_VERSION_PATCH}"
            SOVERSION "${CAMITK_VERSION_MAJOR}"
        )
        # set the library specific info (SONAME...)
        set_target_properties(${${TYPE_EXTENSION_CMAKE}_TARGET_NAME} PROPERTIES ${${TYPE_EXTENSION_CMAKE}_LIBRARY_PROPERTIES} LINK_INTERFACE_LIBRARIES "")

        # see http://www.cmake.org/pipermail/cmake/2012-April/049889.html
        # target properties (outputname and remove soname)
        #  set_property(TARGET ${${TYPE_EXTENSION_CMAKE}_TARGET_NAME} PROPERTY NO_SONAME 1)
        # in CEP the version patch might not have been set
        if (NOT CAMITK_VERSION_PATCH)
            set(CAMITK_VERSION_PATCH 0)
        endif()



        #########################################################################
        #                                                                       #
        #   INSTALLATION                                                        #
        #                                                                       #
        #   * When installing the project, header files (.h) and test data are  #
        #     copied into a installation folder to determine.                   #
        #   * Indicate in this section, where to install your project and which #
        #     files to copy into that folder (during local/global installation) #
        #                                                                       #
        #########################################################################

        # FOLDER INSTALLATION
        # Indicate where to install the action/component
        install(TARGETS ${${TYPE_EXTENSION_CMAKE}_TARGET_NAME}
                # TODO always use private lib, even for runtime
                RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR}/${CAMITK_SHORT_VERSION_STRING}/${TYPE_EXTENSION}s
                LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/${CAMITK_SHORT_VERSION_STRING}/${TYPE_EXTENSION}s
                ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/${CAMITK_SHORT_VERSION_STRING}/${TYPE_EXTENSION}s
                COMPONENT ${${TYPE_EXTENSION_CMAKE}_TARGET_NAME}
        )

        # HEADERS INSTALLATION
        # Build target to install provided headers to install (with HEADERS_TO_INSTALL option)
        if(${EXTENSION_NAME_CMAKE}_HEADERS_TO_INSTALL)
            export_headers(${${EXTENSION_NAME_CMAKE}_HEADERS_TO_INSTALL} COMPONENT ${${TYPE_EXTENSION_CMAKE}_TARGET_NAME} GROUP ${TYPE_EXTENSION}s)
        endif()

        # Build target to install all header files(with INSTALL_ALL_HEADERS option)
        if(${EXTENSION_NAME_CMAKE}_INSTALL_ALL_HEADERS)
            export_headers(${${EXTENSION_NAME_CMAKE}_HEADERS} COMPONENT ${${TYPE_EXTENSION_CMAKE}_TARGET_NAME} GROUP ${TYPE_EXTENSION}s)
        endif()

        # TESTDATA INSTALLATION
        if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/testdata")
            # Check test data dir directory
            if (NOT EXISTS ${CAMITK_BUILD_TESTDATA_DIR})
                 make_directory( ${CAMITK_BUILD_TESTDATA_DIR} )
            endif()

            # copy the files to test data directory
            execute_process(COMMAND ${CMAKE_COMMAND} -E copy_directory testdata ${CAMITK_BUILD_TESTDATA_DIR}
                            WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
                           )

            # during installation, copy the files to install directory
            set (TESTDATA_DEST_DIR share/${CAMITK_SHORT_VERSION_STRING}/testdata)
            install(DIRECTORY testdata/
                  #DESTINATION share/testdata
                  #DESTINATION share/${CAMITK_SHORT_VERSION_STRING}/testdata
                  DESTINATION ${TESTDATA_DEST_DIR}
                  # COMPONENT ${${TYPE_EXTENSION_CMAKE}_TARGET_NAME}
                  PATTERN ".svn" EXCLUDE
                  PATTERN "*~" EXCLUDE
            )
        endif()

        #########################################################################
        #                                                                       #
        #   CDASH SUBPROJECT DESCRIPTION                                        #
        #                                                                       #
        #   * Update the XML description of the subprojects dependencies        #
        #     for CDash.                                                        #
        #                                                                       #
        #########################################################################
        # CDASH XML SUBPROJECTS DESCRIPTION UPDATE
        camitk_register_subproject(${TYPE_EXTENSION_CMAKE} ${${TYPE_EXTENSION_CMAKE}_TARGET_NAME} DEPENDENCIES library-camitkcore ${COMPONENTS_DEPENDENCY_LIST} ${ACTIONS_DEPENDENCY_LIST} ${VIEWERS_DEPENDENCY_LIST} ${CEP_LIBRARIES_DEPENDENCY_LIST})



        #########################################################################
        #                                                                       #
        #   PACKAGING CATEGORIZATION                                            #
        #                                                                       #
        #   * On Windows, when building a package (win32 installer), the        #
        #     install shield wizard proposes you to select which component      #
        #     to install.                                                       #
        #   * Each component to install has a short description following its   #
        #     name to understand its role.                                      #
        #   * This section deals with the categorization and the description    #
        #     of the component in this installer.                               #
        #                                                                       #
        #########################################################################

        # WINDOWS INSTALLER CATEGORIZATION
        if(${EXTENSION_NAME_CMAKE}_CEP_NAME)
            if (${EXTENSION_NAME_CMAKE}_CEP_NAME MATCHES "SDK")
                # The default SDK extensions are categorized as "required" and are not "unselectable" by the user at installation time
                cpack_add_component(${${TYPE_EXTENSION_CMAKE}_TARGET_NAME}
                                    DISPLAY_NAME ${${TYPE_EXTENSION_CMAKE}_TARGET_NAME}
                                    DESCRIPTION ${${EXTENSION_NAME_CMAKE}_DESCRIPTION}
                                    REQUIRED
                                    GROUP SDK
                                    )

            else()
                # Extension is selectable for installation in the wizard of the installer
                cpack_add_component(${${TYPE_EXTENSION_CMAKE}_TARGET_NAME}
                                    DISPLAY_NAME ${${TYPE_EXTENSION_CMAKE}_TARGET_NAME}
                                    DESCRIPTION ${${EXTENSION_NAME_CMAKE}_DESCRIPTION}
                                    GROUP ${${EXTENSION_NAME_CMAKE}_CEP_NAME}
                                    )
            endif()
        else()
            # Extension if not categorized for packaging presentation
            cpack_add_component(${${TYPE_EXTENSION_CMAKE}_TARGET_NAME}
                                DISPLAY_NAME ${${TYPE_EXTENSION_CMAKE}_TARGET_NAME}
                                DESCRIPTION ${${EXTENSION_NAME_CMAKE}_DESCRIPTION}
                                )
        endif()


        #####################################################################################
        #                                                                                   #
        #   TRANSLATION                                                                     #
        #                                                                                   #
        #   * CAMITK_TRANSLATIONS contains the list of language to translate                #
        #    the QString to.                                                                #
        #                                                                                   #
        #   * Create the translate.pro file which contains 4 sections:                      #
        #        - HEADERS:      list of .h/.hpp files to look for tr("") QString           #
        #        - SOURCES:      list of .cpp files to look for tr("") QString              #
        #        - FORMS:        list of .ui files to look for tr("") QString               #
        #        - TRANSLATIONS: list of .ts files which use CAMITK_TRANSLATIONS            #
        #            to define each .ts file                                                #
        #                                                                                   #
        #    * Execute lupdate program to update the .ts files with new QString             #
        #          found.                                                                   #
        #                                                                                   #
        #   * Execute lrelease program to create .qm files (binary equivalent of            #
        #       .ts files                                                                   #
        #                                                                                   #
        #   * Create translate.qrc which contains the list of .qm files.                    #
        #   * Create the flags.qrc file which contains the list of .png flags               #
        #         images                                                                    #
        #                                                                                   #
        #####################################################################################
        if(CAMITK_TRANSLATE)
            if(${EXTENSION_NAME_CMAKE}_EXTRA_TRANSLATE_LANGUAGE)
                if(EXTENSION_NAME STREQUAL "application")
                    camitk_translate(USE_FLAGS
                                     EXTRA_LANGUAGE ${${EXTENSION_NAME_CMAKE}_EXTRA_TRANSLATE_LANGUAGE})
                else()
                    camitk_translate(EXTRA_LANGUAGE ${${EXTENSION_NAME_CMAKE}_EXTRA_TRANSLATE_LANGUAGE})
                endif()
            else()
                if(EXTENSION_NAME STREQUAL "application")
                    camitk_translate(USE_FLAGS)
                else()
                    camitk_translate()
                endif()
            endif()
        endif()



        #########################################################################
        #                                                                       #
        #   CTEST - COMPONENT TESTS DESCRIPTION                                 #
        #                                                                       #
        #########################################################################

        # if auto test possible and required
        if (NOT PACKAGING_NSIS AND BUILD_TESTING AND ${EXTENSION_NAME_CMAKE}_ENABLE_AUTO_TEST)
            if(${EXTENSION_NAME_CMAKE}_COMPONENT_EXTENSION)
                camitk_init_test( camitk-testcomponents )

                camitk_parse_test_add_separator(EXTENSION_TYPE ${TYPE_EXTENSION} EXTENSION_NAME ${EXTENSION_NAME})

                # Retrieve the files in testdata directory - a test will be applied for each of these files
                # or use only the given files
                if (${EXTENSION_NAME_CMAKE}_TEST_FILES)
                    # add testdata dir to filename
                    set(TESTFILES)
                    foreach(COMPONENT_TESTDATA_FILE ${${EXTENSION_NAME_CMAKE}_TEST_FILES})
                        list(APPEND TESTFILES ${CMAKE_CURRENT_SOURCE_DIR}/${COMPONENT_TESTDATA_FILE})
                    endforeach()
                else()
                    get_subdirectoryfiles( ${CMAKE_CURRENT_SOURCE_DIR}/testdata TESTFILES )
                endif()

                if (NOT ${EXTENSION_NAME_CMAKE}_AUTO_TEST_LEVEL)
                    # default
                    set(TESTLEVEL 3)
                else()
                    set(TESTLEVEL ${${EXTENSION_NAME_CMAKE}_AUTO_TEST_LEVEL})
                    if (NOT ${TESTLEVEL} MATCHES "^[1-3]")
                        # default
                        message(WARNING "AUTO_TEST_LEVEL set to 3 (${TESTLEVEL} is not a valid level)")
                        set(TESTLEVEL 3)
                    else()
                        set(TESTLEVEL ${${EXTENSION_NAME_CMAKE}_AUTO_TEST_LEVEL})
                    endif()
                endif()

                # Different the test level are done automatically:
                # - level 1: load component extension, open & close test data
                # - level 2: load component extension, open & close test data, save as
                # - level 3: load component extension, open & close test data, save as and compare input with output
                # disable some tests accordingly to options defined in camitk_extension macro arguments
                if(TESTLEVEL STREQUAL "1")
                    set(TEST_DESCRIPTION "Test loading the extension, opening and closing the component.")
                elseif(TESTLEVEL STREQUAL "2")
                    set(TEST_DESCRIPTION "Test loading the extension, opening the component and saving it as a file.")
                else()
                    # level 3
                    set(TEST_DESCRIPTION "Test loading the extension, opening, saving and closing the component and comparing saved with input component.")
                endif()

                foreach(COMPONENT_TESTDATA_FILE ${TESTFILES})
                    # Give the file name (full path)
                    get_directory_name(${COMPONENT_TESTDATA_FILE} DATA_FILE)

                    # Test procedure: Open an extension and a component- save it - Compare saved file to original file(level3)
                    if(${TESTLEVEL} EQUAL 3)
                        # Level 3 = level 2 + test the output -> test level 2  + add the PASS_FILE_OUTPUT options to the test
                        camitk_add_test(EXECUTABLE_ARGS "-i ${CAMITK_BUILD_TESTDATA_DIR}/${DATA_FILE} -c ${EXTENSION_PLUGIN_FILE} -l 2"
                                        PASS_FILE_OUTPUT ${CAMITK_BUILD_TESTDATA_DIR}/${DATA_FILE}
                                        TEST_SUFFIX "-level3-"
                                        PROJECT_NAME ${${TYPE_EXTENSION_CMAKE}_TARGET_NAME}
                        )
                    endif()

                    if(${TESTLEVEL} EQUAL 2)
                        camitk_add_test(EXECUTABLE_ARGS "-i ${CAMITK_BUILD_TESTDATA_DIR}/${DATA_FILE} -c ${EXTENSION_PLUGIN_FILE} -l 2"
                                        TEST_SUFFIX "-level2-"
                                        PROJECT_NAME ${${TYPE_EXTENSION_CMAKE}_TARGET_NAME}
                        )
                    endif()

                    if(${TESTLEVEL} EQUAL 1)
                        camitk_add_test(EXECUTABLE_ARGS "-i ${CAMITK_BUILD_TESTDATA_DIR}/${DATA_FILE} -c ${EXTENSION_PLUGIN_FILE} -l 1"
                                        TEST_SUFFIX "-level1-"
                                        PROJECT_NAME ${${TYPE_EXTENSION_CMAKE}_TARGET_NAME}
                        )
                    endif()

                    camitk_parse_test_add(NAME ${CAMITK_TEST_NAME} LEVEL ${TESTLEVEL} DESCRIPTION ${TEST_DESCRIPTION})
                endforeach()

            #########################################################################
            #                                                                       #
            #   CTEST - ACTION TESTS DESCRIPTION                                    #
            #                                                                       #
            #########################################################################
            # We do not apply automatic tests on actions like (close, save, save as) as they
            # may not act directly on components
            elseif( ${EXTENSION_NAME_CMAKE}_ACTION_EXTENSION AND NOT (${${TYPE_EXTENSION_CMAKE}_OUTPUT_NAME} MATCHES "application"))
                camitk_init_test( camitk-testactions )

                camitk_parse_test_add_separator(EXTENSION_TYPE ${TYPE_EXTENSION} EXTENSION_NAME ${EXTENSION_NAME})

                # get the names of actions .dlls in lib directory
                get_subdirectoryfiles( ${CAMITK_BUILD_PRIVATE_LIB_DIR}/actions/ ACTIONSDLLS )

                # Retrieve the files in testdata directory - a test will be applied for each of these files
                # or use only the given files
                if (${EXTENSION_NAME_CMAKE}_TEST_FILES)
                    # add testdata dir to filename
                    set(TESTFILES)
                    foreach(ACTION_TESTDATA_FILE ${${EXTENSION_NAME_CMAKE}_TEST_FILES})
                        list(APPEND TESTFILES ${CAMITK_BUILD_TESTDATA_DIR}/${ACTION_TESTDATA_FILE})
                    endforeach()
                else()
                    get_subdirectoryfiles(${CAMITK_BUILD_TESTDATA_DIR} TESTFILES)
                endif()

                foreach( ACTION_TESTDATA_FILE ${TESTFILES})
                    # Test procedure: Open a file - load an action extension - Apply an action on the component wrapping the file
                    camitk_add_test(EXECUTABLE_ARGS "-i ${ACTION_TESTDATA_FILE} -a ${EXTENSION_PLUGIN_FILE}"
                                    TEST_SUFFIX "-level1-"
                                    PROJECT_NAME ${${TYPE_EXTENSION_CMAKE}_TARGET_NAME}
                    )
                    camitk_parse_test_add(NAME ${CAMITK_TEST_NAME} LEVEL 1 DESCRIPTION "Open a file, load the action and apply it on the component.")
                endforeach()
            endif()
        endif() # NOT PACKAGING_NSIS AND BUILD_TESTING AND ${EXTENSION_NAME_CMAKE}_ENABLE_AUTO_TEST)

        #########################################################################
        #                                                                       #
        #   CTEST - Integration test                                            #
        #                                                                       #
        #########################################################################

        if (NOT PACKAGING_NSIS AND BUILD_TESTING AND ${EXTENSION_NAME_CMAKE}_ENABLE_INTEGRATION_TEST)
            # add a specific test to run the action, save the output and compare it to expected
            camitk_add_integration_test()
        endif()

    endif() # ${TYPE_EXTENSION_CMAKE}_${EXTENSION_NAME_CMAKE}_ENABLED

endmacro()
