//----------------------------------------------------------------------------
//
// \file    can_message.cpp
//
// \brief   A simple can message
//
// \date    20141229
// \author  Maximilian Seesslen <mes@seesslen.net>
//
//----------------------------------------------------------------------------


//---Includes-----------------------------------------------------------------


#include <lepto/can_message.h>
#include <lepto/time.h>             // timeStamp
#include <string.h>                 // memcpy
//#include <string>                 // memcpy

#if ! defined(STM32)
   #include <QDateTime>                 // secondsSinceEpoch
#endif

//---Implementation-----------------------------------------------------------

/*
const char *canMessageIdStrings[]=
{
   [eCanMessageIdNull]           ="NULL",

   [eCanMessageIdSetTime]           ="Set Time",
   [eCanMessageIdSendTemperature]   ="Send Temperature",
   [eCanMessageIdScan]   ="Scan for nodes",

   [eCanMessageIdMax]   ="MAX",
};
*/

#if ! defined( STM32 )
int globalCanMessage_cnt=0;
#endif

/*
/// \brief  Le contructeur
constexpr_nobug CCanMessage::CCanMessage()
      :CCanMessage(0)
{
   #if defined LEPTO_CAN_ORGLEN
      originExtended=false;
   #endif

   return;
}
*/

/*
/// \brief  Le contructeur
constexpr_nobug CCanMessage::CCanMessage(int id)
      :CCanMessage(id, 0, nullptr)
{
   #if defined LEPTO_CAN_ORGLEN
      originExtended=false;
   #endif

   return;
}
*/

/*
constexpr_nobug CCanMessage::CCanMessage(int id, int len, const void *data)
   :m_id(id)
   #if ! defined( STM32 )
   ,m_cnt(globalCanMessage_cnt++)
   #endif
   ,m_len{len}
   #if defined LEPTO_CAN_ORGLEN
   ,originExtended(false)
   #endif

   #if ! defined( STM32 )
   //,timeStamp(CTime::currentTimeStamp())
   ,timeStamp( QDateTime::currentSecsSinceEpoch() )
   #endif
{
   if(m_len)
   {
      memcpy(m_data, data, m_len);
   }
}
*/

/// \brief  Le contructeur
CCanMessage::~CCanMessage()
{
}


CCanMessage &CCanMessage::operator <<(char byte)
{
   if(m_len+1<8)
      m_data[m_len++]=byte;

   return(*this);
}


CCanMessage &CCanMessage::operator <<(int16_t value)
{
   if(m_len+2<8)
   {
      // At least CANopen is little endian. We stay with little endian.
      m_data[m_len++]=value&0xFF;
      m_data[m_len++]=(value>>8)&0xFF;
   }

   return(*this);
}


const char *CCanMessage::getIdString() const
{
   #if 0
   if(getId()> sizeof(canMessageIdStrings)/ sizeof(canMessageIdStrings[0]) )
      return("unknown");

   return(canMessageIdStrings[getId()]);
#else
   return("");
   #endif
}


/// \brief  Converts CAN-Message to AsciiZ-Escape-Code
/// \return length of string
int CCanMessage::convertToAscii(char *dest)
{
   int pos=0;
   dest[pos++]=27;
   dest[pos++]='#';
   dest[pos++]=isExtended()?1:0;
   dest[pos++]=0;
   dest[pos++]=0;
   dest[pos++]=0;
   *((canId_t*)(&dest[pos]))=getId();
   pos+=4;
   dest[pos++]=getLen();
   for(int i1=0; i1<getLen(); i1++)
   {
      dest[pos++]=at(i1);
   }
   dest[pos++]=';';
   dest[pos]=0;

   return(pos);
}


bool CCanMessage::fromAscii(const char *src)
{
   int pos=0;
   int len;

   #if defined LEPTO_CAN_ORGLEN
      setOriginExtended( (src[pos]&1)? true:false );
   #endif

   pos+=4;
   setId( *(int *)(&src[pos]) );
   pos+=4;
   len=src[pos++];
   setData(len, (unsigned char *)&src[pos]);
   pos+=len;

   return(true);
}


//----------------------------------------------------------------------------
