/* This file contains the implementation for class Year.

------------------------------------------------------------------*/

#include "Year.h"

/*-----------------------------------------------------------------
   This function overloads the assignment operator for Year values.

   Receive: YearExp, the Year value being assigned
   Return:  The Year object with its data member set equal
              to the data member in YearExp
------------------------------------------------------------------*/

Year& Year::operator=(const Year& YearExp)
{
   YearValue_ = YearExp.YearValue_;  // set YearValue_ member in this
                                     //   object to that in YearExp
   return *this;                     // return this object
}

/*-----------------------------------------------------------------
   This function (destructively) prefix-increments a Year object.

   Return:  The Year object containing this function,
              with YearValue changed to the next value
------------------------------------------------------------------*/

Year Year::operator++(void)
{
  switch(YearValue_)            // change YearValue to its successor
  {
    case Freshman:
      YearValue_ = Sophomore;
      break;
    case Sophomore:
      YearValue_ = Junior;
      break;
    case Junior:
      YearValue_ = Senior;
      break;
    case Senior:
      YearValue_ = Graduate;
      break;
    default:
      cerr << "*** ++: erroneous Year value received!\n";
  }
  return *this;
}

/*----------------------------------------------------------------
   This function (destructively) postfix-increments a Year object.

   Return:  The Year object containing this function,
            with YearValue changed to the next value.
-----------------------------------------------------------------*/

Year Year::operator++(int)
{
  switch(YearValue_)            // change YearValue to its successor
  {
    case Freshman:
      YearValue_ = Sophomore;
      return Freshman;
    case Sophomore:
      YearValue_ = Junior;
      return Sophomore;
    case Junior:
      YearValue_ = Senior;
      return Junior;
    case Senior:
      YearValue_ = Graduate;
      return Senior;
    case Graduate:
      YearValue_ = YearOverflow;
      return Graduate;
    default:
      cerr << "*** ++: erroneous Year value received!\n";
      return YearOverflow;
  }
}

/*-----------------------------------------------------------------
   This function (nondestructively) returns the day after its
      Year object, wrapping around from Saturay to Sunday.

   Return:  The Year value that follows the value of this
            Year object.
------------------------------------------------------------------*/

Year Year::Next(void) const
{
  switch(YearValue_)     // return the YearName that follows YearValue_
  {
    case Freshman:
      return Sophomore;
    case Sophomore:
      return Junior;
    case Junior:
      return Senior;
    case Senior:
      return Graduate;
    case Graduate:
      return Freshman;   // ...wrapping around for the last YearName
    default:
      cerr << "*** Next: erroneous Year value received!\n";
      return YearOverflow;
  }
}

ostream& operator<< (ostream& Out, const Year& OutYear)
{
   const char
      ErrorMsg[] = "\n*** <<: invalid Year value received!\n";

   switch (OutYear.YearValue_)
   {
      case Freshman:       Out << "Freshman";
                           break;
      case Sophomore:      Out << "Sophomore";
                           break;
      case Junior:         Out << "Junior";
                           break;
      case Senior:         Out << "Senior";
                           break;
      case Graduate:       Out << "Graduate";
                           break;
      case YearOverflow:   Out << "Year Overflow";
                           break;
      case YearUnderflow:  Out << "Year Underflow";
                           break;
      default:
                           cerr << ErrorMsg;
   }

   return Out;
}

#include "Strings.h"
#include <ctype.h>

istream& operator>> (istream& In, Year& InYear)
{
   Strings
      Str;                                // the input string
   const char
      ErrorMsg[] = "\n*** >>: invalid Year value received!\n";

   In >> Str;                             // 1. Input the string

   for (int i = 0; i < Str.Length(); i++) // 2. Convert it
      if (isupper(Str[i]))                //      to lowercase
         Str[i] = tolower(Str[i]);

   if (Str == "freshman")                 // 3. Set YearVal  to the
      InYear.YearValue_ = Freshman;       //      value corresponding
   else if (Str == "sophomore")           //      to the string Str
      InYear.YearValue_ = Sophomore;
   else if (Str == "junior")
      InYear.YearValue_ = Junior;
   else if (Str == "senior")
      InYear.YearValue_ = Senior;
   else if (Str == "graduate")
      InYear.YearValue_ = Graduate;
   else
   {
      InYear.YearValue_ = YearOverflow;   // Return error value
      cerr << ErrorMsg;                   // Display error msg
   }

   return In;                             // 4. return In
}

// ... remaining definitions are left as exercises ...

