#ifndef SHUTTERSETTINGS_HPP_INCLUDED
#define SHUTTERSETTINGS_HPP_INCLUDED

#include <iostream>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <vector>
#include <NBO/NBO/OpticalApertureID_Type.h>
#include <NBO/NBO/Settings_Type.h>
#include <NBO/NBO/ShutterMode_Type.h>
#include <NBO/NBO/UnitsLength_Type.h>
#include <NBO/NBO/ENBOType.h>
#include <NBO/NBOGlobal.h>
#include <NBO/Shared/Base/NBOBaseClass.h>


namespace Inscoper::NBO {

/*!
* \brief Represents the XML element ShutterSettings.
*
* This element holds the Setting applied to a Shutter used in the Light Path during the acquisition of this Channel as well as a reference (the ID attribute) to the Shutter in question.
*/
class NBO_EXPORT ShutterSettings : public Settings_Type {

public:
	
	ShutterSettings();
	~ShutterSettings();

	/*!
	* \brief Cast a NBOBaseClass to a ShutterSettings.
	*
	* \param base The base class to cast
	* \return The casted element, or nullptr if the cast fails
	*/
	static std::shared_ptr<ShutterSettings> fromBase(NBOBaseClassPtr base);

	/*!
	* \brief Returns the class type name.
	*
	* \return The class type name
	*/
	std::string getTypeName() const override;

	/*!
	* \brief Returns the XML element name corresponding to this class.
	*
	* \return The XML element name
	*/
	std::string getXMLName() const override;

	/*!
	* \brief Returns the NBO Type corresponding to this class.
	*
	* \return The NBO Type value
	*/
	ENBOType getNBOType() const override;

	/*!
	* \brief Returns a list of all classes derived from this class.
	*
	* \return The list of derived classes
	*/
	std::vector<NBOBaseClassPtr> getChildren() const override;

	/*!
	* \brief Returns a list of all child elements contained in this class.
	*
	* \return The list of child classes
	*/
	std::vector<NBOBaseClassPtr> getSubElements() const override;

	/*!
	* \brief Populates this object from a JSON file.
	*
	* \param path The path to the JSON file
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void fromJsonFile(const std::string& path, bool validate = true);

	/*!
	* \brief Populates this object from a JSON string.
	*
	* \param json_string The JSON content as a string
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void fromJsonString(const std::string& json_string, bool validate = true);

	/*!
	* \brief Populates this object from a XML file.
	*
	* \param path The path to the XML file
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void fromXmlFile(const std::string& path, bool validate = true);

	/*!
	* \brief Populates this object from a XML string.
	*
	* \param xml_string The XML content as a string
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void fromXmlString(const std::string& xml_string, bool validate = true);

	/*!
	* \brief Serializes this object to an XML file.
	*
	* \param filename The path to the output XML file
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void toXmlFile(const std::string& filename, bool validate = true) const;

	/*!
	* \brief Serializes this object to an XML string.
	*
	* \param validate If true, validates constraints on value. Default is true.
	* \return A string containing the XML representation of this object
	*/
	std::string toXmlString(bool validate = true) const;

	/*!
	* \brief Sets the value of the ID attribute.
	*
	* This is the Unique Identifier of the device used in this case.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setID(const Inscoper::NBO::OpticalApertureID_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the ID attribute.
	*
	* This is the Unique Identifier of the device used in this case.
	*
	* \return The value of the attribute
	*/
	OpticalApertureID_TypePtr getID() const;

	/*!
	* \brief Resets the ID attribute to an unset state.
	*
	* This is the Unique Identifier of the device used in this case.
	*/
	void resetID();

	/*!
	* \brief Checks whether the optional ID attribute is present.
	*
	* This is the Unique Identifier of the device used in this case.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasID() const;

	/*!
	* \brief Sets the value of the OpenDuringZMovement attribute.
	*
	* This field captures whether this Shutter was open (True) or closed (False) during Z-movement between successive Z-planes in this Image.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setOpenDuringZMovement(const bool& value, bool validate = true);

	/*!
	* \brief Returns the value of the OpenDuringZMovement attribute.
	*
	* This field captures whether this Shutter was open (True) or closed (False) during Z-movement between successive Z-planes in this Image.
	*
	* \return The value of the attribute
	*/
	bool getOpenDuringZMovement() const;

	/*!
	* \brief Resets the OpenDuringZMovement attribute to an unset state.
	*
	* This field captures whether this Shutter was open (True) or closed (False) during Z-movement between successive Z-planes in this Image.
	*/
	void resetOpenDuringZMovement();

	/*!
	* \brief Checks whether the OpenDuringZMovement attribute is present.
	*
	* This field captures whether this Shutter was open (True) or closed (False) during Z-movement between successive Z-planes in this Image.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasOpenDuringZMovement() const;

	/*!
	* \brief Sets the value of the ApertureDiameter attribute.
	*
	* This field records the actual physical Aperture Diameter that was used for this Shutter during the Acquisition of this Channel.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setApertureDiameter(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the ApertureDiameter attribute.
	*
	* This field records the actual physical Aperture Diameter that was used for this Shutter during the Acquisition of this Channel.
	*
	* \return The value of the attribute
	*/
	float getApertureDiameter() const;

	/*!
	* \brief Resets the ApertureDiameter attribute to an unset state.
	*
	* This field records the actual physical Aperture Diameter that was used for this Shutter during the Acquisition of this Channel.
	*/
	void resetApertureDiameter();

	/*!
	* \brief Checks whether the ApertureDiameter attribute is present.
	*
	* This field records the actual physical Aperture Diameter that was used for this Shutter during the Acquisition of this Channel.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasApertureDiameter() const;

	/*!
	* \brief Sets the value of the ApertureDiameterUnit attribute.
	*
	* No description available in the XSD standard.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setApertureDiameterUnit(const Inscoper::NBO::UnitsLength_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the ApertureDiameterUnit attribute.
	*
	* No description available in the XSD standard.
	*
	* \return The value of the attribute
	*/
	UnitsLength_TypePtr getApertureDiameterUnit() const;

	/*!
	* \brief Resets the ApertureDiameterUnit attribute to an unset state.
	*
	* No description available in the XSD standard.
	*/
	void resetApertureDiameterUnit();

	/*!
	* \brief Checks whether the optional ApertureDiameterUnit attribute is present.
	*
	* No description available in the XSD standard.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasApertureDiameterUnit() const;

	/*!
	* \brief Sets the value of the Mode attribute.
	*
	* This field records the operation mode that was applied to this Shutter during the Acquisition of this Channel. The Fast mode provides the quickest open and close action sequence for which the shutter is capable. The Soft intensity without affecting wavelength is accommodated by a Neutral Density shutter mode (for more details see https://www.microscopyu.com/applications/live-cell-imaging/the-automatic-microscope).
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setMode(const Inscoper::NBO::ShutterMode_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the Mode attribute.
	*
	* This field records the operation mode that was applied to this Shutter during the Acquisition of this Channel. The Fast mode provides the quickest open and close action sequence for which the shutter is capable. The Soft intensity without affecting wavelength is accommodated by a Neutral Density shutter mode (for more details see https://www.microscopyu.com/applications/live-cell-imaging/the-automatic-microscope).
	*
	* \return The value of the attribute
	*/
	ShutterMode_TypePtr getMode() const;

	/*!
	* \brief Resets the Mode attribute to an unset state.
	*
	* This field records the operation mode that was applied to this Shutter during the Acquisition of this Channel. The Fast mode provides the quickest open and close action sequence for which the shutter is capable. The Soft intensity without affecting wavelength is accommodated by a Neutral Density shutter mode (for more details see https://www.microscopyu.com/applications/live-cell-imaging/the-automatic-microscope).
	*/
	void resetMode();

	/*!
	* \brief Checks whether the optional Mode attribute is present.
	*
	* This field records the operation mode that was applied to this Shutter during the Acquisition of this Channel. The Fast mode provides the quickest open and close action sequence for which the shutter is capable. The Soft intensity without affecting wavelength is accommodated by a Neutral Density shutter mode (for more details see https://www.microscopyu.com/applications/live-cell-imaging/the-automatic-microscope).
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasMode() const;


private:
	class Impl;
	std::unique_ptr<Impl> pImpl;

	OpticalApertureID_TypePtr ID = nullptr; // Required attribute
    std::optional<bool> OpenDuringZMovement; // Required attribute
    std::optional<float> ApertureDiameter; // Optional attribute
	UnitsLength_TypePtr ApertureDiameterUnit = nullptr; // Optional attribute
	ShutterMode_TypePtr Mode = nullptr; // Optional attribute
};

/*! Shared pointer for ShutterSettings*/
typedef std::shared_ptr<ShutterSettings> ShutterSettingsPtr;

} // namespace Inscoper::NBO

#endif // SHUTTERSETTINGS_HPP_INCLUDED