#include <vo_stdio.h>
#include <volink.h>     // Linker directives like DLLENTRY
#include <apploader.h>  // RunLibraryFunction etc
#include <string.h>
#include <mutex.h>
#include <kernel.h>
#include <stdlib.h>
#include <timers.h>
#include <audio.h>
#include "time.h"
#include "rtc.h"




ioresult SetDate(register char *p, register s_int16 nParam) {
  int set = 0;
  int i;
  time_t tim = time(NULL);
  struct tm *tm = localtime(&tim);
  ioresult res = S_ERROR;

  while (nParam--) {
    char *setMon=NULL;
    int setTim=0;
    int len = strlen(p);
    if (len == 10 && p[4] == '-' && p[7] == '-')  {
      tm->tm_year = -1900;
      setMon = p+5;
    } else if (len == 8 && p[2] == '-' && p[5] == '-')  {
      tm->tm_year = 100;
      setMon = p+3;
    } else if (len == 8 && p[2] == ':' && p[5] == ':')  {
      tm->tm_sec = atoi(p+6);
      setTim = 1;
    } else if (len == 5 && p[2] == ':')  {
      tm->tm_sec = 0;
      setTim = 1;
    } else {
      printf("E: Malformed parameter \"%s\"\n", p);
      goto finally;
    }

    if (setMon) {
      tm->tm_year += atoi(p+0);
      tm->tm_mon = atoi(setMon)-1;
      tm->tm_mday = atoi(setMon+3);
      set |= 1;
    }

    if (setTim) {
      tm->tm_hour = atoi(p+0);
      tm->tm_min = atoi(p+3);
      set |= 2;
    }

    p += strlen(p)+1;
  }

  if (set) {
    u_int32 t = (u_int32)mktime(tm);
    if (tim < 0 && set < 3) {
      printf("E: RTC not set. You need to set both date and time!\n");
      goto finally;
    }
    if (SetRtc(t) != t) {
      printf("E: RTC not found. Check RTC battery!\n");
      goto finally;
    }
  }

  res = S_OK;
 finally:
  return res;
}





#if 0
char *wday[7] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};

void PrintTime(time_t tt) {
  struct tm *tm = localtime(&tt);
  printf("  %04d-%02d-%02d at %02d:%02d:%02d, d=%s, yd=%d, dst=%d\n",
	 tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
	 tm->tm_hour, tm->tm_min, tm->tm_sec,
	 wday[tm->tm_wday], tm->tm_yday, tm->tm_isdst);
}
#endif



DLLENTRY(main)
ioresult main(char *parameters) {
  int nParam = RunProgram("ParamSpl", parameters);
  char *p = parameters;
  int autoPrint = 1;
  int i, res = S_ERROR;
  int set = 0;
  static char s[256];
  time_t tim = time(NULL);
  struct tm *tm = localtime(&tim);

  if (!strcmp(p, "-s")) {
    res = SetDate(p+3, nParam-1);
    goto finally;
  }

  /* If not help or set mode... */
  if (strcmp(p, "-h")) {
    if (tim == TIME_NOT_FOUND) {
      printf("ERROR! Could not find RTC!\n"
	     "Please check that you have put an LR44 battery to the\n"
	     "BATT1 connector on the VS1005g developer board, or\n"
	     "otherwise powered RTC!\n");
      goto finally;
    } else if (tim == TIME_NOT_SET) {
      printf("ERROR! RTC not set. Please run Date -s YY-MM-DD HH:MM:SS\n"
	     "or C function SetRtc() (e.g. SetRtc(mktime(tm))) to set RTC!\n");
      goto finally;
    }
  }

  for (i=0; i<nParam; i++) {
    if (!strcmp(p, "-h")) {
      printf("Usage: Date [formatString] [-t|-q|-h]\n"
	     "       Date -s [[YY]YY-MM-DD|HH:MM[:SS]]\n"
	     "-t\tPrint uptime\n"
	     "-q\tQuiet mode\n"
	     "-h\tShow this help\n"
	     "-s\tSet date and/or time\n\n"
	     "FormatString:\n"
	     "%%a wdayName   %%A weekdayName   %%b monName    %%B monthName\n"
	     "%%c date&time  %%d dayOfMonth    %%H hour-24    %%h hour-12\n"
	     "%%j dayOfYear  %%m month         %%M minute     %%p AM/PM\n"
	     "%%S second     %%w weekDay,S=0   %%x date       %%X time\n"
	     "%%y yr         %%Y year          %%Z UTC        %%%% %%\n\n"
	     "[YY]YY-MM-DD\tSet date, e.g. 2019-05-13 or 19-05-13\n"
	     "HH:MM[:SS]\tSet time, e.g. 12:34:56 or 12:34\n"
	     );
      res = S_OK;
      goto finally;
    } else if (!strcmp(p, "-q")) {
      res = S_OK;
      goto finally;
    } else if (!strcmp(p, "-t")) {
      if (!autoPrint) {
	putchar(' ');
      }
      printf("%5.3fs", ReadTimeCount()*0.001);
      autoPrint = 0;
    } else {
      if (!autoPrint) {
	putchar(' ');
      }
      strftime(s, 256, p, localtime(&tim));
      fputs(s, stdout);
      autoPrint = 0;
    }
    p += strlen(p)+1;
  }

  if (autoPrint) {
    strftime(s, 256, "%c", localtime(&tim));
    puts(s);
  } else {
    putchar('\n');
  }

  res = S_OK;
 finally:
  return res;
}
