/* ++[ Machine Problem #2 ]++++++++++++++++++++++++++++++++++++++
   +                                                            +
   + Zaczek, Mariusz                                            +
   + CS 223 - Monday 11:00am - 1:00 pm                          +
   + 2/22/98                                                    +
   +                                                            +
   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */

/* Include declarations */
#include <iostream.h>
#include <string.h>
#include <ctype.h>
#include "date.h"

/* Declaration of constant arrays for the names of the months and the
   number of days for each particular month */
  const int SIZE = 13;  
  const char *month_names[SIZE] = {"", "Jan", "Feb", "Mar", "Apr", "May",
				     "Jun", "Jul", "Aug", "Sep", "Oct",
				     "Nov", "Dec"};
  const int days[SIZE] = {0, 31, 28, 31, 30, 31, 30, 
			     31, 31, 30 ,31, 30 ,31};
/* ++[  A  ]+++++++++++++++++++++++++++++++++++++++++++++++++++++
   +                                                            +
   + void Date::Date ()                                         +
   +                                                            +
   + Acts as the constructor.                                   +
   +                                                            +   
   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */

Date::Date() { };


/* ++[  B  ]+++++++++++++++++++++++++++++++++++++++++++++++++++++
   +								+ 
   + void Date::setDate (char m[4], int d, int y)		+
   +                                                            + 
   + Sets the date entered.					+
   +								+
   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */

void Date::setDate(char m[4], int d, int y)
{
  for(int i=0;i<4;i++)
    month[i]=m[i];
  day=d;
  year=y;
}


/* ++[  C  ]+++++++++++++++++++++++++++++++++++++++++++++++++++++
   +                                                            +
   + void Date::isValid()			                +
   +                                                            +
   + Determines if the date entered is a valid date.		+
   +                                                            +
   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ 

int Date::isValid()   
{
  int month_index = whichmonth();

  if (isleapyear() && (month_index == 2) && (day > 0) && (day <= 29))
    return 1;
  else if ((month_index > 0) && (day > 0) && (day <= days[month_index]))
    return 1;
  else
    return 0;
}
  

/* ++[  D  ]+++++++++++++++++++++++++++++++++++++++++++++++++++++
   +                                                            +
   + void Date::isleapyear()					+
   +                                                            +
   + Determines if the year entered is a leap year.		+
   +                                                            +
   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ 

int Date::isleapyear()
{
  if (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0))
    return 1;
  else
    return 0;
}


/* ++[  E  ]+++++++++++++++++++++++++++++++++++++++++++++++++++++
   +                                                            +
   + void Date::whichmonth()                                    +
   +                                                            +
   + Determines if the month entered is a valid month and if so +
   + it returns the position of this month in the month array   +
   + otherwise it returns a ( 0 ) to the main program thus 	+
   + signifying an error.					+
   +                                                            +
   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */

int Date::whichmonth()
{
  for(int j=0;j<SIZE;j++)
    if (strcmp(month,month_names[j]) == 0)
      return j;
      
  return 0;
}
 

/* ++[  F  ]+++++++++++++++++++++++++++++++++++++++++++++++++++++
   +                                                            +
   + void Date::addDays(int number)                             +
   +                                                            +
   + This function performs the incrementing of the original    +
   + date to a final date based on the value of number. This    +
   + function must perform checking of leap years, month and    +
   + year changes, etc.						+
   +                                                            +
   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */

void Date::addDays(int number)
{
  int month_number = whichmonth();
  int max_days;

  /* Add number to days */
  day += number;
  
  /* Determine initial max_days variable */
  if ((month_number == 2) && isleapyear())
    max_days = 29;
  else
    max_days = days[month_number];

  /* Loop until the number (day) is less than or equal to the number of
     maximum days allowed in the current month */
  while (day > max_days)
  {
    day -= max_days;
    
    /* If the month is December then increase the month to January,
       set the maximum days to 31 (corresponding to January) and 
       increase the year by 1 */
    if(month_number == 12)
    {
      month_number = 1;
      max_days = 31;
      year++;
    }
    /* If the month is January increase the month to February but 
       determine the number of maximum days in that month based on
       whether or not the current year is a leap year */
    else if (month_number == 1)
    {
      month_number = 2;
      if (isleapyear())
        max_days = 29;
      else
        max_days = 28;
    }
    /* Otherwise simply increase the month number and determine the
       maximum number of days allowed in that month */
    else
    {
      month_number++;
      max_days = days[month_number];
    }
  }
 
  /* Declare new_month string and then copy the month name to is */
  char new_month[4];
  strcpy(new_month, month_names[month_number]);

  /* Set the new month, day and year */
  setDate(new_month,day,year);

  return;
}
 

/* ++[  G  ]+++++++++++++++++++++++++++++++++++++++++++++++++++++
   +                                                            +
   + void Date::printDate()                                     +
   +                                                            +
   + This function outputs the final date.			+
   +                                                            +
   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */

void Date::printDate()
{
  cout << month << " " << day << " " << year << endl;
  return;
}

