// ***********************************************************
//      Time24 class implementation
// ***********************************************************

#include <cstdlib>  // exit()
#include "simpletime24v2.h"

// Explicit-value constructor
// Initialize time data
// Precondition: h and m >= 0
Time24::Time24(int h, int m) : hour(h), minute(m)
{
   // Precondition check   
   if ((h < 0) || (m < 0))
   {
      cerr << "Time24 constructor: negative argument\n";
      exit(1);
   }  // end check

   // put hour and minute in correct range
   NormalizeTime();
}  // Explicit-value constructor

// Function: AddTime
// Add m minutes to the time
// Precondition: m >= 0
void Time24::AddTime(int m)
{
   // Precondition check   
   if (m < 0)
   {
      cerr << "Time24: negative argument\n";
      exit(1);
   }  // end check

   // add m to minute. minute may exceed 59, so normalize
   minute += m;
   NormalizeTime();
}  // end AddTime

// Function: Duration
// Returns the difference between this time and t
// Precondition: t is after current time
Time24 Time24::Duration(const Time24& t, bool & success) const
{
   // convert current time and time t to minutes
   int currTime = hour * 60 + minute;
   int tTime = t.hour * 60 + t.minute;

   // Precondition check
   if (tTime < currTime)
   {
      success = false;
      // create a dummy object to return
      return Time24();
   }
   else
   {
      success = true;
      // create an anonymous object as the return value
      // will be normalized automatically
      return Time24(0, tTime-currTime);
   }
}  // end Duration

// Function: ReadTime
// Input time in format <hour>:<minute>
// Precondition: hour and minute are not negative
void Time24::ReadTime(istream& in)
{
   char colonSeparator;

   in >> hour >> colonSeparator >> minute;

   // Precondition check   
   if ((hour < 0) || (minute < 0))
   {
      cerr << "Time24 ReadTime(): negative argument\n";
      exit(1);
   }  // end check

   // make sure hour and minute are in range
   NormalizeTime();
}  // end ReadTime

// Function: WriteTime
// Output time in the format <hour>:<minute>
void Time24::WriteTime(ostream& out) const
{
   out << (hour < 10 ? " " : "") << hour << ':'
       << (minute < 10 ? "0" : "") << minute;

}  // end WriteTime

// Function: GetHour
// Returns the hour
int Time24::GetHour() const
{
   return hour;
}  // end GetHour

// Function: GetMinute
// Returns the minute
int Time24::GetMinute() const
{
   return minute;
}  // end GetMinute

// Private Function: NormalizeTime
// Set minute and hour within their proper ranges
// Precondition: minute and hour are not negative (ensured by caller)
void  Time24::NormalizeTime()
{
   int extraHours = minute / 60;

   // set minute in range 0 to 59
   minute %= 60;

   // update hour. set in range 0 to 23
   hour = (hour + extraHours) % 24;
}  // end NormalizeTime
