cmake_minimum_required( VERSION 3.12.0 FATAL_ERROR )

find_package( ecbuild 3.4 REQUIRED HINTS ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${CMAKE_CURRENT_SOURCE_DIR}/../../../ecbuild)

project( codes_ui LANGUAGES C CXX VERSION 1.8.0 )

set(BUILD_WITHIN_METVIEW ${ENABLE_CODES_UI})

remove_definitions(-DMETVIEW)

if (BUILD_WITHIN_METVIEW)
    set(CODES_UI_INSTALL_BIN_SUBDIR "bin/metview_bin")
    set(CODES_UI_BUILD_WITHIN_METVIEW "true")
else()
    set(CODES_UI_INSTALL_BIN_SUBDIR "bin")
    set(CODES_UI_BUILD_WITHIN_METVIEW "false")
endif()


# All executables and scripts apart from the startup script should go into MV_BIN_DIR.
# Users can override by setting METVIEW_INSTALL_EXE_BIN_DIR.
# It should be relative to the root of the install directory.
#if(DEFINED METVIEW_INSTALL_EXE_BIN_DIR)
#    set(MV_BIN_DIR ${METVIEW_INSTALL_EXE_BIN_DIR})
#else()
#    set(MV_BIN_DIR bin/metview_bin)
#endif()

set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/../ecbuild/cmake"  "${CMAKE_CURRENT_SOURCE_DIR}/../../../ecbuild/cmake")
set(CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE OFF)

#set(METVIEW_INSTALL_BIN_DIR "${MV_BIN_DIR}" CACHE PATH "Metview installation directory for executable files")

include( ecbuild_system NO_POLICY_SCOPE )

ecbuild_requires_macro_version( 1.9 )
set (CMAKE_CXX_STANDARD 17)

###############################################################################
# some options of this project

option( ENABLE_QT_DEBUG      "enable Qt debugging messages"                       OFF )

###############################################################################

#C check if it is an exeternal build (outside the metview source)
set(__external_build  1)
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../AppMod")
   set(__external_build 0)
endif()

# ensure we can add non-existent dependencies - required for generating icon files
if( ${CMAKE_VERSION} VERSION_GREATER "2.9.9" )
    cmake_policy(SET CMP0046 OLD)
endif()


# default startup script name
if(NOT DEFINED CODES_UI_SCRIPT )
    set( CODES_UI_SCRIPT "codes_ui" )
endif()

set(FULL_STARTUP_SCRIPT_PATH ${CMAKE_BINARY_DIR}/bin/${CODES_UI_SCRIPT})

# ensure we don't build shared libraries
if (NOT BUILD_WITHIN_METVIEW)
    set(BUILD_SHARED_LIBS OFF)
endif()

message("CMAKE_BINARY_DIR = ${CMAKE_BINARY_DIR}")
message("CMAKE_CURRENT_SOURCE_DIR = ${CMAKE_CURRENT_SOURCE_DIR}")


###############################################################################
# local project requirements

#ecbuild_add_option( FEATURE ECCODES DESCRIPTION "" DEFAULT OFF )

if (NOT BUILD_WITHIN_METVIEW)
    ecbuild_find_package(NAME eccodes VERSION 2.19.0 REQUIRED)
    set( GRIB_API_INCLUDE_DIRS ${eccodes_INCLUDE_DIRS} )
    set( GRIB_API_LIBRARIES    ${eccodes_LIBRARIES} )
    set( GRIB_API_DEFINITIONS  ${eccodes_DEFINITIONS} )
    set( grib_api_BASE_DIR     ${eccodes_BASE_DIR} )
    add_definitions(-DGRIB_HANDLING_PACKAGE=ecCodes)
else()
    set(GRIB_API_PATH )
endif()

ecbuild_declare_project()

###############################################################################
# Find external dependencies

if (NOT BUILD_WITHIN_METVIEW)

    find_package(Qt6Widgets)
    if( Qt6Widgets_FOUND )
        find_package(Qt6Core5Compat      REQUIRED)
        find_package(Qt6Widgets      REQUIRED)
        find_package(Qt6Gui          REQUIRED)
        find_package(Qt6Xml          REQUIRED)
        find_package(Qt6Network      REQUIRED)
        find_package(Qt6Svg          REQUIRED)
        find_package(Qt6SvgWidgets   REQUIRED)
        ecbuild_debug("Qt6 version ${Qt6Widgets_VERSION_STRING} was found")
        include_directories(${Qt6Core5Compat_INCLUDE_DIRS} ${Qt6Widgets_INCLUDE_DIRS} ${Qt6Gui_INCLUDE_DIRS} ${Qt6Xml_INCLUDE_DIRS} ${Qt6Network_INCLUDE_DIRS} ${Qt6Svg_INCLUDE_DIRS} ${Qt6SvgWidgets_INCLUDE_DIRS})
        set( METVIEW_QT 1)
        set( METVIEW_QT6 true)
        add_definitions( -DMETVIEW_QT6 )
    else()
        find_package(Qt5Widgets)
        if( Qt5Widgets_FOUND )
            find_package(Qt5Gui REQUIRED)
            find_package(Qt5Network      REQUIRED)
            find_package(Qt5Xml          REQUIRED)
            find_package(Qt5XmlPatterns  REQUIRED)
            find_package(Qt5Svg          REQUIRED)
            ecbuild_debug("Qt5 version ${Qt5Widgets_VERSION_STRING} was found")
            include_directories(${Qt5Widgets_INCLUDE_DIRS} ${Qt5Gui_INCLUDE_DIRS} ${Qt5Xml_INCLUDE_DIRS} ${Qt5XmlPatterns_INCLUDE_DIRS} ${Qt5Network_INCLUDE_DIRS} ${Qt5Svg_INCLUDE_DIRS})
            set( METVIEW_QT 1)
            set( METVIEW_QT5 true)
            add_definitions( -DMETVIEW_QT5 )
        else()
            ecbuild_critical("Neither Qt5 nor Qt6 were found ...")
        endif()
    endif()

    if( NOT ENABLE_QT_DEBUG )
        add_definitions( -DQT_NO_DEBUG_OUTPUT )
    endif()
endif()

###############################################################################
# contents
######set( METVIEW_TPLS grib_api odb_api EXPAT NetCDF PangoCairo Proj4 libemos)

#When we build outside the ecmwf dev environment (i.e. from the tarball) we have
#a different directory structure.
if(__external_build)
    set(SRC_PATH ${CMAKE_CURRENT_SOURCE_DIR}/src)
    set(SHARE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/share/codes_ui/etc)
    set(STARTUP_SCRIPT_TEMPLATE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/scripts/codes_ui_base.in")
    set(WINDOWS_STARTUP_SCRIPT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/codes_ui.bat")
    set(KEYPROFILE_PATH ${SHARE_PATH})
    set(VERSION_PATH ${SHARE_PATH})
    set(IMAGE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/share/codes_ui/etc/images)
    set(EXE_SRC_PATH ${CMAKE_CURRENT_SOURCE_DIR}/src/codes_ui)
    set(LIBCODESUI_SRC_PATH "${SRC_PATH}/libCodesUi")
else()
    set(SRC_PATH "..")
    set(SHARE_PATH "../../share/metview/app-defaults")
    set(STARTUP_SCRIPT_TEMPLATE_PATH "codes_ui_base.in")
    set(WINDOWS_STARTUP_SCRIPT_PATH "codes_ui.bat")
    set(KEYPROFILE_PATH ".")
    set(VERSION_PATH ".")
    set(IMAGE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../share/metview/app-defaults/images)
    set(EXE_SRC_PATH ".")
    set(LIBCODESUI_SRC_PATH ".")
endif()

message(STATUS "CODES_UI __external_build=${__external_build}")
message(STATUS "CODES_UI BUILD_WITHIN_METVIEW=${BUILD_WITHIN_METVIEW}")


set( METVIEW_STANDARD_INCLUDE_DIRS        
        ${SRC_PATH}/libFTimeUtil
        ${SRC_PATH}/libMetview
        ${LIBCODESUI_SRC_PATH}
        ${SRC_PATH}/BufrExaminer
        ${SRC_PATH}/GribExaminer
        .
       )
set(STANDARD_METVIEW_LIBS MetviewCUI FTimeUtilCUI CodesUi)


set(METVIEW_EXTRA_LIBRARIES eccodes)

set (METVIEW_QT_INCLUDE_DIRS "")
set (METVIEW_QT_LIBRARIES "")
if( METVIEW_QT5)
    list( APPEND METVIEW_QT_INCLUDE_DIRS ${Qt5Widgets_INCLUDE_DIR} ${Qt5Gui_INCLUDE_DIR} ${Qt5Xml_INCLUDE_DIR} ${Qt5XmlPatterns_INCLUDE_DIR} ${Qt5Network_INCLUDE_DIR} ${Qt5Svg_INCLUDE_DIR} ${SRC_PATH}/libMvQtUtil ${SRC_PATH}/libMvQtGui )
    list( APPEND METVIEW_QT_LIBRARIES  MvQtGuiCUI MvQtUtilCUI ${Qt5Widgets_LIBRARIES} ${Qt5Gui_LIBRARIES} ${Qt5Xml_LIBRARIES} ${Qt5XmlPatterns_LIBRARIES} ${Qt5Network_LIBRARIES}  ${Qt5Svg_LIBRARIES})
elseif( METVIEW_QT6)
    list( APPEND METVIEW_QT_INCLUDE_DIRS ${Qt6Widgets_INCLUDE_DIR} ${Qt6Gui_INCLUDE_DIR} ${Qt6Xml_INCLUDE_DIR} ${Qt6Network_INCLUDE_DIR} ${Qt6Svg_INCLUDE_DIR} ${SRC_PATH}/libMvQtUtil ${SRC_PATH}/libMvQtGui )
    list( APPEND METVIEW_QT_LIBRARIES  MvQtGuiCUI MvQtUtilCUI ${Qt6Core5Compat_LIBRARIES} ${Qt6Widgets_LIBRARIES} ${Qt6Gui_LIBRARIES} ${Qt6Xml_LIBRARIES}  ${Qt6Network_LIBRARIES}  ${Qt6Svg_LIBRARIES})
endif()

message(STATUS "CODES_UI METVIEW_EXTRA_LIBRARIES    => ${METVIEW_EXTRA_LIBRARIES}")
message(STATUS "CODES_UI STANDARD_METVIEW_LIBS      => ${STANDARD_METVIEW_LIBS}")
message(STATUS "CODES_UI METVIEW_QT_INCLUDE_DIRS    => ${METVIEW_QT_INCLUDE_DIRS}")


# we need to make sure that
#set(CMAKE_INCLUDE_DIRECTORIES_BEFORE "ON")

set(METVIEW_STANDARD_INCLUDES ${METVIEW_STANDARD_INCLUDE_DIRS})
link_directories( ${CMAKE_CURRENT_SOURCE_DIR}/lib )
message(STATUS "CODES_UI METVIEW_STANDARD_INCLUDE_DIRS  => ${METVIEW_STANDARD_INCLUDES}")


add_definitions( -DR64 -DECCODES_UI -DH_INCLUDES_CC -DUSE_NEW_IO )

# ecbuild automatically test endiness and sets variable EC_BIG_ENDIAN or EC_LITTLE_ENDIAN
if( EC_LITTLE_ENDIAN )
    add_definitions(-DLITTLE_END) # needed for libMars/bufr.h
endif()

# -------------------------
# compiler-specific options
# -------------------------

if     (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" )
    ecbuild_add_cxx_flags("-fpermissive -Wno-write-strings -Wno-deprecated")
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" )
    ecbuild_add_cxx_flags("-fpermissive -Wno-deprecated -undefined dynamic_lookup")
endif()

if     (CMAKE_C_COMPILER_ID STREQUAL "Clang" )
    ecbuild_add_c_flags("-undefined dynamic_lookup")     #  "-fno-common  -mmacosx-version-min=10.8")
endif()

if( EC_OS_NAME MATCHES "windows" )
    # Suppress compiler warnings
    # Suppress warnings about using 'insecure' functions.
    ecbuild_add_cxx_flags("/D_CRT_SECURE_NO_WARNINGS")
    # Suppress warnings about using well-known C functions.
    ecbuild_add_cxx_flags("/D_CRT_NONSTDC_NO_DEPRECATE")
    # Suppress C4267: warns about possible loss of data when converting 'size_t' to 'int'.
    ecbuild_add_cxx_flags("/wd4267")
endif()

set(TAR_ROOT $ENV{TMPDIR}/codes_ui_tar_tmp)
set(NEED_TAR 0)
if(NOT __external_build AND NOT BUILD_WITHIN_METVIEW)
    list( APPEND CPACK_SOURCE_INSTALLED_DIRECTORIES ${TAR_ROOT} .)
    set(NEED_TAR 1)
endif()

macro(add_files_to_tar FILES TAR_DIR)

    if(NEED_TAR)

        message(STATUS "add_files_to_tar()")
        message(STATUS "TAR_DIR=${TAR_DIR}")

        set(tmpdir $ENV{TMPDIR}/codes_ui_tar_tmp/${TAR_DIR})
        message(STATUS "tmpdir=${tmpdir}")

        file(MAKE_DIRECTORY ${tmpdir})
        foreach( f ${FILES} )
            message(STATUS "  file=${f}")
            file(COPY ${f}
                DESTINATION ${tmpdir}
            )
        endforeach()

    endif()

endmacro(add_files_to_tar)

#---------------------------------------
# libCodesUi
#---------------------------------------

set(libCodesUi_srcs_names
    CodesDirHandler.cc
    CodesDirHandler.h
)

foreach( f ${libCodesUi_srcs_names} )
   list(APPEND libCodesUi_srcs ${LIBCODESUI_SRC_PATH}/${f})
endforeach()

ecbuild_add_library( TARGET      CodesUi
                     TYPE        STATIC
                     NOINSTALL
                     SOURCES     ${libCodesUi_srcs}
                     TEMPLATES   ${common_templates}
                     PUBLIC_INCLUDES    ${METVIEW_STANDARD_INCLUDES} ${LOCAL_EXTRA_INCLUDE_DIRS}
                     PUBLIC_LIBS ${METVIEW_EXTRA_LIBRARIES}
)

add_files_to_tar("${libCodesUi_srcs}" "src/libCodesUi")

#---------------------------------------
# libFTimeUtilCUI
#---------------------------------------

set(libFTimeUtilCUI_srcs_names
    fdyntime.cc
    fmettim.cc
    fobject.cc
    fsortabl.cc
    fstatime.cc
    fdyntime.h
    fmettim.h
    fobject.h
    fsortabl.h
    fstatime.h

)

foreach( f ${libFTimeUtilCUI_srcs_names} )
   list(APPEND libFTimeUtilCUI_srcs ${SRC_PATH}/libFTimeUtil/${f})
endforeach()

ecbuild_add_library( TARGET      FTimeUtilCUI
                     TYPE        STATIC
                     NOINSTALL
                     SOURCES     ${libFTimeUtilCUI_srcs}
                     TEMPLATES   ${common_templates}
                     PUBLIC_INCLUDES    ${METVIEW_STANDARD_INCLUDES}
                     PUBLIC_LIBS ${METVIEW_EXTRA_LIBRARIES}
)

add_files_to_tar("${libFTimeUtilCUI_srcs}" "src/libFTimeUtil")

#---------------------------------------
# libMetviewCUI
#---------------------------------------

set(libMetviewCUI_srcs_names
    MvAbstractApplication.cc
    MvLocation.cc
    MvLog.cc
    MvObs.cc
    MvObsSet.cc  
    BufrFilterDef.cc
    BufrFilterEngine.cc
    BufrLocationCollector.cc
    BufrMetaData.cc
    GribMetaData.cc
    LogHandler.cc
    MvBufrEdition.cc
    MvBufrElementTable.cc
    MvEccBufr.cc
    MvException.cc
    MvKeyCondition.cc
    MvKeyProfile.cc
    MvKeyManager.cc
    MvMessageMetaData.cc
    MvMiscellaneous.cc
    MvTmpFile.cc
    MvVariant.cc
    MvVersionInfo.cc
    Tokenizer.cc
    BufrFilterDef.h
    BufrFilterEngine.h
    BufrLocationCollector.h
    BufrMetaData.h
    FortranTypes.h
    GribMetaData.h
    LogHandler.h
    MvAbstractApplication.h
    MvBufrEdition.h
    MvBufrElementTable.h
    MvEccBufr.h
    MvException.h
    MvFwd.h
    MvKeyCondition.h
    MvKeyProfile.h
    MvKeyManager.h
    MvLog.h
    MvMessageMetaData.h
    MvMiscellaneous.h
    MvTmpFile.h
    MvVariant.h
    MvVersionInfo.h
    Tokenizer.h
    MvBufrObs.h
    MvLocation.h
    MvObs.h
    MvObsSet.h
    MvWindef.h
    fstream_mars_fix.h
)

foreach( f ${libMetviewCUI_srcs_names} )
   list(APPEND libMetviewCUI_srcs ${SRC_PATH}/libMetview/${f})
endforeach()

ecbuild_add_library( TARGET      MetviewCUI
                     TYPE        STATIC
                     NOINSTALL
                     SOURCES     ${libMetviewCUI_srcs}
                     TEMPLATES   ${common_templates}
                     PUBLIC_INCLUDES    ${METVIEW_STANDARD_INCLUDES}
                     PUBLIC_LIBS ${METVIEW_EXTRA_LIBRARIES}
)



add_files_to_tar("${libMetviewCUI_srcs}" "src/libMetview")

#---------------------------------------
# libMvQtGuiCUI
#---------------------------------------

set(libMvQtGuiCUI_srcs_names
    AbstractSearchLine.cc
    AbstractTextEditSearchInterface.cc
    CalendarDialog.cc
    DateEditWidget.cc
    GotoLineDialog.cc
    IconProvider.cc
    LocationMap.cc
    LocationView.cc
    LocationWidget.cc
    MessageControlPanel.cc
    MessageLabel.cc
    PlainTextEdit.cc
    PlainTextSearchInterface.cc
    PlainTextSearchLine.cc
    PlainTextWidget.cc
    PropertyLineEditor.cc
    TreeModelMatchCollector.cc
    StatusMsgHandler.cc
    StatusProgBarHandler.cc
    StringMatchCombo.cc
    StringMatchMode.cc
    TextEditSearchLine.cc
    MvQAbout.cc
    MvQArrowSpinWidget.cc
    MvQConfigDialog.cc
    MvQFileDialog.cc
    MvQFileInfoLabel.cc
    MvQFileListModel.cc
    MvQFileListWidget.cc
    MvQKeyMimeData.cc
    MvQKeyModel.cc
    MvQKeyDialog.cc
    MvQKeyProfileModel.cc
    MvQKeyProfileTree.cc  
    MvQLogBrowser.cc
    MvQLogPanel.cc
    MvQAbstractMessageExaminer.cc
    MvQMainWindow.cc
    MvQPanel.cc
    MvQPixmapCache.cc   
    MvQSearchLinePanel.cc
    MvQSimpleApplication.cc
    MvQStackedEditor.cc
    MvQTreeExpandState.cc
    MvQTreeView.cc
    MvQTreeViewSearchLine.cc
    AbstractSearchLine.h
    AbstractTextEditSearchInterface.h
    CalendarDialog.h
    DateEditWidget.h
    GotoLineDialog.h
    IconProvider.h
    LocationMap.h
    LocationView.h
    LocationWidget.h
    MessageControlPanel.h
    MessageLabel.h
    OutputBrowser.h
    PlainTextEdit.h
    PlainTextSearchInterface.h
    PlainTextSearchLine.h
    PlainTextWidget.h
    PropertyLineEditor.h
    StatusMsgHandler.h
    StatusProgBarHandler.h
    StringMatchCombo.h
    StringMatchMode.h
    TextEditSearchLine.h
    TreeModelMatchCollector.h
    MvQAbout.h
    MvQArrowSpinWidget.h
    MvQConfigDialog.h
    MvQFileDialog.h
    MvQFileInfoLabel.h
    MvQFileListModel.h
    MvQFileListWidget.h
    MvQKeyMimeData.h
    MvQKeyModel.h
    MvQKeyDialog.h
    MvQKeyProfileModel.h
    MvQKeyProfileTree.h
    MvQLogBrowser.h
    MvQLogPanel.h
    MvQAbstractMessageExaminer.h
    MvQMainWindow.h
    MvQMenuItem.h
    MvQPanel.h
    MvQPixmapCache.h
    MvQSearchLinePanel.h
    MvQSimpleApplication.h
    MvQStackedEditor.h
    MvQTextEditSearchLine.h
    MvQTreeExpandState.h
    MvQTreeView.h
    MvQTreeViewSearchLine.h
    #edit.qrc examiner.qrc find.qrc keyDialog.qrc window.qrc
)

set(libMvQtGuiCUI_moc_names
    AbstractSearchLine.h
    CalendarDialog.h
    DateEditWidget.h
    GotoLineDialog.h
    LocationMap.h
    LocationView.h
    LocationWidget.h
    MessageControlPanel.h
    MessageLabel.h
    PlainTextEdit.h
    PlainTextWidget.h
    PropertyLineEditor.h
    TextEditSearchLine.h
    MvQAbstractMessageExaminer.h
    MvQArrowSpinWidget.h
    MvQConfigDialog.h
    MvQFileListModel.h
    MvQFileListWidget.h
    MvQKeyDialog.h MvQKeyMimeData.h
    MvQKeyModel.h
    MvQKeyProfileModel.h
    MvQKeyProfileTree.h
    MvQLogBrowser.h
    MvQLogPanel.h    
    MvQSearchLinePanel.h
    MvQStackedEditor.h
    MvQTreeView.h
    MvQTreeViewSearchLine.h
)

set(libMvQtGuiCUI_form_names
    CalendarDialog.ui
    GotoLineDialog.ui
    LocationMap.ui
    LocationWidget.ui
    PlainTextWidget.ui
    SearchLineWidget.ui
   )

#set(libMvQtGuiCUI_res_names
#    edit.qrc examiner.qrc find.qrc keyDialog.qrc window.qrc codes_ui.qrc
#    )

foreach( f ${libMvQtGuiCUI_srcs_names} )
   list(APPEND libMvQtGuiCUI_srcs ${SRC_PATH}/libMvQtGui/${f})
endforeach()

foreach( f ${libMvQtGuiCUI_moc_names} )
   list(APPEND libMvQtGuiCUI_moc ${SRC_PATH}/libMvQtGui/${f})
endforeach()

foreach( f ${libMvQtGuiCUI_form_names} )
   list(APPEND libMvQtGuiCUI_form ${SRC_PATH}/libMvQtGui/${f})
endforeach()

#foreach( f ${libMvQtGuiCUI_res_names} )
#   list(APPEND libMvQtGuiCUI_res ${SRC_PATH}/libMvQtGui/${f})
#endforeach()

if(METVIEW_QT5)
    QT5_WRAP_CPP(libMvQtGuiCUI_MOC ${libMvQtGuiCUI_moc})
#    QT5_ADD_RESOURCES(libMvQtGuiCUI_RES ${libMvQtGuiCUI_res})
    QT5_WRAP_UI(libMvQtGuiCUI_FORMS_HEADERS ${libMvQtGuiCUI_form})
elseif(METVIEW_QT6)
    QT6_WRAP_CPP(libMvQtGuiCUI_MOC ${libMvQtGuiCUI_moc})
#    QT6_ADD_RESOURCES(libMvQtGuiCUI_RES ${libMvQtGuiCUI_res})
    QT6_WRAP_UI(libMvQtGuiCUI_FORMS_HEADERS ${libMvQtGuiCUI_form})
endif()

foreach( f ${generated_srcs} )
    set_source_files_properties( ${f} GENERATED )
endforeach()

ecbuild_add_library( TARGET      MvQtGuiCUI
                     TYPE        STATIC
                     NOINSTALL
                     SOURCES     ${libMvQtGuiCUI_MOC} ${libMvQtGuiCUI_srcs} ${libMvQtGuiCUI_FORMS_HEADERS}
                     TEMPLATES   ${common_templates}
                     PUBLIC_LIBS ${METVIEW_EXTRA_LIBRARIES}
                     PUBLIC_INCLUDES    ${METVIEW_QT_INCLUDE_DIRS} ${METVIEW_STANDARD_INCLUDES} ${CMAKE_CURRENT_BINARY_DIR}
)

add_files_to_tar("${libMvQtGuiCUI_srcs}" "src/libMvQtGui")
add_files_to_tar("${libMvQtGuiCUI_form}" "src/libMvQtGui")
#add_files_to_tar("${libMvQtGuiCUI_res}" "src/libMvQtGui")

#---------------------------------------
# libMvQtUtil
#---------------------------------------

set(libMvQtUtilCUI_srcs_names
    MvQAbstractMessageScanner.cc
    MvQBufrMessageScanner.cc
    MvQGribMessageScanner.cc
    MvQFileInfo.cc
    MvQFileList.cc
    MvQFileUtil.cc
    MvQKeyManager.cc
    MvQLocalSocketServer.cc
    MvQMethods.cc
    MvQProperty.cc
    MvQStreamOper.cc
    MvQTheme.cc
#    MvQXmlQuery.cc
    DocHighlighter.cc
    MvQAbstractMessageScanner.h
    MvQBufrMessageScanner.h
    MvQGribMessageScanner.h
    MvQFileInfo.h
    MvQFileList.h
    MvQFileUtil.h
    MvQKeyManager.h
    MvQLocalSocketServer.h
    MvQMethods.h
    MvQProperty.h
    MvQStreamOper.h
    MvQTheme.h
#    MvQXmlQuery.h
    DocHighlighter.h
)

set(libMvQtUtilCUI_moc_names
    MvQAbstractMessageScanner.h
    MvQBufrMessageScanner.h
    MvQGribMessageScanner.h
    MvQFileList.h
    MvQLocalSocketServer.h
)

foreach( f ${libMvQtUtilCUI_srcs_names} )
   list(APPEND libMvQtUtilCUI_srcs ${SRC_PATH}/libMvQtUtil/${f})
endforeach()

foreach( f ${libMvQtUtilCUI_moc_names} )
   list(APPEND libMvQtUtilCUI_moc ${SRC_PATH}/libMvQtUtil/${f})
endforeach()

if(METVIEW_QT5)
    QT5_WRAP_CPP(libMvQtUtilCUI_MOC ${libMvQtUtilCUI_moc})
elseif(METVIEW_QT6)
    QT6_WRAP_CPP(libMvQtUtilCUI_MOC ${libMvQtUtilCUI_moc})
endif()

foreach( f ${generated_srcs} )
    set_source_files_properties( ${f} GENERATED )
endforeach()

ecbuild_add_library( TARGET      MvQtUtilCUI
                     TYPE        STATIC
                     NOINSTALL
                     SOURCES     ${libMvQtUtilCUI_MOC} ${libMvQtUtilCUI_srcs}
                     TEMPLATES   ${common_templates}
                     PUBLIC_LIBS ${METVIEW_EXTRA_LIBRARIES}
                     PUBLIC_INCLUDES    ${METVIEW_QT_INCLUDE_DIRS} ${METVIEW_STANDARD_INCLUDES}
)

add_files_to_tar("${libMvQtUtilCUI_srcs}" "src/libMvQtUtil")

#---------------------------------------
# BufrExaminer
#---------------------------------------

set(BufrExaminer_exe_srcs_names
    BufrExaminerMain.cc
)

foreach( f ${BufrExaminer_exe_srcs_names} )
   list(APPEND BufrExaminer_exe_srcs ${EXE_SRC_PATH}/${f})
endforeach()

set(BufrExaminer_srcs_names
    BufrExaminer.cc
    BufrCompDataWidget.cc
    BufrExpandDataModel.cc
    BufrFilterDialog.cc
    BufrFilterEditor.cc
    BufrKeyWidget.cc
    MvQBufrDataItem.cc
    MvQBufrDataModel.cc
    BufrExaminer.h
    BufrCompDataWidget.h
    BufrExpandDataModel.h
    BufrFilterDialog.h
    BufrFilterEditor.h
    BufrKeyWidget.h
    MvQBufrDataItem.h
    MvQBufrDataModel.h
)

foreach( f ${BufrExaminer_srcs_names} )
   list(APPEND BufrExaminer_srcs ${SRC_PATH}/BufrExaminer/${f})
endforeach()

set(BufrExaminer_moc_names
    BufrExaminer.h
    BufrCompDataWidget.h
    BufrFilterDialog.h
    BufrFilterEditor.h
    BufrKeyWidget.h
)

foreach( f ${BufrExaminer_moc_names} )
   list(APPEND BufrExaminer_moc ${SRC_PATH}/BufrExaminer/${f})
endforeach()

set(BufrExaminer_form_names
    BufrCompDataWidget.ui
    BufrFilterDialog.ui
    BufrKeyWidget.ui
   )

foreach( f ${BufrExaminer_form_names} )
   list(APPEND BufrExaminer_form  ${SRC_PATH}/BufrExaminer/${f})
endforeach()

if(METVIEW_QT5)
    QT5_WRAP_CPP(BufrExaminer_MOC ${BufrExaminer_moc})
    QT5_WRAP_UI(BufrExaminer_FORMS_HEADERS ${BufrExaminer_form})
elseif(METVIEW_QT6)
    QT6_WRAP_CPP(BufrExaminer_MOC ${BufrExaminer_moc})
    QT6_WRAP_UI(BufrExaminer_FORMS_HEADERS ${BufrExaminer_form})
endif()

ecbuild_add_executable( TARGET       codes_ui_bufr.x
                        SOURCES      ${BufrExaminer_exe_srcs} ${BufrExaminer_srcs} ${BufrExaminer_MOC} ${BufrExaminer_FORMS_HEADERS}
                        INCLUDES     ${METVIEW_STANDARD_INCLUDES} ${METVIEW_QT_INCLUDE_DIRS} ../BufrExaminer
                        LIBS         ${METVIEW_QT_LIBRARIES} ${STANDARD_METVIEW_LIBS}
                    )

add_files_to_tar("${BufrExaminer_exe_srcs}" "src/codes_ui")
add_files_to_tar("${BufrExaminer_srcs}" "src/BufrExaminer")
add_files_to_tar("${BufrExaminer_form}" "src/BufrExaminer")

#---------------------------------------
# GribExaminer
#---------------------------------------

set(GribExaminer_exe_srcs_names
    GribExaminerMain.cc
)

foreach( f ${GribExaminer_exe_srcs_names} )
   list(APPEND GribExaminer_exe_srcs ${EXE_SRC_PATH}/${f})
endforeach()

set(GribExaminer_srcs_names
    GribExaminer.cc
    MvQGribDumpModel.cc
    GribExaminer.h
    MvQGribDumpModel.h
)

foreach( f ${GribExaminer_srcs_names} )
   list(APPEND GribExaminer_srcs  ${SRC_PATH}/GribExaminer/${f})
endforeach()

set(GribExaminer_moc_names
    GribExaminer.h
)

foreach( f ${GribExaminer_moc_names} )
   list(APPEND GribExaminer_moc ${SRC_PATH}/GribExaminer/${f})
endforeach()

if(METVIEW_QT5)
    QT5_WRAP_CPP(GribExaminer_MOC ${GribExaminer_moc})
elseif(METVIEW_QT6)
    QT6_WRAP_CPP(GribExaminer_MOC ${GribExaminer_moc})
endif()

ecbuild_add_executable( TARGET       codes_ui_grib.x
                        SOURCES      ${GribExaminer_exe_srcs} ${GribExaminer_srcs}  ${GribExaminer_MOC}
                        INCLUDES     ${METVIEW_STANDARD_INCLUDES} ${METVIEW_QT_INCLUDE_DIRS} ../GribExaminer
                        LIBS         ${METVIEW_QT_LIBRARIES} ${STANDARD_METVIEW_LIBS}
                    )

add_files_to_tar("${GribExaminer_exe_srcs}" "src/codes_ui")
add_files_to_tar("${GribExaminer_srcs}" "src/GribExaminer")

#---------------------------------------
# getFileType
#---------------------------------------

set(getFileType_exe_srcs_names
    getCodesUiFileType.cc
)

foreach( f ${getFileType_exe_srcs_names} )
   list(APPEND getFileType_exe_srcs ${EXE_SRC_PATH}/${f})
endforeach()

ecbuild_add_executable( TARGET       codes_ui_file_type.x
                        SOURCES      ${getFileType_exe_srcs}
                        INCLUDES     ${METVIEW_STANDARD_INCLUDES} ${METVIEW_QT_INCLUDE_DIRS}
                        LIBS         ${METVIEW_QT_LIBRARIES} ${STANDARD_METVIEW_LIBS}
                    )

add_files_to_tar("${getFileType_exe_srcs}" "src/codes_ui")


configure_file(${VERSION_PATH}/codes_ui_version.in         ${CMAKE_CURRENT_BINARY_DIR}/share/codes_ui/etc/codes_ui_version @ONLY)
configure_file(${VERSION_PATH}/codes_ui_version_details.in  ${CMAKE_BINARY_DIR}/share/metview/app-defaults/codes_ui_version_details @ONLY)



#------------------------------------------
# Share: note the different dir structure
#   when built within metview
#------------------------------------------

if (NOT BUILD_WITHIN_METVIEW)
    set(CUI_ETC_PATH ${CMAKE_CURRENT_BINARY_DIR}/share/codes_ui/etc)
    set(CUI_INSTALL_ETC_PATH share/codes_ui/etc)
else()
    set(CUI_ETC_PATH ${CMAKE_CURRENT_BINARY_DIR}/../../share/metview/app-defaults)
    set(CUI_INSTALL_ETC_PATH share/metview/app-defaults)
endif()

set(CUI_IMAGE_PATH ${CUI_ETC_PATH}/images)
set(CUI_INSTALL_IMAGE_PATH ${CUI_INSTALL_ETC_PATH}/images)

file(MAKE_DIRECTORY ${CUI_ETC_PATH})
file(MAKE_DIRECTORY ${CUI_IMAGE_PATH})

if (NOT BUILD_WITHIN_METVIEW)
    #Files in share
    set(share_file_names
        dark.qss
        light.qss
        highlighter_dark.json
        highlighter_light.json
        uitheme_dark.json
        uitheme_light.json
        GribKeyProfile_default.xml
        BufrFilterDef.json
        world_map_low.svg
        )

    #Files in the codes_ui src directory
    set(share_profile_file_names
        BufrKeyProfile_default.xml
        BufrKeyProfile_all.xml
        )

    foreach( f ${share_file_names} )
        list(APPEND share_files ${SHARE_PATH}/${f})
    endforeach()

    foreach( f ${share_profile_file_names} )
        list(APPEND share_files ${KEYPROFILE_PATH}/${f})
    endforeach()

    foreach( f ${share_files} )
        # copy to the build 'bin' directory
        get_filename_component(fname ${f} NAME)
        configure_file(${f} ${CUI_ETC_PATH}/${fname} COPYONLY)

        # ensure file is installed at install time
        install( FILES ${CUI_ETC_PATH}/${fname}
            DESTINATION ${CUI_INSTALL_ETC_PATH}
            PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ)

    endforeach()

    add_files_to_tar("${share_files}" "share/codes_ui/etc")

endif()

#-----------------------------------
# Version
#-----------------------------------

execute_process(COMMAND           date +%Y
    OUTPUT_VARIABLE   THIS_YEAR
    OUTPUT_STRIP_TRAILING_WHITESPACE)

#Preprocess version
configure_file(${VERSION_PATH}/codes_ui_version.in          ${CUI_ETC_PATH}/codes_ui_version @ONLY)
configure_file(${VERSION_PATH}/codes_ui_version_details.in  ${CUI_ETC_PATH}/codes_ui_version_details @ONLY)

set(version_in_files
    ${VERSION_PATH}/codes_ui_version.in
    ${VERSION_PATH}/codes_ui_version_details.in
    )

#Version files are already in target share directory
set(version_files
    ${CUI_ETC_PATH}/codes_ui_version
    ${CUI_ETC_PATH}/codes_ui_version_details
    )

foreach( f ${version_files} )
    # ensure file is installed at install time
    install( FILES ${f}
        DESTINATION ${CUI_INSTALL_ETC_PATH}
        PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ)

endforeach()

add_files_to_tar("${version_in_files}" "share/codes_ui/etc")

#-----------------------------------
# Images
#-----------------------------------

if (NOT BUILD_WITHIN_METVIEW)

    # the styles. There is a directory for each style containg all the images belonging to it.
    set(STYLE_NAMES
        light
        dark
    )

    # the root name of the qrc resources
    set(QRC_NAMES
        examiner
        keyDialog
        window
        find
        codes_ui
    )

    set(IMAGE_FILE_NAMES
        add.svg
        add_thin.svg
        arrow_down.svg
        arrow_left.svg
        arrow_up.svg
        block_open.svg
        block_close.svg
        block_reset.svg
        chb_indicator.png
        calendar.svg
        clear_left.svg
        close_grey.svg
        close_red.svg
        cogwheel.svg
        codes_ui.svg
        codes_ui_logo.png
        configure.svg
        edit.svg
        editrename.svg
        exit.svg
        fileInfo.svg
        fileList.svg
        filter.svg
        filter_blue.svg
        filter_blue_clear.svg
        fontsize_down.svg
        fontsize_up.svg
        globe.svg
        goto_line.svg
        info_light.svg
        key.svg
        label_error.svg
        label_info.svg
        label_tip.svg
        label_warning.svg
        line_num.svg
        log.svg
        log1.svg
        log_info.svg
        log_error.svg
        magnifier_handler.png
        metview.svg
        metview_logo.png
        minus_black.svg
        panel_close.svg
        panel_config.svg
        panel_info.svg
        panel_filter.svg
        panel_menu_indicator.png
        panel_search.svg
        panel_sidebar.svg
        page_expand.svg
        plus_black.svg
        profile.svg
        profile_import.svg
        profile_manage.svg
        profile_save.svg
        remove.svg
        remove_thin.svg
        reset_line.svg
        saveas_teal.svg
        search.svg
        search_decor.svg
        select_all.svg
        triangle_left.svg
        triangle_right.svg
        triangle_left_orange.svg
        triangle_right_orange.svg
        unselect_all.svg
        wastebasket.svg
        zoom_data.svg
        zoom_minus.svg
        zoom_plus.svg
        metview_and_eccodes_logo.png
    )

    ecbuild_info("Generate QRC/RCC files")

    # generate rcc binary files form image (svg+png) resources to be loaded at
    # runtime by the Qt-based applications. There will one set of rcc files for each style.
    set(RCC_FILES "")

    # iterate through the styles
    foreach( STYLE ${STYLE_NAMES} )

        # generate a qrc + rcc file
        foreach( _N ${QRC_NAMES} )

            # create a qrc file from the template. A qrc file contains paths to
            # a set of images
            set(_QRC_TEMPLATE "${IMAGE_PATH}/${_N}.qrc.in")
            set(_QRC_NAME ${_N}_${STYLE})
            set(_QRC_FILENAME ${_QRC_NAME}.qrc)
            set(_QRC_FILE "${CUI_IMAGE_PATH}/${_QRC_NAME}.qrc")
            set(_CURRENT_STYLE "${IMAGE_PATH}/${STYLE}")
            configure_file("${_QRC_TEMPLATE}" "${_QRC_FILE}"  @ONLY)

            # generate the rcc file from the qrc file. The Qt command will automatically create an
            # rcc target (first arg) depending of the qrc file and the images it points to
            set(_RCC_FILENAME "${_QRC_NAME}.rcc")
            set(_RCC_FILE "${CUI_IMAGE_PATH}/${_RCC_FILENAME}")
            ecbuild_debug("QRC_NAME=${_QRC_NAME} QRC_FILENAME=${_QRC_FILENAME} RCC_FILENAME=${_RCC_FILENAME}")
            if(METVIEW_QT6)
                QT6_ADD_BINARY_RESOURCES(${_QRC_NAME} "${_QRC_FILE}" DESTINATION "${_RCC_FILE}")
            elseif(METVIEW_QT5)
                QT5_ADD_BINARY_RESOURCES(${_QRC_NAME} "${_QRC_FILE}" DESTINATION "${_RCC_FILE}")
            endif()

            list(APPEND RCC_FILES ${_RCC_FILE})

        endforeach()
    endforeach()

    foreach( _F ${RCC_FILES} )
        # ensure file is installed at install time
        install( FILES ${_F}
                 DESTINATION ${CUI_INSTALL_IMAGE_PATH}
                 PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ)
    endforeach()

    # add necessary files to tarball
    set(_QRC_TEMPLATE_FILES "")
    foreach( _N ${QRC_NAMES} )
        list(APPEND _QRC_TEMPLATE_FILES "${IMAGE_PATH}/${_N}.qrc.in")
    endforeach()
#    ecbuild_info("_QRC_TEMPLATE_FILES=${_QRC_TEMPLATE_FILES}")
    add_files_to_tar("${_QRC_TEMPLATE_FILES}" "share/codes_ui/etc/images")

    foreach (STYLE ${STYLE_NAMES})
        set(_IMAGE_FILES "")
        foreach( _N ${IMAGE_FILE_NAMES} )
            list(APPEND _IMAGE_FILES ${IMAGE_PATH}/${STYLE}/${_N})
        endforeach()
        add_files_to_tar("${_IMAGE_FILES}" "share/codes_ui/etc/images/${STYLE}")
    endforeach()

endif()

#-----------------------------------
# Scripts
#-----------------------------------

#set(CODES_UI_SCRIPT codes_ui)

#set(script_files codes_ui)

foreach( f ${script_files} )

    #configure_file(${f} ${CMAKE_BINARY_DIR}/bin COPYONLY)

    file(COPY ${f}
         DESTINATION ${CMAKE_BINARY_DIR}/bin
         FILE_PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ OWNER_EXECUTE GROUP_EXECUTE
        )

    # ensure file is installed at install time
    install( FILES ${CMAKE_BINARY_DIR}/bin/${f}
             DESTINATION bin
             PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE)

endforeach()

set( grib_handling_pkg eccodes )
# first, if GRIB_API_PATH is not defined, then we need to compute the path
if(NOT GRIB_API_PATH)
    get_property(GRIB_LIB_PATH TARGET ${grib_handling_pkg} PROPERTY LIBRARY_OUTPUT_DIRECTORY)
    if(GRIB_LIB_PATH)         
          set(GRIB_API_PATH ${GRIB_LIB_PATH}/..)
    else()
        if (grib_api_BASE_DIR)
            set(GRIB_API_PATH ${grib_api_BASE_DIR})
        else()
            if(CMAKE_PREFIX_PATH)
                set(GRIB_API_PATH ${CMAKE_PREFIX_PATH})
            endif()
        endif()
    endif()
    ecbuild_info("Computed GRIB_PATH: ${GRIB_API_PATH}")
endif()

set(GRIB_API_LIBRARIES_STR_ORIGINAL "${GRIB_API_LIBRARIES_STR}")       # keep a backup for later

if(GRIB_API_PATH)
    if(EXISTS "${GRIB_API_PATH}/lib")
        set(GRIB_API_LIB_DIR "${GRIB_API_PATH}/lib")
    else()
    endif()

    if(EXISTS "${GRIB_API_PATH}/lib64")
        set(GRIB_API_LIB_DIR "${GRIB_API_PATH}/lib64")
    endif()

    set(GRIB_API_LIBRARIES_STR "-L${GRIB_API_PATH}/lib -L${GRIB_API_PATH}/lib64 -Wl,-rpath,${GRIB_API_PATH}/lib:${GRIB_API_PATH}/lib64 ${GRIB_API_LIBRARIES_STR}")
endif()

foreach (inc ${GRIB_API_INCLUDE_DIRS})
    set(GRIB_API_INCLUDE_DIRS_STR "${GRIB_API_INCLUDE_DIRS_STR} -I${inc}")
endforeach()

# this checks if ECCODES is inside a bundle with us
if(MV_BUNDLE_CONTAINS_ECCODES)
    set(GRIB_API_LIBRARIES_STR    "-L${CMAKE_INSTALL_PREFIX}/lib ${GRIB_API_LIBRARIES_STR_ORIGINAL}")
    set(GRIB_API_INCLUDE_DIRS_STR "-I${CMAKE_INSTALL_PREFIX}/include")
    set(GRIB_API_PATH ${CMAKE_INSTALL_PREFIX})
endif()



# create the Metview startup script
#set(FULL_STARTUP_SCRIPT_PATH ${CMAKE_BINARY_DIR}/bin/${CODES_UI_SCRIPT})

# create the codes_ui startup script
#configure_file(${FULL_STARTUP_SCRIPT_PATH}codes_ui_base.in ${FULL_STARTUP_SCRIPT_PATH} @ONLY)

if(EC_OS_NAME MATCHES "windows")
    set(CODES_UI_ON_WINDOWS "true")
    file(COPY ${WINDOWS_STARTUP_SCRIPT_PATH}
         DESTINATION ${CMAKE_BINARY_DIR}/bin)
    add_files_to_tar(${WINDOWS_STARTUP_SCRIPT_PATH} "scripts")
    install(FILES       ${WINDOWS_STARTUP_SCRIPT_PATH}
            DESTINATION bin
            PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE)
else()
    set(CODES_UI_ON_WINDOWS "false")
endif()

configure_file(${STARTUP_SCRIPT_TEMPLATE_PATH} ${FULL_STARTUP_SCRIPT_PATH} @ONLY)

add_files_to_tar(${STARTUP_SCRIPT_TEMPLATE_PATH} "scripts")


# create a 'production' version of this - just the same, but with
# METVIEW_VERSION=prod instead of dev

set(PROD_TEMPORARY_STARTUP_SCRIPT "${FULL_STARTUP_SCRIPT_PATH}_prod")

add_custom_command(
    OUTPUT  ${PROD_TEMPORARY_STARTUP_SCRIPT}
    COMMAND sed "s/CODES_UI_VERSION=dev/CODES_UI_VERSION=prod/g" ${FULL_STARTUP_SCRIPT_PATH} > ${PROD_TEMPORARY_STARTUP_SCRIPT}
    DEPENDS ${FULL_STARTUP_SCRIPT_PATH}
)

ADD_CUSTOM_TARGET(mvsCUI ALL DEPENDS ${FULL_STARTUP_SCRIPT_PATH} ${PROD_TEMPORARY_STARTUP_SCRIPT})

# when we install, we actually want to install the production script and rename it
install( FILES       ${PROD_TEMPORARY_STARTUP_SCRIPT}
         RENAME      ${CODES_UI_SCRIPT}
         DESTINATION bin # NOT ${MV_BIN_DIR}!
         PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE)


ecbuild_dont_pack(REGEX "*.cc" )
ecbuild_dont_pack(REGEX "*.h" )
ecbuild_dont_pack(REGEX "*.xml" )
ecbuild_dont_pack(REGEX "*.in" )

ecbuild_install_project( NAME codes_ui )

ecbuild_print_summary()

#get_cmake_property(_variableNames VARIABLES)
#foreach (_variableName ${_variableNames})
#    ecbuild_info("${_variableName}=${${_variableName}}")
#endforeach()

