//-------------------------------------------------------------------------------------------------
// <copyright file="SBGPCTDControllerSettings.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 SBGPCTDControllerSettings, an serializable entity class that contains the config
//  settings for an instance of SBGPCTDController
// </summary>
//
// <owner>Mike Cookson</owner>
//-------------------------------------------------------------------------------------------------

#ifndef SBGPCTDCONTROLLERSETTINGS_H_
#define SBGPCTDCONTROLLERSETTINGS_H_

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

namespace LiquidRobotics {
namespace SeabirdGPCTD {

/*! \brief A serializable entity that holds static settings for SBGPCTDController
 *  \sa SBGPCTDControllerPersistSettings
 */
class SHARED_LIB_PUBLIC SBGPCTDControllerSettings
{
public:


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

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

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

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

	/*! \brief Read the default output formatter
	 *  \returns The setting for the default formatter
	 *  \sa SetDefaultOutputFormatter()
	 *
	 *  Controllers using SMACFramework's CmdOutputFormatter class factory
	 *  can select the way that command output is formatted by default; for
	 *  example, "basic" for just outputting test or "xml" for XML formatting.
	 *  This applies to any controllers using EventLib's SensorController<T>
	 */
	string GetDefaultOutputFormatter() const;

	/*! \brief Sets the default output formatter
	 *  \sa GetDefaultOutputFormatter()
	 *
	 *  Controllers using SMACFramework's CmdOutputFormatter class factory
	 *  can select the way that command output is formatted by default; for
	 *  example, "basic" for just outputting test or "xml" for XML formatting.
	 *  This applies to any controllers using EventLib's SensorController<T>
	 */
	void SetDefaultOutputFormatter(
			const string& newValue		/**< [in] The class factory selector to be used */
			);

	/*! \brief Get the settings to be used for CSVSampleFileSet
	 *  \returns A reference to the settings for the CSVSampleFileSet
	 *  \sa SetFileSetSettings()
	 *
	 *  The CSVSampleFileSet is used to write log files, optionally, for
	 *  samples, reads and writes from the sensor and device information.
	 */
	const FileSetSettings& GetFileSetSettings() const;

	/*! \brief Save the settings to be used for CSVSampleFileSet
	 *  \sa GetFileSetSettings()
	 *
	 *  The CSVSampleFileSet is used to write log files, optionally, for
	 *  samples, reads and writes from the sensor and device information.
	 */
	void SetFileSetSettings(
			const FileSetSettings& newValue		/**< [in] Settings to be used for the CSVSampleFileSet */
			);

	/*! \brief Get the name of the persistent XML file
	 *  \returns A string containing the path and name of the persistent XML file
	 *  \sa SetPersistentXMLFileName()
	 *
	 *  In the interest of making the persistent file name configurable,
	 *  but wanting to use a boilerplate main, the name of the persistent
	 *  XML file is included in the static configuration.
	 */
	string GetPersistentXMLFileName() const;

	/*! \brief Set the name of the persistent XML file
	 *  \sa GetPersistentXMLFileName()
	 *
	 *  In the interest of making the persistent file name configurable,
	 *  but wanting to use a boilerplate main, the name of the persistent
	 *  XML file is included in the static configuration.
	 */
	void SetPersistentXMLFileName(
			const string& newValue			/**< [in] The name and path of the persistent XML file */
			);

	/*! \brief Get the settings for the sensor class
	 *  \returns A reference to the settings for the sensor class
	 *  \sa SetSensorSettings()
	 */
	const SBGPCTDSensorSettings& GetSensorSettings() const;

	/*! \brief Set the settings for the sensor class
	 *  \sa GetSensorSettings()
	 */
	void SetSensorSettings(
			const SBGPCTDSensorSettings& newValue	/**< [in] The sensor settings to be set */
			);

	/*! \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,					/**< The Boost archive to load (deseriaize) from */
			const unsigned int version	/**< The schema version being loaded */
			)
	{
		ar & BOOST_SERIALIZATION_NVP(defaultOutputFormatter);
		ar & BOOST_SERIALIZATION_NVP(fileSetSettings);
		ar & BOOST_SERIALIZATION_NVP(persistentXMLFileName);
		ar & BOOST_SERIALIZATION_NVP(sensorSettings);
	}

	/*! \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,					/**< The Boost archive to save (serialize) to */
			const unsigned int version	/**< The schema version being saved */
			) const
	{
		ar & BOOST_SERIALIZATION_NVP(defaultOutputFormatter);
		ar & BOOST_SERIALIZATION_NVP(fileSetSettings);
		ar & BOOST_SERIALIZATION_NVP(persistentXMLFileName);
		ar & BOOST_SERIALIZATION_NVP(sensorSettings);
	}

	//! 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 defaultOutputFormatter;				//!< The default output formatter property (for example, "xml" or "basic")
	FileSetSettings fileSetSettings;			//!< Settings for CSVSampleFileSet (data log)
	string persistentXMLFileName;				//!< The name and path of the persistent settings XML file
	SBGPCTDSensorSettings sensorSettings;		//!< The settings for the sensor class
};

}
}

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

#endif /* SBGPCTDPROGRAMSETTINGS_H_ */
