/****************************************************************************
 * This file is part of the project AqHome.
 * AqHome (c) by 2024 Martin Preuss, all rights reserved.
 *
 * The license for this file can be found in the file COPYING which you
 * should have received along with this file.
 ****************************************************************************/

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif


#include "./dataobject_p.h"

#include <gwenhywfar/list.h>
#include <gwenhywfar/debug.h>



GWEN_LIST_FUNCTIONS(AQHREACT_DATAOBJECT, AQHREACT_DataObject)




AQHREACT_DATAOBJECT *AQHREACT_DataObject_new()
{
  AQHREACT_DATAOBJECT *dataObject;

  GWEN_NEW_OBJECT(AQHREACT_DATAOBJECT, dataObject);
  dataObject->_refCount=1;
  GWEN_LIST_INIT(AQHREACT_DATAOBJECT, dataObject);
  return dataObject;
}



void AQHREACT_DataObject_free(AQHREACT_DATAOBJECT *dataObject)
{
  if (dataObject) {
    if (dataObject->_refCount==1) {
      GWEN_LIST_FINI(AQHREACT_DATAOBJECT, dataObject);
      free(dataObject->systemValueId);
      free(dataObject->valueUnits);
      free(dataObject->stringData);
      dataObject->_refCount=0;
      GWEN_FREE_OBJECT(dataObject);
    }
    else if (dataObject->_refCount<1) {
      DBG_ERROR(NULL, "dataobject already freed!");
    }
    else
      dataObject->_refCount--;
  }
}



AQHREACT_DATAOBJECT *AQHREACT_DataObject_dup(const AQHREACT_DATAOBJECT *origObject)
{
  if (origObject) {
    AQHREACT_DATAOBJECT *dataObject;

    dataObject=AQHREACT_DataObject_new();
    dataObject->valueId=origObject->valueId;
    AQHREACT_DataObject_SetSystemValueId(dataObject, origObject->systemValueId);
    AQHREACT_DataObject_SetValueUnits(dataObject, origObject->valueUnits);
    dataObject->timestamp=origObject->timestamp;
    dataObject->dataType=origObject->dataType;
    dataObject->doubleData=origObject->doubleData;
    dataObject->intData=origObject->intData;
    AQHREACT_DataObject_SetStringData(dataObject, origObject->stringData);
    return dataObject;
  }
  else
    return NULL;
}



uint64_t AQHREACT_DataObject_GetValueId(const AQHREACT_DATAOBJECT *dataObject)
{
  return dataObject?(dataObject->valueId):0;
}



void AQHREACT_DataObject_SetValueId(AQHREACT_DATAOBJECT *dataObject, uint64_t i)
{
  if (dataObject)
    dataObject->valueId=i;
}



const char *AQHREACT_DataObject_GetSystemValueId(const AQHREACT_DATAOBJECT *dataObject)
{
  return dataObject?(dataObject->systemValueId):NULL;
}



void AQHREACT_DataObject_SetSystemValueId(AQHREACT_DATAOBJECT *dataObject, const char *s)
{
  if (dataObject) {
    free(dataObject->systemValueId);
    dataObject->systemValueId=(s && *s)?strdup(s):NULL;
  }
}



const char *AQHREACT_DataObject_GetValueUnits(const AQHREACT_DATAOBJECT *dataObject)
{
  return dataObject?(dataObject->valueUnits):NULL;
}



void AQHREACT_DataObject_SetValueUnits(AQHREACT_DATAOBJECT *dataObject, const char *s)
{
  if (dataObject) {
    free(dataObject->valueUnits);
    dataObject->valueUnits=(s && *s)?strdup(s):NULL;
  }
}



uint64_t AQHREACT_DataObject_GetTimestamp(const AQHREACT_DATAOBJECT *dataObject)
{
  return dataObject?(dataObject->timestamp):0;
}



void AQHREACT_DataObject_SetTimestamp(AQHREACT_DATAOBJECT *dataObject, uint64_t i)
{
  if (dataObject)
    dataObject->timestamp=i;
}



int AQHREACT_DataObject_GetDataType(const AQHREACT_DATAOBJECT *dataObject)
{
  return dataObject?(dataObject->dataType):AQHREACT_DATAOBJECTTYPE_UNKNOWN;
}



void AQHREACT_DataObject_SetDataType(AQHREACT_DATAOBJECT *dataObject, int i)
{
  if (dataObject)
    dataObject->dataType=i;
}



double AQHREACT_DataObject_GetDoubleData(const AQHREACT_DATAOBJECT *dataObject)
{
  return dataObject?(dataObject->doubleData):0.0;
}



void AQHREACT_DataObject_SetDoubleData(AQHREACT_DATAOBJECT *dataObject, double i)
{
  if (dataObject)
    dataObject->doubleData=i;
}



const char *AQHREACT_DataObject_GetStringData(const AQHREACT_DATAOBJECT *dataObject)
{
  return dataObject?(dataObject->stringData):NULL;
}



void AQHREACT_DataObject_SetStringData(AQHREACT_DATAOBJECT *dataObject, const char *s)
{
  if (dataObject) {
    free(dataObject->stringData);
    dataObject->stringData=(s && *s)?strdup(s):NULL;
  }
}



int AQHREACT_DataObject_GetIntData(const AQHREACT_DATAOBJECT *dataObject)
{
  return dataObject?(dataObject->intData):0;
}



void AQHREACT_DataObject_SetIntData(AQHREACT_DATAOBJECT *dataObject, int i)
{
  if (dataObject)
    dataObject->intData=i;
}



const char *AQHREACT_DataObjectType_toString(int t)
{
  switch(t) {
  case AQHREACT_DATAOBJECTTYPE_DOUBLE: return "double";
  case AQHREACT_DATAOBJECTTYPE_STRING: return "string";
  case AQHREACT_DATAOBJECTTYPE_INT:    return "int";
  default:                             return "unknown";
  }
}



int AQHREACT_DataObjectType_fromString(const char *s)
{
  if (s && *s) {
    if (strcasecmp(s, "double")==0)
      return AQHREACT_DATAOBJECTTYPE_DOUBLE;
    else if (strcasecmp(s, "string")==0)
      return AQHREACT_DATAOBJECTTYPE_STRING;
    else if (strcasecmp(s, "int")==0)
      return AQHREACT_DATAOBJECTTYPE_INT;
  }

  return AQHREACT_DATAOBJECTTYPE_UNKNOWN;
}



void AQHREACT_DataObject_Dump(const AQHREACT_DATAOBJECT *dataObject, GWEN_BUFFER *buf, int indent)
{
  if (dataObject && buf) {
    const char *sVarSystemId;

    sVarSystemId=AQHREACT_DataObject_GetSystemValueId(dataObject);

    if (indent)
      GWEN_Buffer_FillWithBytes(buf, ' ', indent);

    switch(dataObject->dataType) {
    case AQHREACT_DATAOBJECTTYPE_DOUBLE:
      GWEN_Buffer_AppendArgs(buf, "%f (DOUBLE) [%s]\n", AQHREACT_DataObject_GetDoubleData(dataObject), sVarSystemId?sVarSystemId:"");
      break;
    case AQHREACT_DATAOBJECTTYPE_STRING:
      GWEN_Buffer_AppendArgs(buf, "%s (STRING) [%s]\n", AQHREACT_DataObject_GetStringData(dataObject), sVarSystemId?sVarSystemId:"");
      break;
    case AQHREACT_DATAOBJECTTYPE_INT:
      GWEN_Buffer_AppendArgs(buf, "%d (INT) [%s]\n", AQHREACT_DataObject_GetIntData(dataObject), sVarSystemId?sVarSystemId:"");
      break;
    default:
      break;
    }
  }
}





