/*
  dtostrf - Emulation for dtostrf function from avr-libc
  Copyright (c) 2015 Arduino LLC.  All rights reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include <stdio.h>

char *dtostrf (float val, signed char width, unsigned char prec, char *sout) {
  asm(".global _printf_float");

  if(prec>20) return;
  uint8_t fu;
  if(val<0){ 
    fu = 1;
    val = -val;
  }
  else fu = 0;

  uint32_t _prec = pow(10,prec);
  
  int64_t number_int = floor(val);
  int64_t number_fl = round((val - number_int) * _prec);

  char buf_int[30], buf_fl[30];
  if(fu == 1 )
    sprintf(buf_int, "-%ld", number_int);
  else
    sprintf(buf_int, "%ld", number_int);
  switch(prec)
  {
    case 0: sprintf(buf_fl, ""); break;
    case 1: sprintf(buf_fl, ".%01ld", number_fl); break;
    case 2: sprintf(buf_fl, ".%02ld", number_fl); break;
    case 3: sprintf(buf_fl, ".%03ld", number_fl); break;
    case 4: sprintf(buf_fl, ".%04ld", number_fl); break;
    case 5: sprintf(buf_fl, ".%05ld", number_fl); break;
    case 6: sprintf(buf_fl, ".%06ld", number_fl); break;
    case 7: sprintf(buf_fl, ".%07ld", number_fl); break;
    case 8: sprintf(buf_fl, ".%08ld", number_fl); break;
    case 9: sprintf(buf_fl, ".%09ld", number_fl); break;
    case 10: sprintf(buf_fl, ".%10ld", number_fl); break;
    case 11: sprintf(buf_fl, ".%11ld", number_fl); break;
    case 12: sprintf(buf_fl, ".%12ld", number_fl); break;
    case 13: sprintf(buf_fl, ".%13ld", number_fl); break;
    case 14: sprintf(buf_fl, ".%14ld", number_fl); break;
    case 15: sprintf(buf_fl, ".%15ld", number_fl); break;
    case 16: sprintf(buf_fl, ".%16ld", number_fl); break;
    case 17: sprintf(buf_fl, ".%17ld", number_fl); break;
    case 18: sprintf(buf_fl, ".%18ld", number_fl); break;
    case 19: sprintf(buf_fl, ".%19ld", number_fl); break;
    case 20: sprintf(buf_fl, ".%20ld", number_fl); break;
  }

  strcpy(sout, buf_int);
  strcat(sout, buf_fl);

  return sout;
}

char *dtostrd (double val, signed char width, unsigned char prec, char *sout) {
  asm(".global _printf_float");

  if(prec>20) return;
  uint8_t fu;
  if(val<0){ 
    fu = 1;
    val = -val;
  }
  else fu = 0;

  uint32_t _prec = pow(10,prec);
  
  int64_t number_int = floor(val);
  int64_t number_fl = round((val - number_int) * _prec);

  char buf_int[30], buf_fl[30];
  if(fu == 1 )
    sprintf(buf_int, "-%ld", number_int);
  else
    sprintf(buf_int, "%ld", number_int);
  switch(prec)
  {
    case 0: sprintf(buf_fl, ""); break;
    case 1: sprintf(buf_fl, ".%01ld", number_fl); break;
    case 2: sprintf(buf_fl, ".%02ld", number_fl); break;
    case 3: sprintf(buf_fl, ".%03ld", number_fl); break;
    case 4: sprintf(buf_fl, ".%04ld", number_fl); break;
    case 5: sprintf(buf_fl, ".%05ld", number_fl); break;
    case 6: sprintf(buf_fl, ".%06ld", number_fl); break;
    case 7: sprintf(buf_fl, ".%07ld", number_fl); break;
    case 8: sprintf(buf_fl, ".%08ld", number_fl); break;
    case 9: sprintf(buf_fl, ".%09ld", number_fl); break;
    case 10: sprintf(buf_fl, ".%10ld", number_fl); break;
    case 11: sprintf(buf_fl, ".%11ld", number_fl); break;
    case 12: sprintf(buf_fl, ".%12ld", number_fl); break;
    case 13: sprintf(buf_fl, ".%13ld", number_fl); break;
    case 14: sprintf(buf_fl, ".%14ld", number_fl); break;
    case 15: sprintf(buf_fl, ".%15ld", number_fl); break;
    case 16: sprintf(buf_fl, ".%16ld", number_fl); break;
    case 17: sprintf(buf_fl, ".%17ld", number_fl); break;
    case 18: sprintf(buf_fl, ".%18ld", number_fl); break;
    case 19: sprintf(buf_fl, ".%19ld", number_fl); break;
    case 20: sprintf(buf_fl, ".%20ld", number_fl); break;
  }

  strcpy(sout, buf_int);
  strcat(sout, buf_fl);

  return sout;
}
