#include "PayloadFormatter.h"

PayloadFormatter::PayloadFormatter(uint8_t numOfRow, uint8_t numOfColumn) : _totalPayloads(0), _currentPayload(0), _numOfRow(numOfRow), _numOfColumn(numOfColumn), _payload(NULL), _length(0)
{
  _length = (numOfRow * numOfColumn * 2)/* x2 car il faut deux octets pour une température*/ + 7/*pour la date, le numero de trame et le nombre de lignes et de colonnes*/ + 1/*pour le charactère de fin de ligne*/ + 2/*pour la température exterieure*/;
  _payload = (uint8_t *) calloc(_length, sizeof(uint8_t));
}

PayloadFormatter::~PayloadFormatter()
{
  free(_payload);
}

void PayloadFormatter::startSession(uint8_t totalPayloads)
{
  _totalPayloads = totalPayloads;
  _currentPayload = 0;
}

boolean PayloadFormatter::endSession()
{
  boolean ret = _currentPayload == _totalPayloads;
  if(ret)_totalPayloads = 0;
  
  return ret;
}

int16_t PayloadFormatter::buildPayload(uint8_t **buffer, DateTime *dateTime, double externTemp, double *tempArray, uint8_t numOfRow, uint8_t numOfColumn)
{
  *buffer = _payload;
  if(_currentPayload == _totalPayloads || !_totalPayloads)
  {
      *_payload = '\0';
      return 0;
  }
    
  _currentPayload++;

  //Octet avec nombre de trames et numero de la trame
  _payload[0] = _totalPayloads;
  _payload[0] &= 0x0F;//Permet  de mettre à 0 les overflow
  _payload[0] |= _currentPayload << 4;

  //Octet avec nombre de ligne et nombre de colonne de capteurs
  _payload[1] = _numOfRow;
  _payload[1] &= 0x0F;//Permet  de mettre à 0 les overflow
  _payload[1] |= _numOfColumn << 4;

  //5 octets de dates
  _payload[2] = dateTime->year() - 2000;
  _payload[3] = dateTime->month();
  _payload[4] = dateTime->day();
  _payload[5] = dateTime->hour();
  _payload[6] = dateTime->minute();

  //Octets 7 et 8 pour la température extérieure
  //Format Q10.6
  int16_t q10_6_extern = round(externTemp * pow(2,6));
  _payload[7] = q10_6_extern >> 8;
  _payload[8] = q10_6_extern;
  
  //Partie temperature interne
  for(int i(9),j(0); j < (_numOfRow * _numOfColumn); i+=2, j++)
  {
    //Format Q10.6
    int16_t q10_6 = round(tempArray[j] * pow(2,6));
    
    _payload[i] = q10_6 >> 8;
    _payload[i+1] = q10_6;

  }

  _payload[_length-1] = '\0';
  return _length - 1;
}
