#ifndef NFM_BASE_EXTENDED_CLASS_H
#define NFM_BASE_EXTENDED_CLASS_H
    #include "app/nfm/nfm_base.h"
    typedef struct
    {
        NFMClass_t public;
        
        struct 
        {
            struct
            {
                // device class constructor
                void (* classInit)( void );

                // Get model name (description) by DeviceID
              /*const char * (* getModelNameById)( uint16_t deviceId );*/
                            
                // Get model name (description)
                const char * (* getModelName)();            
                
                // Get device id
                bool (* getModelId)( uint16_t * pDeviceId );
                
                struct
                {
                      bool                       ( * setProtect      )( bool desiredStatus );
                      bool                       ( * getProtect      )( );
                      const sEcalHeader_t *      ( * getCommonHeader )( uint8_t * buffer, size_t size );
                      const sEcalDataHeader_t *  ( * getDataHeader   )( eChrz_t tableId, uint8_t * buffer, size_t size );
                      const sEcalTCompHeader_t * ( * getTCompHeader  )( uint8_t * buffer, size_t size );
                      
                      size_t                     ( * getChrzTableIndex)(ePortComb_t portCombination, ePortStateId_t portState );
                      size_t                     ( * getTCompTableIndex)(ePortComb_t portCombination, ePortStateId_t portState );
                      
                      // getChrzTableHeader = NFM_ROM_ReadChrzTableHeader
                      size_t                     ( * getChrzTableHeader)( eChrz_t sectorId,
                                                                          ePortComb_t portCombination, 
                                                                          ePortStateId_t portState,
                                                                          size_t nPoints,
                                                                          sEcalChrzTableHeader_t * pHeader,
                                                                          unsigned int * pErrCode
                                                                        );
                      
                      size_t                     ( * getChrzPoints)( /*const*/ sNFMGetPoints_t * pContext );
                      
                      size_t                     ( * getTCompMagnTableHeader)( 
                                                                          ePortComb_t portCombination, 
                                                                          ePortStateId_t portState,
                                                                          size_t nPoints,
                                                                          sEcalTCompTableMagnHeader_t * pHeader,
                                                                          unsigned int * pErrCode
                                                                          );
                      
                      size_t                     ( * getTCompPhaseTableHeader)( 
                                                                          ePortComb_t portCombination, 
                                                                          ePortStateId_t portState,
                                                                          size_t nPoints,
                                                                          sEcalTCompTablePhaseHeader_t * pHeader,
                                                                          unsigned int * pErrCode
                                                                          );
                      
                      size_t                     ( * getTCompMagnPoints)( /*const*/ sNFMGetPoints_t * pContext );
                      size_t                     ( * getTCompPhasePoints)( /*const*/ sNFMGetPoints_t * pContext );
                      
                      size_t                     ( * setSettingsBlock)( 
                                                                          uint8_t * buffer, 
                                                                          size_t nOffset,
                                                                          size_t nBytesToWrite );

                      size_t                     ( * getSettingsBlock)( 
                                                                          uint8_t * buffer,
                                                                          size_t nOffset, 
                                                                          size_t nBytesToRead );

                      size_t                     ( * getSettingsBlockSize)();
                      
                      bool                       ( * validateSettings )();

                }
                memory;
            }
            methods;
            
            struct
            {  
              // Device Model ID
                uint16_t deviceId; 
                
                // Device Model Profile
                const sNFMModel_t * modelProfile;
                
                // Memory profile
                const sSwitchMemoryProfile_t * memProfile;
            }
            properties;
        }
        private;
    }
    NFMClassEx_t;

    // sNFMGetFreqPoints_t
    // Control structure to retieve the frequency points
    typedef struct
    {
          double    Fdesc;                // Frequency discrette
          sEcalSegment_t Segment;         // segment data
          uint16_t  nSegments;            // number of segments

          size_t    BufferCapacity;       // user buffer capacity [pDataArray]
          double *  pDataArray;           // Pointer to the buffer to store frequency points

          uint16_t  nStartPoint;          // Starting point
          uint16_t  nStartSegment;        // Starting segment
          
          // make to take 32-bit
          union                           
          {
          struct
          {
          eChrz_t   tableId;              // characterization id
          eChrzScaleType_t scaleType;     // scale type
          };
          uint32_t  reserved0_for_make_u32; 
          };
    }
    sNFMGetFreqPoints_t;
    
    // sSWGetTablePoints_t
    // Control structure to retieve the table points
    typedef struct
    {
          size_t    BufferCapacity;       // user buffer capacity [pDataArray]
          sSWTablePoint_t *  pDataArray;  // Pointer to the buffer to store table points

          uint16_t  nStartPoint;          // Starting point
          uint16_t  nNumberOfPoints;      // Number of table points
          sTableTablePoint_t TablePoint;  //Current readed point value
          
          // make to take 32-bit
          union                           
          {
          struct
          {
          eChrz_t   tableId;              // characterization id
          };
          uint32_t  reserved0_for_make_u32; 
          };
    }
    sSWGetTablePoints_t;

    // sNFMGetPointsSimplified_t
    // Control structure to retieve the data points
    typedef struct
    {
          size_t    BufferCapacity;       // user buffer capacity [pDataArray]
          sNFMGetPoints_t intCtx;

          // make to take 32-bit
          union                           
          {
          struct
          {
          eChrz_t         sectorId;
          ePortComb_t     portComb;
          ePortStateId_t  portState;
          uint8_t         isThermoPhase;  // only for NFMGetPointsThermo_Begin: 0 - magnitue, 1 - phase
          };
          uint32_t  reserved0_for_make_u32; 
          };
    }
    sNFMGetPointsSimplified_t;
#endif
