/*
 * SPDX-FileCopyrightText: 2004 Copyright contributors to the cppTango project
 *
 * SPDX-License-Identifier: LGPL-3.0-or-later
 */

#ifndef TANGO_CLIENT_HELPERS_POGOHELPER_H
#define TANGO_CLIENT_HELPERS_POGOHELPER_H

#include <tango/common/defines.h>
#include <tango/server/Except.h>

//-----------------------------------------------------------------------------
//
// function to delete a scalar attribut : You must pass the pointer to the attributs
// Usage :         DELETE_SCALAR_ATTRIBUTE(attr_hCoordinate_read);

//-----------------------------------------------------------------------------
template <class _SCALAR>
void DELETE_SCALAR_ATTRIBUTE(_SCALAR *attributeName)

{
    if(attributeName)
    {
        delete attributeName;
        attributeName = 0;
    }
}

//=============================================================================
// function to allocate and initialise a read SCALAR attribute as generated by POGO
// Usage : ex : CREATE_SCALAR_ATTRIBUTE(attr_hCoordinate_read);
//=============================================================================
template <class _SCALAR>
void CREATE_SCALAR_ATTRIBUTE(_SCALAR *&attributeName, _SCALAR default_value = 0)
{
    attributeName = new _SCALAR;

    if(attributeName == 0)
    {
        TangoSys_OMemStream o;
        o << "[" << __FILE__ << "::" << __LINE__ << "]" << std::ends;
        Tango::Except::throw_exception(
            (const char *) "OUT OF MEMORY", (const char *) "out of memory error", (const char *) (o.str().c_str()));
    }
    // then initialise scalar
    (*attributeName) = (_SCALAR) default_value;
}

//=============================================================================
// function to allocate and initialise a DevString SCALAR attribute as generated by POGO
// Usage : ex : CREATE_DEVSTRING_ATTRIBUTE(attr_currentUMatrix_read,MAX_STRING_LENGTH,"No U Matrix available");
//=============================================================================
inline void CREATE_DEVSTRING_ATTRIBUTE(Tango::DevString *&attributeName, const int length, const char *init_string = "")
{
    attributeName = new char *;

    if(attributeName == 0)
    {
        TangoSys_OMemStream o;
        o << "[" << __FILE__ << "::" << __LINE__ << "]" << std::ends;
        Tango::Except::throw_exception(
            (const char *) "OUT OF MEMORY", (const char *) "out of memory error", (const char *) (o.str().c_str()));
    }

    // std::cout << length << std::endl;
    (*attributeName) = new char[length];
    if((*attributeName) == 0)
    {
        TangoSys_OMemStream o;
        o << "[" << __FILE__ << "::" << __LINE__ << "]" << std::ends;
        Tango::Except::throw_exception(
            (const char *) "OUT OF MEMORY", (const char *) "out of memory error", (const char *) (o.str().c_str()));
    }
    ::strcpy(*attributeName, init_string);
}

//-----------------------------------------------------------------------------
//
// function to delete a DevString attribut : You must pass the pointer to the attributs
// Usage :         DELETE_DEVSTRING_ATTRIBUTE(attr_currentUMatrix_read)

//-----------------------------------------------------------------------------
inline void DELETE_DEVSTRING_ATTRIBUTE(Tango::DevString *attributeName)
{
    if(attributeName)
    {
        if(*attributeName)
        {
            delete[](*attributeName);
        }
        delete attributeName;
        attributeName = 0;
    }
}

//=============================================================================
// function to allocate and initialise a read SPECTRUM attribute as generated by POGO
// Usage : ex : CREATE_SPECTRUM_ATTRIBUTE(attr_currentspectrum_read,MAX_LENGTH);
//=============================================================================
//
template <class _SPECTRUM>
void CREATE_SPECTRUM_ATTRIBUTE(_SPECTRUM *&attributeName, const int size, _SPECTRUM default_value = 0)
{
    attributeName = new _SPECTRUM[size];

    if(attributeName == 0)
    {
        TangoSys_OMemStream o;
        o << "[" << __FILE__ << "::" << __LINE__ << "]" << std::ends;
        Tango::Except::throw_exception(
            (const char *) "OUT OF MEMORY", (const char *) "out of memory error", (const char *) (o.str().c_str()));
    }
    std::fill(attributeName, attributeName + size, default_value);
}

//=============================================================================
// function to desallocate a read SPECTRUM attribute as generated by POGO
// Usage : ex : DELETE_SPECTRUM_ATTRIBUTE(attr_currentspectrum_read);
//=============================================================================
//
template <class _SPECTRUM>
void DELETE_SPECTRUM_ATTRIBUTE(_SPECTRUM *attributeName)
{
    if(attributeName)
    {
        delete[](attributeName);
    }
}

#endif
