#include <iostream>
#include <string>
#include <sstream> // stringstream

using namespace std;

// class Time
// Goal: manage time with hour, min, seconds
// funtion: perform plus, minus, comparison....

class Time {
protected:
	// private member variable (Data)
	int h;	// 0~23
	int m;	// 0~59
	int s;	// 0~59

	// public member function
public:
	// Constructor
	Time() { h=m=s=0; }
	Time( int hour, int min, int sec );
	Time( int sec );

	// accessor (getter)
	int getHour() { return h; }
	int getMin() { return m; }
	int getSec() { return s; }

	// accessor (setter)
	void setHour( int hour ) { if( 0 <= hour && hour <= 23 ) h = hour; }
	void setMin( int min ) { if( 0 <= min && min <= 59 ) m = min; }
	void setSec( int sec ) { if( 0 <= sec && sec <= 59 ) s = sec; }

	void showTime();
	string toString();

	Time &operator++() { s++; return *this; }
	friend Time operator+( Time t1, Time t2 );
	friend bool operator==( Time t1, Time t2 ) 
	                 { return (t1.h==t2.h && t1.m==t2.m && t1.s == t2.s ); }
	
};

enum Zone {KST, EST};

class TimeZ : public Time
{
	Zone z;
public:
	TimeZ() : z(KST) {} 
	TimeZ( int hour, int min, int sec ) : Time(hour, min, sec), z(KST) {}
	TimeZ( int hour, int min, int sec, Zone zone ) : Time(hour, min, sec), z(zone) {}

	Zone getZone() { return z; }
	void set( int hour, int min, int sec, Zone zone ) { 
		Time::setHour(hour); setMin(min); setSec(sec); z = zone; }
	void setZone( Zone zone );
	string zoneString( Zone zone ) { return (zone==KST) ? "KST" : "EST"; }
	string toString() { return Time::toString()+" " + zoneString(z); }

	// operator overloading
	friend ostream &operator<<( ostream &out, TimeZ t );
	friend bool operator==( TimeZ t1, TimeZ t2 )
		 { return (t1.h==t2.h && t1.m==t2.m && t1.s == t2.s && t1.z == t2.z ); }
	friend TimeZ operator+( TimeZ t1, TimeZ t2 );
};

TimeZ operator+( TimeZ t1, TimeZ t2 )
{
	TimeZ t3;
	t2.setZone( t1.z );
	Time a1(t1.h, t1.m, t1.s);
	Time a2(t2.h, t2.m, t2.s);
	Time a3 = a1 + a2;
	t3.setHour( a3.getHour() );
	t3.setMin( a3.getMin() );
	t3.setSec( a3.getSec() );
	t3.setZone( t1.z );
	return t3;
}

ostream &operator<<( ostream &out, TimeZ t )
{
	out << t.toString();
	return out;
}

Time::Time(int hour, int min, int sec)
{
	s = ( 0 <= sec && sec <= 59 ) ? sec : -1;
	m = ( 0 <= min && min <= 59 ) ? min : -1;
	h = ( 0 <= hour && hour <= 23 ) ? hour : -1;
}

Time::Time(int sec)
{
	h = (sec / 3600) % 24;
	m = (sec % 3600) / 60;
	s = sec % 60;
}

Time operator+( Time t1, Time t2 ) {
	Time t( ( t1.h + t2.h )*3600 + (t1.m + t2.m) * 60 + (t1.s + t2.s) );
	return t;
}

void checkTime( string testname, Time t, int h, int m, int s )
{
    if( t.getHour() == h && t.getMin() == m && t.getSec() == s )
        cout << testname << " passed" << endl;
    else
        cout << testname << "  failed" << endl;
    
}

void Time::showTime() 
{
	cout << h << ":" << m << ":" << s << endl;

}

string Time::toString()
{
	stringstream str;
	str << h << ":" << m << ":" << s;
	return str.str(); 
}

void TimeZ::setZone( Zone zone )
{
	if( z == zone ) return;

	if( z == EST && zone == KST ) h = (h + 13) % 24; // add 13 hour
	if( z == KST && zone == EST ) h = (h - 13) % 24; // subtract 13 hour

	z = zone;
}

int main() 
{
	TimeZ t1(14, 0, 0);
	TimeZ t2(10, 0, 0, EST);

	cout << t1 << endl;
	cout << t2 << endl;

	//t2.setZone(KST);
	cout << t2 << endl;

	if( t1 == t2 )
		cout << "t1 = t2" << endl;
	else
		cout << "t1 != t2" << endl;

	TimeZ t3 = t1 + t2; // add two times according to the time zone of LHS
	 cout << t3 << endl;

	/*
	cout << "Welcome to HW4" << endl;

    Time t1(1, 2, 74);
	// if no showTime() defined
	cout << t1.getHour() << ":" << t1.getMin() << ":" << t1.getSec() << endl;
	// with showTime()
	t1.showTime();
	cout << t1.toString() << endl;

    checkTime( "test 1", t1, 1, 2, -1 );
        
    Time t2(1, -3, 23);
    checkTime( "test 2", t2, 1, -1, 23 );
     
    Time t3(3700);
    checkTime( "test 3", t3, 1, 1, 40 );
            
    Time t4(3, 30, 30);
    Time t5(5, 40, 40);

	if( t4 == t5 )
		cout << "t4 == t5" << endl;
	else
		cout << "t4 != t5" << endl;

    Time t6 = t4 + t5;
    
    checkTime( "test 4", t6, 9, 11, 10 );
    
    Time t7(15, 30, 30);
    Time t8(15, 20, 40);
    Time t9 = t7 + t8;

    checkTime( "test 5", t9, 6, 51, 10 );
    */
    system("pause");
}

