//===========================================================================//
// File:	time.hh                                                             //
// Project: MUNGA           Brick: Time Manager                              //
// Contents: Interface declarations for Time Manager                         //
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  ---------------------------------------------------------- //
// 10/19/94  JMA  Initial coding.                                            //
// 10/24/94  JMA  Reduced operator set to minimum                            //
// 10/28/94  JMA  Made compatible with SGI CC                                //
// 11/03/94  ECH  Made compatible with BC4.0                                 //
//---------------------------------------------------------------------------//
// Copyright (C) 1994-1995, Virtual World Entertainment, Inc.                //
//                      PROPRIETARY AND CONFIDENTIAL                         //
//===========================================================================//

#if !defined(TIME_HPP)
#	define TIME_HPP

#	if !defined(SCALAR_HPP)
#		include <scalar.hpp>
#	endif

	class Time;

	//##########################################################################
	//########################    System Clock    ##############################
	//##########################################################################

	class SystemClock SIGNATURED
	{
		friend class Time;

	public:
		friend float
			Get_Frame_Percent_Used();
		friend volatile Time&
			Now();
		static void
			TogglePause();

		SystemClock();
		~SystemClock()
			{Shutdown();}
		static SystemClock
			timer;
		void
			Shutdown();
		friend Scalar
			GetTicksPerSecond()
				{return ticksPerSecond;}

	protected:
		long
			pauseStart;
		long
			pauseTime;
		static Scalar
			ticksPerSecond;

		static long
			GetRTC();
	};

	//##########################################################################
	//############################    Time    ##################################
	//##########################################################################

	class Time
	{
	public:
		long ticks;
		static Time Null;

		#if defined(USE_SIGNATURE)
			friend int
				Is_Signature_Bad(const volatile Time *p);
		#endif

		Time()
			{}
		Time(const volatile Time &t):
			ticks(t.ticks)
				{}
		Time(SystemClock&):
			ticks(0)
				{}

		Time&
			operator=(const volatile Time &t)
				{Check_Pointer(this); Check(&t); ticks = t.ticks; return *this;}
		Time&
			operator=(long t)
				{Check_Pointer(this); ticks = t; return *this;}
		Time&
			operator=(Scalar t)
				{Check_Pointer(this); ticks = Float_To_Time(t); return *this;}

		operator Scalar() const volatile
			{Check(this); return Time_To_Float(ticks);}
		operator long() const volatile
			{Check(this); return ticks;}

		Scalar
			operator-(const volatile Time &t) const volatile
				{Check(this); Check(&t); return Time_To_Float(ticks - t.ticks);}

		Time&
			operator+=(const volatile Time &t)
				{Check(this); Check(&t); ticks += t.ticks; return *this;}
		Time&
			operator+=(Scalar t)
				{Check(this); ticks += Float_To_Time(t); return *this;}
		Time&
			operator-=(const volatile Time &t)
				{Check(this); Check(&t); ticks -= t.ticks; return *this;}
		Time&
			operator-=(Scalar t)
				{Check(this); ticks -= Float_To_Time(t); return *this;}

		Logical
			operator<(const volatile Time &t) const volatile
				{Check(this); Check(&t); return ticks < t.ticks;}
		Logical
			operator<=(const volatile Time &t) const volatile
				{Check(this); Check(&t); return ticks <= t.ticks;}
		Logical
			operator>(const volatile Time &t) const volatile
				{Check(this); Check(&t); return ticks > t.ticks;}
		Logical
			operator>=(const volatile Time &t) const volatile
				{Check(this); Check(&t); return ticks >= t.ticks;}

		friend ostream&
			operator <<(
				ostream& stream,
				const volatile Time& t
			)
				{Check(&t); return stream << t.ticks;}

		Logical
			TestInstance() const volatile;
		static Logical
			TestClass();

	private:
		static long
			Float_To_Time(Scalar t)
				{return (long)(t * SystemClock::ticksPerSecond + 0.5f);}

		static Scalar
			Time_To_Float(long t)
				{return (Scalar)t / SystemClock::ticksPerSecond;}
	};

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Time functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

	void
		Convert_From_Ascii(
			const char *str,
			Time *time
		);

#endif
