#include "utilities.h"

char *addChar(char *pointer, const char character)
{
    char *tempAddr = NULL;
    if(pointer == NULL)
    {
        tempAddr = (char *) realloc(pointer, 2*sizeof(char));
        if(tempAddr == NULL)
            return NULL;
        else
        {
            pointer = tempAddr;
            pointer[0] = character;
            pointer[1] = '\0';
        }
    }
    else
    {
        tempAddr = (char *) realloc(pointer, (strlen(pointer)+2)*sizeof(char));
        if(tempAddr == NULL)
        {
            free(pointer);
            return NULL;
        }
        else
        {
            pointer = tempAddr;
            pointer[strlen(pointer)+1] = '\0';
            pointer[strlen(pointer)] = character;
        }
    }

    return pointer;
}

char *dateTimeFormater(char *pointer, const uint8_t value, const char character)
{
  if(pointer == NULL)
    return pointer;

  if(value < 10)
  {
    sprintf(pointer,"%d", value);
    *(pointer+1) = *(pointer);*(pointer) = character;*(pointer+2) = '\0';
  }
  else
    sprintf(pointer,"%d", value);
  
  return pointer;
}

/**
 * The monthNumTo3LetterAbbreviation function takes the month number from 1 to 12 and returns the abbreviation in a 3 letter
 * format.
 */
uint32_t monthNumTo3LetterAbbreviation(const uint8_t monthNumber)
{
  /**
   * This array contains months as 3 letter abbreviations
   * Jan is written \0naJ and in hex : 0x006E614A an so on. They are thus 4Bytes aligned and easy to put and read back from prog mem :)
   */
  static const uint32_t PROGMEM monthArray[] = {0x6E614A, 0x626546, 0x72614D, 0x727041, 0x79614D, 0x6E754A, 0x6C754A, 0x677541, 0x706553, 0x74634F, 0x766f4E, 0x636544};
  uint32_t toReturn(0x6E614A); //Default to Jan.
  
  if(monthNumber >= 1 && monthNumber <= 12)
    toReturn = monthArray[monthNumber - 1];
    
  return toReturn;
}

void *mallocWithFallback(size_t requestedSize, size_t *acceptedSize)
{
  void *allocAddr(nullptr);
  uint32_t divider(1);
  
  do
  {
    requestedSize /= divider++;
    allocAddr = malloc(requestedSize);
  } while(!allocAddr && requestedSize >= 50); //If we can't even manage to malloc 50 bytes then we should give up and cry

  if(acceptedSize && allocAddr)*acceptedSize = requestedSize;
  else if(acceptedSize)*acceptedSize = 0;

  return allocAddr;
}