/*
 * dates_1.c
 * This program reads a date and prints the dates of the days before and after
 * this date.
 */

#include <stdio.h>

struct Date
{
  int  day;
  int  month;
  int  year;
};

/* Prototypes: */
void print_date (struct Date date);
struct Date next_date (struct Date date);
struct Date prev_date (struct Date date);

int main ()
{
  int          dd, mm, yy;
  struct Date  date;
  struct Date  prev;
  struct Date  next;

  /* Read the date (no validity checks for now). */
  printf ("Please enter a date: ");
  scanf ("%d %d %d", &dd, &mm, &yy);

  /* Set the date. */
  date.day = dd;
  date.month = mm;
  date.year = yy;

  /* Compute the previous date and the next date. */
  prev = prev_date (date);
  next = next_date (date);

  /* Print out the results. */
  printf ("Yesterday was: ");
  print_date (prev);
  printf ("\n");

  printf ("Today is: ");
  print_date (date);
  printf ("\n");

  printf ("Tomorrow will be: ");
  print_date (next);
  printf ("\n");

  return (0);
}

/* ------------------------------------------------------------------------
 * Function: print_date
 * Purpose : Print a date in a nice format.
 * Input   : date - The date.
 * Returns : Nothing.
 */
void print_date (struct Date date)
{
  const char* month_names[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
                                 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};

  printf ("%d %s %d", date.day, month_names[date.month - 1], date.year);
  return;
}

/* ------------------------------------------------------------------------
 * Function: next_date
 * Purpose : Compute the next date.
 * Input   : date - The current date.
 * Returns : The date of the next day.
 */
struct Date next_date (struct Date date)
{
  int         days_in_month[12] = {31, 28, 31, 30, 31, 30, 
                                   31, 31, 30, 31, 30, 31};
  struct Date res = date;

  /* Increment the day and check whether the date is still legal. */
  res.day++;

  if (res.day > days_in_month[res.month - 1])
  {
    /* Move to the next month. */
    res.day = 1;
    res.month++;

    if (res.month > 12)
    {
      /* Move to the next year. */
      res.month = 1;
      res.year++;
    }
  }
  
  return (res);
}

/* ------------------------------------------------------------------------
 * Function: prev_date
 * Purpose : Compute the previous date.
 * Input   : date - The current date.
 * Returns : The date of the previous day.
 */
struct Date prev_date (struct Date date)
{
  int         days_in_month[12] = {31, 28, 31, 30, 31, 30, 
                                   31, 31, 30, 31, 30, 31};
  struct Date res = date;

  /* Decrement the day and check whether the date is still legal. */
  res.day--;

  if (res.day == 0)
  {
    /* Move to the previous month. */
    res.month--;

    if (res.month == 0)
    {
      /* Move to the previous year. */
      res.month = 12;
      res.year--;
    }

    /* Set the day to be the last of the month. */
    res.day = days_in_month[res.month - 1];
  }
  
  return (res);
}

