#ifndef C_P1_META_DATA_H
#define C_P1_META_DATA_H

#include "C_P1ImageCommonLinkage.h"
#include "C_P1ImageCommonErrorCodes.h"
#include "C_P1ImageCommonTypes.h"

#include <vector>
#include <string>

namespace P1
{    
namespace ImageSdkC
{
    // forward declarations
    typedef void* P1ImageSDK_CaptureImage;
    class CMetaDataDatabase;

    struct CURational
    {
        uint32_t nom, denom;
    };


    struct CSRational
    {
        int32_t nom, denom;
    };


    class P1MetaData
    {
    public:
        virtual uint32_t GetDataType() { return 0; }
    };

    class P1MetaObject
    {
    public:
        P1MetaObject(P1MetaData* p=nullptr) : mData(p) {}


        /**
        * @brief Is meta object valid.
        *
        * @return A boolean flag that indicates if object is valid. True means it is valid
        */
        bool IsValid();

        /**
        * @brief Return the type of the object. <dni!> where to find the types.
        *
        * @return The type of the object is returned.
        */
        uint32_t GetType() const;

        /**
        * @brief Return the number of elements in the object. 
        *
        * Use this function to get the number of elements in an array type metaobject. An object that contains a string will return the value 1.
        * @return Return the number of elements of the object. 
        */
        uint32_t GetCount() const;


        /**
        * @brief Get scalar unsigned byte from object. Can only be used on binary metaobjects with the correct type. 
        *
        * It is the users responsability to use this function correctly. The type of the object can be retrieved by using the GetType() method.
        * If function is used on a wrong kind of object the function will set the error flag. A binary metaobject is eg. exif, gps and geotiff kind of metadata.
        * @param error: This parameter refers to a variable where function can store the error state.      
        * @return The value of the object. If it was not successfull the error flag will be set and 0 is returned.
        */
        uint8_t GetUByte(bool& error);   

        /**
        * @brief Get scalar unsigned word from object. Can only be used on binary metaobjects with the correct type.
        *
        * It is the users responsability to use this function correctly. The type of the object can be retrieved by using the GetType() method.
        * If function is used on a wrong kind of object the function will set the error flag. A binary metaobject is eg. exif, gps and geotiff kind of metadata.
        * @param error: This parameter refers to a variable where function can store the error state.
        * @return The value of the object. If it was not successfull the error flag will be set and 0 is returned.
        */
        uint16_t GetUWord(bool& error);

        /**
        * @brief Get scalar unsigned long from object. Can only be used on binary metaobjects with the correct type.
        *
        * It is the users responsability to use this function correctly. The type of the object can be retrieved by using the GetType() method.
        * If function is used on a wrong kind of object the function will set the error flag. A binary metaobject is eg. exif, gps and geotiff kind of metadata.
        * @param error: This parameter refers to a variable where function can store the error state.
        * @return The value of the object. If it was not successfull the error flag will be set and 0 is returned.
        */
        uint32_t GetULong(bool& error);   

        /**
        * @brief Get scalar signed byte from object. Can only be used on binary metaobjects with the correct type.
        *
        * It is the users responsability to use this function correctly. The type of the object can be retrieved by using the GetType() method.
        * If function is used on a wrong kind of object the function will set the error flag. A binary metaobject is eg. exif, gps and geotiff kind of metadata.
        * @param error: This parameter refers to a variable where function can store the error state.
        * @return The value of the object. If it was not successfull the error flag will be set and 0 is returned.
        */
        uint8_t GetSByte(bool& error);  

        /**
        * @brief Get scalar signed word from object. Can only be used on binary metaobjects with the correct type.
        *
        * It is the users responsability to use this function correctly. The type of the object can be retrieved by using the GetType() method.
        * If function is used on a wrong kind of object the function will set the error flag. A binary metaobject is eg. exif, gps and geotiff kind of metadata.
        * @param error: This parameter refers to a variable where function can store the error state.
        * @return The value of the object. If it was not successfull the error flag will be set and 0 is returned.
        */
        uint16_t GetSWord(bool& error);  

        /**
        * @brief Get scalar signed long from object. Can only be used on binary metaobjects with the correct type.
        *
        * It is the users responsability to use this function correctly. The type of the object can be retrieved by using the GetType() method.
        * If function is used on a wrong kind of object the function will set the error flag. A binary metaobject is eg. exif, gps and geotiff kind of metadata.
        * @param error: This parameter refers to a variable where function can store the error state.
        * @return The value of the object. If it was not successfull the error flag will be set and 0 is returned.
        */
        uint32_t GetSLong(bool& error); 

        /**
        * @brief Get scalar float from object. Can only be used on binary metaobjects with the correct type.
        *
        * It is the users responsability to use this function correctly. The type of the object can be retrieved by using the GetType() method.
        * If function is used on a wrong kind of object the function will set the error flag. A binary metaobject is eg. exif, gps and geotiff kind of metadata.
        * @param error: This parameter refers to a variable where function can store the error state.
        * @return The value of the object. If it was not successfull the error flag will be set and 0 is returned.
        */
        float GetFloat(bool& error);   

        /**
        * @brief Get scalar double from object. Can only be used on binary metaobjects with the correct type.
        *
        * It is the users responsability to use this function correctly. The type of the object can be retrieved by using the GetType() method.
        * If function is used on a wrong kind of object the function will set the error flag. A binary metaobject is eg. exif, gps and geotiff kind of metadata.
        * @param error: This parameter refers to a variable where function can store the error state.
        * @return The value of the object. If it was not successfull the error flag will be set and 0 is returned.
        */
        double GetDouble(bool& error);  

        /**
        * @brief Get scalar unsigned rational from object. Can only be used on binary metaobjects with the correct type.
        *
        * It is the users responsability to use this function correctly. The type of the object can be retrieved by using the GetType() method.
        * If function is used on a wrong kind of object the function will set the error flag. A binary metaobject is eg. exif, gps and geotiff kind of metadata.
        * A rational is value represented as a fraction (nom/denom) instead of a float or double. nom and denon is of type unsigned long
        * @param error: This parameter refers to a variable where function can store the error state.
        * @return The value of the object. If it was not successfull the error flag will be set and 0/0 is returned.
        */
        CURational GetURational(bool& error);

        /**
        * @brief Get scalar unsigned rational from object. Can only be used on binary metaobjects with the correct type.
        *
        * It is the users responsability to use this function correctly. The type of the object can be retrieved by using the GetType() method.
        * If function is used on a wrong kind of object the function will set the error flag. A binary metaobject is eg. exif, gps and geotiff kind of metadata.
        * A rational is value represented as a fraction (nom/denom) instead of a float or double. nom and denon is of type signed long
        * @param error: This parameter refers to a variable where function can store the error state.
        * @return The value of the object. If it was not successfull the error flag will be set and 0/0 is returned.
        */
        CSRational GetSRational(bool& error);

        /**
        * @brief Get Raw string from object (including zero padding). Can be used on both binary and textual metaobjects. textual metaobject is e.g. an xmp value
        *
        * It is the users responsability to use this function correctly. The type of the object can be retrieved by using the GetType() method.
        * If function is used on a wrong kind of object the function will set the error flag.
        * @param error: This parameter refers to a variable where function can store the error state.
        * @return The value of the object. If it was not successfull the error flag will be set and "" is returned.
        */
        std::string GetRawString(bool& error);

        /**
        * @brief Get string from object (removes padding). Can be used on both binary and textual metaobjects. textual metaobject is e.g. an xmp value
        *
        * It is the users responsability to use this function correctly. The type of the object can be retrieved by using the GetType() method.
        * If function is used on a wrong kind of object the function will set the error flag.
        * @param error: This parameter refers to a variable where function can store the error state.
        * @return The value of the object. If it was not successfull the error flag will be set and "" is returned.
        */
        std::string GetString(bool& error);


        // Getters of arrays

        /** @brief Get array of unsigned bytes from object. Can only be used on binary metaobjects with the correct type.
        *
        * It is the users responsability to use this function correctly. The type of the object can be retrieved by using the GetType() method. The GetCount() method
        * returns the number of array elements, but is not needed, since function itself returns all elements
        * If function is used on a wrong kind of object the function will set the error flag. A binary metaobject is eg. exif, gps and geotiff kind of metadata.
        * @param error: This parameter refers to a variable where function can store the error state.
        * @return A vector with values of the object. If it was not successfull the error flag will be set and empty vector is returned.
        */
        std::vector<uint8_t> GetUBytes(bool& error);

        /** @brief Get array of unsigned words from object. Can only be used on binary metaobjects with the correct type.
        *
        * It is the users responsability to use this function correctly. The type of the object can be retrieved by using the GetType() method. The GetCount() method
        * returns the number of array elements, but is not needed, since function itself returns all elements
        * If function is used on a wrong kind of object the function will set the error flag. A binary metaobject is eg. exif, gps and geotiff kind of metadata.
        * @param error: This parameter refers to a variable where function can store the error state.
        * @return A vector with values of the object. If it was not successfull the error flag will be set and empty vector is returned.
        */
        std::vector<uint16_t> GetUWords(bool& error);

        /** @brief Get array of unsigned longs from object. Can only be used on binary metaobjects with the correct type.
        *
        * It is the users responsability to use this function correctly. The type of the object can be retrieved by using the GetType() method. The GetCount() method
        * returns the number of array elements, but is not needed, since function itself returns all elements
        * If function is used on a wrong kind of object the function will set the error flag. A binary metaobject is eg. exif, gps and geotiff kind of metadata.
        * @param error: This parameter refers to a variable where function can store the error state.
        * @return A vector with values of the object. If it was not successfull the error flag will be set and empty vector is returned.
        */
        std::vector<uint32_t> GetULongs(bool& error);

        /** @brief Get array of signed bytes from object. Can only be used on binary metaobjects with the correct type.
        *
        * It is the users responsability to use this function correctly. The type of the object can be retrieved by using the GetType() method. The GetCount() method
        * returns the number of array elements, but is not needed, since function itself returns all elements
        * If function is used on a wrong kind of object the function will set the error flag. A binary metaobject is eg. exif, gps and geotiff kind of metadata.
        * @param error: This parameter refers to a variable where function can store the error state.
        * @return A vector with values of the object. If it was not successfull the error flag will be set and empty vector is returned.
        */
        std::vector<int8_t> GetSBytes(bool& error);

        /** @brief Get array of signed words from object. Can only be used on binary metaobjects with the correct type.
        *
        * It is the users responsability to use this function correctly. The type of the object can be retrieved by using the GetType() method. The GetCount() method
        * returns the number of array elements, but is not needed, since function itself returns all elements
        * If function is used on a wrong kind of object the function will set the error flag. A binary metaobject is eg. exif, gps and geotiff kind of metadata.
        * @param error: This parameter refers to a variable where function can store the error state.
        * @return A vector with values of the object. If it was not successfull the error flag will be set and empty vector is returned.
        */
        std::vector<int16_t> GetSWords(bool& error);

        /** @brief Get array of signed longs from object. Can only be used on binary metaobjects with the correct type.
        *
        * It is the users responsability to use this function correctly. The type of the object can be retrieved by using the GetType() method. The GetCount() method
        * returns the number of array elements, but is not needed, since function itself returns all elements
        * If function is used on a wrong kind of object the function will set the error flag. A binary metaobject is eg. exif, gps and geotiff kind of metadata.
        * @param error: This parameter refers to a variable where function can store the error state.
        * @return A vector with values of the object. If it was not successfull the error flag will be set and empty vector is returned.
        */
        std::vector<int32_t> GetSLongs(bool& error);

        /** @brief Get array of floats from object. Can only be used on binary metaobjects with the correct type.
        *
        * It is the users responsability to use this function correctly. The type of the object can be retrieved by using the GetType() method. The GetCount() method
        * returns the number of array elements, but is not needed, since function itself returns all elements
        * If function is used on a wrong kind of object the function will set the error flag. A binary metaobject is eg. exif, gps and geotiff kind of metadata.
        * @param error: This parameter refers to a variable where function can store the error state.
        * @return A vector with values of the object. If it was not successfull the error flag will be set and empty vector is returned.
        */
        std::vector<float> GetFloats(bool& error);

        /** @brief Get array of doubles from object. Can only be used on binary metaobjects with the correct type.
        *
        * It is the users responsability to use this function correctly. The type of the object can be retrieved by using the GetType() method. The GetCount() method
        * returns the number of array elements, but is not needed, since function itself returns all elements
        * If function is used on a wrong kind of object the function will set the error flag. A binary metaobject is eg. exif, gps and geotiff kind of metadata.
        * @param error: This parameter refers to a variable where function can store the error state.
        * @return A vector with values of the object. If it was not successfull the error flag will be set and empty vector is returned.
        */
        std::vector<double> GetDoubles(bool& error);        


        /**
        * @brief Set scalar unsigned byte value of object. Can only be used on binary metaobjects with the correct type.
        *
        * It is the users responsability to use this function correctly. The type of the object can be retrieved by using the GetType() method.
        * If function is used on a wrong kind of object the function will set the error flag. A binary metaobject is eg. exif, gps and geotiff kind of metadata.
        * @param value: This parameter is the value to be set
        * @return true is returned it setting the value was successfull, on error false is returned.
        */
        bool SetUByte(uint8_t value);

        /**
        * @brief Set scalar unsigned word value of object. Can only be used on binary metaobjects with the correct type.
        *
        * It is the users responsability to use this function correctly. The type of the object can be retrieved by using the GetType() method.
        * If function is used on a wrong kind of object the function will set the error flag. A binary metaobject is eg. exif, gps and geotiff kind of metadata.
        * @param value: This parameter is the value to be set
        * @return true is returned it setting the value was successfull, on error false is returned.
        */
        bool SetUWord(uint16_t value);
        
        /**
        * @brief Set scalar unsigned long value of object. Can only be used on binary metaobjects with the correct type.
        *
        * It is the users responsability to use this function correctly. The type of the object can be retrieved by using the GetType() method.
        * If function is used on a wrong kind of object the function will set the error flag. A binary metaobject is eg. exif, gps and geotiff kind of metadata.
        * @param value: This parameter is the value to be set
        * @return true is returned it setting the value was successfull, on error false is returned.
        */
        bool SetULong(uint32_t value);

        /**
        * @brief Set scalar signed byte value of object. Can only be used on binary metaobjects with the correct type.
        *
        * It is the users responsability to use this function correctly. The type of the object can be retrieved by using the GetType() method.
        * If function is used on a wrong kind of object the function will set the error flag. A binary metaobject is eg. exif, gps and geotiff kind of metadata.
        * @param value: This parameter is the value to be set
        * @return true is returned it setting the value was successfull, on error false is returned.
        */
        bool SetSByte(uint8_t value);

        /**
        * @brief Set scalar signed word value of object. Can only be used on binary metaobjects with the correct type.
        *
        * It is the users responsability to use this function correctly. The type of the object can be retrieved by using the GetType() method.
        * If function is used on a wrong kind of object the function will set the error flag. A binary metaobject is eg. exif, gps and geotiff kind of metadata.
        * @param value: This parameter is the value to be set
        * @return true is returned it setting the value was successfull, on error false is returned.
        */
        bool SetSWord(uint16_t value);

        /**
        * @brief Set scalar signed long value of object. Can only be used on binary metaobjects with the correct type.
        *
        * It is the users responsability to use this function correctly. The type of the object can be retrieved by using the GetType() method.
        * If function is used on a wrong kind of object the function will set the error flag. A binary metaobject is eg. exif, gps and geotiff kind of metadata.
        * @param value: This parameter is the value to be set
        * @return true is returned it setting the value was successfull, on error false is returned.
        */
        bool SetSLong(uint32_t value);

        /**
        * @brief Set scalar float value of object. Can only be used on binary metaobjects with the correct type.
        *
        * It is the users responsability to use this function correctly. The type of the object can be retrieved by using the GetType() method.
        * If function is used on a wrong kind of object the function will set the error flag. A binary metaobject is eg. exif, gps and geotiff kind of metadata.
        * @param value: This parameter is the value to be set
        * @return true is returned it setting the value was successfull, on error false is returned.
        */
        bool SetFloat(float value);

        /**
        * @brief Set scalar double value of object. Can only be used on binary metaobjects with the correct type.
        *
        * It is the users responsability to use this function correctly. The type of the object can be retrieved by using the GetType() method.
        * If function is used on a wrong kind of object the function will set the error flag. A binary metaobject is eg. exif, gps and geotiff kind of metadata.
        * @param value: This parameter is the value to be set
        * @return true is returned it setting the value was successfull, on error false is returned.
        */
        bool SetDouble(double value);

        /**
        * @brief Set scalar unsigned rational value of object. Can only be used on binary metaobjects with the correct type.
        *
        * It is the users responsability to use this function correctly. The type of the object can be retrieved by using the GetType() method.
        * If function is used on a wrong kind of object the function will set the error flag. A binary metaobject is eg. exif, gps and geotiff kind of metadata.
        * A rational is value represented as a fraction (nom/denom) instead of a float or double. nom and denon is of type unsigned long
        * @param value: This parameter is the value to be set
        * @return true is returned it setting the value was successfull, on error false is returned.
        */
        bool SetURational(CURational value);

        /**
        * @brief Set scalar signed rational value of object. Can only be used on binary metaobjects with the correct type.
        *
        * It is the users responsability to use this function correctly. The type of the object can be retrieved by using the GetType() method.
        * If function is used on a wrong kind of object the function will set the error flag. A binary metaobject is eg. exif, gps and geotiff kind of metadata.
        * A rational is value represented as a fraction (nom/denom) instead of a float or double. nom and denon is of type signed long
        * @param value: This parameter is the value to be set
        * @return true is returned it setting the value was successfull, on error false is returned.
        */
        bool SetSRational(CSRational value);

        /**
        * @brief Set string value of object. Can be used on both binary and textual metaobjects. textual metaobject is e.g. an xmp value
        *
        * It is the users responsability to use this function correctly. The type of the object can be retrieved by using the GetType() method.
        * If function is used on a wrong kind of object the function will set the error flag. 
        * @param value: This parameter is the value to be set
        * @return true is returned it setting the value was successfull, on error false is returned.
        */
        bool SetString(std::string buffer);

        /** @brief Set array of unsigned bytes to object. Can only be used on binary metaobjects with the correct type.
        *
        * It is the users responsability to use this function correctly. The type of the object can be retrieved by using the GetType() method. 
        * If function is used on a wrong kind of object the function will set the error flag. A binary metaobject is eg. exif, gps and geotiff kind of metadata.
        * @param values: Points to array of values to be set.
        * @param count: The number of values in the array to be set
        * @return true is returned it setting the value was successfull, on error false is returned.
        */
        bool SetUBytes(uint8_t* values, uint32_t count);

        /** @brief Set array of unsigned words to object. Can only be used on binary metaobjects with the correct type.
        *
        * It is the users responsability to use this function correctly. The type of the object can be retrieved by using the GetType() method.
        * If function is used on a wrong kind of object the function will set the error flag. A binary metaobject is eg. exif, gps and geotiff kind of metadata.
        * @param values: Points to array of values to be set.
        * @param count: The number of values in the array to be set
        * @return true is returned it setting the value was successfull, on error false is returned.
        */
        bool SetUWords(uint16_t* values, uint32_t count);

        /** @brief Set array of unsigned longs to object. Can only be used on binary metaobjects with the correct type.
        *
        * It is the users responsability to use this function correctly. The type of the object can be retrieved by using the GetType() method.
        * If function is used on a wrong kind of object the function will set the error flag. A binary metaobject is eg. exif, gps and geotiff kind of metadata.
        * @param values: Points to array of values to be set.
        * @param count: The number of values in the array to be set
        * @return true is returned it setting the value was successfull, on error false is returned.
        */
        bool SetULongs(uint32_t* values, uint32_t count);

        /** @brief Set array of signed bytes to object. Can only be used on binary metaobjects with the correct type.
        *
        * It is the users responsability to use this function correctly. The type of the object can be retrieved by using the GetType() method.
        * If function is used on a wrong kind of object the function will set the error flag. A binary metaobject is eg. exif, gps and geotiff kind of metadata.
        * @param values: Points to array of values to be set.
        * @param count: The number of values in the array to be set
        * @return true is returned it setting the value was successfull, on error false is returned.
        */
        bool SetSBytes(int8_t* values, uint32_t count);

        /** @brief Set array of signed words to object. Can only be used on binary metaobjects with the correct type.
        *
        * It is the users responsability to use this function correctly. The type of the object can be retrieved by using the GetType() method.
        * If function is used on a wrong kind of object the function will set the error flag. A binary metaobject is eg. exif, gps and geotiff kind of metadata.
        * @param values: Points to array of values to be set.
        * @param count: The number of values in the array to be set
        * @return true is returned it setting the value was successfull, on error false is returned.
        */
        bool SetSWords(int16_t* values, uint32_t count);

        /** @brief Set array of signed longs to object. Can only be used on binary metaobjects with the correct type.
        *
        * It is the users responsability to use this function correctly. The type of the object can be retrieved by using the GetType() method.
        * If function is used on a wrong kind of object the function will set the error flag. A binary metaobject is eg. exif, gps and geotiff kind of metadata.
        * @param values: Points to array of values to be set.
        * @param count: The number of values in the array to be set
        * @return true is returned it setting the value was successfull, on error false is returned.
        */
        bool SetSLongs(int32_t* values, uint32_t count);

        /** @brief Set array of floats to object. Can only be used on binary metaobjects with the correct type.
        *
        * It is the users responsability to use this function correctly. The type of the object can be retrieved by using the GetType() method.
        * If function is used on a wrong kind of object the function will set the error flag. A binary metaobject is eg. exif, gps and geotiff kind of metadata.
        * @param values: Points to array of values to be set.
        * @param count: The number of values in the array to be set
        * @return true is returned it setting the value was successfull, on error false is returned.
        */
        bool SetFloats(float* values, uint32_t count);

        /** @brief Set array of doubles to object. Can only be used on binary metaobjects with the correct type.
        *
        * It is the users responsability to use this function correctly. The type of the object can be retrieved by using the GetType() method.
        * If function is used on a wrong kind of object the function will set the error flag. A binary metaobject is eg. exif, gps and geotiff kind of metadata.
        * @param values: Points to array of values to be set.
        * @param count: The number of values in the array to be set
        * @return true is returned it setting the value was successfull, on error false is returned.
        */
        bool SetDoubles(double* values, uint32_t count);
      
        /** @brief Get state of readonly atttribute. If metaobject is readonly then it can only be read (using a getter function)
        *       
        * Its the underlying system that determines if a value is readonly. The user cannot set this. The corresponding user functions is SetDisabled(bool state)
        * @return true is returned if it is readonly. otherwise false is returned.
        */
        bool IsReadOnly();

        /** @brief Get state of writable atttribute. If metaobject writable then it will be written to output files, otherwise it will not.
        *
        * This is a way to control if a metaobject should be written to an output image file.
        * @return true is returned if it is writable. otherwise false is returned.
        */
        bool IsWritable();

        /** @brief Set state of writable atttribute. 
        *
        * With this method the user can decide if a metaobject is allowed to be written to an output image file.
        * @param state: Set the writable state of the metaobject. True means it is writable.
        */
        void SetWritable(bool state);

        /** @brief Get state of disabled atttribute. If metaobject disabled then it cannot be changed.
        *
        * This is a user way of controlling access to the metaobject. it cannot overrule the readonly attribute.
        * @return true is returned if it is writable. otherwise false is returned.
        */
        bool IsDisabled();

        /** @brief Set state of disabled atttribute.
        *
        * With this method the user can protect the value in an object from being changed.
        * @param state: Set the disabled state of the metaobject. True means it is disabled.
        */
        void SetDisabled(bool state);

        /** @brief Is the metaobject modifiable. Use this function to check if its possible to modify the value of the metaobject
        *
        * It is just a convinience function to check if the readonly or disabled attribute has been set
        * @return true is returned if the value of the metaobject can be changed. otherwise false is returned.
        */
        bool IsModifiable();


        // Internal function, do not use
        P1MetaData* GetPtr() { return mData;  }

    private:
        P1MetaData* mData = nullptr;
    };
                 




    class EXPORT_API P1MetaDataBase
    {
    public:

        /** @brief Create a metadatabase and populate it with metadata in an capture image (from an iiq file).
        *
        * There can be created more than one metadatabase for a captureimage. This can eg. be helpfull if multiple
        * output image files are to be created with different metadata content.
        */
        P1MetaDataBase(P1::ImageSdkC::P1ImageSDK_CaptureImage image, bool useDbFromFile = false);

        /** @brief Destroy metadatabase object. This will destroy all lists and objects in the metadatabase as well
        */
        ~P1MetaDataBase();


        /** @brief Retrieve a metadata object from the metadatabase
        *
        * A P1MetaData object will always be returned not matter if the metaobject was found or not.
        * To chech the validity of the object the IsValid() method can be used.
        * It is safe to nest both a GetMetaObject call with a getter or setter without checking for validity. 
        * If metaobject is not found then an error will just be returned by the getter or setter.
        * @param path: The path to the object. The metaobjects are orginized in a tree structure where each level of the tree is divided by a ":" 
        * @return a P1MetaObject. To check if an object was found can be checked with the IsValid() function. But it is safe to nest this function with a getter or setter.
        */
        P1MetaObject GetMetaObject(std::string path);

        /** @brief Create a new metadata object and insert it in the metadatabase
        *
        * A P1MetaData object will always be returned not matter if function was able to create object or not.
        * To chech the validity of the object the IsValid() method can be used.
        * It is safe to nest a CreateMetaObject call with a getter or setter without checking for validity. But the final error code or return value should be tested for success.        
        * @param path: The path to the object that the user wants to create. The metaobjects are orginized in a tree structure where each level of the tree is divided by a ":". The last part
        * of the path must be a unique name of the new object.
        * @return a P1MetaObject. To check if an object was found can be checked with the IsValid() function. But it is safe to nest this function with a getter or setter.
        */
        P1MetaObject CreateMetaObject(std::string path);
    
        /** @brief Check for existance of a metaobject in the metadatabase
        *
        * @param path: The path to the object that the user wants to create. The metaobjects are orginized in a tree structure where each level of the tree is divided by a ":".
        * This function can also be used to check if a list of objects exist or not. Eg. a namespace in the xmp block.
        * @return A boolean value that indicates if metaobject exist or not. true means it does exist.
        */
        bool Exist(std::string path);               

        /** @brief Create a new Xmp namespace in an xmp block. This requires that an xmp block exist in the database
        *
        * For now it is only possible to create new lists of objects in the xmp block. Therefore the function refers only to the xmp block
        * @param name: The name of the new namespace.
        * @param url: The url for the xmp namespace. 
        * @return A boolean value that indicates if creation of the namespace was successfull or not.
        */
        bool CreateXmpNamespace(std::string name, std::string url);

        /** @brief A debug function for internal use
        */
        void Dump();
        
        /** @brief function is only for internal use
        */
        CMetaDataDatabase* GetDb();

    private:
        CMetaDataDatabase* mDb = nullptr;
        bool releaseData = false;
    };

}
}



#endif
