#ifndef CONDENSER_HPP_INCLUDED
#define CONDENSER_HPP_INCLUDED

#include <iostream>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <vector>
#include <NBO/NBO/CondenserCategory_Type.h>
#include <NBO/NBO/CondenserCorrection_Type.h>
#include <NBO/NBO/OpticalAssembly_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 Condenser.
*
* Condensers are Lens Systems located above the Light Source and under the sample in an Upright Microscope, and above the stage and below the Light Source in an Inverted Microscope. They act to gather light from the Light Source and concentrate it into a cone of light that illuminates the specimen. They typically include a Turret system and Diaphragms. The aperture and angle of the light cone must be adjusted (via the size of the Diaphragm) for each different Objective.
*/
class NBO_EXPORT Condenser : public OpticalAssembly_Type {

public:
	
	Condenser();
	~Condenser();

	/*!
	* \brief Cast a NBOBaseClass to a Condenser.
	*
	* \param base The base class to cast
	* \return The casted element, or nullptr if the cast fails
	*/
	static std::shared_ptr<Condenser> 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 Correction attribute.
	*
	* This field captures any type of Aberration (i.e., failure of an optical system to produce a perfect image) this Condenser is design to correct. 
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setCorrection(const Inscoper::NBO::CondenserCorrection_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the Correction attribute.
	*
	* This field captures any type of Aberration (i.e., failure of an optical system to produce a perfect image) this Condenser is design to correct. 
	*
	* \return The value of the attribute
	*/
	CondenserCorrection_TypePtr getCorrection() const;

	/*!
	* \brief Resets the Correction attribute to an unset state.
	*
	* This field captures any type of Aberration (i.e., failure of an optical system to produce a perfect image) this Condenser is design to correct. 
	*/
	void resetCorrection();

	/*!
	* \brief Checks whether the optional Correction attribute is present.
	*
	* This field captures any type of Aberration (i.e., failure of an optical system to produce a perfect image) this Condenser is design to correct. 
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasCorrection() const;

	/*!
	* \brief Sets the value of the Type attribute.
	*
	* This field captures the general category this Condenser belongs to according to ISO 10934-1:2002. Specifically, this category refers to the type of Correction or Contrast Enhancement Method this Condenser is designed to achieve. According to ISO 10934-1:2002, options include: 1) Abbe, this is a condenser of simple design introduced by Abbe, in which there is only limited correction for spherical aberration and none for chromatic aberration. 2) Achromatic-aplanatic, this is a in which chromatic aberrations and spherical aberrations have been reduced. 3) Cardioid, this is a dark field condenser for transmitted light illumination that has spherical aberration and coma (i.e., aberration in which the image of an off-axis point object is deformed so that the image is shaped like a comet) correction. 4) Dark-field, this is a dark-ground condenser designed for dark-field microscopy, which for reflected-light microscopy might be located within the mount of the objective. 5) Pancratic, this is a condenser containing a variable “zoom” (pancratic) lens which allows the size of the illuminated field at the object to be varied while the illuminated field diaphragm remains of constant size. 6) Phase-contrast, this is condenser designed for phasecontrast microscopy. 6) Universal, this is a condenser designed for multiple contrast methods such as bright field, dark field, phase contrast, differential interference contrast, polarized light and modulation contrast.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setType(const Inscoper::NBO::CondenserCategory_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the Type attribute.
	*
	* This field captures the general category this Condenser belongs to according to ISO 10934-1:2002. Specifically, this category refers to the type of Correction or Contrast Enhancement Method this Condenser is designed to achieve. According to ISO 10934-1:2002, options include: 1) Abbe, this is a condenser of simple design introduced by Abbe, in which there is only limited correction for spherical aberration and none for chromatic aberration. 2) Achromatic-aplanatic, this is a in which chromatic aberrations and spherical aberrations have been reduced. 3) Cardioid, this is a dark field condenser for transmitted light illumination that has spherical aberration and coma (i.e., aberration in which the image of an off-axis point object is deformed so that the image is shaped like a comet) correction. 4) Dark-field, this is a dark-ground condenser designed for dark-field microscopy, which for reflected-light microscopy might be located within the mount of the objective. 5) Pancratic, this is a condenser containing a variable “zoom” (pancratic) lens which allows the size of the illuminated field at the object to be varied while the illuminated field diaphragm remains of constant size. 6) Phase-contrast, this is condenser designed for phasecontrast microscopy. 6) Universal, this is a condenser designed for multiple contrast methods such as bright field, dark field, phase contrast, differential interference contrast, polarized light and modulation contrast.
	*
	* \return The value of the attribute
	*/
	CondenserCategory_TypePtr getType() const;

	/*!
	* \brief Resets the Type attribute to an unset state.
	*
	* This field captures the general category this Condenser belongs to according to ISO 10934-1:2002. Specifically, this category refers to the type of Correction or Contrast Enhancement Method this Condenser is designed to achieve. According to ISO 10934-1:2002, options include: 1) Abbe, this is a condenser of simple design introduced by Abbe, in which there is only limited correction for spherical aberration and none for chromatic aberration. 2) Achromatic-aplanatic, this is a in which chromatic aberrations and spherical aberrations have been reduced. 3) Cardioid, this is a dark field condenser for transmitted light illumination that has spherical aberration and coma (i.e., aberration in which the image of an off-axis point object is deformed so that the image is shaped like a comet) correction. 4) Dark-field, this is a dark-ground condenser designed for dark-field microscopy, which for reflected-light microscopy might be located within the mount of the objective. 5) Pancratic, this is a condenser containing a variable “zoom” (pancratic) lens which allows the size of the illuminated field at the object to be varied while the illuminated field diaphragm remains of constant size. 6) Phase-contrast, this is condenser designed for phasecontrast microscopy. 6) Universal, this is a condenser designed for multiple contrast methods such as bright field, dark field, phase contrast, differential interference contrast, polarized light and modulation contrast.
	*/
	void resetType();

	/*!
	* \brief Checks whether the optional Type attribute is present.
	*
	* This field captures the general category this Condenser belongs to according to ISO 10934-1:2002. Specifically, this category refers to the type of Correction or Contrast Enhancement Method this Condenser is designed to achieve. According to ISO 10934-1:2002, options include: 1) Abbe, this is a condenser of simple design introduced by Abbe, in which there is only limited correction for spherical aberration and none for chromatic aberration. 2) Achromatic-aplanatic, this is a in which chromatic aberrations and spherical aberrations have been reduced. 3) Cardioid, this is a dark field condenser for transmitted light illumination that has spherical aberration and coma (i.e., aberration in which the image of an off-axis point object is deformed so that the image is shaped like a comet) correction. 4) Dark-field, this is a dark-ground condenser designed for dark-field microscopy, which for reflected-light microscopy might be located within the mount of the objective. 5) Pancratic, this is a condenser containing a variable “zoom” (pancratic) lens which allows the size of the illuminated field at the object to be varied while the illuminated field diaphragm remains of constant size. 6) Phase-contrast, this is condenser designed for phasecontrast microscopy. 6) Universal, this is a condenser designed for multiple contrast methods such as bright field, dark field, phase contrast, differential interference contrast, polarized light and modulation contrast.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasType() const;


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

	CondenserCorrection_TypePtr Correction = nullptr; // Optional attribute
	CondenserCategory_TypePtr Type = nullptr; // Required attribute
};

/*! Shared pointer for Condenser*/
typedef std::shared_ptr<Condenser> CondenserPtr;

} // namespace Inscoper::NBO

#endif // CONDENSER_HPP_INCLUDED