//
//  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:   7kCommand.h
//
//  Project:    6046.
//
//  Author(s):  W. Arcus
//
//  Purpose:    
//
//  Notes:      

#if !defined(AFX_7KCOMMAND_H__146DEF08_3D96_486D_9287_0EDF26C2FB11__INCLUDED_)
#define AFX_7KCOMMAND_H__146DEF08_3D96_486D_9287_0EDF26C2FB11__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "7kProtocol.h"
#include "SystemTime.h"

class EXPORT_DLL C7kCommand : public C7kProtocol
{
public:

    ///////////////
    // Definitions.

    typedef enum tagECOMMANDACTION                                                  // Command mode (setting or getting).
    {
        commandActionUnspecified = 0,                                               // Unspecified; meaning is context specific on a per command basis.
        commandActionSet,                                                           // Sets or otherwise takes an action.
        commandActionGet                                                            // Solicits a response.
    }
    ECOMMANDMODE;

    typedef enum tagSENSORINDEX                                                     // Addresses command to PLC or suborinate sensors.
    {
        sensorIndexPLC  = -1                                                        // Addess command to the PLC only.
    }
    ESENSORINDEX;

    typedef enum tagECOMMAND                                                        // Command types.
    {
        commandGeneric,                                                             // Generic ASCII command.
        commandLogging,                                                             // Logging enable/disable
        commandSwitch,                                                              // Change logging file name.
        commandPath,                                                                // Set logging path.
        commandVersion,                                                             // PLC version number.
        commandLoad,                                                                // Load run list from stored file.
        commandSave,                                                                // Save current run list to stored file.
        commandSubscribe,                                                           // Subscribe a client to a given data source.
        commandUnsubscribe,                                                         // Unsubscribe from a data source.
        commandAlarm,                                                               // Acknowlege or disable/enable an alarm.
        commandStatus,                                                              // Solicit a status message.
        commandVerbose,                                                             // Enable/disable the PLC verbose mode.
        commandReset,                                                               // Reset system or given sensor to default state.
        commandShutdown,                                                            // Shuts down the PLC or the PLC and the OS.
        commandModules,                                                             // Solicits the identified module list.
        commandRunList,                                                             // Solicits the running sensor list.
        commandAdd,                                                                 // Adds a sensor the to runlist.
        commandRemove,                                                              // Removes a sensor from the runlist.
        commandReport,                                                              // 
        commandPort,                                                                // 
        commandTimeSync,                                                            // Timesync the 6046 to this message.
        commandHealth,                                                              // Solicits a health message for the specified sensor.
        commandAutoStart,                                                           // Sets the PLC's auto-start mode and adjusts the registry setting accordingly.
        commandAutoHealthCheck,                                                     // Sets, disables or enables the auto-health check, reporting and recover period cycle.
        commandRouteMessages,                                                       // Sets (enables) or disables the default routing command for 7k messages.
        commandReportAlarms,                                                        // Solicits the currently active alarm list.
        commandLoggingSetup,                                                        // Solicits or sets the default logging file size, record overlap between files and target directory.
        commandSimulate,                                                            // Sends a command to the PLC to set various internal simulation features... a useful testing and diagnostic tool.
        commandTimeMessage,                                                         // Command to enable/disable emission of periodic time message to all connected hosts.
        commandCommandIsAlive,                                                      // Is alive command. Can be used by remote hosts so solicit an ACK to test communications.

        // Add new commands here to maintain an accurate count.

        maxCommandTypes
    }
    ECOMMAND;

    ///////////////
    // Services.

    // Construction, destruction and assignment.

                    C7kCommand                  (   void );
                    C7kCommand                  (   const C7kCommand    &rRhs );

    virtual        ~C7kCommand                  (   void );

    C7kCommand &    operator =                  (   const C7kCommand    &rRhs );

    // Decoding.

    bool            Decode                      (   BYTE                *pbyStream,
                                                    const unsigned long &rulTotalBytes,
                                                    const bool          &rbUseChecksum,
                                                    int                 &riSensorIndex,
                                                    unsigned long       &rulCommand,
                                                    unsigned long       &rulAction );

    // Encoding.

    bool            Encode                      (   const int           &riSensorIndex,
                                                    const unsigned long &rulCommand,
                                                    const unsigned long &rulAction,
                                                    const bool          &rbUseChecksum,
                                                    const CString       &rExtended );

    bool            Encode                      (   const int           &riSensorIndex,
                                                    const unsigned long &rulCommand,
                                                    const unsigned long &rulAction,
                                                    const bool          &rbUseChecksum,
                                                    LPCTSTR              lpszExtended,
                                                    ... );

    static
    unsigned long   RecordType                  (   void );

    // Validity checking and data access.

    operator        BYTE *                      (   void )  const;                  // Entire 7k record.
    operator        unsigned long               (   void )  const;                  // Size in bytes of entire record.

    CString         Command                     (   void )  const;                  // Command data (record's dynamic data section).

private:

    ///////////////
    // Definitions.

#pragma pack( push, COMMAND7K_H_PACK, 1 )

    typedef struct tagRECORDTYPEHEADER
    {
        int             m_iSensorIndex;
        unsigned long   m_ulCommand;
        unsigned long   m_ulAction;
        unsigned long   m_ulBytesToFollow;

        static unsigned long Size( void )
        {
            return sizeof( struct tagRECORDTYPEHEADER );
        }

        tagRECORDTYPEHEADER(    const int           &riSensorIndex = sensorIndexPLC,
                                const unsigned long &rulCommand    = commandGeneric,
                                const unsigned long &rulAction     = commandActionGet )
        {
            Reset();

            m_iSensorIndex = riSensorIndex;
            m_ulCommand    = rulCommand;
            m_ulAction     = rulAction;
        }

        void Reset( void )
        {
            memset( this, 0x00, Size() );
        }
    }
    RECORDTYPEHEADER, *PRECORDTYPEHEADER;

#pragma pack( pop, COMMAND7K_H_PACK )

    ///////////////
    // Attributes.

    const unsigned long     m_ulRecordHeaderSize;
    const unsigned long     m_ulRecordType;

    CString                 m_DecodedCommand;

    ///////////////
    // Services.

    void                    SetDefaultHeader    (   RECORDHEADER7K      *psRecordHeader );

};

#endif // !defined(AFX_7KCOMMAND_H__146DEF08_3D96_486D_9287_0EDF26C2FB11__INCLUDED_)
