SET(HEADERS "")
SET(SOURCES "")

#
# Package-specific configuration options
#

# access explicit instantiation
SET(BDIR ${CMAKE_CURRENT_BINARY_DIR})
IF(${PACKAGE_NAME}_ENABLE_EXPLICIT_INSTANTIATION)
  TRIBITS_INCLUDE_DIRECTORIES(${BDIR}/)
  APPEND_GLOB(HEADERS ${BDIR}/MueLu_ExplicitInstantiation.hpp)
ENDIF()

ASSERT_DEFINED(Tpetra_INST_INT_INT)
#
# Belos
#
IF (${PACKAGE_NAME}_ENABLE_Belos)

  TRIBITS_INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/belos)

  APPEND_SET(HEADERS
    belos/BelosXpetraStatusTestGenResSubNorm.hpp
    belos/BelosMueLuAdapter.hpp
    )

ENDIF()

#
# Epetra
#
IF (${PACKAGE_NAME}_ENABLE_Epetra)

  TRIBITS_INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/epetra)
  TRIBITS_SET_AND_INC_DIRS(DIR ${CMAKE_CURRENT_SOURCE_DIR}/aztecoo)

  APPEND_SET(HEADERS
    epetra/MueLu_EpetraOperator.hpp
    epetra/MueLu_CreateEpetraPreconditioner.hpp
    aztecoo/MueLu_AztecEpetraOperator.hpp
    )

  APPEND_SET(SOURCES
    epetra/MueLu_EpetraOperator.cpp
    epetra/MueLu_CreateEpetraPreconditioner.cpp
    aztecoo/MueLu_AztecEpetraOperator.cpp
    )

ENDIF()

#
# Tpetra
#
TRIBITS_SET_AND_INC_DIRS(DIR ${CMAKE_CURRENT_SOURCE_DIR}/tpetra)

APPEND_SET(HEADERS
  tpetra/MueLu_CreateTpetraPreconditioner.hpp
  tpetra/MueLu_TpetraOperator_decl.hpp
  tpetra/MueLu_TpetraOperator_def.hpp
  tpetra/MueLu_TpetraOperatorAsRowMatrix.hpp
)

IF (${PACKAGE_NAME}_ENABLE_Belos AND ${PACKAGE_NAME}_ENABLE_Ifpack2 AND Tpetra_INST_INT_INT AND ${PACKAGE_NAME}_ENABLE_Experimental)

  APPEND_SET(HEADERS
    tpetra/MueLu_ShiftedLaplacian_decl.hpp
    tpetra/MueLu_ShiftedLaplacian_def.hpp
    tpetra/MueLu_ShiftedLaplacianOperator_decl.hpp
    tpetra/MueLu_ShiftedLaplacianOperator_def.hpp
  )

ENDIF()

# TAW 1/20/2016
# it seems that the *.hpp files are automatically generated
# out of the *_decl.hpp and *_def.hpp files. So we do not have
# to call the CREATE_CLIENT_TEMPLATE_HEADERS routine again
#### TRILINOS_CREATE_CLIENT_TEMPLATE_HEADERS(${DIR})

#
# Stratimikos
#
IF (${PACKAGE_NAME}_ENABLE_Stratimikos)
  TRIBITS_SET_AND_INC_DIRS(DIR ${CMAKE_CURRENT_SOURCE_DIR}/stratimikos)

  APPEND_SET(SOURCES
    ${DIR}/Stratimikos_MueLuHelpers.cpp
    )

  # TAW 1/20/2016
  # The *.hpp filse should be autogenerated by the CREATE_CLIENT_TEMPLATE_HEADERS
  # call, but we need them already for compilation. Therefore we include them directly.
  APPEND_SET(HEADERS
    ${DIR}/Stratimikos_MueLuHelpers.hpp
    ${DIR}/Thyra_MueLuPreconditionerFactory_decl.hpp
    ${DIR}/Thyra_MueLuPreconditionerFactory_def.hpp
    ${DIR}/Thyra_MueLuPreconditionerFactory.hpp
    ${DIR}/Thyra_MueLuRefMaxwellPreconditionerFactory_decl.hpp
    ${DIR}/Thyra_MueLuRefMaxwellPreconditionerFactory_def.hpp
    ${DIR}/Thyra_MueLuRefMaxwellPreconditionerFactory.hpp
    ${DIR}/Thyra_MueLuMaxwell1PreconditionerFactory_decl.hpp
    ${DIR}/Thyra_MueLuMaxwell1PreconditionerFactory_def.hpp
    ${DIR}/Thyra_MueLuMaxwell1PreconditionerFactory.hpp
    ${DIR}/Thyra_XpetraLinearOp_decl.hpp
    ${DIR}/Thyra_XpetraLinearOp_def.hpp
    ${DIR}/Thyra_XpetraLinearOp.hpp
    ${DIR}/Xpetra_ThyraLinearOp.hpp
    )

  # Tpetra specific extensions
  IF (${PACKAGE_NAME}_ENABLE_Stratimikos AND ${PACKAGE_NAME}_ENABLE_ThyraTpetraAdapters)
    TRIBITS_SET_AND_INC_DIRS(DIR ${CMAKE_CURRENT_SOURCE_DIR}/stratimikos)
    IF (${PACKAGE_NAME}_ENABLE_Teko AND ${PACKAGE_NAME}_ENABLE_Experimental)
      TRIBITS_INCLUDE_DIRECTORIES(${DIR}/../../research/q2q1)
      APPEND_SET(HEADERS
        ${DIR}/Thyra_MueLuTpetraQ2Q1PreconditionerFactory_decl.hpp
        ${DIR}/Thyra_MueLuTpetraQ2Q1PreconditionerFactory_def.hpp
        ${DIR}/Thyra_MueLuTpetraQ2Q1PreconditionerFactory.hpp
        )
    ENDIF()
  ENDIF()
ENDIF()

IF (${PACKAGE_NAME}_ENABLE_AmgX)

  TRIBITS_SET_AND_INC_DIRS(DIR ${CMAKE_CURRENT_SOURCE_DIR}/amgx)

  APPEND_GLOB(HEADERS ${DIR}/*.hpp)
  APPEND_GLOB(SOURCES ${DIR}/*.cpp)

   # TAW 1/20/2016
   # it seems that the *.hpp files are automatically generated
   # out of the *_decl.hpp and *_def.hpp files. So we do not have
   # to call the CREATE_CLIENT_TEMPLATE_HEADERS routine again
   # #TRILINOS_CREATE_CLIENT_TEMPLATE_HEADERS(${DIR})

ENDIF()

###################################################
## TAW: 9/22/15
## CMake-based ETI system inspired by Ifpack2 ETI
## - no support for KokkosClassic
## - ETI system for muelu-adapters only
## - The ETI system of MueLu is not touched!
###################################################

# Function to generate ETI (explicit template instantiation) files
# from a template and list of class names
FUNCTION(MUELUADAPTERS_PROCESS_ETI_TEMPLATE ETI_CLASSES TEMPLATE_FILE PROCESSED_FILE SOURCES_LIST)
  SET(SRCS "")
  FOREACH(CLASS ${ETI_CLASSES})
    string(REPLACE "::" "_" CLASS_FILE_NAME "${CLASS}")
    string(TOUPPER "${CLASS_FILE_NAME}" UPPER_CASE_CLASS)
    string(REPLACE "CLASS_FILE_NAME" "${CLASS_FILE_NAME}" FINAL_FILE_NAME "${PROCESSED_FILE}")
    CONFIGURE_FILE(${TEMPLATE_FILE} ${FINAL_FILE_NAME})
    SET(SRCS ${SRCS} ${FINAL_FILE_NAME})
  ENDFOREACH()
  SET(${SOURCES_LIST} ${SRCS} PARENT_SCOPE)
ENDFUNCTION(MUELUADAPTERS_PROCESS_ETI_TEMPLATE)

SET(MUELUADAPTERS_ETI_CPP_SOURCES "")
IF(${PACKAGE_NAME}_ENABLE_EXPLICIT_INSTANTIATION)
  # Set the list of classes in MueLu adapters that are templated
  # on <Scalar, LO, GO, Node> for which we want to do ETI using this system.
  GLOBAL_SET(MUELUADAPTERS_ETI_CLASSES  )
  IF (${PACKAGE_NAME}_ENABLE_Stratimikos)
    APPEND_GLOBAL_SET(MUELUADAPTERS_ETI_CLASSES
      Thyra::MueLuPreconditionerFactory
      Thyra::XpetraLinearOp
    )
  ENDIF()
  IF (${PACKAGE_NAME}_ENABLE_AmgX)
    APPEND_GLOBAL_SET(MUELUADAPTERS_ETI_CLASSES
      MueLu::AMGXOperator
    )
  ENDIF()

  # Set the list of classes in MueLu adapters that are templated on <LO, GO, Node> for
  # which we want to do ETI using this system.
  GLOBAL_SET(MUELUADAPTERS_ETI_LO_GO_CLASSES
  )

  MUELUADAPTERS_PROCESS_ETI_TEMPLATE(
    "${MUELUADAPTERS_ETI_CLASSES}"
    ExplicitInstantiation/MueLu_ETI_SC_LO_GO.tmpl
    "ExplicitInstantiation/CLASS_FILE_NAME.cpp"
    MueLuAdapters_SRCS)
  LIST(APPEND MUELUADAPTERS_ETI_CPP_SOURCES ${MueLuAdapters_SRCS})
  MUELUADAPTERS_PROCESS_ETI_TEMPLATE(
    "${MUELUADAPTERS_ETI_LO_GO_CLASSES}"
    ExplicitInstantiation/MueLu_ETI_LO_GO.tmpl
    "ExplicitInstantiation/CLASS_FILE_NAME.cpp"
    MueLuAdapters_SRCS)
  LIST(APPEND MUELUADAPTERS_ETI_CPP_SOURCES ${MueLuAdapters_SRCS})

  # add only automatically generated ETI cpp files
  APPEND_SET(SOURCES ${MUELUADAPTERS_ETI_CPP_SOURCES})
ENDIF()

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

# Must glob the binary dir last to get all of the auto-generated headers
TRIBITS_SET_AND_INC_DIRS(DIR ${CMAKE_CURRENT_BINARY_DIR})
APPEND_GLOB(HEADERS ${DIR}/*.hpp)
APPEND_GLOB(SOURCES ${DIR}/*.cpp)

IF ("${SOURCES}" STREQUAL "")
  # always include at least one file in the adapters library.
  TRIBITS_SET_AND_INC_DIRS(DIR ${CMAKE_CURRENT_SOURCE_DIR})
  APPEND_GLOB(SOURCES ${DIR}/muelu-trivial-adapter.cpp)
ENDIF()
TRIBITS_ADD_LIBRARY(
  muelu-adapters
  HEADERS ${HEADERS}
  SOURCES ${SOURCES}
  DEPLIBS muelu
  ADDED_LIB_TARGET_NAME_OUT MUELU_ADAPTERS_LIBNAME
  )

# Set linker language explicitly for CUDA builds.
set_target_properties(
  ${MUELU_ADAPTERS_LIBNAME}
  PROPERTIES LINKER_LANGUAGE CXX
  )
