#include <config.h>

#include <glib.h>
#include <glib/gi18n.h>

#include <string.h>

#include "e_date.h"

/*
  all this code comes from evolution
  - e-util.c
  - message-list.c
*/


static size_t
e_strftime (char            *s,
            size_t           max,
            const char      *fmt,
            const struct tm *tm)
{
#ifdef HAVE_LKSTRFTIME
  return strftime (s, max, fmt, tm);
#else
  char *c, *ffmt, *ff;
  size_t ret;

  ffmt = g_strdup (fmt);
  ff = ffmt;
  while ((c = strstr (ff, "%l")) != NULL)
    {
      c[1] = 'I';
      ff = c;
    }

  ff = ffmt;
  while ((c = strstr (ff, "%k")) != NULL)
    {
      c[1] = 'H';
      ff = c;
    }

  ret = strftime (s, max, ffmt, tm);
  g_free (ffmt);
  return ret;
#endif
}


/**
 * Function to do a last minute fixup of the AM/PM stuff if the locale
 * and gettext haven't done it right. Most English speaking countries
 * except the USA use the 24 hour clock (UK, Australia etc). However
 * since they are English nobody bothers to write a language
 * translation (gettext) file. So the locale turns off the AM/PM, but
 * gettext does not turn on the 24 hour clock. Leaving a mess.
 *
 * This routine checks if AM/PM are defined in the locale, if not it
 * forces the use of the 24 hour clock.
 *
 * The function itself is a front end on strftime and takes exactly
 * the same arguments.
 *
 * TODO: Actually remove the '%p' from the fixed up string so that
 * there isn't a stray space.
 **/

static size_t
e_strftime_fix_am_pm (char            *s,
                      size_t           max,
                      const char      *fmt,
                      const struct tm *tm)
{
  char buf[10];
  char *sp;
  char *ffmt;
  size_t ret;

  if (strstr (fmt, "%p") == NULL && strstr (fmt, "%P") == NULL)
    {
      /* No AM/PM involved - can use the fmt string directly */
      ret = e_strftime (s, max, fmt, tm);
    }
  else
    {
      /* Get the AM/PM symbol from the locale */
      e_strftime (buf, 10, "%p", tm);

      if (buf[0])
        {
          /**
           * AM/PM have been defined in the locale
           * so we can use the fmt string directly
           **/
          ret = e_strftime (s, max, fmt, tm);
        }
      else
        {
          /**
           * No AM/PM defined by locale
           * must change to 24 hour clock
           **/
          ffmt = g_strdup (fmt);
          for (sp = ffmt; (sp = strstr (sp, "%l")); sp++)
            /**
             * Maybe this should be 'k', but I have never
             * seen a 24 clock actually use that format
             **/
            sp[1] = 'H';
          for (sp = ffmt; (sp = strstr (sp, "%I")); sp++)
            sp[1] = 'H';
          ret = e_strftime (s, max, ffmt, tm);
          g_free (ffmt);
        }
    }
  return(ret);
}

static size_t
e_utf8_strftime_fix_am_pm (char            *s,
                           size_t           max,
                           const char      *fmt,
                           const struct tm *tm)
{
  size_t sz, ret;
  char *locale_fmt, *buf;

  locale_fmt = g_locale_from_utf8 (fmt, -1, NULL, &sz, NULL);
  if (!locale_fmt)
    return 0;

  ret = e_strftime_fix_am_pm (s, max, locale_fmt, tm);
  if (!ret)
    {
      g_free (locale_fmt);
      return 0;
    }

  buf = g_locale_to_utf8 (s, ret, NULL, &sz, NULL);
  if (!buf)
    {
      g_free (locale_fmt);
      return 0;
    }

  if (sz >= max)
    {
      char *tmp = buf + max - 1;
      tmp = g_utf8_find_prev_char (buf, tmp);
      if (tmp)
        sz = tmp - buf;
      else
        sz = 0;
    }
  memcpy (s, buf, sz);
  s[sz] = '\0';
  g_free (locale_fmt);
  g_free (buf);
  return sz;
}


static char *
filter_date (time_t date)
{
  time_t nowdate = time (NULL);
  time_t yesdate;
  struct tm then, now, yesterday;
  char buf[26];
  gboolean done = FALSE;

  if (date == 0)
    // xgettext: ? stands for unknown
    return g_strdup (_("?"));

  localtime_r (&date, &then);
  localtime_r (&nowdate, &now);
  if (then.tm_mday == now.tm_mday &&
      then.tm_mon == now.tm_mon &&
      then.tm_year == now.tm_year)
    {
      e_utf8_strftime_fix_am_pm (buf, 26, _("Today %l∶%M %p"), &then);
      done = TRUE;
    }
  if (!done)
    {
      yesdate = nowdate - 60 * 60 * 24;
      localtime_r (&yesdate, &yesterday);
      if (then.tm_mday == yesterday.tm_mday &&
          then.tm_mon == yesterday.tm_mon &&
          then.tm_year == yesterday.tm_year)
        {
          e_utf8_strftime_fix_am_pm (buf, 26, _("Yesterday %l∶%M %p"), &then);
          done = TRUE;
        }
    }
  if (!done)
    {
      int i;
      for (i = 2; i < 7; i++)
        {
          yesdate = nowdate - 60 * 60 * 24 * i;
          localtime_r (&yesdate, &yesterday);
          if (then.tm_mday == yesterday.tm_mday &&
              then.tm_mon == yesterday.tm_mon &&
              then.tm_year == yesterday.tm_year)
            {
              e_utf8_strftime_fix_am_pm (buf, 26, _("%a %l∶%M %p"), &then);
              done = TRUE;
              break;
            }
        }
    }
  if (!done)
    {
      if (then.tm_year == now.tm_year)
        e_utf8_strftime_fix_am_pm (buf, 26, _("%b %d %l∶%M %p"), &then);
      else
        e_utf8_strftime_fix_am_pm (buf, 26, _("%b %d %Y"), &then);
    }

  return g_strdup (buf);
}




char *
procman_format_date_for_display (time_t d)
{
  return filter_date (d);
}
