#ifndef SOFTWARE_TYPE_HPP_INCLUDED
#define SOFTWARE_TYPE_HPP_INCLUDED

#include <iostream>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <vector>
#include <NBO/NBO/AnnotationRef.h>
#include <NBO/NBO/LSID_Type.h>
#include <NBO/NBO/SoftwareModuleRef.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 Software.
*
* This element represents a commercial, or open-source Software, script, macro, plugin or module utilized for any Image Acquisition or Quality Control task related to this Instrument.
*/
class NBO_EXPORT Software_Type : public NBOBaseClass {

public:
	
	Software_Type();
	~Software_Type();

	/*!
	* \brief Cast a NBOBaseClass to a Software_Type.
	*
	* \param base The base class to cast
	* \return The casted element, or nullptr if the cast fails
	*/
	static std::shared_ptr<Software_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 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::LSID_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
	*/
	LSID_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.
	*
	* This field records the Name or any other designation the Author uses for this Software.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setName(const std::string& value, bool validate = true);

	/*!
	* \brief Returns the value of the Name attribute.
	*
	* This field records the Name or any other designation the Author uses for this Software.
	*
	* \return The value of the attribute
	*/
	std::string getName() const;

	/*!
	* \brief Resets the Name attribute to an unset state.
	*
	* This field records the Name or any other designation the Author uses for this Software.
	*/
	void resetName();

	/*!
	* \brief Checks whether the Name attribute is present.
	*
	* This field records the Name or any other designation the Author uses for this Software.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasName() const;

	/*!
	* \brief Returns the allowed values for this attribut.
	*
	* This field records the Name or any other designation the Author uses for this Software.
	*
	* \return The list of allowed values
	*/
	static const std::set<std::string>& getNameAllowedValues();

	/*!
	* \brief Sets the value of the Version attribute.
	*
	* This field records the Version of this Software.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setVersion(const std::string& value, bool validate = true);

	/*!
	* \brief Returns the value of the Version attribute.
	*
	* This field records the Version of this Software.
	*
	* \return The value of the attribute
	*/
	std::string getVersion() const;

	/*!
	* \brief Resets the Version attribute to an unset state.
	*
	* This field records the Version of this Software.
	*/
	void resetVersion();

	/*!
	* \brief Checks whether the Version attribute is present.
	*
	* This field records the Version of this Software.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasVersion() const;

	/*!
	* \brief Returns the allowed values for this attribut.
	*
	* This field records the Version of this Software.
	*
	* \return The list of allowed values
	*/
	static const std::set<std::string>& getVersionAllowedValues();

	/*!
	* \brief Sets the value of the Developer attribute.
	*
	* This field records the Developer(s) of this Software. In case this is a non-commercial, open-source Software, this refers to the name of the individual or consortium who developed the Software. In the case of a commercial Software, this might refer to the Commercial entity but it can also be used to refer to the individual developer, if knonw.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setDeveloper(const std::string& value, bool validate = true);

	/*!
	* \brief Returns the value of the Developer attribute.
	*
	* This field records the Developer(s) of this Software. In case this is a non-commercial, open-source Software, this refers to the name of the individual or consortium who developed the Software. In the case of a commercial Software, this might refer to the Commercial entity but it can also be used to refer to the individual developer, if knonw.
	*
	* \return The value of the attribute
	*/
	std::string getDeveloper() const;

	/*!
	* \brief Resets the Developer attribute to an unset state.
	*
	* This field records the Developer(s) of this Software. In case this is a non-commercial, open-source Software, this refers to the name of the individual or consortium who developed the Software. In the case of a commercial Software, this might refer to the Commercial entity but it can also be used to refer to the individual developer, if knonw.
	*/
	void resetDeveloper();

	/*!
	* \brief Checks whether the Developer attribute is present.
	*
	* This field records the Developer(s) of this Software. In case this is a non-commercial, open-source Software, this refers to the name of the individual or consortium who developed the Software. In the case of a commercial Software, this might refer to the Commercial entity but it can also be used to refer to the individual developer, if knonw.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasDeveloper() const;

	/*!
	* \brief Returns the allowed values for this attribut.
	*
	* This field records the Developer(s) of this Software. In case this is a non-commercial, open-source Software, this refers to the name of the individual or consortium who developed the Software. In the case of a commercial Software, this might refer to the Commercial entity but it can also be used to refer to the individual developer, if knonw.
	*
	* \return The list of allowed values
	*/
	static const std::set<std::string>& getDeveloperAllowedValues();

	/*!
	* \brief Sets the value of the WebsiteURL attribute.
	*
	* This field records the URL address of any Website where the Software can be obtained. In case of open-source Software this field should record the URL for the Git repository from which to obtain the source-code.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setWebsiteURL(const std::string& value, bool validate = true);

	/*!
	* \brief Returns the value of the WebsiteURL attribute.
	*
	* This field records the URL address of any Website where the Software can be obtained. In case of open-source Software this field should record the URL for the Git repository from which to obtain the source-code.
	*
	* \return The value of the attribute
	*/
	std::string getWebsiteURL() const;

	/*!
	* \brief Resets the WebsiteURL attribute to an unset state.
	*
	* This field records the URL address of any Website where the Software can be obtained. In case of open-source Software this field should record the URL for the Git repository from which to obtain the source-code.
	*/
	void resetWebsiteURL();

	/*!
	* \brief Checks whether the WebsiteURL attribute is present.
	*
	* This field records the URL address of any Website where the Software can be obtained. In case of open-source Software this field should record the URL for the Git repository from which to obtain the source-code.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasWebsiteURL() const;

	/*!
	* \brief Returns the allowed values for this attribut.
	*
	* This field records the URL address of any Website where the Software can be obtained. In case of open-source Software this field should record the URL for the Git repository from which to obtain the source-code.
	*
	* \return The list of allowed values
	*/
	static const std::set<std::string>& getWebsiteURLAllowedValues();

	/*!
	* \brief Sets the value of the PrimaryPublicationID attribute.
	*
	* This field captures the a Unique Identifier for the Primary Publication describing this Software. Examples include, Digital Object Identifier (DOI), PubMed Central Identifier (PMCID), ArXiv.org ID etc.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setPrimaryPublicationID(const std::string& value, bool validate = true);

	/*!
	* \brief Returns the value of the PrimaryPublicationID attribute.
	*
	* This field captures the a Unique Identifier for the Primary Publication describing this Software. Examples include, Digital Object Identifier (DOI), PubMed Central Identifier (PMCID), ArXiv.org ID etc.
	*
	* \return The value of the attribute
	*/
	std::string getPrimaryPublicationID() const;

	/*!
	* \brief Resets the PrimaryPublicationID attribute to an unset state.
	*
	* This field captures the a Unique Identifier for the Primary Publication describing this Software. Examples include, Digital Object Identifier (DOI), PubMed Central Identifier (PMCID), ArXiv.org ID etc.
	*/
	void resetPrimaryPublicationID();

	/*!
	* \brief Checks whether the PrimaryPublicationID attribute is present.
	*
	* This field captures the a Unique Identifier for the Primary Publication describing this Software. Examples include, Digital Object Identifier (DOI), PubMed Central Identifier (PMCID), ArXiv.org ID etc.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasPrimaryPublicationID() const;

	/*!
	* \brief Returns the allowed values for this attribut.
	*
	* This field captures the a Unique Identifier for the Primary Publication describing this Software. Examples include, Digital Object Identifier (DOI), PubMed Central Identifier (PMCID), ArXiv.org ID etc.
	*
	* \return The list of allowed values
	*/
	static const std::set<std::string>& getPrimaryPublicationIDAllowedValues();

	/*!
	* \brief Sets the value of the OpenSource attribute.
	*
	* This records whether this Software is OpenSource (True) or proprietary (False).
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setOpenSource(const bool& value, bool validate = true);

	/*!
	* \brief Returns the value of the OpenSource attribute.
	*
	* This records whether this Software is OpenSource (True) or proprietary (False).
	*
	* \return The value of the attribute
	*/
	bool getOpenSource() const;

	/*!
	* \brief Resets the OpenSource attribute to an unset state.
	*
	* This records whether this Software is OpenSource (True) or proprietary (False).
	*/
	void resetOpenSource();

	/*!
	* \brief Checks whether the OpenSource attribute is present.
	*
	* This records whether this Software is OpenSource (True) or proprietary (False).
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasOpenSource() const;

	/*!
	* \brief Sets the value of the Macro attribute.
	*
	* This field records whether this Software is a Macro or a Scprit (True) or is it a full free-standing program.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setMacro(const bool& value, bool validate = true);

	/*!
	* \brief Returns the value of the Macro attribute.
	*
	* This field records whether this Software is a Macro or a Scprit (True) or is it a full free-standing program.
	*
	* \return The value of the attribute
	*/
	bool getMacro() const;

	/*!
	* \brief Resets the Macro attribute to an unset state.
	*
	* This field records whether this Software is a Macro or a Scprit (True) or is it a full free-standing program.
	*/
	void resetMacro();

	/*!
	* \brief Checks whether the Macro attribute is present.
	*
	* This field records whether this Software is a Macro or a Scprit (True) or is it a full free-standing program.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasMacro() const;

	/*!
	* \brief Sets the value of the Build attribute.
	*
	* The specific build of this Software.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setBuild(const std::string& value, bool validate = true);

	/*!
	* \brief Returns the value of the Build attribute.
	*
	* The specific build of this Software.
	*
	* \return The value of the attribute
	*/
	std::string getBuild() const;

	/*!
	* \brief Resets the Build attribute to an unset state.
	*
	* The specific build of this Software.
	*/
	void resetBuild();

	/*!
	* \brief Checks whether the Build attribute is present.
	*
	* The specific build of this Software.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasBuild() const;

	/*!
	* \brief Returns the allowed values for this attribut.
	*
	* The specific build of this Software.
	*
	* \return The list of allowed values
	*/
	static const std::set<std::string>& getBuildAllowedValues();

	/*!
	* \brief Sets the value of the Patch attribute.
	*
	* This recodes the version for an optional Patch, HotFix or Update used for this Sofware to run this Instrument. A Patch (aka HotFix, or Update) is a set of changes to a computer program or its supporting data designed to update, fix, or improve it. This includes fixing security vulnerabilities, and other bugs, with such patches usually being called bugfixes or bug fixes, and improving the functionality, usability or performance.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setPatch(const std::string& value, bool validate = true);

	/*!
	* \brief Returns the value of the Patch attribute.
	*
	* This recodes the version for an optional Patch, HotFix or Update used for this Sofware to run this Instrument. A Patch (aka HotFix, or Update) is a set of changes to a computer program or its supporting data designed to update, fix, or improve it. This includes fixing security vulnerabilities, and other bugs, with such patches usually being called bugfixes or bug fixes, and improving the functionality, usability or performance.
	*
	* \return The value of the attribute
	*/
	std::string getPatch() const;

	/*!
	* \brief Resets the Patch attribute to an unset state.
	*
	* This recodes the version for an optional Patch, HotFix or Update used for this Sofware to run this Instrument. A Patch (aka HotFix, or Update) is a set of changes to a computer program or its supporting data designed to update, fix, or improve it. This includes fixing security vulnerabilities, and other bugs, with such patches usually being called bugfixes or bug fixes, and improving the functionality, usability or performance.
	*/
	void resetPatch();

	/*!
	* \brief Checks whether the Patch attribute is present.
	*
	* This recodes the version for an optional Patch, HotFix or Update used for this Sofware to run this Instrument. A Patch (aka HotFix, or Update) is a set of changes to a computer program or its supporting data designed to update, fix, or improve it. This includes fixing security vulnerabilities, and other bugs, with such patches usually being called bugfixes or bug fixes, and improving the functionality, usability or performance.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasPatch() const;

	/*!
	* \brief Returns the allowed values for this attribut.
	*
	* This recodes the version for an optional Patch, HotFix or Update used for this Sofware to run this Instrument. A Patch (aka HotFix, or Update) is a set of changes to a computer program or its supporting data designed to update, fix, or improve it. This includes fixing security vulnerabilities, and other bugs, with such patches usually being called bugfixes or bug fixes, and improving the functionality, usability or performance.
	*
	* \return The list of allowed values
	*/
	static const std::set<std::string>& getPatchAllowedValues();

	/*!
	* \brief Sets the value of the ReleaseDate attribute.
	*
	* The date in which this Software was resleased.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setReleaseDate(const std::string& value, bool validate = true);

	/*!
	* \brief Returns the value of the ReleaseDate attribute.
	*
	* The date in which this Software was resleased.
	*
	* \return The value of the attribute
	*/
	std::string getReleaseDate() const;

	/*!
	* \brief Resets the ReleaseDate attribute to an unset state.
	*
	* The date in which this Software was resleased.
	*/
	void resetReleaseDate();

	/*!
	* \brief Checks whether the ReleaseDate attribute is present.
	*
	* The date in which this Software was resleased.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasReleaseDate() const;

	/*!
	* \brief Returns the allowed values for this attribut.
	*
	* The date in which this Software was resleased.
	*
	* \return The list of allowed values
	*/
	static const std::set<std::string>& getReleaseDateAllowedValues();

	/*!
	* \brief Sets the value of the Language attribute.
	*
	* This records the computer Language in which this Software was developed.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setLanguage(const std::string& value, bool validate = true);

	/*!
	* \brief Returns the value of the Language attribute.
	*
	* This records the computer Language in which this Software was developed.
	*
	* \return The value of the attribute
	*/
	std::string getLanguage() const;

	/*!
	* \brief Resets the Language attribute to an unset state.
	*
	* This records the computer Language in which this Software was developed.
	*/
	void resetLanguage();

	/*!
	* \brief Checks whether the Language attribute is present.
	*
	* This records the computer Language in which this Software was developed.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasLanguage() const;

	/*!
	* \brief Returns the allowed values for this attribut.
	*
	* This records the computer Language in which this Software was developed.
	*
	* \return The list of allowed values
	*/
	static const std::set<std::string>& getLanguageAllowedValues();

	/*!
	* \brief Sets the list of SoftwareModuleRef elements.
	*
	* No description available in the XSD standard.
	*
	* \param value The new list of SoftwareModuleRef elements
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setSoftwareModuleRef_List(const std::vector<Inscoper::NBO::SoftwareModuleRefPtr>& value, bool validate = true);

	/*!
	* \brief Returns the list of SoftwareModuleRef elements.
	*
	* No description available in the XSD standard.
	*
	* \return The list of SoftwareModuleRef elements
	*/
	std::vector<Inscoper::NBO::SoftwareModuleRefPtr> getSoftwareModuleRef_List() const;

	/*!
	* \brief Adds a new SoftwareModuleRef element to this object.
	*
	* No description available in the XSD standard.
	*
	* \param value The element to add
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void addToSoftwareModuleRef_List(const Inscoper::NBO::SoftwareModuleRefPtr& value, bool validate = true);

	/*!
	* \brief Clear the list of SoftwareModuleRef.
	*
	* No description available in the XSD standard.
	*/
	void clearSoftwareModuleRef_List();

	/*!
	* \brief Sets the list of AnnotationRef elements.
	*
	* No description available in the XSD standard.
	*
	* \param value The new list of AnnotationRef elements
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setAnnotationRef_List(const std::vector<Inscoper::NBO::AnnotationRefPtr>& value, bool validate = true);

	/*!
	* \brief Returns the list of AnnotationRef elements.
	*
	* No description available in the XSD standard.
	*
	* \return The list of AnnotationRef elements
	*/
	std::vector<Inscoper::NBO::AnnotationRefPtr> getAnnotationRef_List() const;

	/*!
	* \brief Adds a new AnnotationRef element to this object.
	*
	* No description available in the XSD standard.
	*
	* \param value The element to add
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void addToAnnotationRef_List(const Inscoper::NBO::AnnotationRefPtr& value, bool validate = true);

	/*!
	* \brief Clear the list of AnnotationRef.
	*
	* No description available in the XSD standard.
	*/
	void clearAnnotationRef_List();


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

	LSID_TypePtr ID = nullptr; // Required attribute
    std::optional<std::string> Name; // Required attribute
    static const std::set<std::string> NameAllowedValues;
    std::optional<std::string> Version; // Required attribute
    static const std::set<std::string> VersionAllowedValues;
    std::optional<std::string> Developer; // Required attribute
    static const std::set<std::string> DeveloperAllowedValues;
    std::optional<std::string> WebsiteURL; // Required attribute
    static const std::set<std::string> WebsiteURLAllowedValues;
    std::optional<std::string> PrimaryPublicationID; // Optional attribute
    static const std::set<std::string> PrimaryPublicationIDAllowedValues;
    std::optional<bool> OpenSource; // Optional attribute
    std::optional<bool> Macro; // Optional attribute
    std::optional<std::string> Build; // Optional attribute
    static const std::set<std::string> BuildAllowedValues;
    std::optional<std::string> Patch; // Optional attribute
    static const std::set<std::string> PatchAllowedValues;
    std::optional<std::string> ReleaseDate; // Optional attribute
    static const std::set<std::string> ReleaseDateAllowedValues;
    std::optional<std::string> Language; // Optional attribute
    static const std::set<std::string> LanguageAllowedValues;
    std::vector<Inscoper::NBO::SoftwareModuleRefPtr> SoftwareModuleRef_List;
    std::vector<Inscoper::NBO::AnnotationRefPtr> AnnotationRef_List;
};

/*! Shared pointer for Software_Type*/
typedef std::shared_ptr<Software_Type> Software_TypePtr;

} // namespace Inscoper::NBO

#endif // SOFTWARE_TYPE_HPP_INCLUDED