//==============================================================================
//! 
//! \brief Milagm CAPI header (Magm...)
//! 
//! AUTHOR:  Matrox Imaging
//!
//! COPYRIGHT NOTICE:
//! Copyright (c) Matrox Electronic Systems Ltd., 1992-2023.
//! All Rights Reserved 
//  Revision:  10.60.0776
//==============================================================================

#ifndef __MIL_AGM_H__
#define __MIL_AGM_H__

#if (!M_MIL_LITE)

/* C++ directive if needed */
#ifdef __cplusplus
extern "C"
   {
#endif

//==============================================================================
// MagmAlloc/MagmAllocResult Context/ResultTypes
#define M_GLOBAL_EDGE_BASED_TRAIN                 0x00001000L // TBM
#define M_GLOBAL_EDGE_BASED_TRAIN_RESULT          0x00002000L // TBM
#define M_GLOBAL_EDGE_BASED_FIND                  0x00004000L // TBM
#define M_GLOBAL_EDGE_BASED_FIND_RESULT           0x00008000L // TBM

//==============================================================================
// MagmDefine Operations
#define M_ADD                                       0x0000L // already defined in milim.h
#define M_DELETE                                         3L // already defined in mil.h

////////////////////////////////////////////////////////////////////////////////
// MagmControl / MagmInquire
// Context 
#define M_STOP_FIND                                    115L  // already defined in milmod.h
#define M_SMOOTHNESS                                   108L  // already defined in milmod.h
#define M_THRESHOLD_MODE                                33L  // Already defined in miledge.h
#define M_MODEL_PRECISION                             5656L 

#define M_LOW                                            1L  // Already defined in  miledge.h, milcode.h, milmod.h, milocr, milpat.h, mil.h
#define M_MEDIUM                                         2L  // Already defined in  miledge.h, milcode.h, milmod.h, milocr, milpat.h
#define M_HIGH                                           3L  // Already defined in  miledge.h, milcode.h, milmod.h, milocr, milpat.h, mil.h
#define M_VERY_HIGH                                      4L  // Already defined in  miledge.h, milcode.h, milmod.h, milocr, milpat.h


#define M_AUTO                                         444L  // Already defined in mil.h
#define M_USER_DEFINED                                  21L  // Already defined in mil.h
#define M_ENABLE                                     -9997L  // Already defined in mil.h
#define M_DISABLE                                    -9999L  // Already defined in mil.h

#define M_TRUE                                           1L  // Already defined in mil.h, milmeas.h, miledge.h, milmod.h
#define M_FALSE                                          0L  // Already defined in mil.h, milmeas.h, miledge.h, milmod.h

#define M_ACCEPTANCE_DETECTION_SOURCE                 5838L  
#define M_ACCEPTANCE_DETECTION_FROM_TRAIN             5839L  
#define M_ACCEPTANCE_DETECTION                        5840L  
#define M_ACCEPTANCE_FIT                              5841L  
#define M_ACCEPTANCE_COVERAGE                         5842L  
#define M_MAX_ASSOCIATION_DISTANCE                    1503L  // Already defined in milmeas.h

#define M_EDGEL_ANGLE_MODE                            5658L
#define M_SINGLE                                0x01000000L  // Already defined in mil.h
#define M_COMPOSITE                                      1L  // Already defined in mil.h

#define M_MAX_ACCEPTED_OVERLAP                        5661L

#define M_MODEL_IMAGE                                 1019L  // Already defined in milim.h
                                                      
#define M_EDGEL_ANGLE_FACTOR                          5663L
#define M_NUMBER_OF_MODELS                            5664L
#define M_ORIENTATION                           0x00002400L  // Already defined in milmeas.h
#define M_EMPTY_REGIONS_MODE                          5668L
#define M_NO_NEIGHBOR                                 5669L
#define M_USE_EDGELS_MAGNITUDE                        5670L
#define M_NEIGHBOR_TYPE                               5671L
#define M_STABLE_EDGELS_MODE                          5856L  
#define M_SMOOTHNESS_STABLE                           5857L  
#define M_TRAINED_MODEL                               5672L  

#define M_PERSEVERANCE_DETECTION                      5859L  
#define M_MODEL_SOURCE                                5860L  
#define M_USER_IMAGE                                  5861L  
#define M_HAS_USER_MODEL                              5862L  
#define M_FROM_TRAIN                                  5863L  
                                                      
#define M_SMOOTHNESS_SOURCE                           5864L  
#define M_SMOOTHNESS_FROM_TRAIN                       5865L  
#define M_THRESHOLD_MODE_SOURCE                       5866L  
#define M_THRESHOLD_MODE_FROM_TRAIN                   5867L

#define M_STEP_X                                      3971L  // Already defind
#define M_STEP_Y                                      3972L  // Already defind
#define M_CERTAINTY                                    202L  // Already defined in milmod.h
#define M_APPROXIMATION_TOLERANCE                       26L  // already defined

#define M_GENERAL                               0x20000000L  // Already defined in milmod.h
#define M_CONTEXT                               0x08000000L  // Already defined in    milmod.h, milreg.h, milstr.h, milocr.h
#define M_ALL                                   0x40000000L  // Already defined in    milmod.h, milmeas.h, milocr.h,  milpat.h,  mil.h, miledge.h
#define M_DEFAULT                               0x10000000L  // Already defined in    milmod.h, milocr.h,  milcode.h, mil.h, miledge.h

#define M_MODIFICATION_COUNT                          5010L  // Already define in mil.h
#define M_OWNER_SYSTEM                                1101L  // Already define in mil.h

#define M_SIZE_X                                      1536L  // Already in mil.h
#define M_SIZE_Y                                      1537L  // Already in mil.h

#define M_REFERENCE_X                                  100L  // Already defined in milreg.h
#define M_REFERENCE_Y                                  101L  // Already defined in milreg.h

#define M_RESET                                          9L  // Already defined

// Model
#define M_AGM_MODEL_INDEX_FLAG             0x02000000L
#define M_AGM_MODEL_INDEX(IndexValue)      (M_AGM_MODEL_INDEX_FLAG      | (IndexValue))


////////////////////////////////////////////////////////////////////////////////
// MagmGetResult ResultTypes

#define M_STATUS                                0x00008002L // Already defined
#define M_TIMEOUT_REACHED                             2554L // Already defined
#define M_STOPPED_BY_REQUEST                          2555L // Already defined
#define M_NOT_ENOUGH_MEMORY                              4L // Already defined
#define M_COMPLETE                              0x00000000L // Already defined
#define M_INTERNAL_ERROR                                 5L // Already defined
#define M_CURRENTLY_CALCULATING                       2718L // Already defined

#define M_STATUS                                0x00008002L // Already defined

#define M_SCORE_FIT                    2461L    // Already defined in milmod.h
#define M_SCORE_DETECTION              5674L 
#define M_SCORE_COVERAGE               5675L

#define M_SORT_CANDIDATES_SCORE        5868L

////////////////////////////////////////////////////////////////////////////////
// MagmDraw options
#define M_DRAW_IMAGE                    0x00000002L   // Already defined in milmod.h
#define M_DRAW_EDGES                    0x00000004L   // Already defined in milmod.h

#define M_DRAW_BOX                      0x00000020L   // Already defined in milmod.h
#define M_DRAW_POSITION                 0x00000040L   // Already defined in milmod.h
#define M_DRAW_TRAINED_MODEL            0x00000800L
#define M_DRAW_AXIS                     0x00000200L   // Already define in MilBlob.h





// CAPI function prototypes
MIL_ID MFTYPE MagmAlloc(MIL_ID    SysId,
                        MIL_INT64 ContextType,
                        MIL_INT64 ControlFlag,
                        MIL_ID*   ContextIdPtr);

MIL_ID MFTYPE MagmAllocResult(MIL_ID    SysId,
                              MIL_INT64 ResultType,
                              MIL_INT64 ControlFlag,
                              MIL_ID*   AgmResultIdPtr);

MIL_INT64 MFTYPE MagmInquire(MIL_ID    ContextOrResultId,
                             MIL_INT64 Index,
                             MIL_INT64 InquireType,   
                             void*     UserVarPtr);       

MIL_DOUBLE MFTYPE MagmGetResult(MIL_ID    AgmResultId,
                                MIL_INT64 Index,
                                MIL_INT64 AgmResultType,
                                void*     ResultArrayPtr);

void MFTYPE MagmPreprocess(MIL_ID    AgmContextId,
                           MIL_INT64 ControlFlag);

MIL_INT64 MFTYPE MagmDefine(MIL_ID    ContextId,
                            MIL_INT64 Operation,
                            MIL_INT64 SourceType,
                            MIL_INT64 ModelType,
                            MIL_INT64 Param1,
                            MIL_INT64 ControlFlag);

void MFTYPE MagmFind(MIL_ID      AgmContextId,
                     MIL_ID      TargetImageId,
                     MIL_ID      AgmResultId,
                     MIL_INT64   ControlFlag);

void MFTYPE MagmTrain(MIL_ID        TrainContextId,
                      const MIL_ID* ImageArrayPtr,
                      MIL_INT       NumImages,
                      MIL_ID        TrainResultId,
                      MIL_INT64     ControlFlag);

void MFTYPE MagmCopyResult(MIL_ID        SrcTrainResultId,
                           MIL_INT64     SrcIndex,
                           MIL_ID        DstContextId,
                           MIL_INT64     DstIndex,
                           MIL_INT64     CopyType,
                           MIL_INT64     ControlFlag);

void MFTYPE MagmDraw(MIL_ID    ContextGraId,
                     MIL_ID    ContextOrResultAgmId,
                     MIL_ID    DstImageBufOrListGraId,
                     MIL_INT64 Operation,
                     MIL_INT64 Index,
                     MIL_INT64 ControlFlag);

void MFTYPE MagmFree(MIL_ID ContextOrResultAgmId);

#if M_MIL_USE_64BIT
// Prototypes for 64 bits OSs
void MFTYPE MagmControlInt64(MIL_ID     ContextId,
                             MIL_INT64  Index,
                             MIL_INT64  ControlType,
                             MIL_INT64  ControlValue);

void MFTYPE MagmControlDouble(MIL_ID     ContextId,
                              MIL_INT64  Index,
                              MIL_INT64  ControlType,
                              MIL_DOUBLE ControlValue);

#else
// Prototypes for 32 bits OSs
#define MagmControlInt64  MagmControl
#define MagmControlDouble MagmControl

void MFTYPE MagmControl(MIL_ID     ContextId,
                        MIL_INT64  Index,
                        MIL_INT64  ControlType,
                        MIL_DOUBLE ControlValue);
#endif //M_MIL_USE_64BIT


#if M_MIL_USE_UNICODE
void MFTYPE MagmSaveA(MIL_CONST_TEXTA_PTR FileName,
                      MIL_ID              ContextId,
                      MIL_INT64           ControlFlag);

MIL_ID MFTYPE MagmRestoreA(MIL_CONST_TEXTA_PTR FileName,
                           MIL_ID              SysId,
                           MIL_INT64           ControlFlag,
                           MIL_ID*             ContextAgmPtr);

void MFTYPE MagmStreamA(MIL_TEXTA_PTR MemPtrOrFileName,
                        MIL_ID        SysId,
                        MIL_INT64     Operation,
                        MIL_INT64     StreamType,
                        MIL_DOUBLE    Version,
                        MIL_INT64     ControlFlag,
                        MIL_ID*       ContextAgmIdPtr,
                        MIL_INT*      SizeByteVarPtr);

void MFTYPE MagmSaveW(MIL_CONST_TEXTW_PTR FileName,
                      MIL_ID              ContextId,
                      MIL_INT64           ControlFlag);

MIL_ID MFTYPE MagmRestoreW(MIL_CONST_TEXTW_PTR FileName,
                           MIL_ID              SysId,
                           MIL_INT64           ControlFlag,
                           MIL_ID*             ContextAgmPtr);

void MFTYPE MagmStreamW(MIL_TEXTW_PTR MemPtrOrFileName,
                        MIL_ID        SysId,
                        MIL_INT64     Operation,
                        MIL_INT64     StreamType,
                        MIL_DOUBLE    Version,
                        MIL_INT64     ControlFlag,
                        MIL_ID*       ContextAgmIdPtr,
                        MIL_INT*      SizeByteVarPtr);

#if M_MIL_UNICODE_API
#define MagmSave               MagmSaveW
#define MagmRestore            MagmRestoreW
#define MagmStream             MagmStreamW
#else
#define MagmSave               MagmSaveA
#define MagmRestore            MagmRestoreA
#define MagmStream             MagmStreamA
#endif //M_MIL_UNICODE_API

#else

void MFTYPE   MagmSave(MIL_CONST_TEXT_PTR FileName,
                       MIL_ID             ContextId,
                       MIL_INT64          ControlFlag);

MIL_ID MFTYPE MagmRestore(MIL_CONST_TEXT_PTR FileName,
                          MIL_ID             SysId,
                          MIL_INT64          ControlFlag,
                          MIL_ID*            ContextAgmPtr);

void MFTYPE   MagmStream(MIL_TEXT_PTR MemPtrOrFileName,
                         MIL_ID       SysId,
                         MIL_INT64    Operation,
                         MIL_INT64    StreamType,
                         MIL_DOUBLE   Version,
                         MIL_INT64    ControlFlag,
                         MIL_ID*      ContextAgmIdPtr,
                         MIL_INT*     SizeByteVarPtr);

#endif //M_MIL_USE_UNICODE

/* C++ directive if needed */
#ifdef __cplusplus
   }
#endif

//==============================================================================
#ifdef __cplusplus
   inline void MFTYPE MagmStreamCpp(MilStreamParam MemPtrOrFileName,
                                    MIL_ID         SysId,
                                    MIL_INT64      Operation,
                                    MIL_INT64      StreamType,
                                    MIL_DOUBLE     Version,
                                    MIL_INT64      ControlFlag,
                                    MIL_ID*        ContextAgmIdPtr,
                                    MIL_INT*       SizeByteVarPtr)
      {
      MagmStream(MemPtrOrFileName.m_Param, SysId, Operation, StreamType, Version, ControlFlag, ContextAgmIdPtr, SizeByteVarPtr);
      }

#undef  MagmStream
#define MagmStream MagmStreamCpp

#endif // __cplusplus

#if M_MIL_USE_STRING
#if M_MIL_USE_UNICODE
#if M_MIL_UNICODE_API

inline void MFTYPE MagmSaveW(const MIL_STRING& FileName, MIL_ID ContextId, MIL_INT64 ControlFlag)
   {
   return MagmSaveW(FileName.c_str(), ContextId, ControlFlag);
   }

inline MIL_ID MFTYPE MagmRestoreW(const MIL_STRING& FileName, MIL_ID SysId, MIL_INT64 ControlFlag, MIL_ID* ContextAgmPtr)
   {
   return MagmRestoreW(FileName.c_str(), SysId, ControlFlag, ContextAgmPtr);
   }

#else // M_MIL_UNICODE_API
inline void MFTYPE MagmSaveA(const MIL_STRING& FileName, MIL_ID ContextId, MIL_INT64 ControlFlag)
   {
   return MagmSaveA(FileName.c_str(), ContextId, ControlFlag);
   }

inline MIL_ID MFTYPE MagmRestoreA(const MIL_STRING& FileName, MIL_ID SysId, MIL_INT64 ControlFlag, MIL_ID* ContextAgmPtr)
   {
   return MagmRestoreA(FileName.c_str(), SysId, ControlFlag, ContextAgmPtr);
   }

#endif // M_MIL_UNICODE_API

#else // M_MIL_USE_UNICODE
inline void MFTYPE MagmSave(const MIL_STRING& FileName, MIL_ID ContextId, MIL_INT64 ControlFlag)
   {
   return MagmSave(FileName.c_str(), ContextId, ControlFlag);
   }

inline MIL_ID MFTYPE MagmRestore(const MIL_STRING& FileName, MIL_ID SysId, MIL_INT64 ControlFlag, MIL_ID* ContextAgmPtr)
   {
   return MagmRestore(FileName.c_str(), SysId, ControlFlag, ContextAgmPtr);
   }
#endif // M_MIL_USE_UNICODE

#endif // M_MIL_USE_STRING



#if M_MIL_USE_64BIT
#ifdef __cplusplus

//////////////////////////////////////////////////////////////
// MagmControl function overloads when compiling c++ files
//////////////////////////////////////////////////////////////
inline void MagmControl(MIL_ID ContextId, MIL_INT64 Index, MIL_INT64 ControlType, float ControlValue)
   {
   MagmControlDouble(ContextId, Index, ControlType, ControlValue);
   }

inline void MagmControl(MIL_ID ContextId, MIL_INT64 Index, MIL_INT64 ControlType, MIL_DOUBLE ControlValue)
   {
   MagmControlDouble(ContextId, Index, ControlType, ControlValue);
   }

#if M_MIL_USE_MIL_UNIQUE_ID
// Overload for applicable MIL_UNIQUE_..._IDs.
inline void MagmControl(MIL_ID ContextId, MIL_INT64 Index, MIL_INT64 ControlType, const MIL_UNIQUE_BUF_ID& ControlValue)
   {
   MagmControlInt64(ContextId, Index, ControlType, ControlValue.get());
   }
#endif

template <typename T>
inline void MagmControl(MIL_ID ContextId, MIL_INT64 Index, MIL_INT64 ControlType, T* ControlValue)
   {
   MagmControlInt64(ContextId, Index, ControlType, M_PTR_TO_MIL_INT(ControlValue));
   }

template <typename T>
inline void MagmControl(MIL_ID ContextId, MIL_INT64 Index, MIL_INT64 ControlType, T ControlValue)
   {
   MagmControlInt64(ContextId, Index, ControlType, (MIL_INT64) ControlValue);
   }

#else // __cplusplus

//////////////////////////////////////////////////////////////
// For C file, call the default function, i.e. Double one
//////////////////////////////////////////////////////////////
#define MagmControl            MagmControlDouble

#endif // __cplusplus
#endif // M_MIL_USE_64BIT


//==============================================================================
// MIL_UNIQUE_ID support

#if M_MIL_USE_MIL_UNIQUE_ID

#if M_MIL_USE_SAFE_TYPE
template <> inline bool MilIsCorrectObjectType<&MagmFree>(MIL_INT64 ObjectType)
   {
   return (ObjectType & ~M_USER_DEFINE_LOW_ATTRIBUTE) == M_AGM_OBJECT;
   }
#endif

typedef MIL_UNIQUE_ID<&MagmFree> MIL_UNIQUE_AGM_ID;

#if M_MIL_USE_MOVE_SEMANTICS

inline MIL_UNIQUE_AGM_ID MagmAlloc(MIL_ID SysId, MIL_INT64 ObjectType, MIL_INT64 InitFlag, MIL_UNIQUE_ID_TAG)
   {
   return MIL_UNIQUE_AGM_ID(MagmAlloc(SysId, ObjectType, InitFlag, M_NULL));
   }

inline MIL_UNIQUE_AGM_ID MagmAllocResult(MIL_ID SysId, MIL_INT64 AgmResultType, MIL_INT64 ControlFlag, MIL_UNIQUE_ID_TAG)
   {
   return MIL_UNIQUE_AGM_ID(MagmAllocResult(SysId, AgmResultType, ControlFlag, M_NULL));
   }

inline MIL_UNIQUE_AGM_ID MagmRestore(MIL_CONST_TEXT_PTR FileName, MIL_ID SysId, MIL_INT64 ControlFlag, MIL_UNIQUE_ID_TAG)
   {
   return MIL_UNIQUE_AGM_ID(MagmRestore(FileName, SysId, ControlFlag, M_NULL));
   }

#if M_MIL_USE_STRING
inline MIL_UNIQUE_AGM_ID MagmRestore(const MIL_STRING& FileName, MIL_ID SysId, MIL_INT64 ControlFlag, MIL_UNIQUE_ID_TAG)
   {
   return MIL_UNIQUE_AGM_ID(MagmRestore(FileName.c_str(), SysId, ControlFlag, M_NULL));
   }
#endif // M_MIL_USE_STRING

template <MilFreeFuncType FreeFunc> inline void MagmFree(const MIL_UNIQUE_ID<FreeFunc>&) = delete;

inline void MagmStream(MilStreamParam       MemPtrOrFileName,
                       MIL_ID               SysId,
                       MIL_INT64            Operation,
                       MIL_INT64            StreamType,
                       MIL_DOUBLE           Version,
                       MIL_INT64            ControlFlag,
                       MIL_UNIQUE_AGM_ID*   ContextAgmIdPtr,
                       MIL_INT*             SizeByteVarPtr)
   {
   MxxxStreamForMilUniqueId(MemPtrOrFileName, SysId, Operation, StreamType, Version, ControlFlag, ContextAgmIdPtr, SizeByteVarPtr, MagmStream);
   }

inline void MagmTrain(MIL_ID                     TrainContextId,
                      MilConstArrayIdParam       ImageArrayPtr,
                      MIL_INT                    NumImages,
                      MIL_ID                     TrainResultId,
                      MIL_INT64                  ControlFlag)
   {
   MagmTrain(TrainContextId,
             ImageArrayPtr.m_IdArrayPtr,
             NumImages,
             TrainResultId,
             ControlFlag);
   }

#endif // M_MIL_USE_MOVE_SEMANTICS
#endif // M_MIL_USE_MIL_UNIQUE_ID

// End of MIL_UNIQUE_ID support
//=====================================================

#if M_MIL_USE_SAFE_TYPE


// -------------------------------------------------------------------------
// MagmGetResult safe type definitions
inline MIL_DOUBLE MagmGetResultSafeType(MIL_ID AgmResultId, MIL_INT64 Index, MIL_INT64 AgmResultType, MilVoidPtr ResultArrayPtr)
   {
   MIL_INT64 RequiredParamType = M_PARAM_TYPE_MIL_INT64;
   if((AgmResultType & M_DATA_TYPE_MASK) == 0)
      {
      MagmGetResult(AgmResultId, Index, AgmResultType | M_DEFAULT_DATA_TYPE, &RequiredParamType);
      }
   if(!MfuncPointerIsCompatible(RequiredParamType, ResultArrayPtr.Type, AgmResultType))
      {
      SafeTypeError(MIL_TEXT("MagmGetResult"));
      }
   return MagmGetResult(AgmResultId, Index, AgmResultType, ResultArrayPtr.Ptr);
   }

// -------------------------------------------------------------------------
// MagmGetResult Unsafe type definitions
inline MIL_DOUBLE MagmGetResultUnsafe(MIL_ID AgmResultId, MIL_INT64 Index, MIL_INT64 AgmResultType, void* ResultArrayPtr)
   {
   return MagmGetResult(AgmResultId, Index, AgmResultType, ResultArrayPtr);
   }

// ----------------------------------------------------------
// MagmInquire safe type definitions

inline MIL_INT64 MFTYPE MagmInquireSafeType(MIL_ID ContextOrResultId, MIL_INT64 Index, MIL_INT64 InquireType, MilVoidPtr UserVarPtr)
   {
   MIL_INT64 RequiredParamType = M_PARAM_TYPE_MIL_INT64;
   if((InquireType & M_DATA_TYPE_MASK) == 0)
      {
      MagmInquire(ContextOrResultId, Index, InquireType | M_DEFAULT_DATA_TYPE, &RequiredParamType);
      }
   if(!MfuncPointerIsCompatible(RequiredParamType, UserVarPtr.Type, InquireType))
      {
      SafeTypeError(MIL_TEXT("MagmInquire"));
      }
   return MagmInquire(ContextOrResultId, Index, InquireType, UserVarPtr.Ptr);
   }

inline MIL_INT64 MFTYPE MagmInquireUnsafe(MIL_ID ContextOrResultId, MIL_INT64 Index, MIL_INT64 InquireType, void* UserVarPtr)
   {
   return MagmInquire(ContextOrResultId, Index, InquireType, UserVarPtr);
   }

//------------------------------
// Safetype functions assignment

#define MagmGetResult            MagmGetResultSafeType
#define MagmInquire              MagmInquireSafeType


#else // #if M_MIL_USE_SAFE_TYPE

#define MagmGetResultUnsafe       MagmGetResult
#define MagmInquireUnsafe         MagmInquire

#endif // #if M_MIL_USE_SAFE_TYPE

// ----------------------------------------------------------
// Overload for std::vector.
#if defined(M_MIL_USE_VECTOR) && M_MIL_USE_VECTOR


template <typename UserType>
inline MIL_DOUBLE MFTYPE MagmGetResult(MIL_ID AgmResultId, MIL_INT64 Index, MIL_INT64  AgmResultType, std::vector<UserType> &ResultArrayPtr)
   {
   //! If the given MIL data type is not the same as the SrcType, change it to the correct one
   //! and give a warning.
   MIL_INT64 InternalTrueDataTypeForStdVector = MilTraits<UserType>::TypeFlag;

#if M_MIL_USE_SAFE_TYPE
   if(M_GET_HLVLDATATYPE(AgmResultType) != 0)
      {
      SafeTypeError(MIL_TEXT("MagmGetResult"), MIL_TEXT("Combination value for the required data type is not supported with std::vector overload."));
      }
#endif

   AgmResultType = M_STRIP_HLVLDATATYPE(AgmResultType) + InternalTrueDataTypeForStdVector;

   MIL_INT InternalNumberOfElementsForStdVector = 0;
   MagmGetResult(AgmResultId, Index, M_STRIP_HLVLDATATYPE(AgmResultType) + M_NB_ELEMENTS + M_TYPE_MIL_INT, &InternalNumberOfElementsForStdVector);

   ResultArrayPtr.resize(InternalNumberOfElementsForStdVector);

   if(InternalNumberOfElementsForStdVector > 0)
      {
      return MagmGetResult(AgmResultId, Index, AgmResultType, &ResultArrayPtr[0]);
      }

   return 0;
   }

template <typename UserType>
inline MIL_INT64 MFTYPE MagmInquire(MIL_ID ContextOrResultId, MIL_INT64 Index, MIL_INT64  InquireType, std::vector<UserType> &UserVarPtr)
   {
   // If the given MIL data type is not the same as the SrcType, change it to the correct one
   // and give a warning.
   MIL_INT64 InternalTrueDataTypeForStdVector = MilTraits<UserType>::TypeFlag;

#if M_MIL_USE_SAFE_TYPE
   if(M_GET_HLVLDATATYPE(InquireType) != 0)
      {
      SafeTypeError(MIL_TEXT("MagmInquire"), MIL_TEXT("Combination value for the required data type is not supported with std::vector overload."));
      }
#endif

   InquireType = M_STRIP_HLVLDATATYPE(InquireType) + InternalTrueDataTypeForStdVector;

   MIL_INT InternalNumberOfElementsForStdVector = 0;
   MagmInquire(ContextOrResultId, Index, M_STRIP_HLVLDATATYPE(InquireType) + M_NB_ELEMENTS + M_TYPE_MIL_INT, &InternalNumberOfElementsForStdVector);

   UserVarPtr.resize(InternalNumberOfElementsForStdVector);

   if(InternalNumberOfElementsForStdVector > 0)
      {
      return MagmInquire(ContextOrResultId, Index, InquireType, &UserVarPtr[0]);
      }
   return 0;
   }

//=======================================================================================
inline void MFTYPE MagmTrain(MIL_ID                     TrainContextId,
                             const std::vector<MIL_ID>& ImageVector,
                             MIL_INT                    NumImages,
                             MIL_ID                     TrainResultId,
                             MIL_INT64                  ControlFlag)
   {
   MIL_INT ImageVectorSize = static_cast<MIL_INT>(ImageVector.size());
#if M_MIL_USE_SAFE_TYPE
   if((NumImages > ImageVectorSize) && (NumImages != M_DEFAULT))
      {
      SafeTypeError(MIL_TEXT("MagmTrain"), MIL_TEXT("NumImages parameter must be smaller or equal (M_DEFAULT) to the size of input vector."));
      }
   if(NumImages < 0)
      {
      SafeTypeError(MIL_TEXT("MagmTrain"), MIL_TEXT("NumImages parameter must be positive."));
      }
#endif

   MIL_INT SafeNumImages = NumImages;
   if((NumImages > ImageVectorSize) || (NumImages == M_DEFAULT))
      {
      SafeNumImages = ImageVectorSize;
      }
   else if(NumImages < 0)
      {
      SafeNumImages = 0;
      }

   MagmTrain(TrainContextId,
             ImageVector.empty() ? nullptr : &ImageVector[0],
             SafeNumImages,
             TrainResultId,
             ControlFlag);
   }

// ----------------------------------------------------------
// Overloads for std::vector in MxxxStream.
inline void MFTYPE MagmStream(std::vector<MIL_UINT8> &MemPtrOrFileName,
                              MIL_ID                 SysId,
                              MIL_INT64              Operation,
                              MIL_INT64              StreamType,
                              MIL_DOUBLE             Version,
                              MIL_INT64              ControlFlag,
                              MIL_ID*                ContextAgmIdPtr,
                              MIL_INT*               SizeByteVarPtr)
   {
   MxxxStreamForStdVector(MemPtrOrFileName,
                          SysId,
                          Operation,
                          StreamType,
                          Version,
                          ControlFlag,
                          ContextAgmIdPtr,
                          SizeByteVarPtr,
                          MagmStream);
   }

#endif // defined(M_MIL_USE_VECTOR) && M_MIL_USE_VECTOR



#endif // !M_MIL_LITE
#endif // __MIL_AGM_H__
