#ifndef LIGHTSOURCESETTINGS_HPP_INCLUDED
#define LIGHTSOURCESETTINGS_HPP_INCLUDED

#include <iostream>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <vector>
#include <NBO/NBO/LightSourceID_Type.h>
#include <NBO/NBO/PercentFraction_Type.h>
#include <NBO/NBO/Settings_Type.h>
#include <NBO/NBO/UnitsPower_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 LightSourceSettings.
*
* This element holds the Setting applied to a Light Source used in the Light Path during the acquisition of this Channel as well as a reference to the LightSource (the ID attribute) in question.
*/
class NBO_EXPORT LightSourceSettings : public Settings_Type {

public:
	
	LightSourceSettings();
	~LightSourceSettings();

	/*!
	* \brief Cast a NBOBaseClass to a LightSourceSettings.
	*
	* \param base The base class to cast
	* \return The casted element, or nullptr if the cast fails
	*/
	static std::shared_ptr<LightSourceSettings> 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::LightSourceID_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
	*/
	LightSourceID_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 IlluminationPowerSettings attribute.
	*
	* This field records the nominal Illumination Power (also known as Power Output or Illumination Intensity) that was set for the Acquisition of this Image or was reported by the Image Acquisition Software, as advertised by the Manufacturer. Depending on the system this might be reported as a % value.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setIlluminationPowerSettings(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the IlluminationPowerSettings attribute.
	*
	* This field records the nominal Illumination Power (also known as Power Output or Illumination Intensity) that was set for the Acquisition of this Image or was reported by the Image Acquisition Software, as advertised by the Manufacturer. Depending on the system this might be reported as a % value.
	*
	* \return The value of the attribute
	*/
	float getIlluminationPowerSettings() const;

	/*!
	* \brief Resets the IlluminationPowerSettings attribute to an unset state.
	*
	* This field records the nominal Illumination Power (also known as Power Output or Illumination Intensity) that was set for the Acquisition of this Image or was reported by the Image Acquisition Software, as advertised by the Manufacturer. Depending on the system this might be reported as a % value.
	*/
	void resetIlluminationPowerSettings();

	/*!
	* \brief Checks whether the IlluminationPowerSettings attribute is present.
	*
	* This field records the nominal Illumination Power (also known as Power Output or Illumination Intensity) that was set for the Acquisition of this Image or was reported by the Image Acquisition Software, as advertised by the Manufacturer. Depending on the system this might be reported as a % value.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasIlluminationPowerSettings() const;

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

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

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

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

	/*!
	* \brief Sets the value of the Attenuation attribute.
	*
	* This field records the actual Attenuation of the excitation light power that was applied during the Acquisition of this Channel, expressed as a fractional value from 0.0 to 1.0.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setAttenuation(const Inscoper::NBO::PercentFraction_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the Attenuation attribute.
	*
	* This field records the actual Attenuation of the excitation light power that was applied during the Acquisition of this Channel, expressed as a fractional value from 0.0 to 1.0.
	*
	* \return The value of the attribute
	*/
	PercentFraction_TypePtr getAttenuation() const;

	/*!
	* \brief Resets the Attenuation attribute to an unset state.
	*
	* This field records the actual Attenuation of the excitation light power that was applied during the Acquisition of this Channel, expressed as a fractional value from 0.0 to 1.0.
	*/
	void resetAttenuation();

	/*!
	* \brief Checks whether the optional Attenuation attribute is present.
	*
	* This field records the actual Attenuation of the excitation light power that was applied during the Acquisition of this Channel, expressed as a fractional value from 0.0 to 1.0.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasAttenuation() const;

	/*!
	* \brief Sets the value of the AttenuationMethod attribute.
	*
	* This field records the Method that was used to Attenuate the Laser beam during the acquisition of this Image.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setAttenuationMethod(const std::string& value, bool validate = true);

	/*!
	* \brief Returns the value of the AttenuationMethod attribute.
	*
	* This field records the Method that was used to Attenuate the Laser beam during the acquisition of this Image.
	*
	* \return The value of the attribute
	*/
	std::string getAttenuationMethod() const;

	/*!
	* \brief Resets the AttenuationMethod attribute to an unset state.
	*
	* This field records the Method that was used to Attenuate the Laser beam during the acquisition of this Image.
	*/
	void resetAttenuationMethod();

	/*!
	* \brief Checks whether the AttenuationMethod attribute is present.
	*
	* This field records the Method that was used to Attenuate the Laser beam during the acquisition of this Image.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasAttenuationMethod() const;

	/*!
	* \brief Returns the allowed values for this attribut.
	*
	* This field records the Method that was used to Attenuate the Laser beam during the acquisition of this Image.
	*
	* \return The list of allowed values
	*/
	static const std::set<std::string>& getAttenuationMethodAllowedValues();

	/*!
	* \brief Sets the value of the UsedAcoustoOpticalDevice attribute.
	*
	* In case a Laser was used for this Image Acquisition, this field records whether (True) or not (False) an AcoustoOptical Device was employed for intensity modulation.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setUsedAcoustoOpticalDevice(const bool& value, bool validate = true);

	/*!
	* \brief Returns the value of the UsedAcoustoOpticalDevice attribute.
	*
	* In case a Laser was used for this Image Acquisition, this field records whether (True) or not (False) an AcoustoOptical Device was employed for intensity modulation.
	*
	* \return The value of the attribute
	*/
	bool getUsedAcoustoOpticalDevice() const;

	/*!
	* \brief Resets the UsedAcoustoOpticalDevice attribute to an unset state.
	*
	* In case a Laser was used for this Image Acquisition, this field records whether (True) or not (False) an AcoustoOptical Device was employed for intensity modulation.
	*/
	void resetUsedAcoustoOpticalDevice();

	/*!
	* \brief Checks whether the UsedAcoustoOpticalDevice attribute is present.
	*
	* In case a Laser was used for this Image Acquisition, this field records whether (True) or not (False) an AcoustoOptical Device was employed for intensity modulation.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasUsedAcoustoOpticalDevice() const;


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

	LightSourceID_TypePtr ID = nullptr; // Required attribute
    std::optional<float> IlluminationPowerSettings; // Required attribute
	UnitsPower_TypePtr lluminationPowerSettingsUnit = nullptr; // Optional attribute
	PercentFraction_TypePtr Attenuation = nullptr; // Optional attribute
    std::optional<std::string> AttenuationMethod; // Optional attribute
    static const std::set<std::string> AttenuationMethodAllowedValues;
    std::optional<bool> UsedAcoustoOpticalDevice; // Optional attribute
};

/*! Shared pointer for LightSourceSettings*/
typedef std::shared_ptr<LightSourceSettings> LightSourceSettingsPtr;

} // namespace Inscoper::NBO

#endif // LIGHTSOURCESETTINGS_HPP_INCLUDED