#ifndef PRISM_HPP_INCLUDED
#define PRISM_HPP_INCLUDED

#include <iostream>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <vector>
#include <NBO/NBO/AnnotationRef.h>
#include <NBO/NBO/DICPrismType_Type.h>
#include <NBO/NBO/Denomination_Type.h>
#include <NBO/NBO/ManufacturerSpec_Type.h>
#include <NBO/NBO/OpticalMaterialName_Type.h>
#include <NBO/NBO/PrismDesign_Type.h>
#include <NBO/NBO/PrismFunction_Type.h>
#include <NBO/NBO/PrismID_Type.h>
#include <NBO/NBO/UnitsAngle_Type.h>
#include <NBO/NBO/UnitsDensity_Type.h>
#include <NBO/NBO/PositiveFloat_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 Prism.
*
* This element describes a Prism positioned in the Light Path for one or more Channels available for this Instrument. A Prism is a block of glass or other transparent material with at least two intersecting flat, polished surfaces, used to disperse light or deviate it through an angle. A Prism can be viewed as an ensemble of different rigidly mounted Mirrors, with each face having a permanent orientation with respect to others. A Prism can be employed to deflect or deviate a light beam, rotate or invert an Image, separate polarization states, or disperse light into its component Wavelengths. An Instrument may have several Prisms with different functionality such as Polarizing, Reflecting, or Refracting (or Dispersing). Polarizing Prisms are birefringent crystals that divide incident non-polarized light into separate components polarized orthogonally to each other. Reflecting Prisms are useful for redirecting light beams by total internal reflection. Refracting (or Dispersing) Prisms can be employed to bend and separate light into its component colors. This element can be associated with an optional Optics Turret.
*/
class NBO_EXPORT Prism : public ManufacturerSpec_Type {

public:
	/*!
	* \brief Represents the XML element WavelengthRange.
	*
	* This element records the Range of Wavelengths this device is designed for, according to the Manufacturer. Multiple of this element may be used.
	*/
	class NBO_EXPORT InlineWavelengthRange : public NBOBaseClass {
	
	public:
		
		InlineWavelengthRange();
		~InlineWavelengthRange();
	
		/*!
		* \brief Cast a NBOBaseClass to a InlineWavelengthRange.
		*
		* \param base The base class to cast
		* \return The casted element, or nullptr if the cast fails
		*/
		static std::shared_ptr<InlineWavelengthRange> 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 PeakWavelength attribute.
		*
		* This field records the nominal Wavelength associated with the peak response rate of this device. 
		*
		* \param value The value to set
		* \param validate If true, validates constraints on value. Default is true.
		*/
		void setPeakWavelength(const float& value, bool validate = true);
	
		/*!
		* \brief Returns the value of the PeakWavelength attribute.
		*
		* This field records the nominal Wavelength associated with the peak response rate of this device. 
		*
		* \return The value of the attribute
		*/
		float getPeakWavelength() const;
	
		/*!
		* \brief Resets the PeakWavelength attribute to an unset state.
		*
		* This field records the nominal Wavelength associated with the peak response rate of this device. 
		*/
		void resetPeakWavelength();
	
		/*!
		* \brief Checks whether the PeakWavelength attribute is present.
		*
		* This field records the nominal Wavelength associated with the peak response rate of this device. 
		*
		* \return true if the attribute has been set, false otherwise
		*/
		bool hasPeakWavelength() const;
	
		/*!
		* \brief Sets the value of the PeakWavelengthUnit 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 setPeakWavelengthUnit(const Inscoper::NBO::UnitsLength_TypePtr& value, bool validate = true);
	
		/*!
		* \brief Returns the value of the PeakWavelengthUnit attribute.
		*
		* No description available in the XSD standard.
		*
		* \return The value of the attribute
		*/
		UnitsLength_TypePtr getPeakWavelengthUnit() const;
	
		/*!
		* \brief Resets the PeakWavelengthUnit attribute to an unset state.
		*
		* No description available in the XSD standard.
		*/
		void resetPeakWavelengthUnit();
	
		/*!
		* \brief Checks whether the optional PeakWavelengthUnit attribute is present.
		*
		* No description available in the XSD standard.
		*
		* \return true if the optional attribute has been set, false otherwise
		*/
		bool hasPeakWavelengthUnit() const;
	
		/*!
		* \brief Sets the value of the CutOn attribute.
		*
		* CutOn is the Wavelength below which the response rate is below 50%.
		*
		* \param value The value to set
		* \param validate If true, validates constraints on value. Default is true.
		*/
		void setCutOn(const Inscoper::NBO::PositiveFloat_TypePtr& value, bool validate = true);
	
		/*!
		* \brief Returns the value of the CutOn attribute.
		*
		* CutOn is the Wavelength below which the response rate is below 50%.
		*
		* \return The value of the attribute
		*/
		PositiveFloat_TypePtr getCutOn() const;
	
		/*!
		* \brief Resets the CutOn attribute to an unset state.
		*
		* CutOn is the Wavelength below which the response rate is below 50%.
		*/
		void resetCutOn();
	
		/*!
		* \brief Checks whether the optional CutOn attribute is present.
		*
		* CutOn is the Wavelength below which the response rate is below 50%.
		*
		* \return true if the optional attribute has been set, false otherwise
		*/
		bool hasCutOn() const;
	
		/*!
		* \brief Sets the value of the CutOnUnit 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 setCutOnUnit(const Inscoper::NBO::UnitsLength_TypePtr& value, bool validate = true);
	
		/*!
		* \brief Returns the value of the CutOnUnit attribute.
		*
		* No description available in the XSD standard.
		*
		* \return The value of the attribute
		*/
		UnitsLength_TypePtr getCutOnUnit() const;
	
		/*!
		* \brief Resets the CutOnUnit attribute to an unset state.
		*
		* No description available in the XSD standard.
		*/
		void resetCutOnUnit();
	
		/*!
		* \brief Checks whether the optional CutOnUnit attribute is present.
		*
		* No description available in the XSD standard.
		*
		* \return true if the optional attribute has been set, false otherwise
		*/
		bool hasCutOnUnit() const;
	
		/*!
		* \brief Sets the value of the CutOff attribute.
		*
		* CutOff is the Wavelength above which the response rate is below 50%.
		*
		* \param value The value to set
		* \param validate If true, validates constraints on value. Default is true.
		*/
		void setCutOff(const Inscoper::NBO::PositiveFloat_TypePtr& value, bool validate = true);
	
		/*!
		* \brief Returns the value of the CutOff attribute.
		*
		* CutOff is the Wavelength above which the response rate is below 50%.
		*
		* \return The value of the attribute
		*/
		PositiveFloat_TypePtr getCutOff() const;
	
		/*!
		* \brief Resets the CutOff attribute to an unset state.
		*
		* CutOff is the Wavelength above which the response rate is below 50%.
		*/
		void resetCutOff();
	
		/*!
		* \brief Checks whether the optional CutOff attribute is present.
		*
		* CutOff is the Wavelength above which the response rate is below 50%.
		*
		* \return true if the optional attribute has been set, false otherwise
		*/
		bool hasCutOff() const;
	
		/*!
		* \brief Sets the value of the CutOffUnit 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 setCutOffUnit(const Inscoper::NBO::UnitsLength_TypePtr& value, bool validate = true);
	
		/*!
		* \brief Returns the value of the CutOffUnit attribute.
		*
		* No description available in the XSD standard.
		*
		* \return The value of the attribute
		*/
		UnitsLength_TypePtr getCutOffUnit() const;
	
		/*!
		* \brief Resets the CutOffUnit attribute to an unset state.
		*
		* No description available in the XSD standard.
		*/
		void resetCutOffUnit();
	
		/*!
		* \brief Checks whether the optional CutOffUnit attribute is present.
		*
		* No description available in the XSD standard.
		*
		* \return true if the optional attribute has been set, false otherwise
		*/
		bool hasCutOffUnit() const;
	
		/*!
		* \brief Sets the value of the WavelengthProfile attribute.
		*
		* The location of a file containing the Wavelength profile of this hardware component.
		*
		* \param value The value to set
		* \param validate If true, validates constraints on value. Default is true.
		*/
		void setWavelengthProfile(const std::string& value, bool validate = true);
	
		/*!
		* \brief Returns the value of the WavelengthProfile attribute.
		*
		* The location of a file containing the Wavelength profile of this hardware component.
		*
		* \return The value of the attribute
		*/
		std::string getWavelengthProfile() const;
	
		/*!
		* \brief Resets the WavelengthProfile attribute to an unset state.
		*
		* The location of a file containing the Wavelength profile of this hardware component.
		*/
		void resetWavelengthProfile();
	
		/*!
		* \brief Checks whether the WavelengthProfile attribute is present.
		*
		* The location of a file containing the Wavelength profile of this hardware component.
		*
		* \return true if the attribute has been set, false otherwise
		*/
		bool hasWavelengthProfile() const;
	
		/*!
		* \brief Returns the allowed values for this attribut.
		*
		* The location of a file containing the Wavelength profile of this hardware component.
		*
		* \return The list of allowed values
		*/
		static const std::set<std::string>& getWavelengthProfileAllowedValues();
	
	
	private:
		class Impl;
		std::unique_ptr<Impl> pImpl;
	
	    std::optional<float> PeakWavelength; // Optional attribute
		UnitsLength_TypePtr PeakWavelengthUnit = nullptr; // Optional attribute
		PositiveFloat_TypePtr CutOn = nullptr; // Required attribute
		UnitsLength_TypePtr CutOnUnit = nullptr; // Optional attribute
		PositiveFloat_TypePtr CutOff = nullptr; // Required attribute
		UnitsLength_TypePtr CutOffUnit = nullptr; // Optional attribute
	    std::optional<std::string> WavelengthProfile; // Required attribute
	    static const std::set<std::string> WavelengthProfileAllowedValues;
	};
	
	/*! Shared pointer for InlineWavelengthRange*/
	typedef std::shared_ptr<InlineWavelengthRange> InlineWavelengthRangePtr;
	
	
	Prism();
	~Prism();

	/*!
	* \brief Cast a NBOBaseClass to a Prism.
	*
	* \param base The base class to cast
	* \return The casted element, or nullptr if the cast fails
	*/
	static std::shared_ptr<Prism> 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::PrismID_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
	*/
	PrismID_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 DIC attribute.
	*
	* This field records whether this Prism is used for Differential Interference Contrast (DIC) microscopy and, if so, what DIC-compatible type it is (i.e., deSenarmont, Nomarski or Wollaston).
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setDIC(const Inscoper::NBO::DICPrismType_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the DIC attribute.
	*
	* This field records whether this Prism is used for Differential Interference Contrast (DIC) microscopy and, if so, what DIC-compatible type it is (i.e., deSenarmont, Nomarski or Wollaston).
	*
	* \return The value of the attribute
	*/
	DICPrismType_TypePtr getDIC() const;

	/*!
	* \brief Resets the DIC attribute to an unset state.
	*
	* This field records whether this Prism is used for Differential Interference Contrast (DIC) microscopy and, if so, what DIC-compatible type it is (i.e., deSenarmont, Nomarski or Wollaston).
	*/
	void resetDIC();

	/*!
	* \brief Checks whether the optional DIC attribute is present.
	*
	* This field records whether this Prism is used for Differential Interference Contrast (DIC) microscopy and, if so, what DIC-compatible type it is (i.e., deSenarmont, Nomarski or Wollaston).
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasDIC() const;

	/*!
	* \brief Sets the value of the Function attribute.
	*
	* This field records the function of this Prism. Beam-shaping (i.e., Anamorphic) Prism pairs are used for reshaping the profile of a laser beam. For example, the elliptical beam from a laser diode can be transformed into a beam with circular cross-section, by magnifying the elliptical beam in one dimension. They can also be used to convert a circular beam into an elliptical beam. Dispersing prisms can be employed to bend and separate light into its component wavelengths. Polarizing prisms (i.e., Glan–Thompson, Nomarski, Wollaston) are birefringent crystals, which divide incident non-polarized light into separate components polarized orthogonally to each other. Reflecting prisms are useful for redirecting (i.e., flip, invert, rotate, etc.) light beams by total internal reflection or for dividing them into two or more separate beams (i.e., beam-splitting) one.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setFunction(const Inscoper::NBO::PrismFunction_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the Function attribute.
	*
	* This field records the function of this Prism. Beam-shaping (i.e., Anamorphic) Prism pairs are used for reshaping the profile of a laser beam. For example, the elliptical beam from a laser diode can be transformed into a beam with circular cross-section, by magnifying the elliptical beam in one dimension. They can also be used to convert a circular beam into an elliptical beam. Dispersing prisms can be employed to bend and separate light into its component wavelengths. Polarizing prisms (i.e., Glan–Thompson, Nomarski, Wollaston) are birefringent crystals, which divide incident non-polarized light into separate components polarized orthogonally to each other. Reflecting prisms are useful for redirecting (i.e., flip, invert, rotate, etc.) light beams by total internal reflection or for dividing them into two or more separate beams (i.e., beam-splitting) one.
	*
	* \return The value of the attribute
	*/
	PrismFunction_TypePtr getFunction() const;

	/*!
	* \brief Resets the Function attribute to an unset state.
	*
	* This field records the function of this Prism. Beam-shaping (i.e., Anamorphic) Prism pairs are used for reshaping the profile of a laser beam. For example, the elliptical beam from a laser diode can be transformed into a beam with circular cross-section, by magnifying the elliptical beam in one dimension. They can also be used to convert a circular beam into an elliptical beam. Dispersing prisms can be employed to bend and separate light into its component wavelengths. Polarizing prisms (i.e., Glan–Thompson, Nomarski, Wollaston) are birefringent crystals, which divide incident non-polarized light into separate components polarized orthogonally to each other. Reflecting prisms are useful for redirecting (i.e., flip, invert, rotate, etc.) light beams by total internal reflection or for dividing them into two or more separate beams (i.e., beam-splitting) one.
	*/
	void resetFunction();

	/*!
	* \brief Checks whether the optional Function attribute is present.
	*
	* This field records the function of this Prism. Beam-shaping (i.e., Anamorphic) Prism pairs are used for reshaping the profile of a laser beam. For example, the elliptical beam from a laser diode can be transformed into a beam with circular cross-section, by magnifying the elliptical beam in one dimension. They can also be used to convert a circular beam into an elliptical beam. Dispersing prisms can be employed to bend and separate light into its component wavelengths. Polarizing prisms (i.e., Glan–Thompson, Nomarski, Wollaston) are birefringent crystals, which divide incident non-polarized light into separate components polarized orthogonally to each other. Reflecting prisms are useful for redirecting (i.e., flip, invert, rotate, etc.) light beams by total internal reflection or for dividing them into two or more separate beams (i.e., beam-splitting) one.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasFunction() const;

	/*!
	* \brief Sets the value of the Condenser attribute.
	*
	* This field records whether this Prism is within the Condenser (True) or the Objective (False).
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setCondenser(const bool& value, bool validate = true);

	/*!
	* \brief Returns the value of the Condenser attribute.
	*
	* This field records whether this Prism is within the Condenser (True) or the Objective (False).
	*
	* \return The value of the attribute
	*/
	bool getCondenser() const;

	/*!
	* \brief Resets the Condenser attribute to an unset state.
	*
	* This field records whether this Prism is within the Condenser (True) or the Objective (False).
	*/
	void resetCondenser();

	/*!
	* \brief Checks whether the Condenser attribute is present.
	*
	* This field records whether this Prism is within the Condenser (True) or the Objective (False).
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasCondenser() const;

	/*!
	* \brief Sets the value of the OilObjective attribute.
	*
	* This field records whether this Prism is designed to work with oil Objectives (True) or not (False).
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setOilObjective(const bool& value, bool validate = true);

	/*!
	* \brief Returns the value of the OilObjective attribute.
	*
	* This field records whether this Prism is designed to work with oil Objectives (True) or not (False).
	*
	* \return The value of the attribute
	*/
	bool getOilObjective() const;

	/*!
	* \brief Resets the OilObjective attribute to an unset state.
	*
	* This field records whether this Prism is designed to work with oil Objectives (True) or not (False).
	*/
	void resetOilObjective();

	/*!
	* \brief Checks whether the OilObjective attribute is present.
	*
	* This field records whether this Prism is designed to work with oil Objectives (True) or not (False).
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasOilObjective() const;

	/*!
	* \brief Sets the value of the Compound attribute.
	*
	* This field records whether this Prism is a Compound Prism (i.e., a set of multiple triangular prism elements placed in contact, and often cemented together to form a solid assembly; True) or a Simple Prism (False).
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setCompound(const bool& value, bool validate = true);

	/*!
	* \brief Returns the value of the Compound attribute.
	*
	* This field records whether this Prism is a Compound Prism (i.e., a set of multiple triangular prism elements placed in contact, and often cemented together to form a solid assembly; True) or a Simple Prism (False).
	*
	* \return The value of the attribute
	*/
	bool getCompound() const;

	/*!
	* \brief Resets the Compound attribute to an unset state.
	*
	* This field records whether this Prism is a Compound Prism (i.e., a set of multiple triangular prism elements placed in contact, and often cemented together to form a solid assembly; True) or a Simple Prism (False).
	*/
	void resetCompound();

	/*!
	* \brief Checks whether the Compound attribute is present.
	*
	* This field records whether this Prism is a Compound Prism (i.e., a set of multiple triangular prism elements placed in contact, and often cemented together to form a solid assembly; True) or a Simple Prism (False).
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasCompound() const;

	/*!
	* \brief Sets the value of the RefractiveIndex attribute.
	*
	* This field records the Refractive Index of the material this Prism is made of, as specified by the Manufacturer.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setRefractiveIndex(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the RefractiveIndex attribute.
	*
	* This field records the Refractive Index of the material this Prism is made of, as specified by the Manufacturer.
	*
	* \return The value of the attribute
	*/
	float getRefractiveIndex() const;

	/*!
	* \brief Resets the RefractiveIndex attribute to an unset state.
	*
	* This field records the Refractive Index of the material this Prism is made of, as specified by the Manufacturer.
	*/
	void resetRefractiveIndex();

	/*!
	* \brief Checks whether the RefractiveIndex attribute is present.
	*
	* This field records the Refractive Index of the material this Prism is made of, as specified by the Manufacturer.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasRefractiveIndex() const;

	/*!
	* \brief Sets the value of the Reflectance attribute.
	*
	* This field records the maximum amount of light this Prism is capable of transmitting at peak Wavelength. It is represented as a fractional value from 0.0 to 1.0.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setReflectance(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the Reflectance attribute.
	*
	* This field records the maximum amount of light this Prism is capable of transmitting at peak Wavelength. It is represented as a fractional value from 0.0 to 1.0.
	*
	* \return The value of the attribute
	*/
	float getReflectance() const;

	/*!
	* \brief Resets the Reflectance attribute to an unset state.
	*
	* This field records the maximum amount of light this Prism is capable of transmitting at peak Wavelength. It is represented as a fractional value from 0.0 to 1.0.
	*/
	void resetReflectance();

	/*!
	* \brief Checks whether the Reflectance attribute is present.
	*
	* This field records the maximum amount of light this Prism is capable of transmitting at peak Wavelength. It is represented as a fractional value from 0.0 to 1.0.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasReflectance() const;

	/*!
	* \brief Sets the value of the AngleOfIncidence attribute.
	*
	* This field records the Angle Of Incidence (AOI) is the angle between a beam of light incident on the Prism surface and the line perpendicular to the surface at the point of incidence, called the normal.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setAngleOfIncidence(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the AngleOfIncidence attribute.
	*
	* This field records the Angle Of Incidence (AOI) is the angle between a beam of light incident on the Prism surface and the line perpendicular to the surface at the point of incidence, called the normal.
	*
	* \return The value of the attribute
	*/
	float getAngleOfIncidence() const;

	/*!
	* \brief Resets the AngleOfIncidence attribute to an unset state.
	*
	* This field records the Angle Of Incidence (AOI) is the angle between a beam of light incident on the Prism surface and the line perpendicular to the surface at the point of incidence, called the normal.
	*/
	void resetAngleOfIncidence();

	/*!
	* \brief Checks whether the AngleOfIncidence attribute is present.
	*
	* This field records the Angle Of Incidence (AOI) is the angle between a beam of light incident on the Prism surface and the line perpendicular to the surface at the point of incidence, called the normal.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasAngleOfIncidence() const;

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

	/*!
	* \brief Returns the value of the AngleOfIncidenceUnit attribute.
	*
	* No description available in the XSD standard.
	*
	* \return The value of the attribute
	*/
	UnitsAngle_TypePtr getAngleOfIncidenceUnit() const;

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

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

	/*!
	* \brief Sets the value of the DeviationAngle attribute.
	*
	* This field records the Deviation Angle of this Prism. A beam passing through an object like a prism is deflected twice: once entering, and again when exiting. The sum of these two deflections is called the deviation angle and is measured with respect to the incident ray.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setDeviationAngle(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the DeviationAngle attribute.
	*
	* This field records the Deviation Angle of this Prism. A beam passing through an object like a prism is deflected twice: once entering, and again when exiting. The sum of these two deflections is called the deviation angle and is measured with respect to the incident ray.
	*
	* \return The value of the attribute
	*/
	float getDeviationAngle() const;

	/*!
	* \brief Resets the DeviationAngle attribute to an unset state.
	*
	* This field records the Deviation Angle of this Prism. A beam passing through an object like a prism is deflected twice: once entering, and again when exiting. The sum of these two deflections is called the deviation angle and is measured with respect to the incident ray.
	*/
	void resetDeviationAngle();

	/*!
	* \brief Checks whether the DeviationAngle attribute is present.
	*
	* This field records the Deviation Angle of this Prism. A beam passing through an object like a prism is deflected twice: once entering, and again when exiting. The sum of these two deflections is called the deviation angle and is measured with respect to the incident ray.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasDeviationAngle() const;

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

	/*!
	* \brief Returns the value of the DevianceAngleUnit attribute.
	*
	* No description available in the XSD standard.
	*
	* \return The value of the attribute
	*/
	UnitsAngle_TypePtr getDevianceAngleUnit() const;

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

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

	/*!
	* \brief Sets the value of the PrismAngle attribute.
	*
	* This field records the Angle between two surfaces of this Prism.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setPrismAngle(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the PrismAngle attribute.
	*
	* This field records the Angle between two surfaces of this Prism.
	*
	* \return The value of the attribute
	*/
	float getPrismAngle() const;

	/*!
	* \brief Resets the PrismAngle attribute to an unset state.
	*
	* This field records the Angle between two surfaces of this Prism.
	*/
	void resetPrismAngle();

	/*!
	* \brief Checks whether the PrismAngle attribute is present.
	*
	* This field records the Angle between two surfaces of this Prism.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasPrismAngle() const;

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

	/*!
	* \brief Returns the value of the PrismAngleUnit attribute.
	*
	* No description available in the XSD standard.
	*
	* \return The value of the attribute
	*/
	UnitsAngle_TypePtr getPrismAngleUnit() const;

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

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

	/*!
	* \brief Sets the value of the Design attribute.
	*
	* This field records the shape of the Prism with specific reference to the angles defined by its faces.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setDesign(const Inscoper::NBO::PrismDesign_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the Design attribute.
	*
	* This field records the shape of the Prism with specific reference to the angles defined by its faces.
	*
	* \return The value of the attribute
	*/
	PrismDesign_TypePtr getDesign() const;

	/*!
	* \brief Resets the Design attribute to an unset state.
	*
	* This field records the shape of the Prism with specific reference to the angles defined by its faces.
	*/
	void resetDesign();

	/*!
	* \brief Checks whether the optional Design attribute is present.
	*
	* This field records the shape of the Prism with specific reference to the angles defined by its faces.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasDesign() const;

	/*!
	* \brief Sets the value of the AbbeNumber attribute.
	*
	* This field records the Abbe number of this Prism. The Abbe Number is a measure of the material's dispersion (variation of Refractive Index versus Wavelength), with high values indicating low dispersion.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setAbbeNumber(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the AbbeNumber attribute.
	*
	* This field records the Abbe number of this Prism. The Abbe Number is a measure of the material's dispersion (variation of Refractive Index versus Wavelength), with high values indicating low dispersion.
	*
	* \return The value of the attribute
	*/
	float getAbbeNumber() const;

	/*!
	* \brief Resets the AbbeNumber attribute to an unset state.
	*
	* This field records the Abbe number of this Prism. The Abbe Number is a measure of the material's dispersion (variation of Refractive Index versus Wavelength), with high values indicating low dispersion.
	*/
	void resetAbbeNumber();

	/*!
	* \brief Checks whether the AbbeNumber attribute is present.
	*
	* This field records the Abbe number of this Prism. The Abbe Number is a measure of the material's dispersion (variation of Refractive Index versus Wavelength), with high values indicating low dispersion.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasAbbeNumber() const;

	/*!
	* \brief Sets the value of the MaterialName attribute.
	*
	* This field records the chemical composition or designation of the Material this Prism is made of.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setMaterialName(const Inscoper::NBO::OpticalMaterialName_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the MaterialName attribute.
	*
	* This field records the chemical composition or designation of the Material this Prism is made of.
	*
	* \return The value of the attribute
	*/
	OpticalMaterialName_TypePtr getMaterialName() const;

	/*!
	* \brief Resets the MaterialName attribute to an unset state.
	*
	* This field records the chemical composition or designation of the Material this Prism is made of.
	*/
	void resetMaterialName();

	/*!
	* \brief Checks whether the optional MaterialName attribute is present.
	*
	* This field records the chemical composition or designation of the Material this Prism is made of.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasMaterialName() const;

	/*!
	* \brief Sets the value of the GlassCode attribute.
	*
	* If available, this field records the international Glass Code of the material that constitutes this Prism. The Glass Code designation is based on U.S. military standard MIL-G-174, and it consists of a six-digit number specifying the glass according to its Refractive Index nd at the Fraunhofer d- (or D3-) line, and its Abbe Number Vd also taken at that line. The resulting Glass Code is the value of nd-1 rounded to three digits, followed by Vd rounded to three digits, with all decimal points ignored. For example, BK7 has nd = 1.5168 and Vd = 64.17, giving a six-digit Glass Code of 517642.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setGlassCode(const std::string& value, bool validate = true);

	/*!
	* \brief Returns the value of the GlassCode attribute.
	*
	* If available, this field records the international Glass Code of the material that constitutes this Prism. The Glass Code designation is based on U.S. military standard MIL-G-174, and it consists of a six-digit number specifying the glass according to its Refractive Index nd at the Fraunhofer d- (or D3-) line, and its Abbe Number Vd also taken at that line. The resulting Glass Code is the value of nd-1 rounded to three digits, followed by Vd rounded to three digits, with all decimal points ignored. For example, BK7 has nd = 1.5168 and Vd = 64.17, giving a six-digit Glass Code of 517642.
	*
	* \return The value of the attribute
	*/
	std::string getGlassCode() const;

	/*!
	* \brief Resets the GlassCode attribute to an unset state.
	*
	* If available, this field records the international Glass Code of the material that constitutes this Prism. The Glass Code designation is based on U.S. military standard MIL-G-174, and it consists of a six-digit number specifying the glass according to its Refractive Index nd at the Fraunhofer d- (or D3-) line, and its Abbe Number Vd also taken at that line. The resulting Glass Code is the value of nd-1 rounded to three digits, followed by Vd rounded to three digits, with all decimal points ignored. For example, BK7 has nd = 1.5168 and Vd = 64.17, giving a six-digit Glass Code of 517642.
	*/
	void resetGlassCode();

	/*!
	* \brief Checks whether the GlassCode attribute is present.
	*
	* If available, this field records the international Glass Code of the material that constitutes this Prism. The Glass Code designation is based on U.S. military standard MIL-G-174, and it consists of a six-digit number specifying the glass according to its Refractive Index nd at the Fraunhofer d- (or D3-) line, and its Abbe Number Vd also taken at that line. The resulting Glass Code is the value of nd-1 rounded to three digits, followed by Vd rounded to three digits, with all decimal points ignored. For example, BK7 has nd = 1.5168 and Vd = 64.17, giving a six-digit Glass Code of 517642.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasGlassCode() const;

	/*!
	* \brief Returns the allowed values for this attribut.
	*
	* If available, this field records the international Glass Code of the material that constitutes this Prism. The Glass Code designation is based on U.S. military standard MIL-G-174, and it consists of a six-digit number specifying the glass according to its Refractive Index nd at the Fraunhofer d- (or D3-) line, and its Abbe Number Vd also taken at that line. The resulting Glass Code is the value of nd-1 rounded to three digits, followed by Vd rounded to three digits, with all decimal points ignored. For example, BK7 has nd = 1.5168 and Vd = 64.17, giving a six-digit Glass Code of 517642.
	*
	* \return The list of allowed values
	*/
	static const std::set<std::string>& getGlassCodeAllowedValues();

	/*!
	* \brief Sets the value of the Density attribute.
	*
	* This field records the Density of the material this Prism is made of.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setDensity(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the Density attribute.
	*
	* This field records the Density of the material this Prism is made of.
	*
	* \return The value of the attribute
	*/
	float getDensity() const;

	/*!
	* \brief Resets the Density attribute to an unset state.
	*
	* This field records the Density of the material this Prism is made of.
	*/
	void resetDensity();

	/*!
	* \brief Checks whether the Density attribute is present.
	*
	* This field records the Density of the material this Prism is made of.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasDensity() const;

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

	/*!
	* \brief Returns the value of the DensityUnit attribute.
	*
	* No description available in the XSD standard.
	*
	* \return The value of the attribute
	*/
	UnitsDensity_TypePtr getDensityUnit() const;

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

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

	/*!
	* \brief Sets the list of WavelengthRange elements.
	*
	* This element records the Range of Wavelengths this device is designed for, according to the Manufacturer. Multiple of this element may be used.
	*
	* \param value The new list of WavelengthRange elements
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setWavelengthRange_List(const std::vector<Inscoper::NBO::Prism::InlineWavelengthRangePtr>& value, bool validate = true);

	/*!
	* \brief Returns the list of WavelengthRange elements.
	*
	* This element records the Range of Wavelengths this device is designed for, according to the Manufacturer. Multiple of this element may be used.
	*
	* \return The list of WavelengthRange elements
	*/
	std::vector<Inscoper::NBO::Prism::InlineWavelengthRangePtr> getWavelengthRange_List() const;

	/*!
	* \brief Adds a new WavelengthRange element to this object.
	*
	* This element records the Range of Wavelengths this device is designed for, according to the Manufacturer. Multiple of this element may be used.
	*
	* \param value The element to add
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void addToWavelengthRange_List(const Inscoper::NBO::Prism::InlineWavelengthRangePtr& value, bool validate = true);

	/*!
	* \brief Clear the list of WavelengthRange.
	*
	* This element records the Range of Wavelengths this device is designed for, according to the Manufacturer. Multiple of this element may be used.
	*/
	void clearWavelengthRange_List();

	/*!
	* \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;

	PrismID_TypePtr ID = nullptr; // Required attribute
	Denomination_TypePtr Name = nullptr; // Optional attribute
	DICPrismType_TypePtr DIC = nullptr; // Optional attribute
	PrismFunction_TypePtr Function = nullptr; // Required attribute
    std::optional<bool> Condenser; // Required attribute
    std::optional<bool> OilObjective; // Required attribute
    std::optional<bool> Compound; // Optional attribute
    std::optional<float> RefractiveIndex; // Optional attribute
    std::optional<float> Reflectance; // Required attribute
    std::optional<float> AngleOfIncidence; // Optional attribute
	UnitsAngle_TypePtr AngleOfIncidenceUnit = nullptr; // Optional attribute
    std::optional<float> DeviationAngle; // Optional attribute
	UnitsAngle_TypePtr DevianceAngleUnit = nullptr; // Optional attribute
    std::optional<float> PrismAngle; // Optional attribute
	UnitsAngle_TypePtr PrismAngleUnit = nullptr; // Optional attribute
	PrismDesign_TypePtr Design = nullptr; // Optional attribute
    std::optional<float> AbbeNumber; // Optional attribute
	OpticalMaterialName_TypePtr MaterialName = nullptr; // Optional attribute
    std::optional<std::string> GlassCode; // Optional attribute
    static const std::set<std::string> GlassCodeAllowedValues;
    std::optional<float> Density; // Optional attribute
	UnitsDensity_TypePtr DensityUnit = nullptr; // Optional attribute
    std::vector<Inscoper::NBO::Prism::InlineWavelengthRangePtr> WavelengthRange_List;
    Inscoper::NBO::AnnotationRefPtr AnnotationRef = nullptr;
};

/*! Shared pointer for Prism*/
typedef std::shared_ptr<Prism> PrismPtr;

} // namespace Inscoper::NBO

#endif // PRISM_HPP_INCLUDED