/*=============================================================================
	CAVolumeCurve.h

	$Log: CAVolumeCurve.h,v $
	Revision 1.4  2004/05/21 00:11:30  jcm10
	add support for the driver to say that a level control shouldn't use the volume curve
	
	Revision 1.3  2003/11/20 22:56:53  dwyatt
	__COREAUDIO_USE_FLAT_INCLUDES__
	
	Revision 1.2  2002/11/07 21:14:14  jcm10
	fix some naming in CAVolumeCurve to better match the usage in the HAL API
	
	Revision 1.1  2002/10/31 01:04:44  jcm10
	moved here from AudioHardware/Utility
	
	Revision 1.1  2002/05/21 00:55:49  jcm10
	new sample rate properties and new volume control behavior
	
	Revision 0.0  Sun May 19 2002 16:31:42 US/Pacific  moorf
	Created
		
	$NoKeywords: $
=============================================================================*/
#if !defined(__CAVolumeCurve_h__)
#define __CAVolumeCurve_h__

//=============================================================================
//	Includes
//=============================================================================

#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
	#include <CoreAudio/CoreAudioTypes.h>
#else
	#include <CoreAudioTypes.h>
#endif
#include <map>

//=============================================================================
//	Types
//=============================================================================

struct CARawPoint
{
	SInt32	mMinimum;
	SInt32	mMaximum;
	
	CARawPoint() : mMinimum(0), mMaximum(0) {}
	CARawPoint(const CARawPoint& inPoint) : mMinimum(inPoint.mMinimum), mMaximum(inPoint.mMaximum) {}
	CARawPoint(SInt32 inMinimum, SInt32 inMaximum) : mMinimum(inMinimum), mMaximum(inMaximum) {}
	CARawPoint&	operator=(const CARawPoint& inPoint) { mMinimum = inPoint.mMinimum; mMaximum = inPoint.mMaximum; return *this; }
	
	static bool	Overlap(const CARawPoint& x, const CARawPoint& y) { return (x.mMinimum < y.mMaximum) && (x.mMaximum > y.mMinimum); }
};

inline bool	operator<(const CARawPoint& x, const CARawPoint& y) { return x.mMinimum < y.mMinimum; }
inline bool	operator==(const CARawPoint& x, const CARawPoint& y) { return (x.mMinimum == y.mMinimum) && (x.mMaximum == y.mMaximum); }
inline bool	operator!=(const CARawPoint& x, const CARawPoint& y) { return !(x == y); }
inline bool	operator<=(const CARawPoint& x, const CARawPoint& y) { return (x < y) || (x == y); }
inline bool	operator>=(const CARawPoint& x, const CARawPoint& y) { return !(x < y); }
inline bool	operator>(const CARawPoint& x, const CARawPoint& y) { return !((x < y) || (x == y)); }

struct CADBPoint
{
	Float64	mMinimum;
	Float64	mMaximum;
	
	CADBPoint() : mMinimum(0), mMaximum(0) {}
	CADBPoint(const CADBPoint& inPoint) : mMinimum(inPoint.mMinimum), mMaximum(inPoint.mMaximum) {}
	CADBPoint(Float64 inMinimum, Float64 inMaximum) : mMinimum(inMinimum), mMaximum(inMaximum) {}
	CADBPoint&	operator=(const CADBPoint& inPoint) { mMinimum = inPoint.mMinimum; mMaximum = inPoint.mMaximum; return *this; }
	
	static bool	Overlap(const CADBPoint& x, const CADBPoint& y) { return (x.mMinimum < y.mMaximum) && (x.mMaximum >= y.mMinimum); }
};

inline bool	operator<(const CADBPoint& x, const CADBPoint& y) { return x.mMinimum < y.mMinimum; }
inline bool	operator==(const CADBPoint& x, const CADBPoint& y) { return (x.mMinimum == y.mMinimum) && (x.mMaximum == y.mMaximum); }
inline bool	operator!=(const CADBPoint& x, const CADBPoint& y) { return !(x == y); }
inline bool	operator<=(const CADBPoint& x, const CADBPoint& y) { return (x < y) || (x == y); }
inline bool	operator>=(const CADBPoint& x, const CADBPoint& y) { return !(x < y); }
inline bool	operator>(const CADBPoint& x, const CADBPoint& y) { return !((x < y) || (x == y)); }

//=============================================================================
//	CAVolumeCurve
//=============================================================================

class CAVolumeCurve
{

//	Construction/Destruction
public:
					CAVolumeCurve();
	virtual			~CAVolumeCurve();

//	Attributes
public:
	SInt32			GetMinimumRaw() const;
	SInt32			GetMaximumRaw() const;
	Float64			GetMinimumDB() const;
	Float64			GetMaximumDB() const;
	
	void			SetIsApplyingCurve(bool inIsApplyingCurve)  { mIsApplyingCurve = inIsApplyingCurve; }

//	Operations
public:
	void			AddRange(SInt32 mMinRaw, SInt32 mMaxRaw, Float64 inMinDB, Float64 inMaxDB);
	void			ResetRange();
	bool			CheckForContinuity() const;
	
	SInt32			ConvertDBToRaw(Float64 inDB) const;
	Float64			ConvertRawToDB(SInt32 inRaw) const;
	Float64			ConvertRawToScalar(SInt32 inRaw) const;
	Float64			ConvertDBToScalar(Float64 inDB) const;
	SInt32			ConvertScalarToRaw(Float64 inScalar) const;
	Float64			ConvertScalarToDB(Float64 inScalar) const;

//	Implementation
private:
	typedef	std::map<CARawPoint, CADBPoint>	CurveMap;
	
	CurveMap		mCurveMap;
	bool			mIsApplyingCurve;

};

#endif
