#ifndef DICHROIC_TYPE_HPP_INCLUDED
#define DICHROIC_TYPE_HPP_INCLUDED

#include <iostream>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <vector>
#include <NBO/NBO/AttenuationMethodType_Type.h>
#include <NBO/NBO/CoatingMethod_Type.h>
#include <NBO/NBO/FilterPolarizationType_Type.h>
#include <NBO/NBO/FilterTechnologyType_Type.h>
#include <NBO/NBO/FilterType_Type.h>
#include <NBO/NBO/LightPathLocationOptions_Type.h>
#include <NBO/NBO/MirroringDevice_Type.h>
#include <NBO/NBO/ReflectanceProfileFile.h>
#include <NBO/NBO/ReflectanceRange.h>
#include <NBO/NBO/TransmittanceProfileFile.h>
#include <NBO/NBO/TransmittanceRange.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 complex type Dichroic.
*
* A Dichroic Mirror (also often referred to as Dichroic Beamsplitter or simply as Dichroic) is a Mirror that spectrally separate light by transmitting and reflecting light as a function of wavelength. In the context of fluorescence microscopy, they are typically used to reflect the excitation light, but transmit the emitted fluorescence. Dichroic Mirrors can be categorized in different manners. However, the most important criteria for choosing a Dichoric Mirror are the Transmittance and the Reflectance Wavelength ranges.
*/
class NBO_EXPORT Dichroic_Type : public MirroringDevice_Type {

public:
	
	Dichroic_Type();
	~Dichroic_Type();

	/*!
	* \brief Cast a NBOBaseClass to a Dichroic_Type.
	*
	* \param base The base class to cast
	* \return The casted element, or nullptr if the cast fails
	*/
	static std::shared_ptr<Dichroic_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 Type attribute.
	*
	* This field captures the Type of Dichroic used in this case.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setType(const Inscoper::NBO::FilterType_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the Type attribute.
	*
	* This field captures the Type of Dichroic used in this case.
	*
	* \return The value of the attribute
	*/
	FilterType_TypePtr getType() const;

	/*!
	* \brief Resets the Type attribute to an unset state.
	*
	* This field captures the Type of Dichroic used in this case.
	*/
	void resetType();

	/*!
	* \brief Checks whether the optional Type attribute is present.
	*
	* This field captures the Type of Dichroic used in this case.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasType() const;

	/*!
	* \brief Sets the value of the CoatingMethod attribute.
	*
	* This field records the type of Coating used in this case. An optical coating is one or more thin layers of material deposited on an optical component such as a Lens, Filter or Mirror, which alters the way in which the optic reflects and transmits light.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setCoatingMethod(const Inscoper::NBO::CoatingMethod_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the CoatingMethod attribute.
	*
	* This field records the type of Coating used in this case. An optical coating is one or more thin layers of material deposited on an optical component such as a Lens, Filter or Mirror, which alters the way in which the optic reflects and transmits light.
	*
	* \return The value of the attribute
	*/
	CoatingMethod_TypePtr getCoatingMethod() const;

	/*!
	* \brief Resets the CoatingMethod attribute to an unset state.
	*
	* This field records the type of Coating used in this case. An optical coating is one or more thin layers of material deposited on an optical component such as a Lens, Filter or Mirror, which alters the way in which the optic reflects and transmits light.
	*/
	void resetCoatingMethod();

	/*!
	* \brief Checks whether the optional CoatingMethod attribute is present.
	*
	* This field records the type of Coating used in this case. An optical coating is one or more thin layers of material deposited on an optical component such as a Lens, Filter or Mirror, which alters the way in which the optic reflects and transmits light.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasCoatingMethod() const;

	/*!
	* \brief Sets the value of the LightPathLocation attribute.
	*
	* This field records the location of this component in the Microscope Light Path. The most common positions are: Infinity Space, Camera Port or Illumination Port.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setLightPathLocation(const Inscoper::NBO::LightPathLocationOptions_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the LightPathLocation attribute.
	*
	* This field records the location of this component in the Microscope Light Path. The most common positions are: Infinity Space, Camera Port or Illumination Port.
	*
	* \return The value of the attribute
	*/
	LightPathLocationOptions_TypePtr getLightPathLocation() const;

	/*!
	* \brief Resets the LightPathLocation attribute to an unset state.
	*
	* This field records the location of this component in the Microscope Light Path. The most common positions are: Infinity Space, Camera Port or Illumination Port.
	*/
	void resetLightPathLocation();

	/*!
	* \brief Checks whether the optional LightPathLocation attribute is present.
	*
	* This field records the location of this component in the Microscope Light Path. The most common positions are: Infinity Space, Camera Port or Illumination Port.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasLightPathLocation() const;

	/*!
	* \brief Sets the value of the Technology attribute.
	*
	* This field records the filtering Technology utilized for this optical element. The main types of technologies used in fluorescence analysis are Absorption (aka colored) glass, Polymer or Thin-film coating.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setTechnology(const Inscoper::NBO::FilterTechnologyType_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the Technology attribute.
	*
	* This field records the filtering Technology utilized for this optical element. The main types of technologies used in fluorescence analysis are Absorption (aka colored) glass, Polymer or Thin-film coating.
	*
	* \return The value of the attribute
	*/
	FilterTechnologyType_TypePtr getTechnology() const;

	/*!
	* \brief Resets the Technology attribute to an unset state.
	*
	* This field records the filtering Technology utilized for this optical element. The main types of technologies used in fluorescence analysis are Absorption (aka colored) glass, Polymer or Thin-film coating.
	*/
	void resetTechnology();

	/*!
	* \brief Checks whether the optional Technology attribute is present.
	*
	* This field records the filtering Technology utilized for this optical element. The main types of technologies used in fluorescence analysis are Absorption (aka colored) glass, Polymer or Thin-film coating.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasTechnology() const;

	/*!
	* \brief Sets the value of the AttenuationMethod attribute.
	*
	* This field records the mean by which this optical element achieves out-of-band transmission attenuation.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setAttenuationMethod(const Inscoper::NBO::AttenuationMethodType_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the AttenuationMethod attribute.
	*
	* This field records the mean by which this optical element achieves out-of-band transmission attenuation.
	*
	* \return The value of the attribute
	*/
	AttenuationMethodType_TypePtr getAttenuationMethod() const;

	/*!
	* \brief Resets the AttenuationMethod attribute to an unset state.
	*
	* This field records the mean by which this optical element achieves out-of-band transmission attenuation.
	*/
	void resetAttenuationMethod();

	/*!
	* \brief Checks whether the optional AttenuationMethod attribute is present.
	*
	* This field records the mean by which this optical element achieves out-of-band transmission attenuation.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasAttenuationMethod() const;

	/*!
	* \brief Sets the value of the AttenuationCoefficient attribute.
	*
	* This field records the Attenuation Coefficient (AC) of this optical element. The AC (aka blocking coefficient) is a material property that characterizes the degree to which light is being blocked (i.e., scattered or absorbed) by it. AC is used as a measure of the out-of-band blocking of an optical Lens, Filter, Dichroic mirror over an extended range of the spectrum. AC is often reported in units of optical density (OD), whereas OD= -log10(T), and T=Transmittance (0≤T≤1).
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setAttenuationCoefficient(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the AttenuationCoefficient attribute.
	*
	* This field records the Attenuation Coefficient (AC) of this optical element. The AC (aka blocking coefficient) is a material property that characterizes the degree to which light is being blocked (i.e., scattered or absorbed) by it. AC is used as a measure of the out-of-band blocking of an optical Lens, Filter, Dichroic mirror over an extended range of the spectrum. AC is often reported in units of optical density (OD), whereas OD= -log10(T), and T=Transmittance (0≤T≤1).
	*
	* \return The value of the attribute
	*/
	float getAttenuationCoefficient() const;

	/*!
	* \brief Resets the AttenuationCoefficient attribute to an unset state.
	*
	* This field records the Attenuation Coefficient (AC) of this optical element. The AC (aka blocking coefficient) is a material property that characterizes the degree to which light is being blocked (i.e., scattered or absorbed) by it. AC is used as a measure of the out-of-band blocking of an optical Lens, Filter, Dichroic mirror over an extended range of the spectrum. AC is often reported in units of optical density (OD), whereas OD= -log10(T), and T=Transmittance (0≤T≤1).
	*/
	void resetAttenuationCoefficient();

	/*!
	* \brief Checks whether the AttenuationCoefficient attribute is present.
	*
	* This field records the Attenuation Coefficient (AC) of this optical element. The AC (aka blocking coefficient) is a material property that characterizes the degree to which light is being blocked (i.e., scattered or absorbed) by it. AC is used as a measure of the out-of-band blocking of an optical Lens, Filter, Dichroic mirror over an extended range of the spectrum. AC is often reported in units of optical density (OD), whereas OD= -log10(T), and T=Transmittance (0≤T≤1).
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasAttenuationCoefficient() const;

	/*!
	* \brief Sets the value of the Thickness attribute.
	*
	* This field describes the Thickness of this optical element.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setThickness(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the Thickness attribute.
	*
	* This field describes the Thickness of this optical element.
	*
	* \return The value of the attribute
	*/
	float getThickness() const;

	/*!
	* \brief Resets the Thickness attribute to an unset state.
	*
	* This field describes the Thickness of this optical element.
	*/
	void resetThickness();

	/*!
	* \brief Checks whether the Thickness attribute is present.
	*
	* This field describes the Thickness of this optical element.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasThickness() const;

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

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

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

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

	/*!
	* \brief Sets the value of the Polarization attribute.
	*
	* This field records the polarization effect of this optical element. Any thin-film interference coating that is used at non-normal angles-of-incidence will cause some amount of polarization, the precise effect varying greatly with wavelength and with the particular coating design.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setPolarization(const Inscoper::NBO::FilterPolarizationType_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the Polarization attribute.
	*
	* This field records the polarization effect of this optical element. Any thin-film interference coating that is used at non-normal angles-of-incidence will cause some amount of polarization, the precise effect varying greatly with wavelength and with the particular coating design.
	*
	* \return The value of the attribute
	*/
	FilterPolarizationType_TypePtr getPolarization() const;

	/*!
	* \brief Resets the Polarization attribute to an unset state.
	*
	* This field records the polarization effect of this optical element. Any thin-film interference coating that is used at non-normal angles-of-incidence will cause some amount of polarization, the precise effect varying greatly with wavelength and with the particular coating design.
	*/
	void resetPolarization();

	/*!
	* \brief Checks whether the optional Polarization attribute is present.
	*
	* This field records the polarization effect of this optical element. Any thin-film interference coating that is used at non-normal angles-of-incidence will cause some amount of polarization, the precise effect varying greatly with wavelength and with the particular coating design.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasPolarization() const;

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

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

	/*!
	* \brief Adds a new TransmittanceProfileFile 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 addToTransmittanceProfileFile_List(const Inscoper::NBO::TransmittanceProfileFilePtr& value, bool validate = true);

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

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

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

	/*!
	* \brief Adds a new ReflectanceProfileFile 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 addToReflectanceProfileFile_List(const Inscoper::NBO::ReflectanceProfileFilePtr& value, bool validate = true);

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

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

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

	/*!
	* \brief Adds a new TransmittanceRange 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 addToTransmittanceRange_List(const Inscoper::NBO::TransmittanceRangePtr& value, bool validate = true);

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

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

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

	/*!
	* \brief Adds a new ReflectanceRange 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 addToReflectanceRange_List(const Inscoper::NBO::ReflectanceRangePtr& value, bool validate = true);

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


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

	FilterType_TypePtr Type = nullptr; // Required attribute
	CoatingMethod_TypePtr CoatingMethod = nullptr; // Required attribute
	LightPathLocationOptions_TypePtr LightPathLocation = nullptr; // Required attribute
	FilterTechnologyType_TypePtr Technology = nullptr; // Optional attribute
	AttenuationMethodType_TypePtr AttenuationMethod = nullptr; // Required attribute
    std::optional<float> AttenuationCoefficient; // Optional attribute
    std::optional<float> Thickness; // Optional attribute
	UnitsLength_TypePtr ThicknessUnit = nullptr; // Optional attribute
	FilterPolarizationType_TypePtr Polarization = nullptr; // Optional attribute
    std::vector<Inscoper::NBO::TransmittanceProfileFilePtr> TransmittanceProfileFile_List;
    std::vector<Inscoper::NBO::ReflectanceProfileFilePtr> ReflectanceProfileFile_List;
    std::vector<Inscoper::NBO::TransmittanceRangePtr> TransmittanceRange_List;
    std::vector<Inscoper::NBO::ReflectanceRangePtr> ReflectanceRange_List;
};

/*! Shared pointer for Dichroic_Type*/
typedef std::shared_ptr<Dichroic_Type> Dichroic_TypePtr;

} // namespace Inscoper::NBO

#endif // DICHROIC_TYPE_HPP_INCLUDED