#ifndef OBJECTIVE_HPP_INCLUDED
#define OBJECTIVE_HPP_INCLUDED

#include <iostream>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <vector>
#include <NBO/NBO/AnnotationRef.h>
#include <NBO/NBO/ContrastModulationPlate_Type.h>
#include <NBO/NBO/CorrectionCollarTypeList_Type.h>
#include <NBO/NBO/Denomination_Type.h>
#include <NBO/NBO/DippingType_Type.h>
#include <NBO/NBO/ImmersionTypeList_Type.h>
#include <NBO/NBO/ManufacturerSpec_Type.h>
#include <NBO/NBO/ObjectiveCorrection_Type.h>
#include <NBO/NBO/ObjectiveID_Type.h>
#include <NBO/NBO/ObjectiveLightType_Type.h>
#include <NBO/NBO/PhaseContrastDesignationType_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 Objective.
*
* The Microscope's Objective lens consists of a lens, its mount, and any associated parts. It is the part of the imaging system, which forms a primary image of the object, either alone or in conjunction with a tube lens. The Objective typically consists of a compound lens consisting of along a common axis.
*/
class NBO_EXPORT Objective : public ManufacturerSpec_Type {

public:
	
	Objective();
	~Objective();

	/*!
	* \brief Cast a NBOBaseClass to a Objective.
	*
	* \param base The base class to cast
	* \return The casted element, or nullptr if the cast fails
	*/
	static std::shared_ptr<Objective> 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::ObjectiveID_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
	*/
	ObjectiveID_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 Magnification attribute.
	*
	* This field captures the Magnification of the Objective as specified by the Manufacturer - i.e., 60 represents a 60X lens.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setMagnification(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the Magnification attribute.
	*
	* This field captures the Magnification of the Objective as specified by the Manufacturer - i.e., 60 represents a 60X lens.
	*
	* \return The value of the attribute
	*/
	float getMagnification() const;

	/*!
	* \brief Resets the Magnification attribute to an unset state.
	*
	* This field captures the Magnification of the Objective as specified by the Manufacturer - i.e., 60 represents a 60X lens.
	*/
	void resetMagnification();

	/*!
	* \brief Checks whether the Magnification attribute is present.
	*
	* This field captures the Magnification of the Objective as specified by the Manufacturer - i.e., 60 represents a 60X lens.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasMagnification() const;

	/*!
	* \brief Sets the value of the LensNA attribute.
	*
	* This field captures the nominal Numerical Aperture (NA) of this Objective as specified by the Manufactuer, expressed as a floating-point (real) number (e.g. 1.27 NA). NA is a number that was defined initially by Abbe to characterize Objectives and Condensers. NA can be calculated by the expression n sin alpha, where n is the Refractive Index of the medium between the Lens and the Sample, and alpha is half the Angular Aperture of the Lens. NA is a measure of how much of the illumination that leaves the specimen actually passes through the Lens. The larger the NA, the more information the lens can transmit. Expected range 0.02 - 1.5.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setLensNA(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the LensNA attribute.
	*
	* This field captures the nominal Numerical Aperture (NA) of this Objective as specified by the Manufactuer, expressed as a floating-point (real) number (e.g. 1.27 NA). NA is a number that was defined initially by Abbe to characterize Objectives and Condensers. NA can be calculated by the expression n sin alpha, where n is the Refractive Index of the medium between the Lens and the Sample, and alpha is half the Angular Aperture of the Lens. NA is a measure of how much of the illumination that leaves the specimen actually passes through the Lens. The larger the NA, the more information the lens can transmit. Expected range 0.02 - 1.5.
	*
	* \return The value of the attribute
	*/
	float getLensNA() const;

	/*!
	* \brief Resets the LensNA attribute to an unset state.
	*
	* This field captures the nominal Numerical Aperture (NA) of this Objective as specified by the Manufactuer, expressed as a floating-point (real) number (e.g. 1.27 NA). NA is a number that was defined initially by Abbe to characterize Objectives and Condensers. NA can be calculated by the expression n sin alpha, where n is the Refractive Index of the medium between the Lens and the Sample, and alpha is half the Angular Aperture of the Lens. NA is a measure of how much of the illumination that leaves the specimen actually passes through the Lens. The larger the NA, the more information the lens can transmit. Expected range 0.02 - 1.5.
	*/
	void resetLensNA();

	/*!
	* \brief Checks whether the LensNA attribute is present.
	*
	* This field captures the nominal Numerical Aperture (NA) of this Objective as specified by the Manufactuer, expressed as a floating-point (real) number (e.g. 1.27 NA). NA is a number that was defined initially by Abbe to characterize Objectives and Condensers. NA can be calculated by the expression n sin alpha, where n is the Refractive Index of the medium between the Lens and the Sample, and alpha is half the Angular Aperture of the Lens. NA is a measure of how much of the illumination that leaves the specimen actually passes through the Lens. The larger the NA, the more information the lens can transmit. Expected range 0.02 - 1.5.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasLensNA() const;

	/*!
	* \brief Sets the value of the Correction attribute.
	*
	* This field captures the type of optical correction (i.e. chromatic correction, or flatness correction, etc.) associated with this Objective.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setCorrection(const Inscoper::NBO::ObjectiveCorrection_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the Correction attribute.
	*
	* This field captures the type of optical correction (i.e. chromatic correction, or flatness correction, etc.) associated with this Objective.
	*
	* \return The value of the attribute
	*/
	ObjectiveCorrection_TypePtr getCorrection() const;

	/*!
	* \brief Resets the Correction attribute to an unset state.
	*
	* This field captures the type of optical correction (i.e. chromatic correction, or flatness correction, etc.) associated with this Objective.
	*/
	void resetCorrection();

	/*!
	* \brief Checks whether the optional Correction attribute is present.
	*
	* This field captures the type of optical correction (i.e. chromatic correction, or flatness correction, etc.) associated with this Objective.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasCorrection() const;

	/*!
	* \brief Sets the value of the ImmersionType attribute.
	*
	* According to ISO 10934-1:2002, an Immersion Liquid is a liquid (commonly immersion oil, water or glycerol) specified as suitable for use in the space between the front of an immersion lens and the object NOTE Because the immersion liquid is considered in the computing of corrections to be part of the lens, its refractive index and dispersion (or Abbe number) are critical. Please refer to ISO 8036-1 for more details on Immersion Oil. This field describes the general category of the Immersion Liquid this Objective is designed for, according to the Manufacturer. If the general category is not Air, the actual Immersion Liquid that was used during the Acquisition of a specific Image must be specified in Objective Settings.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setImmersionType(const Inscoper::NBO::ImmersionTypeList_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the ImmersionType attribute.
	*
	* According to ISO 10934-1:2002, an Immersion Liquid is a liquid (commonly immersion oil, water or glycerol) specified as suitable for use in the space between the front of an immersion lens and the object NOTE Because the immersion liquid is considered in the computing of corrections to be part of the lens, its refractive index and dispersion (or Abbe number) are critical. Please refer to ISO 8036-1 for more details on Immersion Oil. This field describes the general category of the Immersion Liquid this Objective is designed for, according to the Manufacturer. If the general category is not Air, the actual Immersion Liquid that was used during the Acquisition of a specific Image must be specified in Objective Settings.
	*
	* \return The value of the attribute
	*/
	ImmersionTypeList_TypePtr getImmersionType() const;

	/*!
	* \brief Resets the ImmersionType attribute to an unset state.
	*
	* According to ISO 10934-1:2002, an Immersion Liquid is a liquid (commonly immersion oil, water or glycerol) specified as suitable for use in the space between the front of an immersion lens and the object NOTE Because the immersion liquid is considered in the computing of corrections to be part of the lens, its refractive index and dispersion (or Abbe number) are critical. Please refer to ISO 8036-1 for more details on Immersion Oil. This field describes the general category of the Immersion Liquid this Objective is designed for, according to the Manufacturer. If the general category is not Air, the actual Immersion Liquid that was used during the Acquisition of a specific Image must be specified in Objective Settings.
	*/
	void resetImmersionType();

	/*!
	* \brief Checks whether the optional ImmersionType attribute is present.
	*
	* According to ISO 10934-1:2002, an Immersion Liquid is a liquid (commonly immersion oil, water or glycerol) specified as suitable for use in the space between the front of an immersion lens and the object NOTE Because the immersion liquid is considered in the computing of corrections to be part of the lens, its refractive index and dispersion (or Abbe number) are critical. Please refer to ISO 8036-1 for more details on Immersion Oil. This field describes the general category of the Immersion Liquid this Objective is designed for, according to the Manufacturer. If the general category is not Air, the actual Immersion Liquid that was used during the Acquisition of a specific Image must be specified in Objective Settings.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasImmersionType() const;

	/*!
	* \brief Sets the value of the InfinityCorrected attribute.
	*
	* This field records whether (True) or not (False) this Objective is infinity corrected. An Infinity-corrected Objective is corrected for an infinite sample to primary image distance and needs to be used with a Tube Lens of appropriate focal length to obtains its nominal magnification.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setInfinityCorrected(const bool& value, bool validate = true);

	/*!
	* \brief Returns the value of the InfinityCorrected attribute.
	*
	* This field records whether (True) or not (False) this Objective is infinity corrected. An Infinity-corrected Objective is corrected for an infinite sample to primary image distance and needs to be used with a Tube Lens of appropriate focal length to obtains its nominal magnification.
	*
	* \return The value of the attribute
	*/
	bool getInfinityCorrected() const;

	/*!
	* \brief Resets the InfinityCorrected attribute to an unset state.
	*
	* This field records whether (True) or not (False) this Objective is infinity corrected. An Infinity-corrected Objective is corrected for an infinite sample to primary image distance and needs to be used with a Tube Lens of appropriate focal length to obtains its nominal magnification.
	*/
	void resetInfinityCorrected();

	/*!
	* \brief Checks whether the InfinityCorrected attribute is present.
	*
	* This field records whether (True) or not (False) this Objective is infinity corrected. An Infinity-corrected Objective is corrected for an infinite sample to primary image distance and needs to be used with a Tube Lens of appropriate focal length to obtains its nominal magnification.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasInfinityCorrected() const;

	/*!
	* \brief Sets the value of the ContrastModulation attribute.
	*
	* This field specifies the presence in this Objective of a contrast modulation device, such as a Phase Ring (Ph1, Ph2, Ph3), a Hoffman modulator, a Varel modulator, or similar.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setContrastModulation(const Inscoper::NBO::ContrastModulationPlate_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the ContrastModulation attribute.
	*
	* This field specifies the presence in this Objective of a contrast modulation device, such as a Phase Ring (Ph1, Ph2, Ph3), a Hoffman modulator, a Varel modulator, or similar.
	*
	* \return The value of the attribute
	*/
	ContrastModulationPlate_TypePtr getContrastModulation() const;

	/*!
	* \brief Resets the ContrastModulation attribute to an unset state.
	*
	* This field specifies the presence in this Objective of a contrast modulation device, such as a Phase Ring (Ph1, Ph2, Ph3), a Hoffman modulator, a Varel modulator, or similar.
	*/
	void resetContrastModulation();

	/*!
	* \brief Checks whether the optional ContrastModulation attribute is present.
	*
	* This field specifies the presence in this Objective of a contrast modulation device, such as a Phase Ring (Ph1, Ph2, Ph3), a Hoffman modulator, a Varel modulator, or similar.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasContrastModulation() const;

	/*!
	* \brief Sets the value of the DIC attribute.
	*
	* This field specifies whether (True) the Objective is designed for Differential Interference Contrast (DIC) or not (False). DIC is a contrast modality due to double-beam interference in which two waves that fall on the object Plane or Image Plane are separated laterally by a distance similar to the minimum resolvable distance.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setDIC(const bool& value, bool validate = true);

	/*!
	* \brief Returns the value of the DIC attribute.
	*
	* This field specifies whether (True) the Objective is designed for Differential Interference Contrast (DIC) or not (False). DIC is a contrast modality due to double-beam interference in which two waves that fall on the object Plane or Image Plane are separated laterally by a distance similar to the minimum resolvable distance.
	*
	* \return The value of the attribute
	*/
	bool getDIC() const;

	/*!
	* \brief Resets the DIC attribute to an unset state.
	*
	* This field specifies whether (True) the Objective is designed for Differential Interference Contrast (DIC) or not (False). DIC is a contrast modality due to double-beam interference in which two waves that fall on the object Plane or Image Plane are separated laterally by a distance similar to the minimum resolvable distance.
	*/
	void resetDIC();

	/*!
	* \brief Checks whether the DIC attribute is present.
	*
	* This field specifies whether (True) the Objective is designed for Differential Interference Contrast (DIC) or not (False). DIC is a contrast modality due to double-beam interference in which two waves that fall on the object Plane or Image Plane are separated laterally by a distance similar to the minimum resolvable distance.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasDIC() const;

	/*!
	* \brief Sets the value of the LightType attribute.
	*
	* This field specifies whether this Objective is designed for a special Light application (e.g., IR or UV).
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setLightType(const Inscoper::NBO::ObjectiveLightType_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the LightType attribute.
	*
	* This field specifies whether this Objective is designed for a special Light application (e.g., IR or UV).
	*
	* \return The value of the attribute
	*/
	ObjectiveLightType_TypePtr getLightType() const;

	/*!
	* \brief Resets the LightType attribute to an unset state.
	*
	* This field specifies whether this Objective is designed for a special Light application (e.g., IR or UV).
	*/
	void resetLightType();

	/*!
	* \brief Checks whether the optional LightType attribute is present.
	*
	* This field specifies whether this Objective is designed for a special Light application (e.g., IR or UV).
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasLightType() const;

	/*!
	* \brief Sets the value of the DippingMedium attribute.
	*
	* In case the Immersion Type for this Objective is designated as Dipping, this field captures the type of Dipping Medium this Objective is compatible with. Examples include, water-based (biological buffers, culture media, other water-based solutions) organic-based [FocusClear (CLARITY); CUBIC-1, CUBIC-2, CUBIC-R1, CUBIC-R2; 2,2-thiodiethanol (TDE); ethyl cinnamate; Benzyl Benzoate and BB-PEG (PEGASOS); Benzyl Alcohol, Benzyl Benzoate (BABB); dibenzyl ether (DBE); 100% Ethanol].
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setDippingMedium(const Inscoper::NBO::DippingType_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the DippingMedium attribute.
	*
	* In case the Immersion Type for this Objective is designated as Dipping, this field captures the type of Dipping Medium this Objective is compatible with. Examples include, water-based (biological buffers, culture media, other water-based solutions) organic-based [FocusClear (CLARITY); CUBIC-1, CUBIC-2, CUBIC-R1, CUBIC-R2; 2,2-thiodiethanol (TDE); ethyl cinnamate; Benzyl Benzoate and BB-PEG (PEGASOS); Benzyl Alcohol, Benzyl Benzoate (BABB); dibenzyl ether (DBE); 100% Ethanol].
	*
	* \return The value of the attribute
	*/
	DippingType_TypePtr getDippingMedium() const;

	/*!
	* \brief Resets the DippingMedium attribute to an unset state.
	*
	* In case the Immersion Type for this Objective is designated as Dipping, this field captures the type of Dipping Medium this Objective is compatible with. Examples include, water-based (biological buffers, culture media, other water-based solutions) organic-based [FocusClear (CLARITY); CUBIC-1, CUBIC-2, CUBIC-R1, CUBIC-R2; 2,2-thiodiethanol (TDE); ethyl cinnamate; Benzyl Benzoate and BB-PEG (PEGASOS); Benzyl Alcohol, Benzyl Benzoate (BABB); dibenzyl ether (DBE); 100% Ethanol].
	*/
	void resetDippingMedium();

	/*!
	* \brief Checks whether the optional DippingMedium attribute is present.
	*
	* In case the Immersion Type for this Objective is designated as Dipping, this field captures the type of Dipping Medium this Objective is compatible with. Examples include, water-based (biological buffers, culture media, other water-based solutions) organic-based [FocusClear (CLARITY); CUBIC-1, CUBIC-2, CUBIC-R1, CUBIC-R2; 2,2-thiodiethanol (TDE); ethyl cinnamate; Benzyl Benzoate and BB-PEG (PEGASOS); Benzyl Alcohol, Benzyl Benzoate (BABB); dibenzyl ether (DBE); 100% Ethanol].
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasDippingMedium() const;

	/*!
	* \brief Sets the value of the WorkingDistance attribute.
	*
	* This field reports the Working Distance of this Objective under normal operating conditions. The Working Distance is the distance (in air, or in the specified immersion liquid) between the front of an Objective and the surface of the cover glass or of the specimen if uncovered.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setWorkingDistance(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the WorkingDistance attribute.
	*
	* This field reports the Working Distance of this Objective under normal operating conditions. The Working Distance is the distance (in air, or in the specified immersion liquid) between the front of an Objective and the surface of the cover glass or of the specimen if uncovered.
	*
	* \return The value of the attribute
	*/
	float getWorkingDistance() const;

	/*!
	* \brief Resets the WorkingDistance attribute to an unset state.
	*
	* This field reports the Working Distance of this Objective under normal operating conditions. The Working Distance is the distance (in air, or in the specified immersion liquid) between the front of an Objective and the surface of the cover glass or of the specimen if uncovered.
	*/
	void resetWorkingDistance();

	/*!
	* \brief Checks whether the WorkingDistance attribute is present.
	*
	* This field reports the Working Distance of this Objective under normal operating conditions. The Working Distance is the distance (in air, or in the specified immersion liquid) between the front of an Objective and the surface of the cover glass or of the specimen if uncovered.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasWorkingDistance() const;

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

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

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

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

	/*!
	* \brief Sets the value of the CorrectionCollar attribute.
	*
	* This field records whether (True) or not (False) the Objective was fitted with a Correction Collar. When using high NA dry Objectives (NA 0.8 or greater), cover glass thickness variations of only a few micrometers, immersion medium, and temperature changes result in dramatic image degradation due to aberration. To compensate for these errors, the more highly corrected Objectives are equipped with a Correction Collar mechanism, which is provided to adjust the central lens group position to compensate for deviations from correct optical path length due to changes in Cover Glass Thickness, the nature of the Immersion Liquid, different Numerical Apertures, and Temperature.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setCorrectionCollar(const bool& value, bool validate = true);

	/*!
	* \brief Returns the value of the CorrectionCollar attribute.
	*
	* This field records whether (True) or not (False) the Objective was fitted with a Correction Collar. When using high NA dry Objectives (NA 0.8 or greater), cover glass thickness variations of only a few micrometers, immersion medium, and temperature changes result in dramatic image degradation due to aberration. To compensate for these errors, the more highly corrected Objectives are equipped with a Correction Collar mechanism, which is provided to adjust the central lens group position to compensate for deviations from correct optical path length due to changes in Cover Glass Thickness, the nature of the Immersion Liquid, different Numerical Apertures, and Temperature.
	*
	* \return The value of the attribute
	*/
	bool getCorrectionCollar() const;

	/*!
	* \brief Resets the CorrectionCollar attribute to an unset state.
	*
	* This field records whether (True) or not (False) the Objective was fitted with a Correction Collar. When using high NA dry Objectives (NA 0.8 or greater), cover glass thickness variations of only a few micrometers, immersion medium, and temperature changes result in dramatic image degradation due to aberration. To compensate for these errors, the more highly corrected Objectives are equipped with a Correction Collar mechanism, which is provided to adjust the central lens group position to compensate for deviations from correct optical path length due to changes in Cover Glass Thickness, the nature of the Immersion Liquid, different Numerical Apertures, and Temperature.
	*/
	void resetCorrectionCollar();

	/*!
	* \brief Checks whether the CorrectionCollar attribute is present.
	*
	* This field records whether (True) or not (False) the Objective was fitted with a Correction Collar. When using high NA dry Objectives (NA 0.8 or greater), cover glass thickness variations of only a few micrometers, immersion medium, and temperature changes result in dramatic image degradation due to aberration. To compensate for these errors, the more highly corrected Objectives are equipped with a Correction Collar mechanism, which is provided to adjust the central lens group position to compensate for deviations from correct optical path length due to changes in Cover Glass Thickness, the nature of the Immersion Liquid, different Numerical Apertures, and Temperature.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasCorrectionCollar() const;

	/*!
	* \brief Sets the value of the CorrectionCollarType attribute.
	*
	* This field records the type of Correction Collar with which this Objective is fitted. In case the Objective has more than one Correction Collar please enter "Multi" and provide more details in Description.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setCorrectionCollarType(const Inscoper::NBO::CorrectionCollarTypeList_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the CorrectionCollarType attribute.
	*
	* This field records the type of Correction Collar with which this Objective is fitted. In case the Objective has more than one Correction Collar please enter "Multi" and provide more details in Description.
	*
	* \return The value of the attribute
	*/
	CorrectionCollarTypeList_TypePtr getCorrectionCollarType() const;

	/*!
	* \brief Resets the CorrectionCollarType attribute to an unset state.
	*
	* This field records the type of Correction Collar with which this Objective is fitted. In case the Objective has more than one Correction Collar please enter "Multi" and provide more details in Description.
	*/
	void resetCorrectionCollarType();

	/*!
	* \brief Checks whether the optional CorrectionCollarType attribute is present.
	*
	* This field records the type of Correction Collar with which this Objective is fitted. In case the Objective has more than one Correction Collar please enter "Multi" and provide more details in Description.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasCorrectionCollarType() const;

	/*!
	* \brief Sets the value of the PhaseContrastDesignation attribute.
	*
	* If the Objective is designed for Phase, this field specifies the Phase Contrast type designation (see: https://www.microscopyu.com/techniques/phase-contrast/phase-contrast-Microscope-configuration).
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setPhaseContrastDesignation(const Inscoper::NBO::PhaseContrastDesignationType_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the PhaseContrastDesignation attribute.
	*
	* If the Objective is designed for Phase, this field specifies the Phase Contrast type designation (see: https://www.microscopyu.com/techniques/phase-contrast/phase-contrast-Microscope-configuration).
	*
	* \return The value of the attribute
	*/
	PhaseContrastDesignationType_TypePtr getPhaseContrastDesignation() const;

	/*!
	* \brief Resets the PhaseContrastDesignation attribute to an unset state.
	*
	* If the Objective is designed for Phase, this field specifies the Phase Contrast type designation (see: https://www.microscopyu.com/techniques/phase-contrast/phase-contrast-Microscope-configuration).
	*/
	void resetPhaseContrastDesignation();

	/*!
	* \brief Checks whether the optional PhaseContrastDesignation attribute is present.
	*
	* If the Objective is designed for Phase, this field specifies the Phase Contrast type designation (see: https://www.microscopyu.com/techniques/phase-contrast/phase-contrast-Microscope-configuration).
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasPhaseContrastDesignation() const;

	/*!
	* \brief Sets the value of the CalibratedMagnification attribute.
	*
	* This field captures the Magnification of the Objective as measured via a calibration process- i.e., '59.987' for a 60x lens.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setCalibratedMagnification(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the CalibratedMagnification attribute.
	*
	* This field captures the Magnification of the Objective as measured via a calibration process- i.e., '59.987' for a 60x lens.
	*
	* \return The value of the attribute
	*/
	float getCalibratedMagnification() const;

	/*!
	* \brief Resets the CalibratedMagnification attribute to an unset state.
	*
	* This field captures the Magnification of the Objective as measured via a calibration process- i.e., '59.987' for a 60x lens.
	*/
	void resetCalibratedMagnification();

	/*!
	* \brief Checks whether the CalibratedMagnification attribute is present.
	*
	* This field captures the Magnification of the Objective as measured via a calibration process- i.e., '59.987' for a 60x lens.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasCalibratedMagnification() const;

	/*!
	* \brief Sets the value of the Iris attribute.
	*
	* This field records whether (True) or not (False) the Objective was fitted with an Iris. Manufacturers offer high NA Objectives, which are equipped with an internal Iris Diaphragm that increases image contrast during digital imaging to compensate for image flare artifacts due to light emitted from areas outside the focal plane. Opening or closing the Iris Diaphragm determines the size of the Objective rear aperture yielding a variable NA range between 0.5 and the Objective's upper limit.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setIris(const bool& value, bool validate = true);

	/*!
	* \brief Returns the value of the Iris attribute.
	*
	* This field records whether (True) or not (False) the Objective was fitted with an Iris. Manufacturers offer high NA Objectives, which are equipped with an internal Iris Diaphragm that increases image contrast during digital imaging to compensate for image flare artifacts due to light emitted from areas outside the focal plane. Opening or closing the Iris Diaphragm determines the size of the Objective rear aperture yielding a variable NA range between 0.5 and the Objective's upper limit.
	*
	* \return The value of the attribute
	*/
	bool getIris() const;

	/*!
	* \brief Resets the Iris attribute to an unset state.
	*
	* This field records whether (True) or not (False) the Objective was fitted with an Iris. Manufacturers offer high NA Objectives, which are equipped with an internal Iris Diaphragm that increases image contrast during digital imaging to compensate for image flare artifacts due to light emitted from areas outside the focal plane. Opening or closing the Iris Diaphragm determines the size of the Objective rear aperture yielding a variable NA range between 0.5 and the Objective's upper limit.
	*/
	void resetIris();

	/*!
	* \brief Checks whether the Iris attribute is present.
	*
	* This field records whether (True) or not (False) the Objective was fitted with an Iris. Manufacturers offer high NA Objectives, which are equipped with an internal Iris Diaphragm that increases image contrast during digital imaging to compensate for image flare artifacts due to light emitted from areas outside the focal plane. Opening or closing the Iris Diaphragm determines the size of the Objective rear aperture yielding a variable NA range between 0.5 and the Objective's upper limit.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasIris() const;

	/*!
	* \brief Sets the value of the ObjectiveViewField attribute.
	*
	* This field records the maximal diameter of the view field allowed by this Objective, expressed in mm, and measured at the intermediate Image Plane. NB: The field of view is influenced by the magnification and diameter of the ocular (eyepiece) field diaphragm, but also by the limits imposed by the design of the Objective.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setObjectiveViewField(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the ObjectiveViewField attribute.
	*
	* This field records the maximal diameter of the view field allowed by this Objective, expressed in mm, and measured at the intermediate Image Plane. NB: The field of view is influenced by the magnification and diameter of the ocular (eyepiece) field diaphragm, but also by the limits imposed by the design of the Objective.
	*
	* \return The value of the attribute
	*/
	float getObjectiveViewField() const;

	/*!
	* \brief Resets the ObjectiveViewField attribute to an unset state.
	*
	* This field records the maximal diameter of the view field allowed by this Objective, expressed in mm, and measured at the intermediate Image Plane. NB: The field of view is influenced by the magnification and diameter of the ocular (eyepiece) field diaphragm, but also by the limits imposed by the design of the Objective.
	*/
	void resetObjectiveViewField();

	/*!
	* \brief Checks whether the ObjectiveViewField attribute is present.
	*
	* This field records the maximal diameter of the view field allowed by this Objective, expressed in mm, and measured at the intermediate Image Plane. NB: The field of view is influenced by the magnification and diameter of the ocular (eyepiece) field diaphragm, but also by the limits imposed by the design of the Objective.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasObjectiveViewField() const;

	/*!
	* \brief Sets the value of the ImageDistance attribute.
	*
	* This field records the distance in air between the rear principal Plane of this Objective and the primary Image Plane.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setImageDistance(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the ImageDistance attribute.
	*
	* This field records the distance in air between the rear principal Plane of this Objective and the primary Image Plane.
	*
	* \return The value of the attribute
	*/
	float getImageDistance() const;

	/*!
	* \brief Resets the ImageDistance attribute to an unset state.
	*
	* This field records the distance in air between the rear principal Plane of this Objective and the primary Image Plane.
	*/
	void resetImageDistance();

	/*!
	* \brief Checks whether the ImageDistance attribute is present.
	*
	* This field records the distance in air between the rear principal Plane of this Objective and the primary Image Plane.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasImageDistance() const;

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

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

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

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

	/*!
	* \brief Sets the value of the FrontFocalLength attribute.
	*
	* This field records the distance (f) measured along the optical axis from the front principal Plane of this Lens to the front focal Plane (F).
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setFrontFocalLength(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the FrontFocalLength attribute.
	*
	* This field records the distance (f) measured along the optical axis from the front principal Plane of this Lens to the front focal Plane (F).
	*
	* \return The value of the attribute
	*/
	float getFrontFocalLength() const;

	/*!
	* \brief Resets the FrontFocalLength attribute to an unset state.
	*
	* This field records the distance (f) measured along the optical axis from the front principal Plane of this Lens to the front focal Plane (F).
	*/
	void resetFrontFocalLength();

	/*!
	* \brief Checks whether the FrontFocalLength attribute is present.
	*
	* This field records the distance (f) measured along the optical axis from the front principal Plane of this Lens to the front focal Plane (F).
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasFrontFocalLength() const;

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

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

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

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

	/*!
	* \brief Sets the value of the BackFocalLength attribute.
	*
	* This field records the distance (f') measured along the optical axis from the rear principal Plane of this Lens to the rear focal Plane (F').
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setBackFocalLength(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the BackFocalLength attribute.
	*
	* This field records the distance (f') measured along the optical axis from the rear principal Plane of this Lens to the rear focal Plane (F').
	*
	* \return The value of the attribute
	*/
	float getBackFocalLength() const;

	/*!
	* \brief Resets the BackFocalLength attribute to an unset state.
	*
	* This field records the distance (f') measured along the optical axis from the rear principal Plane of this Lens to the rear focal Plane (F').
	*/
	void resetBackFocalLength();

	/*!
	* \brief Checks whether the BackFocalLength attribute is present.
	*
	* This field records the distance (f') measured along the optical axis from the rear principal Plane of this Lens to the rear focal Plane (F').
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasBackFocalLength() const;

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

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

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

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

	/*!
	* \brief Sets the value of the ParfocalizingDistance attribute.
	*
	* This field records the distance between the mounting Plane of this Objective and the specimen Plane.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setParfocalizingDistance(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the ParfocalizingDistance attribute.
	*
	* This field records the distance between the mounting Plane of this Objective and the specimen Plane.
	*
	* \return The value of the attribute
	*/
	float getParfocalizingDistance() const;

	/*!
	* \brief Resets the ParfocalizingDistance attribute to an unset state.
	*
	* This field records the distance between the mounting Plane of this Objective and the specimen Plane.
	*/
	void resetParfocalizingDistance();

	/*!
	* \brief Checks whether the ParfocalizingDistance attribute is present.
	*
	* This field records the distance between the mounting Plane of this Objective and the specimen Plane.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasParfocalizingDistance() const;

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

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

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

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

	/*!
	* \brief Sets the value of the AnnotationRef element.
	*
	* This is a simple multi-line comment or annotation describing this component.
	*
	* \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.
	*
	* This is a simple multi-line comment or annotation describing this component.
	*
	* \return The value of the element
	*/
	Inscoper::NBO::AnnotationRefPtr getAnnotationRef() const;

	/*!
	* \brief Resets the AnnotationRef element to an unset state.
	*
	* This is a simple multi-line comment or annotation describing this component.
	*/
	void resetAnnotationRef();

	/*!
	* \brief Checks whether the optional AnnotationRef element is present.
	*
	* This is a simple multi-line comment or annotation describing this component.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasAnnotationRef() const;


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

	ObjectiveID_TypePtr ID = nullptr; // Required attribute
	Denomination_TypePtr Name = nullptr; // Optional attribute
    std::optional<float> Magnification; // Required attribute
    std::optional<float> LensNA; // Required attribute
	ObjectiveCorrection_TypePtr Correction = nullptr; // Required attribute
	ImmersionTypeList_TypePtr ImmersionType = nullptr; // Required attribute
    std::optional<bool> InfinityCorrected; // Required attribute
	ContrastModulationPlate_TypePtr ContrastModulation = nullptr; // Required attribute
    std::optional<bool> DIC; // Required attribute
	ObjectiveLightType_TypePtr LightType = nullptr; // Optional attribute
	DippingType_TypePtr DippingMedium = nullptr; // Optional attribute
    std::optional<float> WorkingDistance; // Required attribute
	UnitsLength_TypePtr WorkingDistanceUnit = nullptr; // Optional attribute
    std::optional<bool> CorrectionCollar; // Required attribute
	CorrectionCollarTypeList_TypePtr CorrectionCollarType = nullptr; // Optional attribute
	PhaseContrastDesignationType_TypePtr PhaseContrastDesignation = nullptr; // Optional attribute
    std::optional<float> CalibratedMagnification; // Optional attribute
    std::optional<bool> Iris; // Optional attribute
    std::optional<float> ObjectiveViewField; // Required attribute
    std::optional<float> ImageDistance; // Required attribute
	UnitsLength_TypePtr ImageDistanceUnit = nullptr; // Optional attribute
    std::optional<float> FrontFocalLength; // Optional attribute
	UnitsLength_TypePtr FrontFocalLengthUnit = nullptr; // Optional attribute
    std::optional<float> BackFocalLength; // Optional attribute
	UnitsLength_TypePtr BackFocalLengthUnit = nullptr; // Optional attribute
    std::optional<float> ParfocalizingDistance; // Optional attribute
	UnitsLength_TypePtr ParfocalizingDistanceUnit = nullptr; // Optional attribute
    Inscoper::NBO::AnnotationRefPtr AnnotationRef = nullptr;
};

/*! Shared pointer for Objective*/
typedef std::shared_ptr<Objective> ObjectivePtr;

} // namespace Inscoper::NBO

#endif // OBJECTIVE_HPP_INCLUDED