#pragma once

#include "style.h"
#include "audio.h"

//##########################################################################
//########################    AudioWeighting    ############################
//##########################################################################

class AudioWeighting SIGNATURED
{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Construction, Destruction, and Testing
//
public:
	AudioWeighting();
	AudioWeighting(const AudioWeighting&);
	AudioWeighting(AudioSourcePriority audio_priority, AudioControlValue audio_volume);

	AudioWeighting& operator=(const AudioWeighting&);

	Logical TestInstance() const;

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

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

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Private Data
//
private:
	Scalar weight;
};

//~~~~~~~~~~~~~~~~~~~~~~~~~~ AudioWeighting inlines  ~~~~~~~~~~~~~~~~~~~~~~~

inline AudioWeighting::AudioWeighting():
	weight(0.0f)
{
}

inline AudioWeighting::AudioWeighting(const AudioWeighting &audio_weighting):
	weight(audio_weighting.weight)
{
}

inline AudioWeighting::AudioWeighting(
	AudioSourcePriority audio_priority, 
	AudioControlValue audio_volume
)
{
	Verify(
		(Enumeration)audio_priority >= 0 &&
		(Enumeration)audio_priority < AUDIO_SOURCE_PRIORITY_COUNT
	);
	Verify(
		(Enumeration)audio_priority >= (Enumeration)MinAudioSourcePriority &&
		(Enumeration)audio_priority <= (Enumeration)MaxAudioSourcePriority
	);
	Verify(
		audio_volume >= 0.0f &&
		audio_volume <= 1.0f			
	);
	weight = 0.0f -(Scalar)audio_priority - audio_volume;
}

inline AudioWeighting&
	AudioWeighting::operator=(const AudioWeighting &audio_weighting)
{
	Check(this);
	weight = audio_weighting.weight; 
	return *this;
}

inline Logical
	AudioWeighting::operator<(const AudioWeighting &audio_weighting) const
{
	Check(this);
	return weight < audio_weighting.weight;
}

inline Logical
	AudioWeighting::operator<=(const AudioWeighting &audio_weighting) const
{
	Check(this);
	return weight <= audio_weighting.weight;
}

inline Logical
	AudioWeighting::operator>(const AudioWeighting &audio_weighting) const
{
	Check(this);
	return weight > audio_weighting.weight;
}

inline Logical
	AudioWeighting::operator>=(const AudioWeighting &audio_weighting) const
{
	Check(this);
	return weight >= audio_weighting.weight;
}

inline Logical
	AudioWeighting::operator==(const AudioWeighting &audio_weighting) const
{
	Check(this);
	return Close_Enough(weight, audio_weighting.weight, 0.01f);
}

inline Logical
	AudioWeighting::operator!=(const AudioWeighting &audio_weighting) const
{
	Check(this);
	return !Close_Enough(weight, audio_weighting.weight, 0.01f);
}
