/*!
	* \brief Plays the music
	*
	* Plays/Resume the music.
	* If the music is currently playing, resets the playing offset to the beginning offset.
	* If the music is currently paused,  resumes the playing.
	* If the music is currently stopped, starts the playing at the previously set playing offset.
	*
	* \remark Music must be valid when calling this function
	*/
	void Music::Play()
	{
		NazaraAssert(m_impl, "Music not created");

		// Maybe we are already playing
		if (m_impl->streaming)
		{
			switch (GetStatus())
			{
				case SoundStatus_Playing:
					SetPlayingOffset(0);
					break;

				case SoundStatus_Paused:
					alSourcePlay(m_source);
					break;

				default:
					break; // We shouldn't be stopped
			}
		}
		else
		{
			// Starting streaming's thread
			m_impl->streaming = true;
			m_impl->thread = Thread(&Music::MusicThread, this);
		}
	}
	/*!
	* \brief Stops the music
	*
	* \remark Music must be valid when calling this function
	*/
	void Music::Stop()
	{
		NazaraAssert(m_impl, "Music not created");

		StopThread();
		SetPlayingOffset(0);
	}
	void Music::Play()
	{
		#if NAZARA_AUDIO_SAFE
		if (!m_impl)
		{
			NazaraError("Music not created");
			return;
		}
		#endif

		// Maybe we are already playing
		if (m_impl->streaming)
		{
			switch (GetStatus())
			{
				case SoundStatus_Playing:
					SetPlayingOffset(0);
					break;

				case SoundStatus_Paused:
					alSourcePlay(m_source);
					break;

				default:
					break; // We shouldn't be stopped
			}
		}
		else
		{
			// Starting streaming's thread
			m_impl->streaming = true;
			m_impl->thread = Thread(&Music::MusicThread, this);
		}
	}
	bool Music::Create(SoundStream* soundStream)
	{
		NazaraAssert(soundStream, "Invalid stream");

		Destroy();

		AudioFormat format = soundStream->GetFormat();

		m_impl = new MusicImpl;
		m_impl->sampleRate = soundStream->GetSampleRate();
		m_impl->audioFormat = OpenAL::AudioFormat[format];
		m_impl->chunkSamples.resize(format * m_impl->sampleRate); // One second of samples
		m_impl->stream = soundStream;

		SetPlayingOffset(0);

		return true;
	}