//---------------------------------------------------------------------------------------------
// <copyright file="SBGPCTDSensorSettings.h" company="LiquidRobotics">
//
// Copyright (c) 2014 Liquid Robotics, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// This software is associated with a release.  Liquid Robotics makes no
// representation that the design, interfaces or component distribution will
// remain unchanged in future releases.
//
// </copyright>
//
// <summary>
// 	Declaration of SBGPCTDSensorSettings, an serializable entity class that contains the config
//  settings for an instance of SBGPCTDSensor
// </summary>
//
// <owner>Mike Cookson</owner>
//---------------------------------------------------------------------------------------------

#ifndef SBGPCTDSENSORSETTINGS_H_
#define SBGPCTDSENSORSETTINGS_H_

#include <boost/serialization/access.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/version.hpp>
#include "LqrSMACSerialListenerSettings.h"
#include "LqrSMACSerialPortSettings.h"
#include "LqrSMACSharedLib.h"
#include <boost/shared_ptr.hpp>
#include <string>

namespace LiquidRobotics {
namespace SeabirdGPCTD {

/*! \brief A serializable entity that holds static settings for SBGPCTDSensor
 */
class SHARED_LIB_PUBLIC SBGPCTDSensorSettings
{
public:

	//! Define a short-cut for SMACFramework's SerialPortSettings (don't want "using namespace" in header files)
	typedef LiquidRobotics::SMACFramework::SerialPortSettings SerialPortSettings;

	//! Define a short-cut for SMACFramework's SerialListenerSettings (don't want "using namespace" in header files)
	typedef LiquidRobotics::SMACFramework::SerialListenerSettings SerialListenerSettings;

	//! Define a short-cut for string (don't want "using namespace" in header files)
	typedef std::string string;

	/*! \brief Class constructor
	 */
	SBGPCTDSensorSettings();

	/*! \brief Class destructor
	 */
	virtual ~SBGPCTDSensorSettings();

	/*! \brief Read the shell command that turns off power to the sensor
	 *  \returns The shell command that turns off power to the sensor
	 *  \sa SetPowerOffVerb(), GetPowerOnVerb(), SetPowerOnVerb(), system()
	 */
	const string& GetPowerOffVerb() const;

	/*! \brief Sets the shell command that turns off power to the sensor
	 *  \sa GetPowerOffVerb(), GetPowerOnVerb(), SetPowerOnVerb(), system()
	 */
	void SetPowerOffVerb(
			const string& newValue			/**< [in] The shell command that turns off power to the sensor */
			);

	/*! \brief Read the shell command that turns on power to the sensor
	 *  \returns The shell command that turns on power to the sensor
	 *  \sa SetPowerOnVerb(), GetPowerOffVerb(), SetPowerOffVerb(), system()
	 */
	const string& GetPowerOnVerb() const;

	/*! \brief Sets the shell command that turns on power to the sensor
	 *  \sa GetPowerOnVerb(), GetPowerOffVerb(), SetPowerOffVerb(), system()
	 */
	void SetPowerOnVerb(
			const string& newValue			/**< [in] The shell command that turns on power to the sensor */
			);

	/*! \brief Reads the settings to use with SerialListener for this sensor
	 *  \returns A reference to the local copy of SerialListenerSettings to be used for this sensor
	 *  \sa SetSerialListenerSettings(), SerialListenerSettings, SerialListener
	 */
	const SerialListenerSettings& GetSerialListenerSettings() const;

	/*! \brief Sets the settings to use with SerialListener for this sensor
	 *  \sa GetSerialListenerSettings(), SerialListenerSettings, SerialListener
	 */
	void SetSerialListenerSettings(
			const SerialListenerSettings& newValue		/**< [in] A reference to the new SerialListenerSettings to be used for this sensor */
			);

	/*! \brief Reads the settings (baud rate, port name, etc.) to use for the SerialPort for this sensor
	 *  \returns A reference to the local copy of SerialPortSettings to be used for this sensor
	 *  \sa SetSerialPortSettings(), SerialPortSettings, SerialPort
	 */
	const SerialPortSettings& GetSerialPortSettings() const;

	/*! \brief Sets the settings (baud rate, port name, etc.) to use for the SerialPort for this sensor
	 *  \returns A reference to the local copy of SerialPortSettings to be used for this sensor
	 *  \sa SetSerialPortSettings(), SerialPortSettings, SerialPort
	 */
	void SetSerialPortSettings(
			const SerialPortSettings& newValue			/**< [in] A reference to the new SerialPortSettings to be used for this sensor */
			);

	/*! \brief Load the properties from the given XML filename
	 *  \sa load(), Save()
	 *
	 *  Throws an std::invalid_argument if the file does not exist.  If the
	 *  file exists, but is empty (zero length), the default XML schema is
	 *  written to the file.
	 *
	 *  If data is successfully loaded, the data is written out again using
	 *  the latest schema; and if the original file doesn't match, a new
	 *  ".upgraded" file is written.
	 */
	void Load(
			const string& fileName			/**< [in] Name and path of the file from which to deserialize */
			);

	/*! \brief Save the properties to the given XML filename
	 *  \sa Load(), save()
	 */
	void Save(
			const string& fileName			/**< [in] Name and path of the file to which to serialize */
			) const;

private:

	//! Provides Boost Serialization libraries with access to the private load() and save() members
	friend class boost::serialization::access;

	/*! \brief Boost Serialization compatible member that loads properties from an Archive object
	 *  \sa Load(), save()
	 *
	 *  The member is implemented in the header to leave the Archive template
	 *  parameter open for multiple cases, but this method was designed to work
	 *  with the XML archive.  The load operation should check the version and
	 *  customize load behavior to be compatible with earlier schemas.
	 */
	template<class Archive>
	void load(Archive & ar, const unsigned int version)
	{
		ar & BOOST_SERIALIZATION_NVP(powerOffVerb);
		ar & BOOST_SERIALIZATION_NVP(powerOnVerb);
		ar & BOOST_SERIALIZATION_NVP(serialListenerSettings);
		ar & BOOST_SERIALIZATION_NVP(serialPortSettings);
	}

	/*! \brief Boost Serialization compatible member that saves properties to an Archive object
	 *  \sa load(), Save()
	 *
	 *  The member is implemented in the header to leave the Archive template
	 *  parameter open for multiple cases, but this method was designed to work
	 *  with the XML archive.  The save operation always works with the latest
	 *  schema.
	 */
	template<class Archive>
	void save(Archive & ar, const unsigned int version) const
	{
		ar & BOOST_SERIALIZATION_NVP(powerOffVerb);
		ar & BOOST_SERIALIZATION_NVP(powerOnVerb);
		ar & BOOST_SERIALIZATION_NVP(serialListenerSettings);
		ar & BOOST_SERIALIZATION_NVP(serialPortSettings);
	}

	//! Used to define load() and save() vs. serialize(); this is especially useful when there are earlier schema formats to support
	BOOST_SERIALIZATION_SPLIT_MEMBER()

	string powerOffVerb;								//!< The shell command that turns off power to the sensor
	string powerOnVerb;									//!< The shell command that turns on power to the sensor
	SerialListenerSettings serialListenerSettings;		//!< The settings to use with SerialListener for this sensor
	SerialPortSettings serialPortSettings;				//!< The settings to use with SerialPort for this sensor
};

}
}

//! Defines the latest schema version (used with save())
BOOST_CLASS_VERSION(LiquidRobotics::SeabirdGPCTD::SBGPCTDSensorSettings, 1)

#endif /* SBGPCTDSENSORSETTINGS_H_ */
