//
//  Copyright © 2001 - 2002, RESON Inc. All Rights Reserved.
//
//  No part of this file may be reproduced or transmitted in any form or by
//  any means, electronic or mechanical, including photocopy, recording, or
//  information storage or retrieval system, without permission in writing
//  from RESON Inc.
//
//  Filename:   7kFileHeader.h
//
//  Project:    6046.
//
//  Author(s):  W. Arcus
//
//  Purpose:    Defines a helper class to decode and encode 7k data records pertaining
//              to record type #7200 "7k File Header" (viz. ICD v0.37 and later).
//
//  Notes:      1)  The reserved field of the RTH is undocumented (here) and may be used for internal
//                  RESON purposes to signal whether the file is open or closed and used to assist with
//                  recovery purposes.
//                  Specifically, it is an unsigned short flag (u16) indicating whether the file is open( 1 )
//                  or closed (0).

#if !defined(AFX_7KFILEHEADER_H__602F5B47_0F11_4560_916A_C990CDD76A9C__INCLUDED_)
#define AFX_7KFILEHEADER_H__602F5B47_0F11_4560_916A_C990CDD76A9C__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "7kProtocol.h"
#include "SystemTime.h"

class EXPORT_DLL C7kFileHeader : public C7kProtocol  
{
public:

#pragma pack( push, FILEHEADER7K_H_PACK, 1 )

    typedef struct tagRECORDTYPEHEADER
    {
        BYTE            m_byRecordId                [ 16 ];     // RESON file identifier: GUID value of 0xF3302F43CFB04d6fA93E2AEC33DF577D
        unsigned short  m_unFormatVersion;                      // File format version number (1 – N).
        BYTE            m_byReserved                [ 2  ];     // Reserved - see also note 1 at top of this file.
        BYTE            m_bySessionId               [ 16 ];     // Session identifier; a user defined session identifier. Used to associate multiple files for a given session.
        unsigned long   m_ulRecordDataSize;                     // Size of record data to follow. 0 if not present.
        unsigned long   m_ulNumberOfSubsystem;                  // Number of subsystems. 0 if not set.

        tagRECORDTYPEHEADER( void )
        {
            ::memset( this, 0x00, tagRECORDTYPEHEADER::Size() );
        }

        static size_t Size( void )
        {
            return sizeof( struct tagRECORDTYPEHEADER );
        }
    }
    RECORDTYPEHEADER, *PRECORDTYPEHEADER;

    typedef struct tagRECORDDATAHEADER
    {
        char            m_szRecordingProgramName    [ 64 ];     // Recording program name as a null terminated US-ASCII string.
        char            m_szRecordingProgramVersion [ 16 ];     // Recording program version number as a null terminated US-ASCII string.
        char            m_szUserDefinedName         [ 64 ];     // User defined name as a null terminated US-ASCII string.
        char            m_szNotes                   [ 128 ];    // User notes as a null terminated US-ASCII string.

        tagRECORDDATAHEADER( void )
        {
            ::memset( this, 0x00, tagRECORDDATAHEADER::Size() );
        }

        static size_t Size( void )
        {
            return sizeof( struct tagRECORDDATAHEADER );
        }
    }
    RECORDDATAHEADER, *PRECORDDATAHEADER;

    typedef struct tagSUBSYSTEMENTRY
    {
        unsigned long   m_ulDeviceId;                           // Device Identifier    -- for record type of embedded data. 
        unsigned short  m_unSubsystemEnumerator;                // System enumerator    -- identifier for the device subsystem.

        tagSUBSYSTEMENTRY( void )
        {
            ::memset( this, 0x00, tagSUBSYSTEMENTRY::Size() );
        }

        static size_t Size( void )
        {
            return sizeof( struct tagSUBSYSTEMENTRY );
        }
    }
    SUBSYSTEMENTRY, *PSUBSYSTEMENTRY;

#pragma pack( pop, FILEHEADER7K_H_PACK )

                        C7kFileHeader                   (   void );
    virtual            ~C7kFileHeader                   (   void );

    // Decoding.

    bool                Decode                          (   PBYTE                   pbyStream,
                                                            const unsigned long    &rulTotalBytes,
                                                            const bool             &rbUseChecksum,
                                                            PRECORDTYPEHEADER      &rpsRecordTypeHeader,
                                                            PRECORDDATAHEADER      &rpsRecordDataHeader,
                                                            PSUBSYSTEMENTRY        &rpsSystemEntryTable );
    // Encoding.

    bool                Encode                          (   const unsigned long    &rulNumberOfSubsystems,
                                                            const PSUBSYSTEMENTRY   psSubsystemEntryTable,
                                                            const bool             &rbUseCheckSum          = false,
                                                            const unsigned short   &runFormatVersion       = 1,
                                                            const unsigned long    &rulSessionId           = 0,
                                                            LPCTSTR                 lpszProgramName        = NULL,
                                                            LPCTSTR                 lpszProgramVersion     = NULL,
                                                            LPCTSTR                 lpszUserName           = NULL,
                                                            LPCTSTR                 lpszNotes              = NULL,
                                                            const TIME7K           *ps7kTime               = NULL );

    // Record access members.

    operator            BYTE *                          (   void )  const;                                  // Entire 7k record.
    operator            unsigned long                   (   void )  const;                                  // Size in bytes of entire record.

    static
    void                SetString                       (   LPTSTR                  lpszDestination,
                                                            LPCTSTR                 lpszSource,
                                                            const int              &riMaxSize );

private:

    ///////////////
    // Attributes.

    const unsigned long m_ulRecordHeaderSize;
    const unsigned long m_ulRecordType;

    ///////////////
    // Services.

    void                SetDefaultHeader                (   PRECORDHEADER7K         psRecordHeader );

                        C7kFileHeader                   (   const C7kFileHeader    &rRhs );                 // Not implemented.
    C7kFileHeader &     operator =                      (   const C7kFileHeader    &rRhs );                 // Not implemented.

};

#endif // !defined(AFX_7KFILEHEADER_H__602F5B47_0F11_4560_916A_C990CDD76A9C__INCLUDED_)
