//
//  Copyright © 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:   Alarm.h
//
//  Project:    6046
//
//  Author(s):  W. Arcus
//
//  Purpose:    Defines the CAlarm class to handle reporting and handling of alarm conditions.
//
//  Notes:      
//

#if !defined(AFX_ALARM_H__F5EEBF5A_2F16_4F19_AC05_6B9094F603DC__INCLUDED_)
#define AFX_ALARM_H__F5EEBF5A_2F16_4F19_AC05_6B9094F603DC__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include ".\Include\SurveyEventTypes.h"
#include "..\Utils\NetUtils\Critical.h"
#include "..\Utils\NetUtils\DynamicBuffer.h"

#pragma warning( disable : 4663 )
#pragma warning( disable : 4018 )
#include <vector>
#pragma warning( default : 4018 )
#pragma warning( default : 4663 )

#include <list>                                                             // Linked list support.

const DWORD g_dwMaxAlarmMessageLength = 80UL;

typedef struct tagALARMENTRY
{
    EALARMID    m_eAlarmId;
    DWORD       m_dwTimestamp;
    TCHAR       m_szMessage             [ g_dwMaxAlarmMessageLength + 1 ];
    int         m_iSecondaryIndex;

    tagALARMENTRY( void )
    {
        m_eAlarmId    = alarmIdUnspecified;
        m_dwTimestamp = 0UL;
        ::memset( &m_szMessage[ 0 ], 0x00, ( sizeof( TCHAR ) * g_dwMaxAlarmMessageLength ) + 1 );

        m_iSecondaryIndex = iUnspecified_c;
    }
}
ALARMENTRY;

class CAlarm  
{
public:

    ///////////////
    // Services.

    // Construction and destruction.

                        CAlarm                  (   void );
    virtual            ~CAlarm                  (   void );

    void                SetThreadNotification   (   const bool             &rbEnable,
                                                    const unsigned long    &rulThreadId,
                                                    const unsigned int     &ruiMessageId );

    bool                Report                  (   const EEVENTACTION     &reEventAction,      // Uses callback syntax to report an alarm.
                                                    const EALARMID         &reAlarmId,
                                                    const DWORD            &rdwTimestamp,
                                                    LPCTSTR                 lpszMessage );

    bool                IsAlarmActive           (   const EALARMID         &reAlarmId,
                                                    const int              &riSecondaryIndex = iUnspecified_c );

    bool                RetrieveAlarm           (   const EALARMID         &reAlarmId,
                                                    const int              &riSecondaryIndex,
                                                    ALARMENTRY * const      psAlarmEntry );

    bool                Retrieve7kAlarmRecord   (   const EALARMID         &reAlarmId,
                                                    const int              &riSecondaryIndex,
                                                    CDynamicBuffer<BYTE>   &rAlarmRecord );

    bool                RetrieveAlarms          (   std::vector<ALARMENTRY> &rAlarmList );

    bool                Set7kAlarmRecord        (   ALARMENTRY * const      psAlarm,
                                                    CDynamicBuffer<BYTE>   &rAlarmRecord );

private:

    ///////////////
    // Defintions.

    class CEntry : public ALARMENTRY
    {
    public:

                    CEntry                      (   void );
        virtual    ~CEntry                      (   void );

        void        Set                         (   const EALARMID         &reAlarmId,
                                                    const DWORD            &rdwTimestamp,
                                                    LPCTSTR                 lpszMessage,
                                                    const int              &riSecondaryIndex );

                    operator ALARMENTRY *       (   void ) const;

        bool        operator ==                 (   const EALARMID         &reAlarmId ) const;

        bool        operator <                  (   const CEntry           &rRhs ) const;

    };

    typedef std::list<CEntry>                   AlarmList_t;
    typedef AlarmList_t::iterator               AlarmListIterator_t;

    ///////////////
    // Attributes

    const unsigned long                         m_ulInvalidThreadId;
    const unsigned int                          m_uiInvalidThreadMessage;

    bool                                        m_bNotification;
    unsigned long                               m_ulThreadToNotify;
    unsigned int                                m_uiThreadMessage;

    mutable CCritical                           m_Critical;
    AlarmList_t                                 m_ActiveAlarmList;
    AlarmList_t                                 m_ClearedAlarmList;

    ///////////////
    // Services.

    void                AddAlarm                (   const EALARMID         &reAlarmId,
                                                    const DWORD            &rdwTimestamp,
                                                    LPCTSTR                 lpszMessage,
                                                    const int              &riSecondaryIndex );

    bool                NotifyClient            (   const EALARMID         &reAlarmId,
                                                    const int              &riSecondaryIndex );

    bool                IsAlarmMatch            (   const EALARMID         &reAlarmId,
                                                    const int              &riSecondaryIndex,
                                                    ALARMENTRY * const      psAlarmEntry );

    int                 SecondaryIndex          (   const EALARMID         &reAlarmId,
                                                    LPCTSTR                 lpszMessage,
                                                    bool                   &rbSecondaryAlarm );

    bool                IsAlarmCleared          (   const EALARMID         &reAlarmId,
                                                    const int              &riSecondaryIndex );

    bool                RetrieveClearedAlarm    (   const EALARMID         &reAlarmId,
                                                    const int              &riSecondaryIndex,
                                                    ALARMENTRY * const      psAlarmEntry,
                                                    const bool             &rbRemoveAlarm );

                        CAlarm                  (   const CAlarm           &rRhs );         // Not implemented.
    CAlarm &            operator =              (   const CAlarm           &rRhs );         // Not implemented.

};

#endif // !defined(AFX_ALARM_H__F5EEBF5A_2F16_4F19_AC05_6B9094F603DC__INCLUDED_)
