//
//  Copyright © 2004, 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:   6046RemoteClient.h
//
//  Project:    6046
//
//  Author(s):  W. Arcus
//
//  Purpose:    Defines a 6046 remote client helper class.
//
//  Notes:      1)  All command and control functions are asyncrhonous. As such, the the 
//                  success boolean return code indicates that the appropriate command was 
//                  sent on the socket.
//
//                  Replys will be asynchonous and passed by the relevant callback.
//
//              2)  All callbacks are specified by the prototype defined by the typedef PFN_REMOTECLIENT_CALLBACK
//                  below. Note that these callbacks will be executed from a thread within the DLL and therefore
//                  implementing clients need to be multi-thread safe when utilizing shared resources.
//

#if !defined(AFX_6046REMOTECLIENT_H__1D681B3C_F18C_42D8_B041_1EBFADA7E97F__INCLUDED_)
#define AFX_6046REMOTECLIENT_H__1D681B3C_F18C_42D8_B041_1EBFADA7E97F__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#ifndef EXPORT_DLL
#ifdef _USRDLL
#define EXPORT_DLL  __declspec( dllexport )
#else
#define EXPORT_DLL
#endif
#endif

//  Callback prototype for data, status and alarms.

typedef void (*PFN_REMOTECLIENT_CALLBACK)   (   void           *pvParam,                                                    // Optional parameter; typically the client's this pointer.
                                                unsigned char  *pbyData,                                                    // Pointer to the data.
                                                unsigned long   ulBytes );                                                  // Number of bytes in data.

class EXPORT_DLL C6046RemoteClient
{
public:

    ///////////////
    // Attributes.

    const unsigned long  m_ulRecordTypeAny;
    const int            m_iSensorAny;

    ///////////////
    // Definitions.

    typedef enum tagE6046ERRORCODE                                                                                          // Error codes for this class.
    {
        errorCodeNone                    = 0,                                                                               // No error.
        errorCodeNotImplemented,                                                                                            // Service not implemented.
        errorCodeNotConnected,                                                                                              // 6046 client is not connected to PLC.
        errorInvalid7kRecord,                                                                                               // Invalid 7k record detected.
        errorInvalidParameter,                                                                                              // Parameter to interface method is invalid.
        errorConnectionFailed                                                                                               // Connection to the PLC is down or the PLC is not responding.

        // Add new error codes here.
    }
    E6046ERRORCODE;

    typedef enum tagEALARMACTION
    {
        alarmActionDisable,
        alarmActionEnable
    }
    EALARMACTION;

    ///////////////
    // Services.

                                C6046RemoteClient   (   void );
    virtual                    ~C6046RemoteClient   (   void );

    // Connection services.

    bool                        Connect             (   PFN_REMOTECLIENT_CALLBACK    pfnStatusCallback,                     // Callback for status and alarm messages - solicited or unsolicited messages.
                                                        void                        *vpStatusCallbackParam,                 // Optional parameter for status callback - typically client's this pointer.
                                                        PFN_REMOTECLIENT_CALLBACK    pfnDataCallback,                       // Callback for subscribed data record; see Subscribe below.
                                                        void                        *pvDataCallbackParam,                   // Optional parameter for data callback - typically client's this pointer.
                                                        const char                  *pszRemoteAddress,                      // IP address of target 6046 wet-end; e.g. "127.0.0.1" for local.
                                                        const unsigned int           uiPort             = 6046U );          // TCP port of 6046 - default is 6046U

    bool                        Disconnect          (   void );                                                             // Disconnects from remote and closes internal communications channel(s); also invoked by destructor.

    // Data subscription services (per sensor per record).

    bool                        Subscribe           (   const int                   &riSensorIndex,                         // Index of sensor to be addressed.
                                                        const unsigned long         &rulRecordType );                       // 7k record type to subscribe to for given sensor.

    bool                        Unsubscribe         (   const int                   &riSensorIndex,                         // Sensor index for which to unsubscribe.
                                                        const unsigned long         &rulRecordType );                       // 7k record to unsubscribe.

    bool                        AliveMonitor        (   const bool                  &rbEnable );

    bool                        IsConnectionAlive   (   void );

    E6046ERRORCODE              GetLastError        (   void ) const;                                                        // Error code retrieval; maybe called whenever a method returns false.

    void                        SetError            (   const E6046ERRORCODE        &reError );

    // General 6046 command and control services.

    bool                        GenericCommand      (   const int                   &riSensorIndex,                         // Sends any generic ASCII string to the specified sensor or PLC or PLC and all sensors.
                                                        char                        *pszString );

    bool                        Logging             (   const bool                  &rbEnable );                            // Start and stop logging of data to disk.

    bool                        SwitchFileName      (   const char                  *pszFileName = NULL );                  // Close and open next automated logging file name or specified file name if given.

    bool                        SetPath             (   const char                  *pszPath );                             // Set the target 6046 path; typically not used.

    bool                        Version             (   void );

    bool                        Load                (   void );

    bool                        Save                (   void );

    bool                        Alarm               (   const int                   &riAlarmId,
                                                        const EALARMACTION          &reAlarmAction );

    bool                        Status              (   const int                   &riSensorIndex );

    bool                        Verbose             (   const bool                  &rbEnable );

    bool                        Reset               (   const int                   &riSensorIndex );

    bool                        Shutdown            (   const int                   &riMode );                              // Shutdown modes are: 0 = logger, 1 = reboots Windows.

    bool                        Modules             (   void );

    bool                        RunList             (   void );

    bool                        Add                 (   const int                   &riModuleNumber,
                                                        const int                   &riSubsystemId,
                                                        const int                   &riPortNumber,
                                                        LPCTSTR                      pszName  );

    bool                        Remove              (   const int                   &riSensorIndex );

    bool                        Report              (   void );

    bool                        Port                (   const int                   &riSensorIndex,
                                                        const int                   &riPort );

    bool                        SyncToTime          (   const SYSTEMTIME            &rsSystemTime );

    bool                        Health              (   void );

    bool                        AutoStart           (   const DWORD                 &rdwMode );

    bool                        AutoHealthCheck     (   const bool                  &rbEnable,                              // Enable or disable Auto-health checking
                                                        const unsigned long         &rulPeriodMilliSeconds );               // Period in ms between end sensor check cycles (end of last to start of first in active run-list).

    bool                        RouteMessages       (   const int                   &riRoutingSensorIndex );

    bool                        ReportAlarms        (   void );

    bool                        Send7kMessage       (   const BYTE                 *pbyMessage,                             // Used to route any (non-command) 7k message.
                                                        const unsigned long        &rulBytes );                             // Total bytes in 7k message (should be same size as the size field in the DRF).

    bool                        LoggingSetup        (   void );                                                             // Queries the system for the logging setup info (max file size and record overlap).

    bool                        LoggingSetup        (   const unsigned long        &rulMaxFileSize,                         // Sets the maximum file size (MBytes) between automatically logged file sizes.
                                                        const unsigned long        &rulRecordOverlap );                     // Number of overlapped records between successive logged files.

    bool                        SimulateCommand     (   const unsigned long        &rulCommandId,
                                                        const char                 *pszOptions,
                                                                                    ... );

    bool                        EmitTime            (   const bool                 &rbEmitTime );

    // Sensor specific command and control that use generic commands internally.

    bool                        PingEnable          (   const int                   &riSensorIndex,                         // Enables or disables pinging for given sensor index.
                                                        const bool                  &rbEnable );

    bool                        SetRange            (   const int                   &riSensorIndex,                         // Sets the pinging range for a given sensor.
                                                        const float                 &rfRange );                             // Range in m.

    bool                        SetDuration         (   const int                   &riSensorIndex,                         // Sets the total duration between pings for the given sensor.
                                                        const float                 &rfDurationInMilliseconds );            // Ping rep period in milliseconds.

    bool                        TxPower             (   const int                   &riSensorIndex,                         // Transmit power as a percentage of max capability.
                                                        const float                 &rfPercentage );

    bool                        RxGain              (   const int                   &riSensorIndex,                         // Rx gain as a percentage of total capability.
                                                        const int                   &riRxGain );

    bool                        SetPulse            (   const int                   &riSensorIndex,                         // Use a specified pulse file.
                                                        const char                  *pszPulseFileName );                     // Pulse file name.

    bool                        GetPulseFiles       (   const int                   &riSensorIndex );                       // Solicits the pulse file list.

    bool                        SetDefaultState     (   const int                   &riSensorIndex );                       // Request the specified sensor to be set to its default state.

    bool                        QueryParameters     (   const int                   &riSensorIndex );                       // Solicits the sensor's general settings.

    bool                        QueryCapabilities   (   const int                   &riSensorIndex );                       // Solicits the sensor's device specific capability settings.

    bool                        QueryRemoteSettings (   const int                   &riSensorIndex );

    bool                        PulseWidth          (   const int                   &riSensorIndex,                         // Transmit pulse width in seconds.
                                                        const float                 &rfPulseWidth );

    bool                        RangeDepthFilters   (   const int                   &riSensorIndex,                         // Filter settings for depth and range in meters.
                                                        const float                 &rfMinRange,
                                                        const float                 &rfMaxRange,
                                                        const float                 &rfMinDepth,
                                                        const float                 &rfMaxDepth );

    bool                        BottomDetectFlags   (   const int                   &riSensorIndex,                         // Bottom detect flags; use bit flags per DFD command ID 1009.
                                                        const unsigned long         &rulBottomDetectFlags );

    bool                        MaxPingRate         (   const int                   &riSensorIndex,                         // Max ping rate in pings per second.
                                                        const float                 &rfMaxPingRate );

    bool                        AbsorptionCoefficient(  const int                   &riSensorIndex,                         // Absorption coefficient in dB/km.
                                                        const float                 &rfAbsorptionCoefficient );

    bool                        SoundSpeed          (   const int                   &riSensorIndex,                         // Sound speed in m/s.
                                                        const float                 &rfSoundSpeed );

    bool                        SpreadingLoss       (   const int                   &riSensorIndex,                         // Set the sensor's spreading loss in dB.
                                                        const float                 &rfSpreadingLoss );
private:

    ///////////////
    // Attributes.

    E6046ERRORCODE              m_eLastErrorCode;
    void                       *m_pvConnection;                                                                             // Opaque connection object.

    ///////////////
    // Services.

    bool                        Send7kRecord        (   const BYTE                  *pby7kRecord,
                                                        const unsigned long         &rulBytes );

                                C6046RemoteClient   (   const C6046RemoteClient     &rRhs );                                // Not implemented thus private to prevent use.
    C6046RemoteClient &         operator =          (   const C6046RemoteClient     &rRhs );                                // Not implemented thus private to prevent use.

};

#endif // !defined(AFX_6046REMOTECLIENT_H__1D681B3C_F18C_42D8_B041_1EBFADA7E97F__INCLUDED_)
