//------------------------------------------------------------------------------------------------
// <copyright file="SBGPCTDClassConfig.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>
// 	Typedef's to configure the SeabirdGPCTD command and an abstract class that the controller will
//  implement and which will be made available to each command.
// </summary>
//
// <owner>Mike Cookson</owner>
//------------------------------------------------------------------------------------------------

#ifndef SBGPCTDCLASSCONFIG_H_
#define SBGPCTDCLASSCONFIG_H_

#include "SensorCommandBase.h"
#include "SensorConcreteCommand.h"
#include "SensorControllerBase.h"
#include "SensorControllerBaseCmdID.h"
#include "SensorControllerExceptions.h"
#include "SBGPCTDSensor.h"

namespace LiquidRobotics {
namespace SeabirdGPCTD {

/*! \var typedef EventLib::SensorControllerBaseCommandID SBGPCTDCmdID
 *
 * The type of data that tracks the remote caller of a command (needed to inform
 * the remote caller when a command completes.)
 */
typedef EventLib::SensorControllerBaseCommandID SBGPCTDCmdID;

/*! \var typedef EventLib::SensorCommandBase<SBGPCTDCmdID> SBGPCTDControllerCommand
 *  \sa SBGPCTDControllerCommandPtr, SBGPCTDConcreteCmd
 *
 * Defines the base class that others will use to handle command class instances
 */
typedef EventLib::SensorCommandBase<SBGPCTDCmdID> SBGPCTDControllerCommand;

/*! \var typedef boost::shared_ptr<SBGPCTDControllerCommand> SBGPCTDControllerCommandPtr
 *  \sa SBGPCTDControllerCommand
 *
 * Smart pointer to a SBGPCTDControllerCommand
 */
typedef boost::shared_ptr<SBGPCTDControllerCommand> SBGPCTDControllerCommandPtr;

/*! \var typedef EventLib::SensorControllerBase<SBGPCTDControllerCommand,SBGPCTDCmdID> SBGPCTDControllerBase0Base
 *  \sa SensorControllerBase, SBGPCTDControllerBase0
 *
 * Defines the most base class for the controller (before command class-accessible
 * members are added.)
 */
typedef EventLib::SensorControllerBase<SBGPCTDControllerCommand,SBGPCTDCmdID> SBGPCTDControllerBase0Base;

class SBGPCTDControllerSettings;
class SBGPCTDControllerPersistSettings;

/*! \brief Specialization of SBGPCTDControllerBase0Base that adds abstract methods for use by command classes.
 *  \sa SBGPCTDControllerBase0Base
 *
 * Command classes can be passed a reference to SBGPCTDControllerBase0 so they can
 * call the controller back, but they won't know about further specializations.
 */
class SHARED_LIB_PUBLIC SBGPCTDControllerBase0
: public SBGPCTDControllerBase0Base
{
public:

	///! \todo add abstract members to be implemented by the controller and to which any command classes will have access
	// TODO: add abstract members to be implemented by the controller and to which
	// any command classes will have access

	/*! \brief Informs all subscribers that the telemetry configuration has changed.
	 *
	 * This method is used by command classes (and others) after the persistent
	 * settings for telemetry reporting have been changed.  (This method is abstract
	 * in SBGPCTDControllerBase0: derived controllers must provide an implementation.)
	 */
	virtual void ConfigureBlockReporting() = 0;

	/*! \brief Gets a pointer to the sensor interface class
	 *  \returns Smart pointer to the sensor interface class (throws if cannot be validly instantiated and initialized)
	 *  \sa SBGPCTDSensor
	 *
	 * Returns any existing pointer to the sensor interface, or creates a new one and
	 * attempts to initialize it.  If "turnOn" is set, and if the pointer is new, an
	 * attempt will be made to communicate with the sensor before returning it.  Command
	 * classes that communicate with the sensor call this method.
	 *
	 * (This method is abstract in SBGPCTDControllerBase0: derived controllers must
	 * provide an implementation.)
	 */
	virtual SBGPCTDSensor::Ptr GetSensorPtr(
			bool turnOn = true			/**< [in] true (default) if the sensor should be functional, false if it doesn't matter */
			) = 0;

	/*! \brief Get a reference to the persistent settings class
	 *  \returns A reference to the persistent settings class
	 *  \sa ConfigureBlockReporting(), SBGPCTDControllerPersistSettings
	 *
	 * Commands that reconfigure the behavior and save those configurations call this
	 * member.
	 *
	 * (This method is abstract in SBGPCTDControllerBase0: derived controllers must
	 * provide an implementation.)
	 */
	virtual SBGPCTDControllerPersistSettings& GetPersistSettings() const = 0;

	/*! \brief Get a reference to the static configuration settings
	 *  \returns A reference to the static configuration settings
	 *  \sa SBGPCTDControllerSettings
	 *
	 * Commands that need access to the static settings call this member.
	 *
	 * (This method is abstract in SBGPCTDControllerBase0: derived controllers must
	 * provide an implementation.)
	 */
	virtual const SBGPCTDControllerSettings& GetSettings() const = 0;

	/*! \brief Read the status summary string
	 *  \returns A string that summarize the sensor state
	 *
	 * Commands that return the summary status call this member.
	 *
	 * (This method is abstract in SBGPCTDControllerBase0: derived controllers must
	 * provide an implementation.)
	 */
	virtual string GetStatus() = 0;

	/*! \brief Reads the dissolved O2 installation flag
	 *  \returns true if the O2 sensor is installed, false if it is not installed
	 *
	 *  Note that the installation status is made when the program begins communicating
	 *  with the sensor: it doesn't check everytime that this method is called.
	 *
	 * (This method is abstract in SBGPCTDControllerBase0: derived controllers must
	 * provide an implementation.)
	 */
	virtual bool IsOxygenInstalled() const = 0;

	/*! \brief Saves the current state of the persistent settings structure
	 *  \sa GetPersistSettings()
	 *
	 * Commands that change persistent settings call this method to be sure that
	 * the changes are saved.
	 *
	 * (This method is abstract in SBGPCTDControllerBase0: derived controllers must
	 * provide an implementation.)
	 */
	virtual void SavePersistentSettings() = 0;

	/*! \brief Turn power on or off to the sensor
	 *
	 * Turns power on or off to the sensor, depending on the parameter passed in.
	 * Note that turning power off to the sensor will require communication to be
	 * re-established before any useful commands can be executed.
	 *
	 * (This method is abstract in SBGPCTDControllerBase0: derived controllers must
	 * provide an implementation.)
	 */
	virtual void SetPower(
			bool on				/**< [in] true if turning the sensor on, false if turning the sensor off */
			) = 0;

	/*! \brief Start background sampling of data
	 *  \sa StopSampling()
	 *
	 * Samples received through background sampling will be reported as Boost events.
	 * Note that the procedure for sampling is not necessarily the one directly
	 * implemented by the sensor.
	 *
	 * (This method is abstract in SBGPCTDControllerBase0: derived controllers must
	 * provide an implementation.)
	 */
	virtual void StartSampling() = 0;

	/*! \brief Stop backgorund sampling of data
	 *  \sa StartSampling()
	 *
	 * (This method is abstract in SBGPCTDControllerBase0: derived controllers must
	 * provide an implementation.)
	 */
	virtual void StopSampling() = 0;
};

/*! \var SBGPCTDConcreteCmd
 *  \brief The base class that all command classes should derive from
 *  \sa SBGPCTDControllerBase0
 */
typedef EventLib::SensorConcreteCommand<SBGPCTDControllerBase0,
										EventLib::SensorCommandBase<SBGPCTDCmdID>,
										SBGPCTDCmdID,
										EventLib::SensorControllerExceptions> SBGPCTDConcreteCmd;

}
}

#endif /* SBGPCTDCLASSCONFIG_H_ */
