//******************************************************************
// IMPLEMENTATION FILE (datetype.cpp)
// This file implements the DateType member functions
//******************************************************************
#include "datetype.h"
#include <iostream>

using namespace std;

// Private members of class:
//     int mo;
//     int day;
//     int yr;

int DaysInMonth( int, int );  // Prototype for auxiliary function

//******************************************************************

DateType::DateType()

// Constructor

// Postcondition:
//     mo == 1  &&  day == 1  &&  yr == 1583

{
    mo = 1;
    day = 1;
    yr = 1583;
}

//******************************************************************

void DateType::Set( /* in */ int newMonth,
                    /* in */ int newDay,
                    /* in */ int newYear  )

// Precondition:
//     1 <= newMonth <= 12
//  && 1 <= newDay <= maximum no. of days in month newMonth
//  && newYear > 1582
// Postcondition:
//     mo == newMonth  &&  day == newDay  &&  yr == newYear

{
    mo = newMonth;
    day = newDay;
    yr = newYear;
}

//******************************************************************

int DateType::Month() const

// Postcondition:
//     Function value == mo

{
    return mo;
}

//******************************************************************

int DateType::Day() const

// Postcondition:
//     Function value == day

{
    return day;
}

//******************************************************************

int DateType::Year() const

// Postcondition:
//     Function value == yr

{
    return yr;
}

//******************************************************************

void DateType::Print() const

// Postcondition:
//     Date has been output in the form
//        month day, year
//     where the name of the month is printed as a string

{
    switch (mo)
    {
        case 1 : cout << "January";
                 break;
        case 2 : cout << "February";
                 break;
        case 3 : cout << "March";
                 break;
        case 4 : cout << "April";
                 break;
        case 5 : cout << "May";
                 break;
        case 6 : cout << "June";
                 break;
        case 7 : cout << "July";
                 break;
        case 8 : cout << "August";
                 break;
        case 9 : cout << "September";
                 break;
        case 10 : cout << "October";
                  break;
        case 11 : cout << "November";
                  break;
        case 12 : cout << "December";
    }
    cout << ' ' << day << ", " << yr;
}

//******************************************************************

RelationType DateType::ComparedTo(
                         /* in */ DateType otherDate ) const

// Postcondition:
//     Function value == BEFORE, if this date is
//                               before otherDate
//                    == SAME, if this date equals otherDate
//                    == AFTER, if this date is
//                              after otherDate

{
    if (yr < otherDate.yr)            // Compare years
        return BEFORE;
    if (yr > otherDate.yr)
        return AFTER;

    if (mo < otherDate.mo)            // Years are equal. Compare
        return BEFORE;                //   months
    if (mo > otherDate.mo)
        return AFTER;

    if (day < otherDate.day)          // Years and months are equal.
        return BEFORE;                //   Compare days
    if (day > otherDate.day)
        return AFTER;

    return SAME;                      // Years, months, and days
}                                     //   are equal

//******************************************************************

void DateType::Increment()

// Postcondition:
//     Date has been advanced by one day

{
    day++;
    if (day > DaysInMonth(mo, yr))
    {
        day = 1;
        mo++;
        if (mo > 12)
        {
            mo = 1;
            yr++;
        }
    }
}

//******************************************************************

int DaysInMonth( /* in */ int month,
                 /* in */ int year  )

// Returns the number of days in month "month", taking
// leap year into account

// Precondition:
//     1 <= month <= 12  &&  year > 1582
// Postcondition:
//     Function value == number of days in month "month"

{
    switch (month)
    {
        case 1: case 3: case 5: case 7: case 8: case 10: case 12:
            return 31;
        case 4: case 6: case 9: case 11:
            return 30;
        case 2:   // It's February.  Check for leap year
            if ((year % 4 == 0 && year % 100 != 0) ||
                 year % 400 == 0)
                return 29;
            else
                return 28;
    }
}
