#ifndef _ALARM_H
#define _ALARM_H

#include "types.h"
#include "ostime.h"
#include "alarmdef.h"

class AlarmManager; //forward declaration

/*--------------------------------------------------------
CLASS 
	Alarm

FILENAME
 	alarm.h

DESCRIPTION	
	Alarm is an alarm object that contains the state and text of an 
	alarm.

HOW TO:
	HOW TO: CREATE AN ALARM OBJECT

	Alarms should be created statically rather than allocated at
	run time - especially if the alarm is frequently triggered,
	This eases run-time memory allocation in the AlarmManager.

HOW TO:
	HOW TO: CREATE AN ALARM OBJECT

	Alarms should be created statically rather than allocated at
	run time - especially if the alarm is frequently triggered,
	This eases run-time memory allocation in the AlarmManager.

	If an alarm must be created dynamically, create the alarm with
	the createAlarm() method. This will dynamically create an acive alarm.

	HOW TO: OVERRIDE ALARM BEHAVIOR

	Two methods are generally overriden to implement alarm specific logic:
	detect(), and isActive(). Detect() is called to detect the alarm, and
	update with a new text message if required. isActive() implements the logic
	to determine if alarm is active (due to number of trips exceeding threshold,
	or time elapsed, etc.). When isActive() returns TRUE, the AlarmManager
	will log the alarm.	

AUTHOR
	Danelle Cline. Copyright 1998 MBARI.				
LOG
	Modifier 	Date    		Change
	--------   	----    		--------
	D. Cline	3/18/98			Alpha prototype
	D. Cline	2/7/01			Delta prototype

--------------------------------------------------------*/
class Alarm
{
	friend class AlarmManager;

public:

	// Dynamic Alarm constructor.	
	// <msg> = alarm message to log. Will be truncated to ALARM_MSG_SIZE
	// <pAM> = alarm manager managing this alarm. If not defined will find a
	// singleton AlarmManager for this application.
	Alarm(char *msg, alarmPriority priority=PRIORITY_MESSAGE, AlarmManager *pAM = NULL);

	// Static Alarm constructor. Returns pointer to allocated alarm.	
	// <msg> = alarm message to log. Will be truncated to ALARM_MSG_SIZE
	// <pAM> = alarm manager managing this alarm. If not defined will find a
	// singleton AlarmManager for this application.
	static Alarm *create(char *msg, alarmPriority priority=PRIORITY_MESSAGE, AlarmManager *pAM = NULL);

	// Destructor
	virtual ~Alarm();
	
	// Calls recover() when alarm is active. This must be overriden 
	// to run alarm specific logic to detect alarm state.
	// MUST be called by parent object following alarm logic.
	virtual void detect();

	// Runs alarm recovery. Is called from detect when alarm is active.
	// This must be verriden by the subclass Alarm object.  Generally used 
	// to either attempt recovery, put system into a state which it can 
	// continue operation w/degraded  functionality, or put system into a 
	// state which it will be disabled, or attempt a  graceful shutdown. 
	virtual void recover();

	// Defaults to TRUE, unless subclass overides this function.
	virtual Boolean isActive();
	
	// Return pointer to alarm msg
	char *msg();

	// Append alarm specific details to alarm message text
	// Truncates appended text to ALARM_MSG_DETAIL_SIZE
	void appendToAlarmMsg(char *appendMsg);	

	// Replaces alarm message with new <text>. Generally called
	// in detect when alarm state changes.
	void updateMsg(char *text);

	// Returns alarm priority; MESSAGE, WARNING, or ALARM
	alarmPriority priority();

protected:

	// If TRUE, AlarmManager deletes this alarm in it's destructor
	// **Only alarms created with createAlarm() sets this TRUE.
	Boolean _cleanup;	

private:
	
	// Format alarm message with alarm specific details
	virtual void formatMsg();

	// Pointer to the alarm manager managing this alarm object
	AlarmManager *_pAlarmMgr;

	// Fixed size alarm text
	char _alarmText[MAX_ALARM_MSG_SIZE + ALARM_MSG_DETAIL_SIZE];

	// Size of alarm text, not including subclass appended format
	size_t _msgLength;

	// The time the alarm was created
	Time _timeCreated;	

	// Alarm priority; MESSAGE, WARNING, or ALARM
	alarmPriority _priority;
};

/*--------------------------------------------------------
CLASS 
	TripAlarm

DESCRIPTION	
	TripAlarm is an alarm object that becomes active after a defined
	number of trips has occured.

HOW TO:
	HOW TO: CREATE A TRIPALARM OBJECT

	To create an overTemp alarm within a class

	1.  Include in the header of foo.h
			.
			.
		private:
			Alarm	_overTemp;
			.
			.

	2.  Initialize the alarm in the constructor of class Foo

		class Foo: _overTemp ("Foo OverTemp", 
							  SET_BY_TRIP_NUM,
							  5)	//After 5 trips activate alarm
AUTHOR
	Danelle Cline. Copyright 1998 MBARI.				
LOG
	Modifier 	Date    		Change
	--------   	----    		--------
	D. Cline	12/14/98		

--------------------------------------------------------*/
class TripAlarm: public Alarm
{
public:

	// Alarm constructor.
	// <pAM> = alarm manager managing this alarm. If not defined will find the
	// singleton AlarmManager for this application.
	// <text> = alarm text to log/display. Will be truncated to ALARM_MSG_SIZE	
	// <nTrips> = 0 - 65535. 
	TripAlarm(char *text, Nat16 nTrips = 0, AlarmManager *pAM = NULL);

	// Destructor
	virtual ~TripAlarm();

	// Updates alarm text, runs alarm logic algorithm, and
	// starts a new alarm record if required
	virtual void detect();

	// Runs alarm recovery. Is called from detect when alarm is active.
	// Does nothing unless overriden by subclass of Trip Alarm.
	virtual void recover();

	// Returns TRUE if the alarm is active.  An alarm is active when the 
	// number of trips has exceeded the defined threshold (defined in the
	// constructor)
	virtual Boolean isActive();

private:

	// Formats alarm text with alarm specific details
	void formatMsg();

	// Maximum number of trips before becoming active
	Nat16 _maxNumTrips;		

	// Number of trips alarm has triggered
	Nat16 _nTrips;
	
};


/*--------------------------------------------------------
CLASS 
	TimedAlarm

DESCRIPTION	
	TimedAlarm is an alarm object that becomes active after the
	time between successive trips has exceeded the defined threshold.

HOW TO:
	HOW TO: CREATE A TIMED ALARM OBJECT

	To create an overTemp alarm within a class

	1.  Include in the header of foo.h
			.
			.
		private:
			Alarm	_overTemp;
			.
			.

	2.  Initialize the alarm in the constructor of class Foo

		class Foo: _overTemp ("Foo OverTemp", 
							  20);  //after 20 seconds have elapsed since last
									//trip activate
AUTHOR
	Danelle Cline. Copyright 1998 MBARI.				
LOG
	Modifier 	Date    		Change
	--------   	----    		--------
	D. Cline	12/14/98		

--------------------------------------------------------*/
class TimedAlarm: public Alarm
{
public:

	// Alarm constructor.
	// <pAM> = alarm manager managing this alarm. If not defined will find the
	// singleton AlarmManager for this application.
	// <text> = alarm text to log/display. Will be truncated to ALARM_MSG_SIZE	
	// <maxElapsedTimeSec> = 0 - 3600 seconds. Maximum time between trips
	// before alarm becomes active.
	// <resetTimeSec> = 0 - 3600 seconds. Maximum time between trips
	// before alarm resets itself and becomes inactive.
	// NOTE* reset time must be larger than max elapsed time
	TimedAlarm(char *text, Nat32 maxElapsedTimeSec,	Nat32 resetTimeSec,
		AlarmManager *pAM = NULL);

	// Destructor
	virtual ~TimedAlarm();

	// Runs alarm logic algorithm to detect presense of fault.
	// Starts a new alarm record if required
	virtual void detect();

	// Runs alarm recovery. Is called from detect when alarm is active. 
	// Does nothing unless overriden by subclass of Timed Alarm.
	virtual void recover();

	// Returns TRUE if the alarm is active.  An alarm is active when the 
	// time between successive trips has exceeded the defined threshold 
	// (threshold defined in the constructor)
	virtual Boolean isActive();

private:
	
	// Formats alarm text with alarm specific details
	void formatMsg();

	// Maximum elapsed time in seconds between trips for alarm to be active 
	Nat32 _maxElapsedTime;		

	// Maximum time in seconds between trips before alarm resets itself.
	Nat32 _resetTimeSec;
	
	// Last trip time.
	Time _lastTripTime;

	// Clock ticks used to calculate elapsed time
	Nat32 _timertcks;

	// Elapsed time between trips
	Nat32 _elapsedTimeSec;

	// TRUE if the maximum elapsed time between trips has occured.
	Boolean _active;

	// Number of trips alarm has triggered
	Nat16 _nTrips;

	// Number of recover attempts made 
	Nat16 _nAttempts;
	
};
#endif
