#ifndef COLOREDBEADSSLIDE_HPP_INCLUDED
#define COLOREDBEADSSLIDE_HPP_INCLUDED

#include <iostream>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <vector>
#include <NBO/NBO/ColoredBeads.h>
#include <NBO/NBO/OpticalCalibrationStandard_Type.h>
#include <NBO/NBO/UnitsVolume_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 ColoredBeadsSlide.
*
* This element describes a Slide coated with Multicolor Fluorescent Microspheres (also known as Multicolored Beads) used for assessing the Optical properties of the Microscope that was used to acquire this experimental Image. These Slides can be used to measure Optical properties such as resolution, chromatic registration, and different kinds of optical distorsions.
*/
class NBO_EXPORT ColoredBeadsSlide : public OpticalCalibrationStandard_Type {

public:
	
	ColoredBeadsSlide();
	~ColoredBeadsSlide();

	/*!
	* \brief Cast a NBOBaseClass to a ColoredBeadsSlide.
	*
	* \param base The base class to cast
	* \return The casted element, or nullptr if the cast fails
	*/
	static std::shared_ptr<ColoredBeadsSlide> 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 Date attribute.
	*
	* This field captures the Date in which this Colored Beads Slide was prepared.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setDate(const std::string& value, bool validate = true);

	/*!
	* \brief Returns the value of the Date attribute.
	*
	* This field captures the Date in which this Colored Beads Slide was prepared.
	*
	* \return The value of the attribute
	*/
	std::string getDate() const;

	/*!
	* \brief Resets the Date attribute to an unset state.
	*
	* This field captures the Date in which this Colored Beads Slide was prepared.
	*/
	void resetDate();

	/*!
	* \brief Checks whether the Date attribute is present.
	*
	* This field captures the Date in which this Colored Beads Slide was prepared.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasDate() const;

	/*!
	* \brief Returns the allowed values for this attribut.
	*
	* This field captures the Date in which this Colored Beads Slide was prepared.
	*
	* \return The list of allowed values
	*/
	static const std::set<std::string>& getDateAllowedValues();

	/*!
	* \brief Sets the value of the BeadVolume attribute.
	*
	* This field captures the Volume of the Multi Color Microspheres preparation that was utilized to prepare this Slide.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setBeadVolume(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the BeadVolume attribute.
	*
	* This field captures the Volume of the Multi Color Microspheres preparation that was utilized to prepare this Slide.
	*
	* \return The value of the attribute
	*/
	float getBeadVolume() const;

	/*!
	* \brief Resets the BeadVolume attribute to an unset state.
	*
	* This field captures the Volume of the Multi Color Microspheres preparation that was utilized to prepare this Slide.
	*/
	void resetBeadVolume();

	/*!
	* \brief Checks whether the BeadVolume attribute is present.
	*
	* This field captures the Volume of the Multi Color Microspheres preparation that was utilized to prepare this Slide.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasBeadVolume() const;

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

	/*!
	* \brief Returns the value of the BeadVolumeUnit attribute.
	*
	* No description available in the XSD standard.
	*
	* \return The value of the attribute
	*/
	UnitsVolume_TypePtr getBeadVolumeUnit() const;

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

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

	/*!
	* \brief Sets the value of the ColoredBeads element.
	*
	* 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 setColoredBeads(const Inscoper::NBO::ColoredBeadsPtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the ColoredBeads element.
	*
	* No description available in the XSD standard.
	*
	* \return The value of the element
	*/
	Inscoper::NBO::ColoredBeadsPtr getColoredBeads() const
;
	/*!
	* \brief Resets the ColoredBeads element to an unset state.
	*
	* No description available in the XSD standard.
	*/
	void resetColoredBeads();

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


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

    std::optional<std::string> Date; // Optional attribute
    static const std::set<std::string> DateAllowedValues;
    std::optional<float> BeadVolume; // Optional attribute
	UnitsVolume_TypePtr BeadVolumeUnit = nullptr; // Optional attribute
    Inscoper::NBO::ColoredBeadsPtr ColoredBeads = nullptr;
};

/*! Shared pointer for ColoredBeadsSlide*/
typedef std::shared_ptr<ColoredBeadsSlide> ColoredBeadsSlidePtr;

} // namespace Inscoper::NBO

#endif // COLOREDBEADSSLIDE_HPP_INCLUDED