/*********************************************************************
*	COggAudioPlayer
*	SOURCE FILE
*	Autor:	Michal Jirouš
*	Datum: 16.7.2008
*	Soubor: oggaudioplayer.cpp
*	Popis: Prehravac ogg audio souboru
**********************************************************************/

#include "oggaudioplayer.h"
#include "sys_console.h"

using namespace systemConsole;

void AudioCallback(void *unused, Uint8 *stream, int len);

COggAudioPlayer::COggAudioPlayer()
{

}

//inicializace audia
bool COggAudioPlayer::init()
{
	// Inicializace SDL_sound
	if(Sound_Init() == 0)
	{
		console << "Unable to initialize SDL_sound: " << Sound_GetError() << endline;
		return false;
	}

	// Nastaveni audia
	m_desired.freq = 22050;// 16-bit. stereo na 22 kHz
	m_desired.format = AUDIO_S16;
	m_desired.channels = 2;
	m_desired.samples = 512;// Vhodne pro hry
	m_desired.callback = AudioCallback;
	m_desired.userdata = this;

	// Otevre audio zarizeni
	if(SDL_OpenAudio( &m_desired, &m_obtained ) == -1)
	{
		console << "Unable to open audio: " << SDL_GetError() << endline;
		return false;
	}
	
	return true;
}

//zruseni prehravace, zavreni audia a ukonceni zvuku
void COggAudioPlayer::destroy()
{
	if( m_pSample )
	{
		Sound_FreeSample( m_pSample );	// Uvolni zvuk
		m_pSample = NULL;
	}
	SDL_CloseAudio();
	Sound_Quit();			// Ukonci SDL_sound
}

//nacte zvuk ze souboru
bool COggAudioPlayer::loadSound( const char * filename )
{
	stop();
	if( m_pSample )
	{
		Sound_FreeSample( m_pSample );	// Uvolni zvuk
		m_pSample = NULL;
	}

	m_uiPosition = 0;

	// Loading audia a dekodovani (vse najednou)
	Sound_AudioInfo info;
	info.channels = m_obtained.channels;
	info.format = m_obtained.format;
	info.rate = m_obtained.freq;

	m_pSample = Sound_NewSampleFromFile( filename, &info, 512);

	if(m_pSample == NULL)
	{
		console << "Unable to load sound: " << Sound_GetError() << endline;
		return false;
	}

	//dekodovani a ulozeni do bufferu
	Sound_DecodeAll(m_pSample);

	if(m_pSample->flags & SOUND_SAMPLEFLAG_ERROR)
	{
		console << "Unable to decode sound: " << Sound_GetError() << endline;
		return false;
	}

	return true;
}

void COggAudioPlayer::play()
{
	if( m_pSample )
	{
		SDL_PauseAudio(0);
	}
}

void COggAudioPlayer::stop()
{
	SDL_PauseAudio(1);
}


//cast kodu prejata z tutorialu
void AudioCallback(void *unused, Uint8 *stream, int len)
{
	COggAudioPlayer *tmpPlayer = (COggAudioPlayer*)unused;

	if( !tmpPlayer->m_pSample )
		return;

	// Ukazatel na cast, kde se ma zacit prehravat
	Uint8 *wave_ptr = (Uint8 *)tmpPlayer->m_pSample->buffer + tmpPlayer->m_uiPosition;

	// Delka zvuku do konce
	int wave_left = tmpPlayer->m_pSample->buffer_size - tmpPlayer->m_uiPosition;

	// Zbyvajici delka je mensi nez pozadovana
	// Cyklus, protoze cely zvuk muze byt kratsi
	while(wave_left <= len)
	{
		// Posle data na zvukovou kartu
		SDL_MixAudio(stream, wave_ptr, wave_left, SDL_MIX_MAXVOLUME);

		// Posune se o prave zapsana data
		stream += wave_left;
		len -= wave_left;

		// Od zacatku zvuku
		wave_ptr = (Uint8 *)tmpPlayer->m_pSample->buffer;
		wave_left = tmpPlayer->m_pSample->buffer_size;
		tmpPlayer->m_uiPosition = 0;
	}

	// Je jistota, ze zbyvajici cast zvuku je delsi nez pozadovana
	SDL_MixAudio(stream, wave_ptr, len, SDL_MIX_MAXVOLUME);
	tmpPlayer->m_uiPosition += len;
}

