#ifndef PIXELS_HPP_INCLUDED
#define PIXELS_HPP_INCLUDED

#include <iostream>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <vector>
#include <NBO/NBO/AdditionalDimensionMap.h>
#include <NBO/NBO/Channel.h>
#include <NBO/NBO/PixelType_Type.h>
#include <NBO/NBO/PixelsDimensionOrder_Type.h>
#include <NBO/NBO/PixelsID_Type.h>
#include <NBO/NBO/Pixels_Choice.h>
#include <NBO/NBO/Plane.h>
#include <NBO/NBO/PositiveFloat_Type.h>
#include <NBO/NBO/PositiveInt_Type.h>
#include <NBO/NBO/UnitsLength_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 element Pixels.
*
* The Pixels element is going to be removed in the future, but it is still required. This is just notice that the contents of Pixels will be moved up to Image in a future release. This is because there has only been 1 Pixels object in each Image for some time. The concept of multiple Pixels sets for one Image failed to take off. It is therefore redundant. The Image will be unreadable if any of the required Pixel attributes are missing. The Pixels themselves can be stored within the OME-XML compressed by Plane, and encoded in Base64. Or the Pixels may be stored in TIFF format. The Pixels element should contain a list of BinData or TiffData, each containing a single Plane of pixels. These Pixels elements, when read in document order, must produce a 5-D Pixel array of the size specified in this element, and in the dimension order specified by 'DimensionOrder'. All of the values in the Pixels object when present should match the same value stored in any associated TIFF format (e.g. SizeX should be the same). Where there is a mismatch our readers will take the value from the TIFF structure as overriding the value in the OME-XML. This is simply a pragmatic decision as it increases the likelihood of reading data from a slightly incorrect file.
*/
class NBO_EXPORT Pixels : public NBOBaseClass {

public:
	
	Pixels();
	~Pixels();

	/*!
	* \brief Cast a NBOBaseClass to a Pixels.
	*
	* \param base The base class to cast
	* \return The casted element, or nullptr if the cast fails
	*/
	static std::shared_ptr<Pixels> 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::PixelsID_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
	*/
	PixelsID_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 DimensionOrder attribute.
	*
	* This field records the order in which the individual Planes of data are interleaved in the Image.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setDimensionOrder(const Inscoper::NBO::PixelsDimensionOrder_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the DimensionOrder attribute.
	*
	* This field records the order in which the individual Planes of data are interleaved in the Image.
	*
	* \return The value of the attribute
	*/
	PixelsDimensionOrder_TypePtr getDimensionOrder() const;

	/*!
	* \brief Resets the DimensionOrder attribute to an unset state.
	*
	* This field records the order in which the individual Planes of data are interleaved in the Image.
	*/
	void resetDimensionOrder();

	/*!
	* \brief Checks whether the optional DimensionOrder attribute is present.
	*
	* This field records the order in which the individual Planes of data are interleaved in the Image.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasDimensionOrder() const;

	/*!
	* \brief Sets the value of the SizeX attribute.
	*
	* This field records the X size of the Pixel data array.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setSizeX(const Inscoper::NBO::PositiveInt_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the SizeX attribute.
	*
	* This field records the X size of the Pixel data array.
	*
	* \return The value of the attribute
	*/
	PositiveInt_TypePtr getSizeX() const;

	/*!
	* \brief Resets the SizeX attribute to an unset state.
	*
	* This field records the X size of the Pixel data array.
	*/
	void resetSizeX();

	/*!
	* \brief Checks whether the optional SizeX attribute is present.
	*
	* This field records the X size of the Pixel data array.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasSizeX() const;

	/*!
	* \brief Sets the value of the SizeY attribute.
	*
	* This field records the Y size of the Pixel data array.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setSizeY(const Inscoper::NBO::PositiveInt_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the SizeY attribute.
	*
	* This field records the Y size of the Pixel data array.
	*
	* \return The value of the attribute
	*/
	PositiveInt_TypePtr getSizeY() const;

	/*!
	* \brief Resets the SizeY attribute to an unset state.
	*
	* This field records the Y size of the Pixel data array.
	*/
	void resetSizeY();

	/*!
	* \brief Checks whether the optional SizeY attribute is present.
	*
	* This field records the Y size of the Pixel data array.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasSizeY() const;

	/*!
	* \brief Sets the value of the SizeZ attribute.
	*
	* This field records the number of Z-Planes acquired for this Image.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setSizeZ(const Inscoper::NBO::PositiveInt_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the SizeZ attribute.
	*
	* This field records the number of Z-Planes acquired for this Image.
	*
	* \return The value of the attribute
	*/
	PositiveInt_TypePtr getSizeZ() const;

	/*!
	* \brief Resets the SizeZ attribute to an unset state.
	*
	* This field records the number of Z-Planes acquired for this Image.
	*/
	void resetSizeZ();

	/*!
	* \brief Checks whether the optional SizeZ attribute is present.
	*
	* This field records the number of Z-Planes acquired for this Image.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasSizeZ() const;

	/*!
	* \brief Sets the value of the SizeC attribute.
	*
	* This field records the number of Channels used in this Image
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setSizeC(const Inscoper::NBO::PositiveInt_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the SizeC attribute.
	*
	* This field records the number of Channels used in this Image
	*
	* \return The value of the attribute
	*/
	PositiveInt_TypePtr getSizeC() const;

	/*!
	* \brief Resets the SizeC attribute to an unset state.
	*
	* This field records the number of Channels used in this Image
	*/
	void resetSizeC();

	/*!
	* \brief Checks whether the optional SizeC attribute is present.
	*
	* This field records the number of Channels used in this Image
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasSizeC() const;

	/*!
	* \brief Sets the value of the SizeT attribute.
	*
	* This field records the number of Timepoints (often referred to as Frames) used in this Image.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setSizeT(const Inscoper::NBO::PositiveInt_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the SizeT attribute.
	*
	* This field records the number of Timepoints (often referred to as Frames) used in this Image.
	*
	* \return The value of the attribute
	*/
	PositiveInt_TypePtr getSizeT() const;

	/*!
	* \brief Resets the SizeT attribute to an unset state.
	*
	* This field records the number of Timepoints (often referred to as Frames) used in this Image.
	*/
	void resetSizeT();

	/*!
	* \brief Checks whether the optional SizeT attribute is present.
	*
	* This field records the number of Timepoints (often referred to as Frames) used in this Image.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasSizeT() const;

	/*!
	* \brief Sets the value of the PhysicalSizeX attribute.
	*
	* This field records the real world Physical Width represented by a Pixel in this Image. This measure is often referred to as X Pixel Size.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setPhysicalSizeX(const Inscoper::NBO::PositiveFloat_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the PhysicalSizeX attribute.
	*
	* This field records the real world Physical Width represented by a Pixel in this Image. This measure is often referred to as X Pixel Size.
	*
	* \return The value of the attribute
	*/
	PositiveFloat_TypePtr getPhysicalSizeX() const;

	/*!
	* \brief Resets the PhysicalSizeX attribute to an unset state.
	*
	* This field records the real world Physical Width represented by a Pixel in this Image. This measure is often referred to as X Pixel Size.
	*/
	void resetPhysicalSizeX();

	/*!
	* \brief Checks whether the optional PhysicalSizeX attribute is present.
	*
	* This field records the real world Physical Width represented by a Pixel in this Image. This measure is often referred to as X Pixel Size.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasPhysicalSizeX() const;

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

	/*!
	* \brief Returns the value of the PhysicalSizeXUnit attribute.
	*
	* No description available in the XSD standard.
	*
	* \return The value of the attribute
	*/
	UnitsLength_TypePtr getPhysicalSizeXUnit() const;

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

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

	/*!
	* \brief Sets the value of the PhysicalSizeY attribute.
	*
	* This field records the real world Physical Height represented by a Pixel in this Image. This measure is often referred to as Y Pixel Size.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setPhysicalSizeY(const Inscoper::NBO::PositiveFloat_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the PhysicalSizeY attribute.
	*
	* This field records the real world Physical Height represented by a Pixel in this Image. This measure is often referred to as Y Pixel Size.
	*
	* \return The value of the attribute
	*/
	PositiveFloat_TypePtr getPhysicalSizeY() const;

	/*!
	* \brief Resets the PhysicalSizeY attribute to an unset state.
	*
	* This field records the real world Physical Height represented by a Pixel in this Image. This measure is often referred to as Y Pixel Size.
	*/
	void resetPhysicalSizeY();

	/*!
	* \brief Checks whether the optional PhysicalSizeY attribute is present.
	*
	* This field records the real world Physical Height represented by a Pixel in this Image. This measure is often referred to as Y Pixel Size.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasPhysicalSizeY() const;

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

	/*!
	* \brief Returns the value of the PhysicalSizeYUnit attribute.
	*
	* No description available in the XSD standard.
	*
	* \return The value of the attribute
	*/
	UnitsLength_TypePtr getPhysicalSizeYUnit() const;

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

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

	/*!
	* \brief Sets the value of the PhysicalSizeZ attribute.
	*
	* This field records the real world Physical distance between the individual Z-Planes recorded for this Image. This measure is sometimes referred to as Z Pixel or Voxel Size.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setPhysicalSizeZ(const Inscoper::NBO::PositiveFloat_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the PhysicalSizeZ attribute.
	*
	* This field records the real world Physical distance between the individual Z-Planes recorded for this Image. This measure is sometimes referred to as Z Pixel or Voxel Size.
	*
	* \return The value of the attribute
	*/
	PositiveFloat_TypePtr getPhysicalSizeZ() const;

	/*!
	* \brief Resets the PhysicalSizeZ attribute to an unset state.
	*
	* This field records the real world Physical distance between the individual Z-Planes recorded for this Image. This measure is sometimes referred to as Z Pixel or Voxel Size.
	*/
	void resetPhysicalSizeZ();

	/*!
	* \brief Checks whether the optional PhysicalSizeZ attribute is present.
	*
	* This field records the real world Physical distance between the individual Z-Planes recorded for this Image. This measure is sometimes referred to as Z Pixel or Voxel Size.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasPhysicalSizeZ() const;

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

	/*!
	* \brief Returns the value of the PhysicalSizeZUnit attribute.
	*
	* No description available in the XSD standard.
	*
	* \return The value of the attribute
	*/
	UnitsLength_TypePtr getPhysicalSizeZUnit() const;

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

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

	/*!
	* \brief Sets the value of the TimeIncrement attribute.
	*
	* In cases in which a time series is acquired with a global timing specification setting, this field describes the time between each sequential plane (or frame) in the series (i.e., from the start of time point 1 to the start of time point 2). Examples include, a video stream or a multi-dimensional Acquisition routine. Note that, this field is not intended to substitute the Timestamp attribute recorded in Plane. Also note that in case this field is not relevant e.g. a time lapse Acquisition with irregular increments, the value -1 should be used to indicate that only the Timestamps (in the Plane element) are valid.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setTimeIncrement(const Inscoper::NBO::PositiveFloat_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the TimeIncrement attribute.
	*
	* In cases in which a time series is acquired with a global timing specification setting, this field describes the time between each sequential plane (or frame) in the series (i.e., from the start of time point 1 to the start of time point 2). Examples include, a video stream or a multi-dimensional Acquisition routine. Note that, this field is not intended to substitute the Timestamp attribute recorded in Plane. Also note that in case this field is not relevant e.g. a time lapse Acquisition with irregular increments, the value -1 should be used to indicate that only the Timestamps (in the Plane element) are valid.
	*
	* \return The value of the attribute
	*/
	PositiveFloat_TypePtr getTimeIncrement() const;

	/*!
	* \brief Resets the TimeIncrement attribute to an unset state.
	*
	* In cases in which a time series is acquired with a global timing specification setting, this field describes the time between each sequential plane (or frame) in the series (i.e., from the start of time point 1 to the start of time point 2). Examples include, a video stream or a multi-dimensional Acquisition routine. Note that, this field is not intended to substitute the Timestamp attribute recorded in Plane. Also note that in case this field is not relevant e.g. a time lapse Acquisition with irregular increments, the value -1 should be used to indicate that only the Timestamps (in the Plane element) are valid.
	*/
	void resetTimeIncrement();

	/*!
	* \brief Checks whether the optional TimeIncrement attribute is present.
	*
	* In cases in which a time series is acquired with a global timing specification setting, this field describes the time between each sequential plane (or frame) in the series (i.e., from the start of time point 1 to the start of time point 2). Examples include, a video stream or a multi-dimensional Acquisition routine. Note that, this field is not intended to substitute the Timestamp attribute recorded in Plane. Also note that in case this field is not relevant e.g. a time lapse Acquisition with irregular increments, the value -1 should be used to indicate that only the Timestamps (in the Plane element) are valid.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasTimeIncrement() const;

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

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

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

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

	/*!
	* \brief Sets the value of the PixelType attribute.
	*
	* This field records the data type used to represent the Pixel Intensity in the Image.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setPixelType(const Inscoper::NBO::PixelType_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the PixelType attribute.
	*
	* This field records the data type used to represent the Pixel Intensity in the Image.
	*
	* \return The value of the attribute
	*/
	PixelType_TypePtr getPixelType() const;

	/*!
	* \brief Resets the PixelType attribute to an unset state.
	*
	* This field records the data type used to represent the Pixel Intensity in the Image.
	*/
	void resetPixelType();

	/*!
	* \brief Checks whether the optional PixelType attribute is present.
	*
	* This field records the data type used to represent the Pixel Intensity in the Image.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasPixelType() const;

	/*!
	* \brief Sets the value of the Interleaved attribute.
	*
	* This field records the order in which the Channels are arranged within the data block: True if Channels are stored RGBRGBRGB...; False if Channels are stored RRR...GGG...BBB…
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setInterleaved(const bool& value, bool validate = true);

	/*!
	* \brief Returns the value of the Interleaved attribute.
	*
	* This field records the order in which the Channels are arranged within the data block: True if Channels are stored RGBRGBRGB...; False if Channels are stored RRR...GGG...BBB…
	*
	* \return The value of the attribute
	*/
	bool getInterleaved() const;

	/*!
	* \brief Resets the Interleaved attribute to an unset state.
	*
	* This field records the order in which the Channels are arranged within the data block: True if Channels are stored RGBRGBRGB...; False if Channels are stored RRR...GGG...BBB…
	*/
	void resetInterleaved();

	/*!
	* \brief Checks whether the Interleaved attribute is present.
	*
	* This field records the order in which the Channels are arranged within the data block: True if Channels are stored RGBRGBRGB...; False if Channels are stored RRR...GGG...BBB…
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasInterleaved() const;

	/*!
	* \brief Sets the value of the SignificantBits attribute.
	*
	* This field records the number of bits within the type storing each Pixel value that are significant. e.g.,. you can store 12-bit data within a 16-bit type. This does not reduce the storage requirements but can be a useful indicator when processing or viewing the Image data.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setSignificantBits(const Inscoper::NBO::PositiveInt_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the SignificantBits attribute.
	*
	* This field records the number of bits within the type storing each Pixel value that are significant. e.g.,. you can store 12-bit data within a 16-bit type. This does not reduce the storage requirements but can be a useful indicator when processing or viewing the Image data.
	*
	* \return The value of the attribute
	*/
	PositiveInt_TypePtr getSignificantBits() const;

	/*!
	* \brief Resets the SignificantBits attribute to an unset state.
	*
	* This field records the number of bits within the type storing each Pixel value that are significant. e.g.,. you can store 12-bit data within a 16-bit type. This does not reduce the storage requirements but can be a useful indicator when processing or viewing the Image data.
	*/
	void resetSignificantBits();

	/*!
	* \brief Checks whether the optional SignificantBits attribute is present.
	*
	* This field records the number of bits within the type storing each Pixel value that are significant. e.g.,. you can store 12-bit data within a 16-bit type. This does not reduce the storage requirements but can be a useful indicator when processing or viewing the Image data.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasSignificantBits() const;

	/*!
	* \brief Sets the value of the BigEndian attribute.
	*
	* This field is True if the pixels data was written in BigEndian order. If this value is present, it should match the value used in BinData or TiffData. If it is not, a reader should be used that honors the value used in the BinData or TiffData. This value is useful for MetadataOnly files and is to allow for future storage solutions. 
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setBigEndian(const bool& value, bool validate = true);

	/*!
	* \brief Returns the value of the BigEndian attribute.
	*
	* This field is True if the pixels data was written in BigEndian order. If this value is present, it should match the value used in BinData or TiffData. If it is not, a reader should be used that honors the value used in the BinData or TiffData. This value is useful for MetadataOnly files and is to allow for future storage solutions. 
	*
	* \return The value of the attribute
	*/
	bool getBigEndian() const;

	/*!
	* \brief Resets the BigEndian attribute to an unset state.
	*
	* This field is True if the pixels data was written in BigEndian order. If this value is present, it should match the value used in BinData or TiffData. If it is not, a reader should be used that honors the value used in the BinData or TiffData. This value is useful for MetadataOnly files and is to allow for future storage solutions. 
	*/
	void resetBigEndian();

	/*!
	* \brief Checks whether the BigEndian attribute is present.
	*
	* This field is True if the pixels data was written in BigEndian order. If this value is present, it should match the value used in BinData or TiffData. If it is not, a reader should be used that honors the value used in the BinData or TiffData. This value is useful for MetadataOnly files and is to allow for future storage solutions. 
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasBigEndian() const;

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

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

	/*!
	* \brief Adds a new Plane 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 addToPlane_List(const Inscoper::NBO::PlanePtr& value, bool validate = true);

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

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

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

	/*!
	* \brief Adds a new Channel 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 addToChannel_List(const Inscoper::NBO::ChannelPtr& value, bool validate = true);

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

	/*!
	* \brief Sets the value of the AdditionalDimensionMap element.
	*
	* 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 setAdditionalDimensionMap(const Inscoper::NBO::AdditionalDimensionMapPtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the AdditionalDimensionMap element.
	*
	* No description available in the XSD standard.
	*
	* \return The value of the element
	*/
	Inscoper::NBO::AdditionalDimensionMapPtr getAdditionalDimensionMap() const
;
	/*!
	* \brief Resets the AdditionalDimensionMap element to an unset state.
	*
	* No description available in the XSD standard.
	*/
	void resetAdditionalDimensionMap();

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

	/*!
	* \brief Sets the value of the pixels_choice element.
	*
	* 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 setpixels_choice(const Inscoper::NBO::Pixels_ChoicePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the pixels_choice element.
	*
	* No description available in the XSD standard.
	*
	* \return The value of the element
	*/
	Inscoper::NBO::Pixels_ChoicePtr getpixels_choice() const
;
	/*!
	* \brief Resets the pixels_choice element to an unset state.
	*
	* No description available in the XSD standard.
	*/
	void resetpixels_choice();

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


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

	PixelsID_TypePtr ID = nullptr; // Required attribute
	PixelsDimensionOrder_TypePtr DimensionOrder = nullptr; // Required attribute
	PositiveInt_TypePtr SizeX = nullptr; // Required attribute
	PositiveInt_TypePtr SizeY = nullptr; // Required attribute
	PositiveInt_TypePtr SizeZ = nullptr; // Required attribute
	PositiveInt_TypePtr SizeC = nullptr; // Required attribute
	PositiveInt_TypePtr SizeT = nullptr; // Required attribute
	PositiveFloat_TypePtr PhysicalSizeX = nullptr; // Required attribute
	UnitsLength_TypePtr PhysicalSizeXUnit = nullptr; // Optional attribute
	PositiveFloat_TypePtr PhysicalSizeY = nullptr; // Required attribute
	UnitsLength_TypePtr PhysicalSizeYUnit = nullptr; // Optional attribute
	PositiveFloat_TypePtr PhysicalSizeZ = nullptr; // Optional attribute
	UnitsLength_TypePtr PhysicalSizeZUnit = nullptr; // Optional attribute
	PositiveFloat_TypePtr TimeIncrement = nullptr; // Optional attribute
	UnitsTime_TypePtr TimeIncrementUnit = nullptr; // Optional attribute
	PixelType_TypePtr PixelType = nullptr; // Required attribute
    std::optional<bool> Interleaved; // Optional attribute
	PositiveInt_TypePtr SignificantBits = nullptr; // Optional attribute
    std::optional<bool> BigEndian; // Optional attribute
    std::vector<Inscoper::NBO::PlanePtr> Plane_List;
    std::vector<Inscoper::NBO::ChannelPtr> Channel_List;
    Inscoper::NBO::AdditionalDimensionMapPtr AdditionalDimensionMap = nullptr;
    Inscoper::NBO::Pixels_ChoicePtr pixels_choice = nullptr;
};

/*! Shared pointer for Pixels*/
typedef std::shared_ptr<Pixels> PixelsPtr;

} // namespace Inscoper::NBO

#endif // PIXELS_HPP_INCLUDED