#include <Common.h>
#include <System/SysAll.h>
#include <UI/UIAll.h>
#include "MathLib.h"
#include "ConvStrToDbl.h"

/* prototypes. */
static int ConvStrToUInt(double*, char*, char**);


static int ConvStrToUInt(double* x, char* a, char** ptr)
{
  *ptr = a;
  *x = 0;
  
  if ((**ptr < '0') || (**ptr > '9')) return 1;
  while ((**ptr >= '0') && (**ptr <= '9')) {
    *x = *x * 10 + (*((*ptr)++) - '0');
  }
  return 0;
}


int ConvStrToDbl(double* x, char* a, char** ptr)
{
  double s = +1, f = 0, e = 0;
  int ret;
  char* end_ptr;

  *x = 0;
  *ptr = a;

  /* sign */
  if (**ptr == '-') {
    s = -1;
    (*ptr)++;
  } else if (**ptr == '+') {
    (*ptr)++;
  }

  /* integer part */
  ret = ConvStrToUInt(x, *ptr, &end_ptr);
  *ptr = end_ptr;

  if (ret == 0) {
    /* fraction part */
    if (**ptr == '.') {
      (*ptr)++;
      while (**ptr == '0') {
	(*ptr)++;
	e += 1.;
      }
      ret = ConvStrToUInt(&f, *ptr, &end_ptr);
      *ptr = end_ptr;
      if (ret == 0) {
	f = f / (pow(10, (floor(log10(f)) + 1) + e));
	*x += f;
      }
    }
  } else {
    /* fraction part without integer part */
    if (**ptr != '.') return 1;
    (*ptr)++;
    while (**ptr == '0') {
      (*ptr)++;
      e += 1.;
    }
    ret = ConvStrToUInt(&f, *ptr, &end_ptr);
    *ptr = end_ptr;
    if (ret != 0) return 1;
    f = f / (pow(10, (floor(log10(f)) + 1) + e));
    *x += f;
  }
  *x *= s;

  /* exponent part */
  if ((**ptr == 'e') || (**ptr == 'E')) {
    (*ptr)++;

    s = +1;
    if (**ptr == '-') {
      s = -1;
      (*ptr)++;
    } else if (**ptr == '+') {
      (*ptr)++;
    }

    ret = ConvStrToUInt(&f, *ptr, &end_ptr);
    *ptr = end_ptr;
    if (ret != 0) return 1;
    f *= s;
    *x *= pow(10, f);
  }

  return 0;
}
