#ifndef CONFOCALSCANNER_TYPE_HPP_INCLUDED
#define CONFOCALSCANNER_TYPE_HPP_INCLUDED

#include <iostream>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <vector>
#include <NBO/NBO/AnnotationRef.h>
#include <NBO/NBO/ConfocalScannerID_Type.h>
#include <NBO/NBO/Denomination_Type.h>
#include <NBO/NBO/UnitsFrequency_Type.h>
#include <NBO/NBO/ENBOType.h>
#include <NBO/NBOGlobal.h>
#include <NBO/Shared/Base/NBOBaseClass.h>


namespace Inscoper::NBO {

/*!
* \brief Represents the XML complex type ConfocalScanner.
*
* According to ISO-10934-2-2007, a confocal microscope is a microscope in which, ideally, a point in the object plane is illuminated by a diffraction-limited spot of light, and light emanating from this point is focused upon and detected from an area smaller than the central area of the diffraction disc. The confocal principle leads to improved axial resolution by suppression of light from out-of-focus planes. In order to utilize this modality, a Confocal Scanner is used to form an Image of an extended Specimen region by controlling the direction of an outgoing Laser beam, the position of the Specimen or the location of the illuminated and detected spots simultaneously. Refer to https://www.iso.org/standard/69820.html for further details and measurement methods.
*/
class NBO_EXPORT ConfocalScanner_Type : public NBOBaseClass {

public:
	
	ConfocalScanner_Type();
	~ConfocalScanner_Type();

	/*!
	* \brief Cast a NBOBaseClass to a ConfocalScanner_Type.
	*
	* \param base The base class to cast
	* \return The casted element, or nullptr if the cast fails
	*/
	static std::shared_ptr<ConfocalScanner_Type> fromBase(NBOBaseClassPtr base);

	/*!
	* \brief Returns the class type name.
	*
	* \return The class type name
	*/
	virtual 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::ConfocalScannerID_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
	*/
	ConfocalScannerID_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 NrOfScanPoints attribute.
	*
	* This field records the number of scanning points available for this scan head.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setNrOfScanPoints(const int& value, bool validate = true);

	/*!
	* \brief Returns the value of the NrOfScanPoints attribute.
	*
	* This field records the number of scanning points available for this scan head.
	*
	* \return The value of the attribute
	*/
	int getNrOfScanPoints() const;

	/*!
	* \brief Resets the NrOfScanPoints attribute to an unset state.
	*
	* This field records the number of scanning points available for this scan head.
	*/
	void resetNrOfScanPoints();

	/*!
	* \brief Checks whether the NrOfScanPoints attribute is present.
	*
	* This field records the number of scanning points available for this scan head.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasNrOfScanPoints() const;

	/*!
	* \brief Sets the value of the MaxFrameRate attribute.
	*
	* This field captures the Maximum full Frame Rate available for this device, as specificed by the Manufacturer.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setMaxFrameRate(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the MaxFrameRate attribute.
	*
	* This field captures the Maximum full Frame Rate available for this device, as specificed by the Manufacturer.
	*
	* \return The value of the attribute
	*/
	float getMaxFrameRate() const;

	/*!
	* \brief Resets the MaxFrameRate attribute to an unset state.
	*
	* This field captures the Maximum full Frame Rate available for this device, as specificed by the Manufacturer.
	*/
	void resetMaxFrameRate();

	/*!
	* \brief Checks whether the MaxFrameRate attribute is present.
	*
	* This field captures the Maximum full Frame Rate available for this device, as specificed by the Manufacturer.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasMaxFrameRate() const;

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

	/*!
	* \brief Returns the value of the MaxFrameRateUnit attribute.
	*
	* No description available in the XSD standard.
	*
	* \return The value of the attribute
	*/
	UnitsFrequency_TypePtr getMaxFrameRateUnit() const;

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

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

	/*!
	* \brief Sets the value of the PointsConfiguration attribute.
	*
	* This field records a description of the arrangement of scan points (can be spiral, linear, grid, other)
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setPointsConfiguration(const std::string& value, bool validate = true);

	/*!
	* \brief Returns the value of the PointsConfiguration attribute.
	*
	* This field records a description of the arrangement of scan points (can be spiral, linear, grid, other)
	*
	* \return The value of the attribute
	*/
	std::string getPointsConfiguration() const;

	/*!
	* \brief Resets the PointsConfiguration attribute to an unset state.
	*
	* This field records a description of the arrangement of scan points (can be spiral, linear, grid, other)
	*/
	void resetPointsConfiguration();

	/*!
	* \brief Checks whether the PointsConfiguration attribute is present.
	*
	* This field records a description of the arrangement of scan points (can be spiral, linear, grid, other)
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasPointsConfiguration() const;

	/*!
	* \brief Returns the allowed values for this attribut.
	*
	* This field records a description of the arrangement of scan points (can be spiral, linear, grid, other)
	*
	* \return The list of allowed values
	*/
	static const std::set<std::string>& getPointsConfigurationAllowedValues();

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

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

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


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

	ConfocalScannerID_TypePtr ID = nullptr; // Required attribute
	Denomination_TypePtr Name = nullptr; // Optional attribute
    std::optional<int> NrOfScanPoints; // Required attribute
    std::optional<float> MaxFrameRate; // Optional attribute
	UnitsFrequency_TypePtr MaxFrameRateUnit = nullptr; // Optional attribute
    std::optional<std::string> PointsConfiguration; // Optional attribute
    static const std::set<std::string> PointsConfigurationAllowedValues;
    Inscoper::NBO::AnnotationRefPtr AnnotationRef = nullptr;
};

/*! Shared pointer for ConfocalScanner_Type*/
typedef std::shared_ptr<ConfocalScanner_Type> ConfocalScanner_TypePtr;

} // namespace Inscoper::NBO

#endif // CONFOCALSCANNER_TYPE_HPP_INCLUDED