//-------------------------------------------------------------------------------------------------
// <copyright file="AlarmMessage.cpp" company="LiquidRobotics">
//  Copyright (c) Liquid Robotics Corporation, confidential and proprietary.  All rights reserved.
// </copyright>
//
// <summary>
//   Declaration of the AlarmMessage class, which models a alarm and which
//   can be used with the EventLib classes to forward events to subscribers.
// </summary>
//
// <owner>Mike Cookson</owner>
//-------------------------------------------------------------------------------------------------

#include "AlarmMessage.h"
#include "nsextend.h"
#include <boost/foreach.hpp>
#include <sys/time.h>
#include <iomanip>

using namespace std;

namespace LiquidRobotics {
namespace EventLib {

const AlarmMessage::PropertyNameType AlarmMessage::reporterTypeIdTag("Reporter Type Id");
const AlarmMessage::PropertyNameType AlarmMessage::alarmTypeTag("Alarm Type");
const AlarmMessage::PropertyNameType AlarmMessage::enumerationTypeTag("Enumerated Type");
const AlarmMessage::PropertyNameType AlarmMessage::notificationIdTag("Notification Id");
const AlarmMessage::PropertyNameType AlarmMessage::freeTextLengthTag("Alarm Message Length");
const AlarmMessage::PropertyNameType AlarmMessage::freeTextTag("Alarm Message");
const AlarmMessage::PropertyNameType AlarmMessage::freeDataLengthTag("Alarm Data Length");
const AlarmMessage::PropertyNameType AlarmMessage::freeDataTag("Alarm Data");

#define IMPL_PROP(proptag,proptype,propname,basetype) \
void AlarmMessage::Clear##propname () { if (ContainsProperty(proptag)) ClearProperty(proptag); } \
basetype AlarmMessage::Get##propname () const { return GetProperty(proptag).Get##proptype (); } \
bool AlarmMessage::Get##propname (basetype & outval) const { const bool result = Has##propname (); if (result) outval = Get##propname (); return result; } \
bool AlarmMessage::Has##propname () const { return ContainsProperty(proptag); } \
void AlarmMessage::Set##propname (const basetype & newValue) { PropertyValueType prop(broker); prop.Set##proptype (newValue); SetProperty(proptag, prop); }

AlarmMessage::AlarmMessage(IObjectBroker& _broker)
: Base(_broker)
{
}

AlarmMessage::AlarmMessage(const EventSettings& _eventSettings, IObjectBroker& _broker)
: Base(_eventSettings, _broker)
{
}

AlarmMessage::AlarmMessage(const EventName& _eventName, const EventType& _eventType, IObjectBroker& _broker)
: Base(_eventName, _eventType, _broker)
{
}

AlarmMessage::AlarmMessage(const EventName& _eventName, const EventType& _eventType, const IOR& _senderIOR, IObjectBroker& _broker)
: Base(_eventName, _eventType, _senderIOR, _broker)
{
}

AlarmMessage::AlarmMessage(const AlarmMessage& other)
: Base(other)
{
}

ostream& AlarmMessage::Describe(ostream& stm) const
{
	Base::Describe(stm);

	if (HasReporterTypeId())
	{
		stm << reporterTypeIdTag << " = " << GetReporterTypeId();
	}

	if (HasAlarmType())
	{
		stm << alarmTypeTag << " = " << GetAlarmType();
	}

	if (HasEnumerationType())
	{
		stm << enumerationTypeTag << " = " << GetEnumerationType();
	}

	if (HasNotificationId())
	{
		stm << notificationIdTag << " = " << GetNotificationId();
	}

	if (HasFreeText())
	{
		stm << freeTextTag << " = " << GetFreeText();
	}

	if (HasFreeData())
	{
		stm << "Has " << freeDataTag << " of length " << GetFreeData()->size();
	}

	return stm;
}

IEventBase::Ptr AlarmMessage::Duplicate() const
{
	IEventBase::Ptr result;
	result.reset(new AlarmMessage(broker));

	((AlarmMessage*) result.get())->Copy(*this);
	return result;
}

//Set all fields
void AlarmMessage::SetAlarmMessage(const int reporterTypeId, const alarmTypes alarmType, const int enumerationType,
		const int notificationId, const string& freeText, const ByteArray& freeData)
{
	SetReporterTypeId(reporterTypeId);
	SetAlarmType((int)alarmType);
	SetEnumerationType(enumerationType);
	SetNotificationId(notificationId);
	SetFreeTextLength(freeText.size());
	SetFreeText(freeText);
	SetFreeDataLength(freeData.size());
	SetFreeData(freeData);
}
////////////////////////////////////////////////////

////////////////////////////////////////////////////
//reporterTypeIdTag
int AlarmMessage::GetReporterTypeId() const
{
	int result;
	result = GetProperty(reporterTypeIdTag).GetInt32();

	return result;
}

bool AlarmMessage::HasReporterTypeId() const
{
	return ContainsProperty(reporterTypeIdTag);
}

void AlarmMessage::SetReporterTypeId(const int& newValue)
{
	PropertyValueType value(broker);
	value.SetInt32(newValue);

	SetProperty(reporterTypeIdTag, value);
}
////////////////////////////////////////////////////

////////////////////////////////////////////////////
//alarmTypeTag
int AlarmMessage::GetAlarmType() const
{
	int result;
	result = GetProperty(alarmTypeTag).GetInt32();

	return result;
}

bool AlarmMessage::HasAlarmType() const
{
	return ContainsProperty(alarmTypeTag);
}

void AlarmMessage::SetAlarmType(const int& newValue)
{
	PropertyValueType value(broker);
	value.SetInt32(newValue);

	SetProperty(alarmTypeTag, value);
}
////////////////////////////////////////////////////

////////////////////////////////////////////////////
//enumerationTypeTag
int AlarmMessage::GetEnumerationType() const
{
	int result;
	result = GetProperty(enumerationTypeTag).GetInt32();

	return result;
}

bool AlarmMessage::HasEnumerationType() const
{
	return ContainsProperty(enumerationTypeTag);
}

void AlarmMessage::SetEnumerationType(const int& newValue)
{
	PropertyValueType value(broker);
	value.SetInt32(newValue);

	SetProperty(enumerationTypeTag, value);
}
////////////////////////////////////////////////////

////////////////////////////////////////////////////
//notificationIdTag
int AlarmMessage::GetNotificationId() const
{
	int result;
	result = GetProperty(notificationIdTag).GetInt32();

	return result;
}

bool AlarmMessage::HasNotificationId() const
{
	return ContainsProperty(notificationIdTag);
}

void AlarmMessage::SetNotificationId(const int& newValue)
{
	PropertyValueType value(broker);
	value.SetInt32(newValue);

	SetProperty(notificationIdTag, value);
}
////////////////////////////////////////////////////

////////////////////////////////////////////////////
//freeTextLengthTag
void AlarmMessage::SetFreeTextLength(const int& newValue)
{
	PropertyValueType value(broker);
	value.SetInt32(newValue);

	SetProperty(freeTextLengthTag, value);
}
////////////////////////////////////////////////////

////////////////////////////////////////////////////
//freeTextTag
string AlarmMessage::GetFreeText() const
{
	return GetProperty(freeTextTag).GetString();
}

bool AlarmMessage::HasFreeText() const
{
	return ContainsProperty(freeTextTag);
}

void AlarmMessage::SetFreeText(const string& newValue)
{
	PropertyValueType value(broker);
	value.SetString(newValue);

	SetProperty(freeTextTag, value);
}
////////////////////////////////////////////////////

////////////////////////////////////////////////////
//freeDataLengthTag
void AlarmMessage::SetFreeDataLength(const int& newValue)
{
	PropertyValueType value(broker);
	value.SetInt32(newValue);

	SetProperty(freeDataLengthTag, value);
}
////////////////////////////////////////////////////

////////////////////////////////////////////////////
//freeDataTag
AlarmMessage::ByteArrayPtr AlarmMessage::GetFreeData() const
{
	ByteArrayPtr returnVal = GetProperty(freeDataTag).GetByteArray();
	return returnVal;
}

bool AlarmMessage::HasFreeData() const
{
	return ContainsProperty(freeDataTag);
}

void AlarmMessage::SetFreeData(const ByteArray& newValue)
{
	PropertyValueType value(broker);
	value.SetByteArray(newValue);

	SetProperty(freeDataTag, value);
}
////////////////////////////////////////////////////
}
}
