//===========================================================================//
// File:	audtime.hpp                                                         //
// Project: MUNGA           Brick: Audio Renderer                            //
// Contents: Interface declarations for AudioTim                         	  //
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  ---------------------------------------------------------- //
// 05/08/96  ECH  Initial coding.                                            //
//---------------------------------------------------------------------------//
// Copyright (C) 1994-1995, Virtual World Entertainment, Inc.                //
//                      PROPRIETARY AND CONFIDENTIAL                         //
//===========================================================================//

#if !defined(AUDTIME_HPP)
#	define AUDTIME_HPP

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

#	if !defined(AUDIO_HPP)
#		include <audio.hpp>
#	endif

	//##########################################################################
	//##########################    AudioTime    ###############################
	//##########################################################################

	class AudioTime SIGNATURED
	{
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Construction, Destruction, and Testing
	//
	public:
		AudioTime();
		AudioTime(const AudioTime&);
		AudioTime(Scalar seconds);
		AudioTime(AudioFrameCount frame_count);
		~AudioTime();
		
		Logical
			TestInstance() const;
		
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Assignment
	//
	public:
		AudioTime&
			operator=(const AudioTime&);
		AudioTime&
			operator=(Scalar seconds);
		AudioTime&
			operator=(AudioFrameCount frame_count);
			
		operator Scalar() const;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Logical Operators
	//
	public:
		Logical
			operator<(const AudioTime&) const;
		Logical
			operator<=(const AudioTime&) const;
		Logical
			operator>(const AudioTime&) const;
		Logical
			operator>=(const AudioTime&) const;
		Logical
			operator==(const AudioTime&) const;
		Logical
			operator!=(const AudioTime&) const;
		
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Addition Operators
	//
	public:
		operator AudioFrameCount() const;

		AudioTime
			operator+(const AudioTime&) const;
		AudioTime
			operator-(const AudioTime&) const;

		AudioTime&
			operator+=(const AudioTime &t);
		AudioTime&
			operator-=(const AudioTime &t);

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Public Constants
	//
	public:
		static const AudioTime
			Null;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Current Time
	//
	public:
		static AudioTime
			Now();

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Private Methods
	//
	private:
		AudioFrameCount
			Seconds_To_Frames(Scalar seconds) const;
		Scalar
			Frames_To_Seconds(AudioFrameCount frames) const;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Private Data
	//
	private:
		AudioFrameCount
			frameCount;		
	};

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~ AudioTime inlines ~~~~~~~~~~~~~~~~~~~~~~~~~~~

	//
	// Construction, Destruction, and Testing
	//
	inline AudioTime::AudioTime():
		frameCount(NullAudioFrameCount)
	{
	}
	
	inline AudioTime::AudioTime(const AudioTime &audio_time):
		frameCount(audio_time.frameCount)
	{
	}

	inline AudioTime::AudioTime(Scalar seconds)
	{
		frameCount = Seconds_To_Frames(seconds);
	}	

	inline AudioTime::AudioTime(AudioFrameCount frame_count):
		frameCount(frame_count)
	{
	}

	inline AudioTime::~AudioTime()
	{
	}

	//
	// Assignment
	//
	inline AudioTime&
		AudioTime::operator=(const AudioTime &audio_time)
	{
		Check(this);
		Check(&audio_time);
		frameCount = audio_time.frameCount; 
		return *this;
	}

	inline AudioTime&
		AudioTime::operator=(Scalar seconds)
	{
		Check(this);
		frameCount = Seconds_To_Frames(seconds); 
		return *this;
	}

	inline AudioTime&
		AudioTime::operator=(AudioFrameCount frame_count)
	{
		Check(this);
		frameCount = frame_count; 
		return *this;
	}
	
	inline 
		AudioTime::operator Scalar() const
	{
		Check(this); 
		return Frames_To_Seconds(frameCount);
	}
	
	//
	// Logical Operators
	//
	inline Logical
		AudioTime::operator<(const AudioTime &audio_time) const
	{
		Check(this);
		Check(&audio_time);
		return frameCount < audio_time.frameCount;
	}
	
	inline Logical
		AudioTime::operator<=(const AudioTime &audio_time) const
	{
		Check(this);
		Check(&audio_time);
		return frameCount <= audio_time.frameCount;
	}

	inline Logical
		AudioTime::operator>(const AudioTime &audio_time) const
	{
		Check(this);
		Check(&audio_time);
		return frameCount > audio_time.frameCount;
	}

	inline Logical
		AudioTime::operator>=(const AudioTime &audio_time) const
	{
		Check(this);
		Check(&audio_time);
		return frameCount >= audio_time.frameCount;
	}

	inline Logical
		AudioTime::operator==(const AudioTime &audio_time) const
	{
		Check(this);
		Check(&audio_time);
		return frameCount == audio_time.frameCount;
	}

	inline Logical
		AudioTime::operator!=(const AudioTime &audio_time) const
	{
		Check(this);
		Check(&audio_time);
		return frameCount != audio_time.frameCount;
	}

	//
	// Addition Operators
	//
	inline AudioTime::operator AudioFrameCount() const
	{
		Check(this);
		return frameCount;
	}
	
	inline AudioTime
		AudioTime::operator+(const AudioTime &audio_time) const
	{
		Check(this);
		Check(&audio_time);
		return AudioTime(frameCount + audio_time.frameCount);
	}

	inline AudioTime
		AudioTime::operator-(const AudioTime &audio_time) const
	{
		Check(this);
		Check(&audio_time);
		return AudioTime(frameCount - audio_time.frameCount);
	}
	
	inline AudioTime&
		AudioTime::operator+=(const AudioTime &audio_time)
	{
		Check(this); 
		Check(&audio_time); 
		frameCount += audio_time.frameCount; 
		return *this;
	}	

	inline AudioTime&
		AudioTime::operator-=(const AudioTime &audio_time)
	{
		Check(this); 
		Check(&audio_time); 
		frameCount -= audio_time.frameCount; 
		return *this;
	}	

#endif
