#ifndef MICROSCOPETABLE_HPP_INCLUDED
#define MICROSCOPETABLE_HPP_INCLUDED

#include <iostream>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <vector>
#include <NBO/NBO/AnnotationRef.h>
#include <NBO/NBO/Denomination_Type.h>
#include <NBO/NBO/LSID_Type.h>
#include <NBO/NBO/ManufacturerSpec_Type.h>
#include <NBO/NBO/MicroscopeTableType_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 MicroscopeTable.
*
* This element describes the Table used to support this Instrument during Image Acquisition.
*/
class NBO_EXPORT MicroscopeTable : public ManufacturerSpec_Type {

public:
	
	MicroscopeTable();
	~MicroscopeTable();

	/*!
	* \brief Cast a NBOBaseClass to a MicroscopeTable.
	*
	* \param base The base class to cast
	* \return The casted element, or nullptr if the cast fails
	*/
	static std::shared_ptr<MicroscopeTable> 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.
	*
	* A Unique Identifier for this component.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setID(const Inscoper::NBO::LSID_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the ID attribute.
	*
	* A Unique Identifier for this component.
	*
	* \return The value of the attribute
	*/
	LSID_TypePtr getID() const;

	/*!
	* \brief Resets the ID attribute to an unset state.
	*
	* A Unique Identifier for this component.
	*/
	void resetID();

	/*!
	* \brief Checks whether the optional ID attribute is present.
	*
	* A Unique Identifier for this component.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasID() const;

	/*!
	* \brief Sets the value of the Name attribute.
	*
	* A User-defined Name for this component.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setName(const Inscoper::NBO::Denomination_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the Name attribute.
	*
	* A User-defined Name for this component.
	*
	* \return The value of the attribute
	*/
	Denomination_TypePtr getName() const;

	/*!
	* \brief Resets the Name attribute to an unset state.
	*
	* A User-defined Name for this component.
	*/
	void resetName();

	/*!
	* \brief Checks whether the optional Name attribute is present.
	*
	* A User-defined Name for this component.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasName() const;

	/*!
	* \brief Sets the value of the MultipleMicroscopes attribute.
	*
	* This field records whether (True) or not (False) multiple Microscopes share this Microscope Table. This is relevant because multiple Microscopes using the same table might affect stability and vibrations during Image Acquisition.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setMultipleMicroscopes(const bool& value, bool validate = true);

	/*!
	* \brief Returns the value of the MultipleMicroscopes attribute.
	*
	* This field records whether (True) or not (False) multiple Microscopes share this Microscope Table. This is relevant because multiple Microscopes using the same table might affect stability and vibrations during Image Acquisition.
	*
	* \return The value of the attribute
	*/
	bool getMultipleMicroscopes() const;

	/*!
	* \brief Resets the MultipleMicroscopes attribute to an unset state.
	*
	* This field records whether (True) or not (False) multiple Microscopes share this Microscope Table. This is relevant because multiple Microscopes using the same table might affect stability and vibrations during Image Acquisition.
	*/
	void resetMultipleMicroscopes();

	/*!
	* \brief Checks whether the MultipleMicroscopes attribute is present.
	*
	* This field records whether (True) or not (False) multiple Microscopes share this Microscope Table. This is relevant because multiple Microscopes using the same table might affect stability and vibrations during Image Acquisition.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasMultipleMicroscopes() const;

	/*!
	* \brief Sets the value of the Type attribute.
	*
	* This field describes the type of this Microscope Table.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setType(const Inscoper::NBO::MicroscopeTableType_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the Type attribute.
	*
	* This field describes the type of this Microscope Table.
	*
	* \return The value of the attribute
	*/
	MicroscopeTableType_TypePtr getType() const;

	/*!
	* \brief Resets the Type attribute to an unset state.
	*
	* This field describes the type of this Microscope Table.
	*/
	void resetType();

	/*!
	* \brief Checks whether the optional Type attribute is present.
	*
	* This field describes the type of this Microscope Table.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasType() const;

	/*!
	* \brief Sets the value of the TableWidth attribute.
	*
	* The Width of this Microscope Table.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setTableWidth(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the TableWidth attribute.
	*
	* The Width of this Microscope Table.
	*
	* \return The value of the attribute
	*/
	float getTableWidth() const;

	/*!
	* \brief Resets the TableWidth attribute to an unset state.
	*
	* The Width of this Microscope Table.
	*/
	void resetTableWidth();

	/*!
	* \brief Checks whether the TableWidth attribute is present.
	*
	* The Width of this Microscope Table.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasTableWidth() const;

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

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

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

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

	/*!
	* \brief Sets the value of the TableDepth attribute.
	*
	* The Depth of this Microscope Table.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setTableDepth(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the TableDepth attribute.
	*
	* The Depth of this Microscope Table.
	*
	* \return The value of the attribute
	*/
	float getTableDepth() const;

	/*!
	* \brief Resets the TableDepth attribute to an unset state.
	*
	* The Depth of this Microscope Table.
	*/
	void resetTableDepth();

	/*!
	* \brief Checks whether the TableDepth attribute is present.
	*
	* The Depth of this Microscope Table.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasTableDepth() const;

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

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

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

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

	/*!
	* \brief Sets the value of the AnnotationRef element.
	*
	* This is a simple multi-line comment or annotation describing this component.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setAnnotationRef(const Inscoper::NBO::AnnotationRefPtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the AnnotationRef element.
	*
	* This is a simple multi-line comment or annotation describing this component.
	*
	* \return The value of the element
	*/
	Inscoper::NBO::AnnotationRefPtr getAnnotationRef() const;

	/*!
	* \brief Resets the AnnotationRef element to an unset state.
	*
	* This is a simple multi-line comment or annotation describing this component.
	*/
	void resetAnnotationRef();

	/*!
	* \brief Checks whether the optional AnnotationRef element is present.
	*
	* This is a simple multi-line comment or annotation describing this component.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasAnnotationRef() const;


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

	LSID_TypePtr ID = nullptr; // Required attribute
	Denomination_TypePtr Name = nullptr; // Optional attribute
    std::optional<bool> MultipleMicroscopes; // Optional attribute
	MicroscopeTableType_TypePtr Type = nullptr; // Required attribute
    std::optional<float> TableWidth; // Optional attribute
	UnitsLength_TypePtr TableWidthUnit = nullptr; // Optional attribute
    std::optional<float> TableDepth; // Optional attribute
	UnitsLength_TypePtr TableDepthUnit = nullptr; // Optional attribute
    Inscoper::NBO::AnnotationRefPtr AnnotationRef = nullptr;
};

/*! Shared pointer for MicroscopeTable*/
typedef std::shared_ptr<MicroscopeTable> MicroscopeTablePtr;

} // namespace Inscoper::NBO

#endif // MICROSCOPETABLE_HPP_INCLUDED