#ifndef PLATE_HPP_INCLUDED
#define PLATE_HPP_INCLUDED

#include <iostream>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <vector>
#include <NBO/NBO/AnnotationRef.h>
#include <NBO/NBO/NamingConvention_Type.h>
#include <NBO/NBO/NonNegativeInt_Type.h>
#include <NBO/NBO/PlateAcquisition.h>
#include <NBO/NBO/PlateID_Type.h>
#include <NBO/NBO/PositiveInt_Type.h>
#include <NBO/NBO/UnitsLength_Type.h>
#include <NBO/NBO/Well.h>
#include <NBO/NBO/ENBOType.h>
#include <NBO/NBOGlobal.h>
#include <NBO/Shared/Base/NBOBaseClass.h>


namespace Inscoper::NBO {

/*!
* \brief Represents the XML element Plate.
*
* A description for the plate. 
*/
class NBO_EXPORT Plate : public NBOBaseClass {

public:
	/*!
	* \brief Represents the XML element Description.
	*
	* No description available in the XSD standard.
	*/
	class NBO_EXPORT InlineDescription : public NBOBaseClass {
	
	public:
		
		InlineDescription();
		~InlineDescription();
	
		/*!
		* \brief Cast a NBOBaseClass to a InlineDescription.
		*
		* \param base The base class to cast
		* \return The casted element, or nullptr if the cast fails
		*/
		static std::shared_ptr<InlineDescription> 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 Assigns a new value to this object (= operator operator).
		*
		* \param v The value to set
		*/
		InlineDescription& operator=(const std::string& v);
	
		/*!
		* \brief Returns the value of this object  (generic conversion operator overload).
		*
		* \return The value of the object
		*/
		operator std::string() const;
	
		/*!
		* \brief Assigns a new value to this object.
		*
		* \param v The value to set
		* \param validate If true, validates constraints on value. Default is true.
		*/
		void set(const std::string& v, bool validate = true);
	
		/*!
		* \brief Returns the value of this object.
		*
		* \return The value of the object
		*/
		std::string get() const;
	
		/*!
		* \brief Returns the allowed values for this object.
		*
		* \return The list of allowed values
		*/
		static const std::set<std::string>& getAllowedValues();
	
		/*!
		* \brief Returns the pattern for this object.
		*
		* \return The pattern
		*/
		static const std::string& getPattern();
	
	private:
		std::string value;
	
		static const std::set<std::string> allowedValues;
		static const std::string validationPattern;
		friend std::ostream& operator<<(std::ostream& os, const InlineDescription& u);
	
	
	private:
		class Impl;
		std::unique_ptr<Impl> pImpl;
	};
	
	/*! Shared pointer for InlineDescription*/
	typedef std::shared_ptr<InlineDescription> InlineDescriptionPtr;
	
	
	Plate();
	~Plate();

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

	/*!
	* \brief Returns the value of the ID attribute.
	*
	* No description available in the XSD standard.
	*
	* \return The value of the attribute
	*/
	PlateID_TypePtr getID() const;

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

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

	/*!
	* \brief Sets the value of the Name attribute.
	*
	* The Name identifies the plate to the user. It is used much like the ID, and so must be unique within the document. If a plate name is not available when one is needed it will be constructed in the following order: 1. If name is available use it. 2. If not use "Start time - End time" (NOTE: Not a subtraction! A string representation of the two times separated by a dash.) 3. If these times are not available use the Plate ID. 
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setName(const std::string& value, bool validate = true);

	/*!
	* \brief Returns the value of the Name attribute.
	*
	* The Name identifies the plate to the user. It is used much like the ID, and so must be unique within the document. If a plate name is not available when one is needed it will be constructed in the following order: 1. If name is available use it. 2. If not use "Start time - End time" (NOTE: Not a subtraction! A string representation of the two times separated by a dash.) 3. If these times are not available use the Plate ID. 
	*
	* \return The value of the attribute
	*/
	std::string getName() const;

	/*!
	* \brief Resets the Name attribute to an unset state.
	*
	* The Name identifies the plate to the user. It is used much like the ID, and so must be unique within the document. If a plate name is not available when one is needed it will be constructed in the following order: 1. If name is available use it. 2. If not use "Start time - End time" (NOTE: Not a subtraction! A string representation of the two times separated by a dash.) 3. If these times are not available use the Plate ID. 
	*/
	void resetName();

	/*!
	* \brief Checks whether the Name attribute is present.
	*
	* The Name identifies the plate to the user. It is used much like the ID, and so must be unique within the document. If a plate name is not available when one is needed it will be constructed in the following order: 1. If name is available use it. 2. If not use "Start time - End time" (NOTE: Not a subtraction! A string representation of the two times separated by a dash.) 3. If these times are not available use the Plate ID. 
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasName() const;

	/*!
	* \brief Returns the allowed values for this attribut.
	*
	* The Name identifies the plate to the user. It is used much like the ID, and so must be unique within the document. If a plate name is not available when one is needed it will be constructed in the following order: 1. If name is available use it. 2. If not use "Start time - End time" (NOTE: Not a subtraction! A string representation of the two times separated by a dash.) 3. If these times are not available use the Plate ID. 
	*
	* \return The list of allowed values
	*/
	static const std::set<std::string>& getNameAllowedValues();

	/*!
	* \brief Sets the value of the Status attribute.
	*
	* A textual annotation of the current state of the plate with respect to the experiment work-flow; e.g. 1. Seed cell: done; 2. Transfection: done; 3. Gel doc: todo. 
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setStatus(const std::string& value, bool validate = true);

	/*!
	* \brief Returns the value of the Status attribute.
	*
	* A textual annotation of the current state of the plate with respect to the experiment work-flow; e.g. 1. Seed cell: done; 2. Transfection: done; 3. Gel doc: todo. 
	*
	* \return The value of the attribute
	*/
	std::string getStatus() const;

	/*!
	* \brief Resets the Status attribute to an unset state.
	*
	* A textual annotation of the current state of the plate with respect to the experiment work-flow; e.g. 1. Seed cell: done; 2. Transfection: done; 3. Gel doc: todo. 
	*/
	void resetStatus();

	/*!
	* \brief Checks whether the Status attribute is present.
	*
	* A textual annotation of the current state of the plate with respect to the experiment work-flow; e.g. 1. Seed cell: done; 2. Transfection: done; 3. Gel doc: todo. 
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasStatus() const;

	/*!
	* \brief Returns the allowed values for this attribut.
	*
	* A textual annotation of the current state of the plate with respect to the experiment work-flow; e.g. 1. Seed cell: done; 2. Transfection: done; 3. Gel doc: todo. 
	*
	* \return The list of allowed values
	*/
	static const std::set<std::string>& getStatusAllowedValues();

	/*!
	* \brief Sets the value of the ExternalIdentifier attribute.
	*
	* The ExternalIdentifier attribute may contain a reference to an external database. 
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setExternalIdentifier(const std::string& value, bool validate = true);

	/*!
	* \brief Returns the value of the ExternalIdentifier attribute.
	*
	* The ExternalIdentifier attribute may contain a reference to an external database. 
	*
	* \return The value of the attribute
	*/
	std::string getExternalIdentifier() const;

	/*!
	* \brief Resets the ExternalIdentifier attribute to an unset state.
	*
	* The ExternalIdentifier attribute may contain a reference to an external database. 
	*/
	void resetExternalIdentifier();

	/*!
	* \brief Checks whether the ExternalIdentifier attribute is present.
	*
	* The ExternalIdentifier attribute may contain a reference to an external database. 
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasExternalIdentifier() const;

	/*!
	* \brief Returns the allowed values for this attribut.
	*
	* The ExternalIdentifier attribute may contain a reference to an external database. 
	*
	* \return The list of allowed values
	*/
	static const std::set<std::string>& getExternalIdentifierAllowedValues();

	/*!
	* \brief Sets the value of the ColumnNamingConvention attribute.
	*
	* The ColumnNamingConvention 
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setColumnNamingConvention(const Inscoper::NBO::NamingConvention_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the ColumnNamingConvention attribute.
	*
	* The ColumnNamingConvention 
	*
	* \return The value of the attribute
	*/
	NamingConvention_TypePtr getColumnNamingConvention() const;

	/*!
	* \brief Resets the ColumnNamingConvention attribute to an unset state.
	*
	* The ColumnNamingConvention 
	*/
	void resetColumnNamingConvention();

	/*!
	* \brief Checks whether the optional ColumnNamingConvention attribute is present.
	*
	* The ColumnNamingConvention 
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasColumnNamingConvention() const;

	/*!
	* \brief Sets the value of the RowNamingConvention attribute.
	*
	* The RowNamingConvention 
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setRowNamingConvention(const Inscoper::NBO::NamingConvention_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the RowNamingConvention attribute.
	*
	* The RowNamingConvention 
	*
	* \return The value of the attribute
	*/
	NamingConvention_TypePtr getRowNamingConvention() const;

	/*!
	* \brief Resets the RowNamingConvention attribute to an unset state.
	*
	* The RowNamingConvention 
	*/
	void resetRowNamingConvention();

	/*!
	* \brief Checks whether the optional RowNamingConvention attribute is present.
	*
	* The RowNamingConvention 
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasRowNamingConvention() const;

	/*!
	* \brief Sets the value of the WellOriginX attribute.
	*
	* This defines the X position to use for the origin of the fields (individual images) taken in a well. It is used with the X in the WellSample to display the fields in the correct position relative to each other. Each Well in the plate has the same well origin. Units are set by WellOriginXUnit. In the OMERO clients by convention we display the WellOrigin in the center of the view. 
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setWellOriginX(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the WellOriginX attribute.
	*
	* This defines the X position to use for the origin of the fields (individual images) taken in a well. It is used with the X in the WellSample to display the fields in the correct position relative to each other. Each Well in the plate has the same well origin. Units are set by WellOriginXUnit. In the OMERO clients by convention we display the WellOrigin in the center of the view. 
	*
	* \return The value of the attribute
	*/
	float getWellOriginX() const;

	/*!
	* \brief Resets the WellOriginX attribute to an unset state.
	*
	* This defines the X position to use for the origin of the fields (individual images) taken in a well. It is used with the X in the WellSample to display the fields in the correct position relative to each other. Each Well in the plate has the same well origin. Units are set by WellOriginXUnit. In the OMERO clients by convention we display the WellOrigin in the center of the view. 
	*/
	void resetWellOriginX();

	/*!
	* \brief Checks whether the WellOriginX attribute is present.
	*
	* This defines the X position to use for the origin of the fields (individual images) taken in a well. It is used with the X in the WellSample to display the fields in the correct position relative to each other. Each Well in the plate has the same well origin. Units are set by WellOriginXUnit. In the OMERO clients by convention we display the WellOrigin in the center of the view. 
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasWellOriginX() const;

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

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

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

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

	/*!
	* \brief Sets the value of the WellOriginY attribute.
	*
	* This defines the Y position to use for the origin of the fields (individual images) taken in a well. It is used with the Y in the WellSample to display the fields in the correct position relative to each other. Each Well in the plate has the same well origin. Units are set by WellOriginYUnit. In the OMERO clients by convention we display the WellOrigin in the center of the view. 
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setWellOriginY(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the WellOriginY attribute.
	*
	* This defines the Y position to use for the origin of the fields (individual images) taken in a well. It is used with the Y in the WellSample to display the fields in the correct position relative to each other. Each Well in the plate has the same well origin. Units are set by WellOriginYUnit. In the OMERO clients by convention we display the WellOrigin in the center of the view. 
	*
	* \return The value of the attribute
	*/
	float getWellOriginY() const;

	/*!
	* \brief Resets the WellOriginY attribute to an unset state.
	*
	* This defines the Y position to use for the origin of the fields (individual images) taken in a well. It is used with the Y in the WellSample to display the fields in the correct position relative to each other. Each Well in the plate has the same well origin. Units are set by WellOriginYUnit. In the OMERO clients by convention we display the WellOrigin in the center of the view. 
	*/
	void resetWellOriginY();

	/*!
	* \brief Checks whether the WellOriginY attribute is present.
	*
	* This defines the Y position to use for the origin of the fields (individual images) taken in a well. It is used with the Y in the WellSample to display the fields in the correct position relative to each other. Each Well in the plate has the same well origin. Units are set by WellOriginYUnit. In the OMERO clients by convention we display the WellOrigin in the center of the view. 
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasWellOriginY() const;

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

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

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

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

	/*!
	* \brief Sets the value of the Rows attribute.
	*
	* The number of rows in the plate 
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setRows(const Inscoper::NBO::PositiveInt_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the Rows attribute.
	*
	* The number of rows in the plate 
	*
	* \return The value of the attribute
	*/
	PositiveInt_TypePtr getRows() const;

	/*!
	* \brief Resets the Rows attribute to an unset state.
	*
	* The number of rows in the plate 
	*/
	void resetRows();

	/*!
	* \brief Checks whether the optional Rows attribute is present.
	*
	* The number of rows in the plate 
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasRows() const;

	/*!
	* \brief Sets the value of the Columns attribute.
	*
	* The number of columns in the plate 
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setColumns(const Inscoper::NBO::PositiveInt_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the Columns attribute.
	*
	* The number of columns in the plate 
	*
	* \return The value of the attribute
	*/
	PositiveInt_TypePtr getColumns() const;

	/*!
	* \brief Resets the Columns attribute to an unset state.
	*
	* The number of columns in the plate 
	*/
	void resetColumns();

	/*!
	* \brief Checks whether the optional Columns attribute is present.
	*
	* The number of columns in the plate 
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasColumns() const;

	/*!
	* \brief Sets the value of the FieldIndex attribute.
	*
	* The index of the WellSample to display as the default Field 
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setFieldIndex(const Inscoper::NBO::NonNegativeInt_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the FieldIndex attribute.
	*
	* The index of the WellSample to display as the default Field 
	*
	* \return The value of the attribute
	*/
	NonNegativeInt_TypePtr getFieldIndex() const;

	/*!
	* \brief Resets the FieldIndex attribute to an unset state.
	*
	* The index of the WellSample to display as the default Field 
	*/
	void resetFieldIndex();

	/*!
	* \brief Checks whether the optional FieldIndex attribute is present.
	*
	* The index of the WellSample to display as the default Field 
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasFieldIndex() const;

	/*!
	* \brief Sets the value of the Description element.
	*
	* A description for the plate. 
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setDescription(const Inscoper::NBO::Plate::InlineDescriptionPtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the Description element.
	*
	* A description for the plate. 
	*
	* \return The value of the element
	*/
	Inscoper::NBO::Plate::InlineDescriptionPtr getDescription() const;

	/*!
	* \brief Resets the Description element to an unset state.
	*
	* A description for the plate. 
	*/
	void resetDescription();

	/*!
	* \brief Checks whether the optional Description element is present.
	*
	* A description for the plate. 
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasDescription() const;

	/*!
	* \brief Sets the list of Well elements.
	*
	* No description available in the XSD standard.
	*
	* \param value The new list of Well elements
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setWell_List(const std::vector<Inscoper::NBO::WellPtr>& value, bool validate = true);

	/*!
	* \brief Returns the list of Well elements.
	*
	* No description available in the XSD standard.
	*
	* \return The list of Well elements
	*/
	std::vector<Inscoper::NBO::WellPtr> getWell_List() const;

	/*!
	* \brief Adds a new Well element to this object.
	*
	* No description available in the XSD standard.
	*
	* \param value The element to add
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void addToWell_List(const Inscoper::NBO::WellPtr& value, bool validate = true);

	/*!
	* \brief Clear the list of Well.
	*
	* No description available in the XSD standard.
	*/
	void clearWell_List();

	/*!
	* \brief Sets the list of AnnotationRef elements.
	*
	* No description available in the XSD standard.
	*
	* \param value The new list of AnnotationRef elements
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setAnnotationRef_List(const std::vector<Inscoper::NBO::AnnotationRefPtr>& value, bool validate = true);

	/*!
	* \brief Returns the list of AnnotationRef elements.
	*
	* No description available in the XSD standard.
	*
	* \return The list of AnnotationRef elements
	*/
	std::vector<Inscoper::NBO::AnnotationRefPtr> getAnnotationRef_List() const;

	/*!
	* \brief Adds a new AnnotationRef element to this object.
	*
	* No description available in the XSD standard.
	*
	* \param value The element to add
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void addToAnnotationRef_List(const Inscoper::NBO::AnnotationRefPtr& value, bool validate = true);

	/*!
	* \brief Clear the list of AnnotationRef.
	*
	* No description available in the XSD standard.
	*/
	void clearAnnotationRef_List();

	/*!
	* \brief Sets the list of PlateAcquisition elements.
	*
	* No description available in the XSD standard.
	*
	* \param value The new list of PlateAcquisition elements
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setPlateAcquisition_List(const std::vector<Inscoper::NBO::PlateAcquisitionPtr>& value, bool validate = true);

	/*!
	* \brief Returns the list of PlateAcquisition elements.
	*
	* No description available in the XSD standard.
	*
	* \return The list of PlateAcquisition elements
	*/
	std::vector<Inscoper::NBO::PlateAcquisitionPtr> getPlateAcquisition_List() const;

	/*!
	* \brief Adds a new PlateAcquisition element to this object.
	*
	* No description available in the XSD standard.
	*
	* \param value The element to add
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void addToPlateAcquisition_List(const Inscoper::NBO::PlateAcquisitionPtr& value, bool validate = true);

	/*!
	* \brief Clear the list of PlateAcquisition.
	*
	* No description available in the XSD standard.
	*/
	void clearPlateAcquisition_List();


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

	PlateID_TypePtr ID = nullptr; // Required attribute
    std::optional<std::string> Name; // Optional attribute
    static const std::set<std::string> NameAllowedValues;
    std::optional<std::string> Status; // Optional attribute
    static const std::set<std::string> StatusAllowedValues;
    std::optional<std::string> ExternalIdentifier; // Optional attribute
    static const std::set<std::string> ExternalIdentifierAllowedValues;
	NamingConvention_TypePtr ColumnNamingConvention = nullptr; // Optional attribute
	NamingConvention_TypePtr RowNamingConvention = nullptr; // Optional attribute
    std::optional<float> WellOriginX; // Optional attribute
	UnitsLength_TypePtr WellOriginXUnit = nullptr; // Optional attribute
    std::optional<float> WellOriginY; // Optional attribute
	UnitsLength_TypePtr WellOriginYUnit = nullptr; // Optional attribute
	PositiveInt_TypePtr Rows = nullptr; // Optional attribute
	PositiveInt_TypePtr Columns = nullptr; // Optional attribute
	NonNegativeInt_TypePtr FieldIndex = nullptr; // Optional attribute
    Inscoper::NBO::Plate::InlineDescriptionPtr Description = nullptr;
    std::vector<Inscoper::NBO::WellPtr> Well_List;
    std::vector<Inscoper::NBO::AnnotationRefPtr> AnnotationRef_List;
    std::vector<Inscoper::NBO::PlateAcquisitionPtr> PlateAcquisition_List;
};

/*! Shared pointer for Plate*/
typedef std::shared_ptr<Plate> PlatePtr;

} // namespace Inscoper::NBO

#endif // PLATE_HPP_INCLUDED