#ifndef HOFFMANPLATE_HPP_INCLUDED
#define HOFFMANPLATE_HPP_INCLUDED

#include <iostream>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <vector>
#include <NBO/NBO/HoffmanPlateSlitDesign_Type.h>
#include <NBO/NBO/OpticalAperture_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 HoffmanPlate.
*
* This element represents a Plate that contains an off-axis slit aperture positioned in the front focal plane of the Condenser. It is used alongside a Hoffman contrast modulator (i.e., optical amplitude spatial filter) present in the back focal plane of the objective or in a succeeding conjugate plane to produce contrast modulation as described by Hoffman (i.e., Hoffman Contrast Modulation, HMC). Hoffman modulation contrast is not hampered by the use of birefringent materials (such as plastic Petri dishes) in the optical pathway, so the technique is more useful for examining specimens in containers constructed with polymeric materials.
*/
class NBO_EXPORT HoffmanPlate : public OpticalAperture_Type {

public:
	
	HoffmanPlate();
	~HoffmanPlate();

	/*!
	* \brief Cast a NBOBaseClass to a HoffmanPlate.
	*
	* \param base The base class to cast
	* \return The casted element, or nullptr if the cast fails
	*/
	static std::shared_ptr<HoffmanPlate> 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 Design attribute.
	*
	* This field captures the design of the slit of this Hoffman Plate.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setDesign(const Inscoper::NBO::HoffmanPlateSlitDesign_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the Design attribute.
	*
	* This field captures the design of the slit of this Hoffman Plate.
	*
	* \return The value of the attribute
	*/
	HoffmanPlateSlitDesign_TypePtr getDesign() const;

	/*!
	* \brief Resets the Design attribute to an unset state.
	*
	* This field captures the design of the slit of this Hoffman Plate.
	*/
	void resetDesign();

	/*!
	* \brief Checks whether the optional Design attribute is present.
	*
	* This field captures the design of the slit of this Hoffman Plate.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasDesign() const;


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

	HoffmanPlateSlitDesign_TypePtr Design = nullptr; // Optional attribute
};

/*! Shared pointer for HoffmanPlate*/
typedef std::shared_ptr<HoffmanPlate> HoffmanPlatePtr;

} // namespace Inscoper::NBO

#endif // HOFFMANPLATE_HPP_INCLUDED