////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// THIS IS AUTO-GENERATED CODE.  PLEASE DO NOT EDIT (File bug reports against tools).
///
/// Auto-generated by: Parameter Parser V5.5.1 (2411131018)
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @file  parameterutils.h
/// @brief Auto-generated Chromatix parameter file
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef PARAMETERUTILS_H
#define PARAMETERUTILS_H

#include "parametertypes.h"

#include <typeinfo>
#include <string>
#include <thread>
#include <mutex>
#include <map>
#include <condition_variable>

#define PARAMETER_MIN(lhs, rhs)     ( (lhs) < (rhs) ? (lhs) : (rhs) )
#define PARAMETER_MAX(lhs, rhs)     ( (lhs) > (rhs) ? (lhs) : (rhs) )
#define REMAINDER(bytes, alignment) ( (bytes % alignment) > 0 ? (alignment - (bytes % alignment)) : 0 )
#define IS_ALIGNED(value)           ( (UINT64)(value) % 8 == 0 )
#define MAX_FILE_LENGTH 1024

class ParameterParserDataType
{
public:
    static constexpr const CHAR* const Module    = "Module";
    static constexpr const CHAR* const Structure = "Structure";
    static constexpr const CHAR* const Enum      = "Enum";
    static constexpr const CHAR* const Boolean   = "Boolean";
    static constexpr const CHAR* const Int8      = "Int8";
    static constexpr const CHAR* const UInt8     = "UInt8";
    static constexpr const CHAR* const Int16     = "Int16";
    static constexpr const CHAR* const UInt16    = "UInt16";
    static constexpr const CHAR* const Int32     = "Int32";
    static constexpr const CHAR* const UInt32    = "UInt32";
    static constexpr const CHAR* const Int64     = "Int64";
    static constexpr const CHAR* const UInt64    = "UInt64";
    static constexpr const CHAR* const Float     = "Float";
    static constexpr const CHAR* const Double    = "Double";
    static constexpr const CHAR* const String    = "String";
};

class IParameterLoggingAPI;
class ParameterLogging
{
public:
    enum class ParameterLogLevel
    {
        Debug,
        Warning,
        Error
    };
    static constexpr INT32 MESSAGE_LEN = 4096;
    static void Write(IParameterLoggingAPI* const logAPI, ParameterLogLevel level, const CHAR* const file, INT32 const line, const CHAR* const str, ...);
    static const CHAR* GetFileName(const CHAR* const file);
};

class IParameterLoggingAPI
{
public:
    virtual const CHAR* GetLoggingIdentifier() = 0;
    virtual bool LoggingEnabled(ParameterLogging::ParameterLogLevel level) = 0;

    virtual ~IParameterLoggingAPI() {}
};

#define PARAMETER_LOG_ERROR(logAPI, ...)   ParameterLogging::Write(logAPI, ParameterLogging::ParameterLogLevel::Error,   __FILE__, __LINE__, ##__VA_ARGS__)
#define PARAMETER_LOG_WARNING(logAPI, ...) ParameterLogging::Write(logAPI, ParameterLogging::ParameterLogLevel::Warning, __FILE__, __LINE__, ##__VA_ARGS__)
#define PARAMETER_LOG_DEBUG(logAPI, ...)   ParameterLogging::Write(logAPI, ParameterLogging::ParameterLogLevel::Debug,   __FILE__, __LINE__, ##__VA_ARGS__)

// Reads buffer value in little-endian format
class ParameterUtils
{
public:
    static constexpr INT32  UNLIMITED    = -1;
    static constexpr UINT32 MAX_DECIMALS = 10U;
    template<typename T> static bool Read(
        T*      value,
        BYTE*   buffer,
        UINT32  length,
        UINT32* pos,
        BYTE    alignment,
        IParameterLoggingAPI* const logAPI)
    {
        constexpr SIZE_T OBJ_SIZE = sizeof(T);
        if ((*pos) + OBJ_SIZE <= length)
        {
            PARAMETER_MEMCPY(value, OBJ_SIZE, &buffer[*pos], OBJ_SIZE);
            *pos += PARAMETER_MAX(OBJ_SIZE, alignment);
            return true;
        }
        else
        {
            PARAMETER_LOG_ERROR(logAPI, "Failed to read %lld bytes from binary file offset %d, length %d\n", OBJ_SIZE, *pos, length);
        }
        return false;
    }

    template<typename T> static bool Write(
        T                     value,
        BYTE*                 buffer,
        UINT32                length,
        UINT32*               pos,
        BYTE                  alignment,
        IParameterLoggingAPI* logAPI)
    {
        constexpr SIZE_T OBJ_SIZE = sizeof(T);
        if ((*pos) + OBJ_SIZE <= length)
        {
            PARAMETER_MEMCPY(&buffer[*pos], OBJ_SIZE, &value, OBJ_SIZE);
            *pos += PARAMETER_MAX(OBJ_SIZE, alignment);
            return true;
        }
        else
        {
            PARAMETER_LOG_ERROR(logAPI, "Failed to write %lld bytes to binary offset %d, length %d\n", OBJ_SIZE, *pos, length);
        }
        return false;
    }

    template<typename T> static bool ReadArray(
        T*      value,
        BYTE*   buffer,
        UINT32  length,
        UINT32* pos,
        UINT32  count,
        BYTE    alignment,
        IParameterLoggingAPI* logAPI)
    {
        return ReadBuffer((BYTE*)value, buffer, length, pos, count * sizeof(T), alignment, logAPI);
    }

    template<typename T> static T* ReadArray(
        BYTE*   buffer,
        UINT32  length,
        UINT32* pos,
        UINT32  count,
        BYTE    alignment,
        IParameterLoggingAPI* logAPI)
    {
        T* result = PARAMETER_NEW T[count];
        if (!ReadBuffer((BYTE*)result, buffer, length, pos, count * sizeof(T), alignment, logAPI))
        {
            PARAMETER_DELETE[] result;
            result = nullptr;
        }
        return result;
    }

    static bool ReadString(
        CHAR* const   value,
        BYTE* const   buffer,
        UINT32 const  length,
        UINT32* const pos,
        UINT32 const  destStrSize,
        UINT32 const  maxChars,
        BYTE const    alignment,
        IParameterLoggingAPI* logAPI);

    static CHAR* ReadString(
        BYTE* const   buffer,
        UINT32 const  length,
        UINT32* const pos,
        UINT32 const  maxChars,
        BYTE const    alignment);

    static bool ReadBuffer(
        BYTE* const   value,
        BYTE* const   buffer,
        UINT32 const  length,
        UINT32* const pos,
        UINT32 const  count,
        BYTE const    alignment,
        IParameterLoggingAPI* logAPI);

    static bool WriteString(
        const CHAR*   value,
        BYTE*         buffer,
        UINT32 const  length,
        UINT32* const pos,
        bool const    includeNul,
        IParameterLoggingAPI* logAPI);

    static INT32 GetStringPos(
        const CHAR* const input,
        CHAR const  ch);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetSubString - Get substring from input (returns up to the separator position)
    ///
    /// Return value - New input string position (separator or string terminator position)
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    static UINT32 GetSubString(
        const CHAR* const input,
        CHAR const        separator,
        CHAR* const       subString,
        UINT32 const      size);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetVariable - Get variable name and array index  (if exists) from input string
    ///
    /// Return value - new input string position
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    static UINT32 GetVariable(
        const CHAR* const input,
        CHAR* const name,
        UINT32&     index,
        SIZE_T const size);

    static double StringToDouble(
        const CHAR* const input,
        bool&             valid);

    static PARAMETER_INLINE double StringToDouble(
        const CHAR* const input)
    {
        bool valid = false;
        return StringToDouble(input, valid);
    }

    static void DoubleToString(
        double const input,
        CHAR* const  string,
        UINT32 const size,
        UINT32 const decimals,
        bool&  valid);

    static PARAMETER_INLINE void DoubleToString(
        double const input,
        CHAR*  const string,
        UINT32 const size,
        UINT32 const decimals = MAX_DECIMALS)
    {
        bool valid = false;
        DoubleToString(input, string, size, decimals, valid);
    }
};

struct ParameterParserInfo
{
    static constexpr INT32 MAX_VALUE = 1024;

    ParameterParserInfo();
    ParameterParserInfo(const CHAR* const name, const CHAR* const type);
    ParameterParserInfo(const CHAR* const name, const CHAR* const type, double const value, UINT32 const decimals = ParameterUtils::MAX_DECIMALS);
    ParameterParserInfo(const CHAR* const name, const CHAR* const type, const CHAR* const value);
    ParameterParserInfo(const CHAR* const name, const CHAR* const type, bool const isArray, bool const isOptional, UINT32 const elements);

    const CHAR* Name;
    const CHAR* Type;
    CHAR        Value[MAX_VALUE];
    UINT32      IsArray;    // True if is an array
    UINT32      IsOptional; // True if is an optional parameter
    UINT32      Elements;   // Number of array elements. If IsOptional, 1 means optional value exists
};

template<typename T> class PList
{
public:
    PList(UINT32 chunkSize = 1)
    {
        m_count = 0;
        m_bufCnt = 0;
        m_chunkSize = chunkSize;
        m_list = nullptr;
    }

    ~PList()
    {
        Clear();
    }

    void Add(T value)
    {
        Insert(Count(), value);
    }

    void Insert(UINT32 index, T value)
    {
        bool valid = m_list != nullptr;
        if (m_count >= m_bufCnt)
        {
            SIZE_T endloc = m_bufCnt;
            m_bufCnt += m_chunkSize;
            T* newPtr = (T*)PARAMETER_REALLOC(m_list, m_bufCnt * sizeof(T));
            valid = newPtr != nullptr;
            if (valid)
            {
                // Initialize the appended memory block
                PARAMETER_MEMSET(&newPtr[endloc], 0, m_chunkSize * sizeof(T));
                m_list = newPtr;
            }
        }

        if (valid)
        {
            for (UINT32 i = m_count; i > index; i--)
            {
                m_list[i] = m_list[i - 1];
            }
            m_list[index] = value;
            m_count++;
        }
    }

    void Remove(T value)
    {
        INT32 index = IndexOf(value);
        if (index >= 0)
        {
            RemoveAt(index);
        }
    }

    void RemoveAt(UINT32 index, UINT32 count = 1)
    {
        for (SIZE_T i = index; i + count < m_count; i++)
        {
            m_list[i] = m_list[i + count];
        }
        m_count -= count;
    }

    INT32 IndexOf(T value)
    {
        INT32 result = -1;

        for (UINT32 i = 0; result < 0 && i < m_count; i++)
        {
            if (m_list[i] == value)
            {
                result = i;
            }
        }
        return result;
    }

    bool Contains(T value)
    {
        return IndexOf(value) >= 0;
    }

    void Clear()
    {
        PARAMETER_FREE(m_list);
        m_count  = 0;
        m_bufCnt = 0;
        m_list   = nullptr;
    }

    T& operator[] (UINT32 index) const
    {
        static T dummy;
        if (index >= m_count)
        {
            return dummy;
        }

        return m_list[index];
    }

    PARAMETER_INLINE UINT32 Count() const
    {
        return m_count;
    }

private:
    T* m_list;
    UINT32 m_count;
    UINT32 m_bufCnt;
    UINT32 m_chunkSize;
};

class DupObjInfo
{
public:
    DupObjInfo(UINT32 const count, const CHAR* const file, UINT32 const line);
    ~DupObjInfo();

    static bool Release(DupObjInfo* const obj);

    void*       Object;
    UINT32      Count;
    const CHAR* File;
    UINT32      Line;
    UINT32      RefCount;
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief ParameterMutex: Provides shared and recursive functionality
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class ParameterMutex
{
public:
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @brief Constructor
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ParameterMutex()
    {
        m_count = 0;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @brief Lock function
    /// @param shared - True if locking as shared
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    void Lock(bool shared);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @brief Unlock function
    /// @param shared - True if unlocking as shared
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    void Unlock(bool shared);

    // Disable copy contructors and assignment operators
    ParameterMutex(const ParameterMutex&)            = delete;
    ParameterMutex& operator=(const ParameterMutex&) = delete;

private:
    PARAMETER_INLINE bool IsLocked()
    {
        return m_count > 0;
    }

    PARAMETER_INLINE bool IsShared()
    {
        return m_shared.size() > 0;
    }

    PARAMETER_INLINE bool CanLock()
    {
        return (!IsLocked() || IsOwner()) && (!IsShared() || IsSharedOnlyOwner());
    }

    PARAMETER_INLINE bool CanLockShared()
    {
        return !IsLocked() || IsOwner();
    }

    PARAMETER_INLINE bool IsSharedOnlyOwner(std::thread::id id)
    {
        return m_shared.size() == 1 && m_shared.find(id) != m_shared.end();
    }

    PARAMETER_INLINE bool IsSharedOnlyOwner()
    {
        return IsSharedOnlyOwner(std::this_thread::get_id());
    }

    PARAMETER_INLINE bool IsOwner(std::thread::id id)
    {
        return m_owner == id;
    }

    PARAMETER_INLINE bool IsOwner()
    {
        return IsOwner(std::this_thread::get_id());
    }

    PARAMETER_INLINE void IncrementShared()
    {
        IncrementShared(std::this_thread::get_id());
    }

    PARAMETER_INLINE void IncrementShared(std::thread::id id)
    {
        if (m_shared.find(id) == m_shared.end())
        {
            m_shared[id] = 1;
        }
        else
        {
            m_shared[id] += 1;
        }
    }

    PARAMETER_INLINE void DecrementShared()
    {
        DecrementShared(std::this_thread::get_id());
    }

    PARAMETER_INLINE void DecrementShared(std::thread::id id)
    {

        if (m_shared.size() == 0 || m_shared.find(id) == m_shared.end())
        {
            // Enable for validation
            // printf("ParameterMutex::Unlock shared called when count is zero\n");
        }
        else
        {
            m_shared[id] -= 1;
            if (m_shared[id] == 0)
            {
                m_shared.erase(id);
            }
        }
    }

    std::mutex                        m_mutex;
    INT32                             m_count;
    std::thread::id                   m_owner;
    std::map<std::thread::id, UINT32> m_shared;
    std::condition_variable           m_condition;
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Lock the mutex while the class is active
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class ParameterMutexLock
{
public:
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @brief Constructor, locks the mutex
    /// @param mutex     - Mutex reference to lock
    /// @param shared    - True if unlocking as shared
    /// @param condition - True: enables mutex, False No Op
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    PARAMETER_INLINE ParameterMutexLock(ParameterMutex& mutex, bool shared, bool condition):
        m_mutex     {mutex},
        m_shared    {shared},
        m_condition {condition}
    {
        if (m_condition)
        {
            m_mutex.Lock(shared);
        }
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @brief Destructor, unlock the mutex
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    PARAMETER_INLINE ~ParameterMutexLock()
    {
        if (m_condition)
        {
            m_mutex.Unlock(m_shared);
        }
    }

private:
    ParameterMutex& m_mutex;
    bool            m_shared;
    bool            m_condition;
};

class ParameterBinaryFile
{
public:
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// ParameterBinaryFile Constructor
    ///
    /// Constructing the ParameterBinaryFile object will open the file and add a reference if the file is valid
    /// After constructing, check the return value of IsValid() to verify if the file was opened
    ///
    /// @param fileName  Name of the file to open
    /// @param logAPI    Logging API used for logging error messages
    /// @param CRCCheck  Check CRC if true
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ParameterBinaryFile(
        const CHAR*           fileName,
        IParameterLoggingAPI* logAPI,
        bool                  CRCCheck = true);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// ParameterBinaryFile Descructor
    ///
    /// Deconstruct the ParameterBinaryFile object will close the file if opened
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ~ParameterBinaryFile();

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// FileName
    ///
    /// Returns the file name
    ///
    /// @return File Name
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    PARAMETER_INLINE const CHAR* FileName()
    {
        return m_fileName;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// Length
    ///
    /// Returns the file length
    ///
    /// @return File Length
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    PARAMETER_INLINE UINT32 Length()
    {
        return m_length;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// Read
    ///
    /// Reads the specified number of bytes from the file at the specified offset + pos
    ///
    /// @param value     Buffer to read into
    /// @param offset    Location in the file to start from
    /// @param pos       offset + position in the file to read from, position is updated after read
    /// @param count     Number of bytes to read
    /// @param alignment Number of bytes to align the returned pos value by
    ///
    /// @return Buffer Pointer or null if read failed
    ///                Caller is responsible for freeing the returned buffer using PARAMETER_DELETE[]
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    bool Read(
        BYTE* const   value,
        UINT32 const  offset,
        UINT32* const pos,
        SIZE_T const  count,
        BYTE const    alignment);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// Read
    ///
    /// Reads the specified number of bytes from the file at the specified offset
    ///
    /// @param offset  Location in the file to start reading
    /// @param count   Number of bytes to read
    ///
    /// @return Buffer Pointer or null if read failed
    ///                Caller is responsible for freeing the returned buffer using PARAMETER_DELETE[]
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    BYTE* Read(
        UINT32 const offset,
        SIZE_T const count);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// IsValid
    ///
    /// Check if the file exists and can be opened
    ///
    /// @return true if the file was successfully opened at construction time
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    PARAMETER_INLINE bool IsValid()
    {
        return m_isValid;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// IsValidCRC
    ///
    /// Check if the file has a valid CRC
    ///
    /// @return true if the CRC was validated at construction time
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    PARAMETER_INLINE bool IsValidCRC()
    {
        return m_isValidCRC;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// Reference
    ///
    /// Add or remove file references.  Opens or closes the file as needed
    ///
    /// @param adjust  Number of references to add (or remove if negative)
    ///
    /// @return The current reference count after the change is applied
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    INT32 Reference(
        INT32 adjust);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// Reload
    ///
    /// Reloads and re-validates the file.  Leaves the reference count unchanged.
    /// This function should be called when IsModified returns true.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    bool Reload();

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// ValidateCRC
    ///
    /// @brief Reads and validates CRC value in the binary buffer
    ///
    /// @param buffer   Binary parameter buffer
    /// @param length   Length of the binary parameter buffer
    /// @param logAPI  Set logAPI for error reporting
    ///
    /// @return True if CRC is valid
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    static bool ValidateCRC(
        BYTE* const           buffer,
        const UINT32          length,
        IParameterLoggingAPI* logAPI);

private:
    void Close();
    void Open(bool logFailures);
    void ValidateCRC();

    FILE*  m_file;
    UINT32 m_length;
    INT32  m_refCnt;
    CHAR   m_fileName[MAX_FILE_LENGTH];
    bool   m_isValid;    // File exists and can be opened
    bool   m_isValidCRC; // File has a valid CRC
    bool   m_isModified;
    time_t m_modTime;
    ParameterMutex m_mutex;
    IParameterLoggingAPI* m_logAPI;

    static UINT32 m_crcLookupTable[256];
};

class IParameterDataAPI : public IParameterLoggingAPI
{
public:
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetValue
    ///
    /// @brief Gets the module value(s) specified by the mode path, and variable path
    ///
    /// @param modePath     Pipe '|' separated Mode path
    ///                     Example: "0|1.0|2.0" (represents Default|Sensor.0|Preview)
    /// @param path         Dot '.' separated Path to the structure (or variable if valriable is nullptr) to set
    ///                     Example: cc14_ipr_v2.control_variables
    /// @param variable     Variable to get, if nullptr, path is used explicitly
    ///                     Example: control_var_type[2]
    /// @param value        Output Value string, comma separated list of array values
    /// @param size         Size of the Value string
    ///
    /// @return True value was found and set
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual bool GetValue(
        const CHAR* const modePath,
        const CHAR* const path,
        const CHAR* const variable,
        CHAR* const       value,
        UINT32 const      size) = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// SetValue
    ///
    /// @brief Sets the module value specified by the mode branch, and variable path
    ///
    /// @param modePath     Pipe '|' separated Mode path
    ///                     Example: "0|1.0|2.0" (represents Default|Sensor.0|Preview)
    /// @param path         Dot '.' separated stucture Path to the variable location
    ///                     Example: cc14_ipr_v2.control_variables
    /// @param variable     Variable to set
    ///                     Example: control_var_type[2]
    /// @param value        Value to set, will be parsed from string to the variable's type
    ///
    /// @return True value was found and set
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual bool SetValue(
        const CHAR* const modePath,
        const CHAR* const path,
        const CHAR* const variable,
        const CHAR* const value) = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetInfo
    ///
    /// @brief Returns information about a specific parameter, or returns the list of parameters from the specified path
    ///
    /// @param modePath     Pipe '|' separated Mode path. If nullptr, last accessed tuning mode branch will be used
    /// @param path         Dot '.' separated Path to the variable to set
    ///                     Example: cc14_ipr_v2.control_variables.control_var_type
    /// @param info         list of info
    ///
    /// @return True if the path was found
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual bool GetInfo(
        const CHAR* const           modePath,
        const CHAR* const           path,
        PList<ParameterParserInfo>& info) = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetActiveModes
    ///
    /// @brief Returns the currently active tuning mode branches
    ///
    /// @param path         Output Pipe '|' separated Mode path, multiple mode paths separated by a semi colon ';'
    /// @param pathSize     Size of path character array, recommended min size is MIN_PATH_SIZE, assuming 7 modes per branch
    ///                     times maximum number of active modes you would like
    ///
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual void GetActiveModes(
        CHAR* const  path,
        UINT32 const pathSize) = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetControlValues
    ///
    /// @brief Returns control values, or empty string if not applicable, or not set by the camera system code
    ///
    /// @param values     Output Value(s), string / comma separated list of <control index>:<control value> pairs
    /// @param size       Input size of the value char array
    ///
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual bool GetControlValues(
        CHAR* const  values,
        UINT32 const size) = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetTriggerValues
    ///
    /// @brief Returns Trigger values, or empty string if not applicable, or not set by the camera system code
    ///
    /// @param values   Output Value(s), string / comma separated list of <Trigger Enum Value>:<Trigger value> pairs
    /// @param size     Input size of the value char array
    ///
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual bool GetTriggerValues(
        CHAR* const  values,
        UINT32 const size) = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetChildModes
    ///
    /// @brief Returns The Mode Information from the given path.
    ///
    /// @param requestPath     Pipe '|' separated Mode path
    ///                        Example: "0|1.0|2.0" (represents Default|Sensor.0|Preview)
    /// @param responsePath    Comma ',' separated, and nul terminated child modes string
    ///                        Example: "1.0,1.1,1.2" (represents Preview,Snapshot,Video)
    /// @param responseSize    Size of the responsePath array
    ///
    /// @return Number of characters written including the nul terminator
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual UINT32 GetChildModes(
        const CHAR* requestPath,
        BYTE*       responsePath,
        UINT32      responseSize) = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetModeShorthand
    ///
    /// @brief Converts an EzTune mode path into a SetManager mode path
    ///
    /// @param input        Pipe '|' separated EzTune Mode path
    ///                     Example: "Default|Sensor.0|Usecase.Preview"
    /// @param output       Pipe '|' separated SetManager Mode path
    ///                     Example: "0|1.0|2.0" (represents Default|Sensor.0|Usecase.Preview)
    ///
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual void GetModeShorthand(
        const CHAR* input,
        CHAR*       output,
        UINT32      length) = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// ~iEzTuneDataAccessAPI
    ///
    /// @brief Virtual destructor to satisfy compiler requirements
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual ~IParameterDataAPI() {};
};

#endif // PARAMETERUTILS_H
