#ifndef CONFOCALSCANNERSETTINGS_HPP_INCLUDED
#define CONFOCALSCANNERSETTINGS_HPP_INCLUDED

#include <iostream>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <vector>
#include <NBO/NBO/ConfocalMultiChannelMode_Type.h>
#include <NBO/NBO/ConfocalScanDirectionality_Type.h>
#include <NBO/NBO/ConfocalScanFormat_Type.h>
#include <NBO/NBO/ConfocalScannerID_Type.h>
#include <NBO/NBO/PercentFraction_Type.h>
#include <NBO/NBO/PositiveInt_Type.h>
#include <NBO/NBO/ScanIntegrationMethod_Type.h>
#include <NBO/NBO/ScanIntegrationMode_Type.h>
#include <NBO/NBO/Settings_Type.h>
#include <NBO/NBO/UnitsAngle_Type.h>
#include <NBO/NBO/UnitsLength_Type.h>
#include <NBO/NBO/UnitsTime_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 ConfocalScannerSettings.
*
* This element holds the Setting applied to a Confocal Scanner used during the Acquisiton of this Channel as well as a reference (the ID attribute) to the Confocal Scanner in question.
*/
class NBO_EXPORT ConfocalScannerSettings : public Settings_Type {

public:
	
	ConfocalScannerSettings();
	~ConfocalScannerSettings();

	/*!
	* \brief Cast a NBOBaseClass to a ConfocalScannerSettings.
	*
	* \param base The base class to cast
	* \return The casted element, or nullptr if the cast fails
	*/
	static std::shared_ptr<ConfocalScannerSettings> 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::ConfocalScannerID_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
	*/
	ConfocalScannerID_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 PresetPinholeSize attribute.
	*
	* In case this Confocal Scanner (i.e., Spinning disk, Swept-field, or other Multi-point scanners) has several fixed Pinhole Sizes to choose from, this field records the Pinhole Size that was set during the Acquisition of this Channel.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setPresetPinholeSize(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the PresetPinholeSize attribute.
	*
	* In case this Confocal Scanner (i.e., Spinning disk, Swept-field, or other Multi-point scanners) has several fixed Pinhole Sizes to choose from, this field records the Pinhole Size that was set during the Acquisition of this Channel.
	*
	* \return The value of the attribute
	*/
	float getPresetPinholeSize() const;

	/*!
	* \brief Resets the PresetPinholeSize attribute to an unset state.
	*
	* In case this Confocal Scanner (i.e., Spinning disk, Swept-field, or other Multi-point scanners) has several fixed Pinhole Sizes to choose from, this field records the Pinhole Size that was set during the Acquisition of this Channel.
	*/
	void resetPresetPinholeSize();

	/*!
	* \brief Checks whether the PresetPinholeSize attribute is present.
	*
	* In case this Confocal Scanner (i.e., Spinning disk, Swept-field, or other Multi-point scanners) has several fixed Pinhole Sizes to choose from, this field records the Pinhole Size that was set during the Acquisition of this Channel.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasPresetPinholeSize() const;

	/*!
	* \brief Sets the value of the PresetPinholeSizeUnit 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 setPresetPinholeSizeUnit(const Inscoper::NBO::UnitsLength_TypePtr& value, bool validate = true);

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

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

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

	/*!
	* \brief Sets the value of the PinholeSpacing attribute.
	*
	* If applicable, this field records the Spacing between individual Pinholes that was set during the Acquisition of this Channel.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setPinholeSpacing(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the PinholeSpacing attribute.
	*
	* If applicable, this field records the Spacing between individual Pinholes that was set during the Acquisition of this Channel.
	*
	* \return The value of the attribute
	*/
	float getPinholeSpacing() const;

	/*!
	* \brief Resets the PinholeSpacing attribute to an unset state.
	*
	* If applicable, this field records the Spacing between individual Pinholes that was set during the Acquisition of this Channel.
	*/
	void resetPinholeSpacing();

	/*!
	* \brief Checks whether the PinholeSpacing attribute is present.
	*
	* If applicable, this field records the Spacing between individual Pinholes that was set during the Acquisition of this Channel.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasPinholeSpacing() const;

	/*!
	* \brief Sets the value of the PinholeSpacingUnit attribute.
	*
	* If applicable, this field records the Spacing between individual Pinholes that was set during the Acquisition of this Channel.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setPinholeSpacingUnit(const Inscoper::NBO::UnitsLength_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the PinholeSpacingUnit attribute.
	*
	* If applicable, this field records the Spacing between individual Pinholes that was set during the Acquisition of this Channel.
	*
	* \return The value of the attribute
	*/
	UnitsLength_TypePtr getPinholeSpacingUnit() const;

	/*!
	* \brief Resets the PinholeSpacingUnit attribute to an unset state.
	*
	* If applicable, this field records the Spacing between individual Pinholes that was set during the Acquisition of this Channel.
	*/
	void resetPinholeSpacingUnit();

	/*!
	* \brief Checks whether the optional PinholeSpacingUnit attribute is present.
	*
	* If applicable, this field records the Spacing between individual Pinholes that was set during the Acquisition of this Channel.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasPinholeSpacingUnit() const;

	/*!
	* \brief Sets the value of the ScanDirectionality attribute.
	*
	* This field records the ScanDirectionality that was set for this device during Acquisition. In Unidirectional scan mode, data are only acquired while the laser beam moves in one direction. In Bidirectional scan mode, one line is scanned in one direction, and the next line in the opposite direction. In other words, the return run, or flyback, of the laser beam is used for recording data as well, thus increasing the scanning frequency when using bidirectional scan mode. Refer to https://www.iso.org/standard/69820.html for further details and measurement methods. 
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setScanDirectionality(const Inscoper::NBO::ConfocalScanDirectionality_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the ScanDirectionality attribute.
	*
	* This field records the ScanDirectionality that was set for this device during Acquisition. In Unidirectional scan mode, data are only acquired while the laser beam moves in one direction. In Bidirectional scan mode, one line is scanned in one direction, and the next line in the opposite direction. In other words, the return run, or flyback, of the laser beam is used for recording data as well, thus increasing the scanning frequency when using bidirectional scan mode. Refer to https://www.iso.org/standard/69820.html for further details and measurement methods. 
	*
	* \return The value of the attribute
	*/
	ConfocalScanDirectionality_TypePtr getScanDirectionality() const;

	/*!
	* \brief Resets the ScanDirectionality attribute to an unset state.
	*
	* This field records the ScanDirectionality that was set for this device during Acquisition. In Unidirectional scan mode, data are only acquired while the laser beam moves in one direction. In Bidirectional scan mode, one line is scanned in one direction, and the next line in the opposite direction. In other words, the return run, or flyback, of the laser beam is used for recording data as well, thus increasing the scanning frequency when using bidirectional scan mode. Refer to https://www.iso.org/standard/69820.html for further details and measurement methods. 
	*/
	void resetScanDirectionality();

	/*!
	* \brief Checks whether the optional ScanDirectionality attribute is present.
	*
	* This field records the ScanDirectionality that was set for this device during Acquisition. In Unidirectional scan mode, data are only acquired while the laser beam moves in one direction. In Bidirectional scan mode, one line is scanned in one direction, and the next line in the opposite direction. In other words, the return run, or flyback, of the laser beam is used for recording data as well, thus increasing the scanning frequency when using bidirectional scan mode. Refer to https://www.iso.org/standard/69820.html for further details and measurement methods. 
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasScanDirectionality() const;

	/*!
	* \brief Sets the value of the IntegrationNumber attribute.
	*
	* Signal integration is generally utilized to improve the overall signal-to-noise ratio of the resulting Image. This field records the number of sequential Scanning Units (Line, Frame or Stack) that have been integrated for the Acquisition of this Channel.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setIntegrationNumber(const Inscoper::NBO::PositiveInt_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the IntegrationNumber attribute.
	*
	* Signal integration is generally utilized to improve the overall signal-to-noise ratio of the resulting Image. This field records the number of sequential Scanning Units (Line, Frame or Stack) that have been integrated for the Acquisition of this Channel.
	*
	* \return The value of the attribute
	*/
	PositiveInt_TypePtr getIntegrationNumber() const;

	/*!
	* \brief Resets the IntegrationNumber attribute to an unset state.
	*
	* Signal integration is generally utilized to improve the overall signal-to-noise ratio of the resulting Image. This field records the number of sequential Scanning Units (Line, Frame or Stack) that have been integrated for the Acquisition of this Channel.
	*/
	void resetIntegrationNumber();

	/*!
	* \brief Checks whether the optional IntegrationNumber attribute is present.
	*
	* Signal integration is generally utilized to improve the overall signal-to-noise ratio of the resulting Image. This field records the number of sequential Scanning Units (Line, Frame or Stack) that have been integrated for the Acquisition of this Channel.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasIntegrationNumber() const;

	/*!
	* \brief Sets the value of the IntegrationUnit attribute.
	*
	* Signal integration is generally utilized to improve the overall signal-to-noise ratio of the resulting Image. This field refers to the nature of the Scanning Units used as the basis of signal integration. Refer to https://www.iso.org/standard/69820.html for further details and measurement methods.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setIntegrationUnit(const Inscoper::NBO::ScanIntegrationMode_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the IntegrationUnit attribute.
	*
	* Signal integration is generally utilized to improve the overall signal-to-noise ratio of the resulting Image. This field refers to the nature of the Scanning Units used as the basis of signal integration. Refer to https://www.iso.org/standard/69820.html for further details and measurement methods.
	*
	* \return The value of the attribute
	*/
	ScanIntegrationMode_TypePtr getIntegrationUnit() const;

	/*!
	* \brief Resets the IntegrationUnit attribute to an unset state.
	*
	* Signal integration is generally utilized to improve the overall signal-to-noise ratio of the resulting Image. This field refers to the nature of the Scanning Units used as the basis of signal integration. Refer to https://www.iso.org/standard/69820.html for further details and measurement methods.
	*/
	void resetIntegrationUnit();

	/*!
	* \brief Checks whether the optional IntegrationUnit attribute is present.
	*
	* Signal integration is generally utilized to improve the overall signal-to-noise ratio of the resulting Image. This field refers to the nature of the Scanning Units used as the basis of signal integration. Refer to https://www.iso.org/standard/69820.html for further details and measurement methods.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasIntegrationUnit() const;

	/*!
	* \brief Sets the value of the IntegrationMethod attribute.
	*
	* Signal integration is generally utilized to improve the overall signal-to-noise ratio of the resulting Image. This field defines the signal Integration Method utilized for the Acquisition of this Channel.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setIntegrationMethod(const Inscoper::NBO::ScanIntegrationMethod_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the IntegrationMethod attribute.
	*
	* Signal integration is generally utilized to improve the overall signal-to-noise ratio of the resulting Image. This field defines the signal Integration Method utilized for the Acquisition of this Channel.
	*
	* \return The value of the attribute
	*/
	ScanIntegrationMethod_TypePtr getIntegrationMethod() const;

	/*!
	* \brief Resets the IntegrationMethod attribute to an unset state.
	*
	* Signal integration is generally utilized to improve the overall signal-to-noise ratio of the resulting Image. This field defines the signal Integration Method utilized for the Acquisition of this Channel.
	*/
	void resetIntegrationMethod();

	/*!
	* \brief Checks whether the optional IntegrationMethod attribute is present.
	*
	* Signal integration is generally utilized to improve the overall signal-to-noise ratio of the resulting Image. This field defines the signal Integration Method utilized for the Acquisition of this Channel.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasIntegrationMethod() const;

	/*!
	* \brief Sets the value of the EffectiveZoom attribute.
	*
	* This field describes the Effective Zoom factor that was utilized for the acquisition of this Image (e.g., zoom = 1.3). In confocal microscopy, it is possible to set a given hardware-based Zoom factor, aka "Confocal Zoom" or "Scan Zoom", by reducing the angle at which the scanning mirrors operate. As a result, the scanned area will be reduced in size, which (because the pixel areas associated with the scan are kept constant) will decrease the effective size of the portion of the sample that is projected on each pixel thus increasing the effective resolving power of the system. For example, with a 512x512 pixel area, and with a 40x objective, zoom 1 we result in a pixel size of 732nm, while zoom 10 will reduce the pixel size to 73nm).In confocal microscopy, it is possible to set a given hardware-based Zoom factor, aka "Confocal Zoom" or "Scan Zoom", by reducing the angle at which the scanning mirrors operate. As a result, the scanned area will be reduced in size, which (because the pixel areas associated with the scan are kept constant) will decrease the effective size of the portion of the sample that is projected on each pixel thus increasing the effective resolving power of the system. For example, with a 512x512 pixel area, and with a 40x objective, zoom 1 we result in a pixel size of 732nm, while zoom 10 will reduce the pixel size to 73nm).
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setEffectiveZoom(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the EffectiveZoom attribute.
	*
	* This field describes the Effective Zoom factor that was utilized for the acquisition of this Image (e.g., zoom = 1.3). In confocal microscopy, it is possible to set a given hardware-based Zoom factor, aka "Confocal Zoom" or "Scan Zoom", by reducing the angle at which the scanning mirrors operate. As a result, the scanned area will be reduced in size, which (because the pixel areas associated with the scan are kept constant) will decrease the effective size of the portion of the sample that is projected on each pixel thus increasing the effective resolving power of the system. For example, with a 512x512 pixel area, and with a 40x objective, zoom 1 we result in a pixel size of 732nm, while zoom 10 will reduce the pixel size to 73nm).In confocal microscopy, it is possible to set a given hardware-based Zoom factor, aka "Confocal Zoom" or "Scan Zoom", by reducing the angle at which the scanning mirrors operate. As a result, the scanned area will be reduced in size, which (because the pixel areas associated with the scan are kept constant) will decrease the effective size of the portion of the sample that is projected on each pixel thus increasing the effective resolving power of the system. For example, with a 512x512 pixel area, and with a 40x objective, zoom 1 we result in a pixel size of 732nm, while zoom 10 will reduce the pixel size to 73nm).
	*
	* \return The value of the attribute
	*/
	float getEffectiveZoom() const;

	/*!
	* \brief Resets the EffectiveZoom attribute to an unset state.
	*
	* This field describes the Effective Zoom factor that was utilized for the acquisition of this Image (e.g., zoom = 1.3). In confocal microscopy, it is possible to set a given hardware-based Zoom factor, aka "Confocal Zoom" or "Scan Zoom", by reducing the angle at which the scanning mirrors operate. As a result, the scanned area will be reduced in size, which (because the pixel areas associated with the scan are kept constant) will decrease the effective size of the portion of the sample that is projected on each pixel thus increasing the effective resolving power of the system. For example, with a 512x512 pixel area, and with a 40x objective, zoom 1 we result in a pixel size of 732nm, while zoom 10 will reduce the pixel size to 73nm).In confocal microscopy, it is possible to set a given hardware-based Zoom factor, aka "Confocal Zoom" or "Scan Zoom", by reducing the angle at which the scanning mirrors operate. As a result, the scanned area will be reduced in size, which (because the pixel areas associated with the scan are kept constant) will decrease the effective size of the portion of the sample that is projected on each pixel thus increasing the effective resolving power of the system. For example, with a 512x512 pixel area, and with a 40x objective, zoom 1 we result in a pixel size of 732nm, while zoom 10 will reduce the pixel size to 73nm).
	*/
	void resetEffectiveZoom();

	/*!
	* \brief Checks whether the EffectiveZoom attribute is present.
	*
	* This field describes the Effective Zoom factor that was utilized for the acquisition of this Image (e.g., zoom = 1.3). In confocal microscopy, it is possible to set a given hardware-based Zoom factor, aka "Confocal Zoom" or "Scan Zoom", by reducing the angle at which the scanning mirrors operate. As a result, the scanned area will be reduced in size, which (because the pixel areas associated with the scan are kept constant) will decrease the effective size of the portion of the sample that is projected on each pixel thus increasing the effective resolving power of the system. For example, with a 512x512 pixel area, and with a 40x objective, zoom 1 we result in a pixel size of 732nm, while zoom 10 will reduce the pixel size to 73nm).In confocal microscopy, it is possible to set a given hardware-based Zoom factor, aka "Confocal Zoom" or "Scan Zoom", by reducing the angle at which the scanning mirrors operate. As a result, the scanned area will be reduced in size, which (because the pixel areas associated with the scan are kept constant) will decrease the effective size of the portion of the sample that is projected on each pixel thus increasing the effective resolving power of the system. For example, with a 512x512 pixel area, and with a 40x objective, zoom 1 we result in a pixel size of 732nm, while zoom 10 will reduce the pixel size to 73nm).
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasEffectiveZoom() const;

	/*!
	* \brief Sets the value of the ZoomAreaWidth attribute.
	*
	* This field records the Width of the Zoom Area that was scanned during the Acquisition of this Channel, expressed in Pixels.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setZoomAreaWidth(const Inscoper::NBO::PositiveInt_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the ZoomAreaWidth attribute.
	*
	* This field records the Width of the Zoom Area that was scanned during the Acquisition of this Channel, expressed in Pixels.
	*
	* \return The value of the attribute
	*/
	PositiveInt_TypePtr getZoomAreaWidth() const;

	/*!
	* \brief Resets the ZoomAreaWidth attribute to an unset state.
	*
	* This field records the Width of the Zoom Area that was scanned during the Acquisition of this Channel, expressed in Pixels.
	*/
	void resetZoomAreaWidth();

	/*!
	* \brief Checks whether the optional ZoomAreaWidth attribute is present.
	*
	* This field records the Width of the Zoom Area that was scanned during the Acquisition of this Channel, expressed in Pixels.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasZoomAreaWidth() const;

	/*!
	* \brief Sets the value of the ZoomAreaHeight attribute.
	*
	* This field records the Height of the Zoom Area that was scanned during the Acquisition of this Channel, expressed in Pixels.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setZoomAreaHeight(const Inscoper::NBO::PositiveInt_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the ZoomAreaHeight attribute.
	*
	* This field records the Height of the Zoom Area that was scanned during the Acquisition of this Channel, expressed in Pixels.
	*
	* \return The value of the attribute
	*/
	PositiveInt_TypePtr getZoomAreaHeight() const;

	/*!
	* \brief Resets the ZoomAreaHeight attribute to an unset state.
	*
	* This field records the Height of the Zoom Area that was scanned during the Acquisition of this Channel, expressed in Pixels.
	*/
	void resetZoomAreaHeight();

	/*!
	* \brief Checks whether the optional ZoomAreaHeight attribute is present.
	*
	* This field records the Height of the Zoom Area that was scanned during the Acquisition of this Channel, expressed in Pixels.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasZoomAreaHeight() const;

	/*!
	* \brief Sets the value of the Descanned attribute.
	*
	* This field indicates whether or not the Acquisition of this Image involved descanning.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setDescanned(const bool& value, bool validate = true);

	/*!
	* \brief Returns the value of the Descanned attribute.
	*
	* This field indicates whether or not the Acquisition of this Image involved descanning.
	*
	* \return The value of the attribute
	*/
	bool getDescanned() const;

	/*!
	* \brief Resets the Descanned attribute to an unset state.
	*
	* This field indicates whether or not the Acquisition of this Image involved descanning.
	*/
	void resetDescanned();

	/*!
	* \brief Checks whether the Descanned attribute is present.
	*
	* This field indicates whether or not the Acquisition of this Image involved descanning.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasDescanned() const;

	/*!
	* \brief Sets the value of the ScanFormat attribute.
	*
	* This field defines the format of the scanned element utilized for this Acquisition. Refer to https://www.iso.org/standard/69820.html for further details and measurement methods.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setScanFormat(const Inscoper::NBO::ConfocalScanFormat_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the ScanFormat attribute.
	*
	* This field defines the format of the scanned element utilized for this Acquisition. Refer to https://www.iso.org/standard/69820.html for further details and measurement methods.
	*
	* \return The value of the attribute
	*/
	ConfocalScanFormat_TypePtr getScanFormat() const;

	/*!
	* \brief Resets the ScanFormat attribute to an unset state.
	*
	* This field defines the format of the scanned element utilized for this Acquisition. Refer to https://www.iso.org/standard/69820.html for further details and measurement methods.
	*/
	void resetScanFormat();

	/*!
	* \brief Checks whether the optional ScanFormat attribute is present.
	*
	* This field defines the format of the scanned element utilized for this Acquisition. Refer to https://www.iso.org/standard/69820.html for further details and measurement methods.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasScanFormat() const;

	/*!
	* \brief Sets the value of the MultiChannelMode attribute.
	*
	* This field defines whether the the the Aquisiton of Multiple Channels for this Image happened in a Parallel (i.e., multiple channels acquired at the same time), or Sequentail (i.e., one channel after the other) manner.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setMultiChannelMode(const Inscoper::NBO::ConfocalMultiChannelMode_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the MultiChannelMode attribute.
	*
	* This field defines whether the the the Aquisiton of Multiple Channels for this Image happened in a Parallel (i.e., multiple channels acquired at the same time), or Sequentail (i.e., one channel after the other) manner.
	*
	* \return The value of the attribute
	*/
	ConfocalMultiChannelMode_TypePtr getMultiChannelMode() const;

	/*!
	* \brief Resets the MultiChannelMode attribute to an unset state.
	*
	* This field defines whether the the the Aquisiton of Multiple Channels for this Image happened in a Parallel (i.e., multiple channels acquired at the same time), or Sequentail (i.e., one channel after the other) manner.
	*/
	void resetMultiChannelMode();

	/*!
	* \brief Checks whether the optional MultiChannelMode attribute is present.
	*
	* This field defines whether the the the Aquisiton of Multiple Channels for this Image happened in a Parallel (i.e., multiple channels acquired at the same time), or Sequentail (i.e., one channel after the other) manner.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasMultiChannelMode() const;

	/*!
	* \brief Sets the value of the ScanTime attribute.
	*
	* This records the time in seconds required to acquire a given number of lines, frames or stacks including the time required for repositioning the scanning device to the starting point. Refer to https://www.iso.org/standard/69820.html for further details and measurement methods.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setScanTime(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the ScanTime attribute.
	*
	* This records the time in seconds required to acquire a given number of lines, frames or stacks including the time required for repositioning the scanning device to the starting point. Refer to https://www.iso.org/standard/69820.html for further details and measurement methods.
	*
	* \return The value of the attribute
	*/
	float getScanTime() const;

	/*!
	* \brief Resets the ScanTime attribute to an unset state.
	*
	* This records the time in seconds required to acquire a given number of lines, frames or stacks including the time required for repositioning the scanning device to the starting point. Refer to https://www.iso.org/standard/69820.html for further details and measurement methods.
	*/
	void resetScanTime();

	/*!
	* \brief Checks whether the ScanTime attribute is present.
	*
	* This records the time in seconds required to acquire a given number of lines, frames or stacks including the time required for repositioning the scanning device to the starting point. Refer to https://www.iso.org/standard/69820.html for further details and measurement methods.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasScanTime() const;

	/*!
	* \brief Sets the value of the ScanTimeUnit 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 setScanTimeUnit(const Inscoper::NBO::UnitsTime_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the ScanTimeUnit attribute.
	*
	* No description available in the XSD standard.
	*
	* \return The value of the attribute
	*/
	UnitsTime_TypePtr getScanTimeUnit() const;

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

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

	/*!
	* \brief Sets the value of the ConfocalFieldNumber attribute.
	*
	* This field recors the Field Number of the Confocal scan optic is expressed as the objective magnification times the maximum diameter of the scanned field; [mm], obtained without shifting the position of the specimen and without stitching single images into a total larger image. Because images generally have a square format, the diameter of the scanned field is equals to the square root of 2 times the length of X dimension of the scanned field. Refer to https://www.iso.org/standard/69820.html for further details and measurement methods.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setConfocalFieldNumber(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the ConfocalFieldNumber attribute.
	*
	* This field recors the Field Number of the Confocal scan optic is expressed as the objective magnification times the maximum diameter of the scanned field; [mm], obtained without shifting the position of the specimen and without stitching single images into a total larger image. Because images generally have a square format, the diameter of the scanned field is equals to the square root of 2 times the length of X dimension of the scanned field. Refer to https://www.iso.org/standard/69820.html for further details and measurement methods.
	*
	* \return The value of the attribute
	*/
	float getConfocalFieldNumber() const;

	/*!
	* \brief Resets the ConfocalFieldNumber attribute to an unset state.
	*
	* This field recors the Field Number of the Confocal scan optic is expressed as the objective magnification times the maximum diameter of the scanned field; [mm], obtained without shifting the position of the specimen and without stitching single images into a total larger image. Because images generally have a square format, the diameter of the scanned field is equals to the square root of 2 times the length of X dimension of the scanned field. Refer to https://www.iso.org/standard/69820.html for further details and measurement methods.
	*/
	void resetConfocalFieldNumber();

	/*!
	* \brief Checks whether the ConfocalFieldNumber attribute is present.
	*
	* This field recors the Field Number of the Confocal scan optic is expressed as the objective magnification times the maximum diameter of the scanned field; [mm], obtained without shifting the position of the specimen and without stitching single images into a total larger image. Because images generally have a square format, the diameter of the scanned field is equals to the square root of 2 times the length of X dimension of the scanned field. Refer to https://www.iso.org/standard/69820.html for further details and measurement methods.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasConfocalFieldNumber() const;

	/*!
	* \brief Sets the value of the Rotation attribute.
	*
	* This field records the Rotation angle of the scan region.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setRotation(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the Rotation attribute.
	*
	* This field records the Rotation angle of the scan region.
	*
	* \return The value of the attribute
	*/
	float getRotation() const;

	/*!
	* \brief Resets the Rotation attribute to an unset state.
	*
	* This field records the Rotation angle of the scan region.
	*/
	void resetRotation();

	/*!
	* \brief Checks whether the Rotation attribute is present.
	*
	* This field records the Rotation angle of the scan region.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasRotation() const;

	/*!
	* \brief Sets the value of the RotationUnit 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 setRotationUnit(const Inscoper::NBO::UnitsAngle_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the RotationUnit attribute.
	*
	* No description available in the XSD standard.
	*
	* \return The value of the attribute
	*/
	UnitsAngle_TypePtr getRotationUnit() const;

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

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

	/*!
	* \brief Sets the value of the ScanningFrequency attribute.
	*
	* This field records the Scanning Frequency is defined at the ratio between the Number of scanning element (Lines, Frames or Stacks) acquired and ScanTime. Refer to https://www.iso.org/standard/69820.html for further details and measurement methods.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setScanningFrequency(const Inscoper::NBO::PercentFraction_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the ScanningFrequency attribute.
	*
	* This field records the Scanning Frequency is defined at the ratio between the Number of scanning element (Lines, Frames or Stacks) acquired and ScanTime. Refer to https://www.iso.org/standard/69820.html for further details and measurement methods.
	*
	* \return The value of the attribute
	*/
	PercentFraction_TypePtr getScanningFrequency() const;

	/*!
	* \brief Resets the ScanningFrequency attribute to an unset state.
	*
	* This field records the Scanning Frequency is defined at the ratio between the Number of scanning element (Lines, Frames or Stacks) acquired and ScanTime. Refer to https://www.iso.org/standard/69820.html for further details and measurement methods.
	*/
	void resetScanningFrequency();

	/*!
	* \brief Checks whether the optional ScanningFrequency attribute is present.
	*
	* This field records the Scanning Frequency is defined at the ratio between the Number of scanning element (Lines, Frames or Stacks) acquired and ScanTime. Refer to https://www.iso.org/standard/69820.html for further details and measurement methods.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasScanningFrequency() const;


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

	ConfocalScannerID_TypePtr ID = nullptr; // Required attribute
    std::optional<float> PresetPinholeSize; // Required attribute
	UnitsLength_TypePtr PresetPinholeSizeUnit = nullptr; // Optional attribute
    std::optional<float> PinholeSpacing; // Optional attribute
	UnitsLength_TypePtr PinholeSpacingUnit = nullptr; // Optional attribute
	ConfocalScanDirectionality_TypePtr ScanDirectionality = nullptr; // Required attribute
	PositiveInt_TypePtr IntegrationNumber = nullptr; // Required attribute
	ScanIntegrationMode_TypePtr IntegrationUnit = nullptr; // Required attribute
	ScanIntegrationMethod_TypePtr IntegrationMethod = nullptr; // Required attribute
    std::optional<float> EffectiveZoom; // Required attribute
	PositiveInt_TypePtr ZoomAreaWidth = nullptr; // Optional attribute
	PositiveInt_TypePtr ZoomAreaHeight = nullptr; // Optional attribute
    std::optional<bool> Descanned; // Required attribute
	ConfocalScanFormat_TypePtr ScanFormat = nullptr; // Required attribute
	ConfocalMultiChannelMode_TypePtr MultiChannelMode = nullptr; // Required attribute
    std::optional<float> ScanTime; // Required attribute
	UnitsTime_TypePtr ScanTimeUnit = nullptr; // Required attribute
    std::optional<float> ConfocalFieldNumber; // Optional attribute
    std::optional<float> Rotation; // Optional attribute
	UnitsAngle_TypePtr RotationUnit = nullptr; // Optional attribute
	PercentFraction_TypePtr ScanningFrequency = nullptr; // Optional attribute
};

/*! Shared pointer for ConfocalScannerSettings*/
typedef std::shared_ptr<ConfocalScannerSettings> ConfocalScannerSettingsPtr;

} // namespace Inscoper::NBO

#endif // CONFOCALSCANNERSETTINGS_HPP_INCLUDED