#ifndef SAMPLEPOSITIONINGSETTINGS_HPP_INCLUDED
#define SAMPLEPOSITIONINGSETTINGS_HPP_INCLUDED

#include <iostream>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <vector>
#include <NBO/NBO/SamplePositioningID_Type.h>
#include <NBO/NBO/Settings_Type.h>
#include <NBO/NBO/UnitsLength_Type.h>
#include <NBO/NBO/UnitsVelocity_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 SamplePositioningSettings.
*
* This element holds the Setting applied to a Sample Positioning Device used  during the Acquisiton of this experimental Image as well as a reference (the ID attribute) to the Sample Positioning Device in question.
*/
class NBO_EXPORT SamplePositioningSettings : public Settings_Type {

public:
	
	SamplePositioningSettings();
	~SamplePositioningSettings();

	/*!
	* \brief Cast a NBOBaseClass to a SamplePositioningSettings.
	*
	* \param base The base class to cast
	* \return The casted element, or nullptr if the cast fails
	*/
	static std::shared_ptr<SamplePositioningSettings> 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 Sample Positioning 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::SamplePositioningID_TypePtr& value, bool validate = true);

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

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

	/*!
	* \brief Checks whether the optional ID attribute is present.
	*
	* This is the Unique Identifier of the Sample Positioning 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 XYVelocitySetting attribute.
	*
	* This field describes the XY Velocity that was set for this Sample Positioning Device during the Acquisition of this experimental Image.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setXYVelocitySetting(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the XYVelocitySetting attribute.
	*
	* This field describes the XY Velocity that was set for this Sample Positioning Device during the Acquisition of this experimental Image.
	*
	* \return The value of the attribute
	*/
	float getXYVelocitySetting() const;

	/*!
	* \brief Resets the XYVelocitySetting attribute to an unset state.
	*
	* This field describes the XY Velocity that was set for this Sample Positioning Device during the Acquisition of this experimental Image.
	*/
	void resetXYVelocitySetting();

	/*!
	* \brief Checks whether the XYVelocitySetting attribute is present.
	*
	* This field describes the XY Velocity that was set for this Sample Positioning Device during the Acquisition of this experimental Image.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasXYVelocitySetting() const;

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

	/*!
	* \brief Returns the value of the XYVelocitySettingUnit attribute.
	*
	* No description available in the XSD standard.
	*
	* \return The value of the attribute
	*/
	UnitsVelocity_TypePtr getXYVelocitySettingUnit() const;

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

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

	/*!
	* \brief Sets the value of the ZVelocitySetting attribute.
	*
	* This field describes the Z-axis Velocity that was set for this Sample Positioning Device during the Acquisition of this experimental Image.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setZVelocitySetting(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the ZVelocitySetting attribute.
	*
	* This field describes the Z-axis Velocity that was set for this Sample Positioning Device during the Acquisition of this experimental Image.
	*
	* \return The value of the attribute
	*/
	float getZVelocitySetting() const;

	/*!
	* \brief Resets the ZVelocitySetting attribute to an unset state.
	*
	* This field describes the Z-axis Velocity that was set for this Sample Positioning Device during the Acquisition of this experimental Image.
	*/
	void resetZVelocitySetting();

	/*!
	* \brief Checks whether the ZVelocitySetting attribute is present.
	*
	* This field describes the Z-axis Velocity that was set for this Sample Positioning Device during the Acquisition of this experimental Image.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasZVelocitySetting() const;

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

	/*!
	* \brief Returns the value of the ZVelocitySettingUnit attribute.
	*
	* No description available in the XSD standard.
	*
	* \return The value of the attribute
	*/
	UnitsVelocity_TypePtr getZVelocitySettingUnit() const;

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

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

	/*!
	* \brief Sets the value of the XYReproducibilitySettings attribute.
	*
	* This field describes the XY Precision that was set for this Sample Positioning Device during the Acquisition of this experimental Image. This metric refers to the capacity this Device of maintaining a given XY Position over time as specified by the Manufacturer. This metric is generally referred to as Reproducibility and it might also be referred to as Lateral Drift. This metric is particularly relevant for Stereology systems and for the calibration of Sample Positioning devices.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setXYReproducibilitySettings(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the XYReproducibilitySettings attribute.
	*
	* This field describes the XY Precision that was set for this Sample Positioning Device during the Acquisition of this experimental Image. This metric refers to the capacity this Device of maintaining a given XY Position over time as specified by the Manufacturer. This metric is generally referred to as Reproducibility and it might also be referred to as Lateral Drift. This metric is particularly relevant for Stereology systems and for the calibration of Sample Positioning devices.
	*
	* \return The value of the attribute
	*/
	float getXYReproducibilitySettings() const;

	/*!
	* \brief Resets the XYReproducibilitySettings attribute to an unset state.
	*
	* This field describes the XY Precision that was set for this Sample Positioning Device during the Acquisition of this experimental Image. This metric refers to the capacity this Device of maintaining a given XY Position over time as specified by the Manufacturer. This metric is generally referred to as Reproducibility and it might also be referred to as Lateral Drift. This metric is particularly relevant for Stereology systems and for the calibration of Sample Positioning devices.
	*/
	void resetXYReproducibilitySettings();

	/*!
	* \brief Checks whether the XYReproducibilitySettings attribute is present.
	*
	* This field describes the XY Precision that was set for this Sample Positioning Device during the Acquisition of this experimental Image. This metric refers to the capacity this Device of maintaining a given XY Position over time as specified by the Manufacturer. This metric is generally referred to as Reproducibility and it might also be referred to as Lateral Drift. This metric is particularly relevant for Stereology systems and for the calibration of Sample Positioning devices.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasXYReproducibilitySettings() const;

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

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

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

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

	/*!
	* \brief Sets the value of the ZReproducibilitySettings attribute.
	*
	* This field describes the Z-Axis Precision that was set for this Sample Positioning Device during the Acquisition of this experimental Image. This metric refers to the capacity this Device of maintaining a given Z-axis Position over time as specified by the Manufacturer. This metric is generally referred to as Reproducibility and it might also be referred to as Focal Drift. This metric is particularly relevant for Stereology systems and for the calibration of Sample Positioning devices.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setZReproducibilitySettings(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the ZReproducibilitySettings attribute.
	*
	* This field describes the Z-Axis Precision that was set for this Sample Positioning Device during the Acquisition of this experimental Image. This metric refers to the capacity this Device of maintaining a given Z-axis Position over time as specified by the Manufacturer. This metric is generally referred to as Reproducibility and it might also be referred to as Focal Drift. This metric is particularly relevant for Stereology systems and for the calibration of Sample Positioning devices.
	*
	* \return The value of the attribute
	*/
	float getZReproducibilitySettings() const;

	/*!
	* \brief Resets the ZReproducibilitySettings attribute to an unset state.
	*
	* This field describes the Z-Axis Precision that was set for this Sample Positioning Device during the Acquisition of this experimental Image. This metric refers to the capacity this Device of maintaining a given Z-axis Position over time as specified by the Manufacturer. This metric is generally referred to as Reproducibility and it might also be referred to as Focal Drift. This metric is particularly relevant for Stereology systems and for the calibration of Sample Positioning devices.
	*/
	void resetZReproducibilitySettings();

	/*!
	* \brief Checks whether the ZReproducibilitySettings attribute is present.
	*
	* This field describes the Z-Axis Precision that was set for this Sample Positioning Device during the Acquisition of this experimental Image. This metric refers to the capacity this Device of maintaining a given Z-axis Position over time as specified by the Manufacturer. This metric is generally referred to as Reproducibility and it might also be referred to as Focal Drift. This metric is particularly relevant for Stereology systems and for the calibration of Sample Positioning devices.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasZReproducibilitySettings() const;

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

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

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

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


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

	SamplePositioningID_TypePtr ID = nullptr; // Required attribute
    std::optional<float> XYVelocitySetting; // Optional attribute
	UnitsVelocity_TypePtr XYVelocitySettingUnit = nullptr; // Optional attribute
    std::optional<float> ZVelocitySetting; // Optional attribute
	UnitsVelocity_TypePtr ZVelocitySettingUnit = nullptr; // Optional attribute
    std::optional<float> XYReproducibilitySettings; // Optional attribute
	UnitsLength_TypePtr XYReproducibilitySettingsUnit = nullptr; // Optional attribute
    std::optional<float> ZReproducibilitySettings; // Optional attribute
	UnitsLength_TypePtr ZReproducibilitySettingsUnit = nullptr; // Optional attribute
};

/*! Shared pointer for SamplePositioningSettings*/
typedef std::shared_ptr<SamplePositioningSettings> SamplePositioningSettingsPtr;

} // namespace Inscoper::NBO

#endif // SAMPLEPOSITIONINGSETTINGS_HPP_INCLUDED