/*
 * dates_2.c
 * This program reads a date and prints the dates of the week after this date.
 */

#include <stdio.h>

#define DAYS_IN_WEEK 7

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

typedef struct _Date Date;

/* Prototypes: */
void print_date (const Date *p_date);
void next_date (const Date *p_date, Date *p_next);

int main ()
{
  int       dd, mm, yy;
  Date      date;
  Date      next_week[1 + DAYS_IN_WEEK];
  int       i;

  /* 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;

  next_week[0] = date;

  /* Compute the dates of the next week. */
  for (i = 0; i < DAYS_IN_WEEK; i++)
  {
    next_date (next_week + i, next_week + i + 1);
    /* Equivalent to: 
       next_date (&(next_week[i]), &(next_week[i + 1])); */
  }

  /* Print out the results. */
  for (i = 1; i <= DAYS_IN_WEEK; i++)
  {
    printf ("After %d day(s): ", i);
    print_date (next_week + i);
    printf ("\n");
  }

  return (0);
}

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

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

/* ------------------------------------------------------------------------
 * Function: next_date
 * Purpose : Compute the next date.
 * Input   : p_date - The current date.
 * Output  : p_next - The next date.
 * Returns : Nothing.
 */
void next_date (const Date *p_date, Date *p_next)
{
  int         days_in_month[12] = {31, 28, 31, 30, 31, 30, 
                                   31, 31, 30, 31, 30, 31};
  int         days_in_curr_month;

  /* Copy the current day. */
  *p_next = *p_date;

  /* Increment the day and check whether the date is still legal. */
  p_next->day++;
  days_in_curr_month = days_in_month[p_date->month - 1];

  if (p_date->month == 2)
  {
    /* February may have 28 or 29 days (in a leap year).
       It has 29 days if the year is divided by 4, but not by 100 or if it is
       divided by 400. */
    if ((p_date->year % 4 == 0) &&
        (p_date->year % 100 != 0 || p_date->year % 400 == 0))
    {
      days_in_curr_month++;
    }
  }

  if (p_next->day > days_in_curr_month)
  {
    /* Move to the next month. */
    p_next->day = 1;
    p_next->month++;

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

