#ifndef POINTDETECTOR_TYPE_HPP_INCLUDED
#define POINTDETECTOR_TYPE_HPP_INCLUDED

#include <iostream>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <vector>
#include <NBO/NBO/CoatingMaterial_Type.h>
#include <NBO/NBO/Detector_Type.h>
#include <NBO/NBO/SignalProcessingMode_Type.h>
#include <NBO/NBO/UnitsPower_Type.h>
#include <NBO/NBO/UnitsTime_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 PointDetector.
*
* This element represents any Detector that collects light from a restricted point-like area of an Image. These detectors are typically used in Laser Scanning Confocal Microscopy.
*/
class NBO_EXPORT PointDetector_Type : public Detector_Type {

public:
	
	PointDetector_Type();
	~PointDetector_Type();

	/*!
	* \brief Cast a NBOBaseClass to a PointDetector_Type.
	*
	* \param base The base class to cast
	* \return The casted element, or nullptr if the cast fails
	*/
	static std::shared_ptr<PointDetector_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 Coating attribute.
	*
	* This field records the Coating Material used to increase the photoelectric properties of the metallic cathode used in this Detector. The coating releases electrons much more readily than the underlying metal, allowing it to detect the low-energy photons in infrared radiation. The lens transmits the radiation from the object being viewed to a layer of coated glass. The photons strike the metal surface and transfer electrons to its rear side. The freed electrons are then collected to produce the final Image.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setCoating(const Inscoper::NBO::CoatingMaterial_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the Coating attribute.
	*
	* This field records the Coating Material used to increase the photoelectric properties of the metallic cathode used in this Detector. The coating releases electrons much more readily than the underlying metal, allowing it to detect the low-energy photons in infrared radiation. The lens transmits the radiation from the object being viewed to a layer of coated glass. The photons strike the metal surface and transfer electrons to its rear side. The freed electrons are then collected to produce the final Image.
	*
	* \return The value of the attribute
	*/
	CoatingMaterial_TypePtr getCoating() const;

	/*!
	* \brief Resets the Coating attribute to an unset state.
	*
	* This field records the Coating Material used to increase the photoelectric properties of the metallic cathode used in this Detector. The coating releases electrons much more readily than the underlying metal, allowing it to detect the low-energy photons in infrared radiation. The lens transmits the radiation from the object being viewed to a layer of coated glass. The photons strike the metal surface and transfer electrons to its rear side. The freed electrons are then collected to produce the final Image.
	*/
	void resetCoating();

	/*!
	* \brief Checks whether the optional Coating attribute is present.
	*
	* This field records the Coating Material used to increase the photoelectric properties of the metallic cathode used in this Detector. The coating releases electrons much more readily than the underlying metal, allowing it to detect the low-energy photons in infrared radiation. The lens transmits the radiation from the object being viewed to a layer of coated glass. The photons strike the metal surface and transfer electrons to its rear side. The freed electrons are then collected to produce the final Image.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasCoating() const;

	/*!
	* \brief Sets the value of the SignalProcessing attribute.
	*
	* This field describes the method employed by this device to process the output signal and convert it into a measure of incident light intensity. In Photon Counting mode the system is set in a manner in which each photon hitting the head of the detector gives either no or 1 discrete pulse. This way by counting the pulses one is sure to be counting individual photons. In Analog mode the system is set so the mean value of all signal pulses is used as a measure of intensity.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setSignalProcessing(const Inscoper::NBO::SignalProcessingMode_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the SignalProcessing attribute.
	*
	* This field describes the method employed by this device to process the output signal and convert it into a measure of incident light intensity. In Photon Counting mode the system is set in a manner in which each photon hitting the head of the detector gives either no or 1 discrete pulse. This way by counting the pulses one is sure to be counting individual photons. In Analog mode the system is set so the mean value of all signal pulses is used as a measure of intensity.
	*
	* \return The value of the attribute
	*/
	SignalProcessingMode_TypePtr getSignalProcessing() const;

	/*!
	* \brief Resets the SignalProcessing attribute to an unset state.
	*
	* This field describes the method employed by this device to process the output signal and convert it into a measure of incident light intensity. In Photon Counting mode the system is set in a manner in which each photon hitting the head of the detector gives either no or 1 discrete pulse. This way by counting the pulses one is sure to be counting individual photons. In Analog mode the system is set so the mean value of all signal pulses is used as a measure of intensity.
	*/
	void resetSignalProcessing();

	/*!
	* \brief Checks whether the optional SignalProcessing attribute is present.
	*
	* This field describes the method employed by this device to process the output signal and convert it into a measure of incident light intensity. In Photon Counting mode the system is set in a manner in which each photon hitting the head of the detector gives either no or 1 discrete pulse. This way by counting the pulses one is sure to be counting individual photons. In Analog mode the system is set so the mean value of all signal pulses is used as a measure of intensity.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasSignalProcessing() const;

	/*!
	* \brief Sets the value of the ResponseTime attribute.
	*
	* This field records the Time required for the Detector to respond to an optical input.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setResponseTime(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the ResponseTime attribute.
	*
	* This field records the Time required for the Detector to respond to an optical input.
	*
	* \return The value of the attribute
	*/
	float getResponseTime() const;

	/*!
	* \brief Resets the ResponseTime attribute to an unset state.
	*
	* This field records the Time required for the Detector to respond to an optical input.
	*/
	void resetResponseTime();

	/*!
	* \brief Checks whether the ResponseTime attribute is present.
	*
	* This field records the Time required for the Detector to respond to an optical input.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasResponseTime() const;

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

	/*!
	* \brief Returns the value of the ResponseTimeUnit attribute.
	*
	* No description available in the XSD standard.
	*
	* \return The value of the attribute
	*/
	UnitsTime_TypePtr getResponseTimeUnit() const;

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

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

	/*!
	* \brief Sets the value of the DeadTime attribute.
	*
	* This field records the Time required for the Detector to become responsive again after being hit by a photon.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setDeadTime(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the DeadTime attribute.
	*
	* This field records the Time required for the Detector to become responsive again after being hit by a photon.
	*
	* \return The value of the attribute
	*/
	float getDeadTime() const;

	/*!
	* \brief Resets the DeadTime attribute to an unset state.
	*
	* This field records the Time required for the Detector to become responsive again after being hit by a photon.
	*/
	void resetDeadTime();

	/*!
	* \brief Checks whether the DeadTime attribute is present.
	*
	* This field records the Time required for the Detector to become responsive again after being hit by a photon.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasDeadTime() const;

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

	/*!
	* \brief Returns the value of the DeadTimeUnit attribute.
	*
	* No description available in the XSD standard.
	*
	* \return The value of the attribute
	*/
	UnitsTime_TypePtr getDeadTimeUnit() const;

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

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

	/*!
	* \brief Sets the value of the RadiantSensitivity attribute.
	*
	* This field records the Radiant Sensitivity observed with this Detector at the peak Wavelength
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setRadiantSensitivity(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the RadiantSensitivity attribute.
	*
	* This field records the Radiant Sensitivity observed with this Detector at the peak Wavelength
	*
	* \return The value of the attribute
	*/
	float getRadiantSensitivity() const;

	/*!
	* \brief Resets the RadiantSensitivity attribute to an unset state.
	*
	* This field records the Radiant Sensitivity observed with this Detector at the peak Wavelength
	*/
	void resetRadiantSensitivity();

	/*!
	* \brief Checks whether the RadiantSensitivity attribute is present.
	*
	* This field records the Radiant Sensitivity observed with this Detector at the peak Wavelength
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasRadiantSensitivity() const;

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

	/*!
	* \brief Returns the value of the RadiantSensitivityUnit attribute.
	*
	* No description available in the XSD standard.
	*
	* \return The value of the attribute
	*/
	UnitsPower_TypePtr getRadiantSensitivityUnit() const;

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

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


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

	CoatingMaterial_TypePtr Coating = nullptr; // Required attribute
	SignalProcessingMode_TypePtr SignalProcessing = nullptr; // Optional attribute
    std::optional<float> ResponseTime; // Optional attribute
	UnitsTime_TypePtr ResponseTimeUnit = nullptr; // Optional attribute
    std::optional<float> DeadTime; // Optional attribute
	UnitsTime_TypePtr DeadTimeUnit = nullptr; // Optional attribute
    std::optional<float> RadiantSensitivity; // Optional attribute
	UnitsPower_TypePtr RadiantSensitivityUnit = nullptr; // Optional attribute
};

/*! Shared pointer for PointDetector_Type*/
typedef std::shared_ptr<PointDetector_Type> PointDetector_TypePtr;

} // namespace Inscoper::NBO

#endif // POINTDETECTOR_TYPE_HPP_INCLUDED