#include "..\includes.h"
#include "ogg.h"
#include "ava_sound_system.h"

static int input_socket = 0;
int *ogg_status;
extern char KillSong;
extern int music_playing;
extern int isopointer;

DWORD PlayNextSongPoll( void );


/***********************************  AVA ENGINE ****************************************/


OGG::OGG( )
{
	pcmout = new char[4096];
}

OGG::~OGG( )
{
}

int OGG::RegisterFileMasks( struct FileType *types )
{
	struct FileType *pointer;

	pointer = types;
	while( pointer->next )
		pointer = pointer->next;

	pointer->next = (struct FileType*)malloc( sizeof(struct FileType));
	pointer = pointer->next;
	strcpy(pointer->mask,".OGG" ); 
	pointer->Player = this;

	pointer->next = 0;

	// 1 filetype registered
	return 1;
}

struct PlaylistNode *OGG::AutoAddItem( char *Path )
{
	struct PlaylistNode *last;

	last = new struct PlaylistNode;
	last->path = new char[strlen(Path)+1];
	strcpy( last->path, Path );
	last->name= new char[strlen(Path)+1];
	strcpy( last->name, Path );
	last ->flag = SOUND_FLAGS_NOTPLAYED;
	last->status = SOUND_STATUS_STOPPED;
	last->next = 0;
	last->localdata = 0;
	last->iso9660 = 0;
	last->Player = this;

	HANDLE h = CreateFile( Path, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, 0 );
	last->size = GetFileSize( h, 0 );
	CloseHandle( h );

	return last;
}

extern int fs;

int userbreak=0;


DWORD OGGPlayer( class OGG *ogg )
{
	static char first = 1;
	DWORD completed2=0;
	DWORD completed=0;
/*	while( ! KillSong )
	{
		if( OGG_engine->Process(&completed) != S_OK )
			KillSong = 1;
		if( completed == 100 )
			KillSong = 1;
		if( completed2 > completed )
			KillSong = 1;
		completed2 = completed;
	    DirectSoundDoWork();
		Sleep(4);
		if( ShuttingDown(0) )
			KillSong = 1;
	}
	*OGG_status = SOUND_STATUS_STOPPED;
	music_playing = 0;
	delete OGG_engine;**/

	if( first )
	{
		for( int t=0; t< MP3_PACKETS; ++t )
			ogg->g_packet_status[t] = XMEDIAPACKET_STATUS_SUCCESS;
		first = 0;
	}
	int eof = 0;
	int current_section = -1;
	while( !KillSong )
	{
		XMEDIAINFO media_info;
		ogg->ds_stream->GetInfo(&media_info);
		for(int i = 0; i < MP3_PACKETS; i++)
		{
			if(ogg->g_packet_status[i] != XMEDIAPACKET_STATUS_PENDING)
			{
				//OutputDebugString("Ogg packet decode\r");
				long ret=ov_read(&ogg->vf,ogg->g_decode_buf[i],MP3_OUTPUT_BUF_SIZE,0,2,1,&current_section);
				if( ret != 0 )
				{
					XMEDIAPACKET mp;
					memset(&mp, 0, sizeof(mp));

//					memcpy((ogg->g_decode_buf[i]),ogg->pcmout,ret);
					mp.pvBuffer = ogg->g_decode_buf[i];
					mp.dwMaxSize = ret;
					mp.pdwCompletedSize = &ogg->g_completed_size[i];
					mp.pdwStatus = &ogg->g_packet_status[i];
					mp.pContext = NULL;    

 					ogg->ds_stream->Process(&mp, NULL);

				}
				else
					eof = 1;
			}
		}
		DirectSoundDoWork();
		Sleep(100);
		if( eof )
		{
			ogg->m_pDSBuffer->Release();
			ogg->ds_stream->Release();
			music_playing=0;
			UnRegisterThread( GetCurrentThread() );
			*ogg->OGG_status = SOUND_STATUS_STOPPED;
			ov_clear( &ogg->vf );
			if( !userbreak )
				AddPollThread((LPTHREAD_START_ROUTINE) PlayNextSongPoll,0,300,"Play next Song - EOF ");
			return 1;
		}
	}
	ogg->m_pDSBuffer->Release();
	ogg->ds_stream->Release();
	ov_clear( &ogg->vf );
	UnRegisterThread( GetCurrentThread() );
	music_playing = 0;
	userbreak = 0;
	KillSong  = 0;
	*ogg->OGG_status = SOUND_STATUS_STOPPED;

	return 1;
}

DWORD timeGetTime2(void);

int	OGG::PlayThisone( struct PlaylistNode * entry)
{
	static int first = 1;
	static DWORD timesincelaststart=0;
	static int alreadyinhere=0;
	int serial = 0;

	if( alreadyinhere ) 
		return 0;
	if( music_playing ) 
		return 0;
	while(music_playing || KillSong)
		Sleep(50);
	music_playing = 1;
	OGG_status = &entry->status;
	*OGG_status = SOUND_STATUS_PLAYING;

	OutputMessagebox("Playing",entry->name,2000 );

	FILE *FP = fopen( entry->name, "rb" );

	int value = ov_open( FP, &vf, NULL, 0 );

	vorbis_info *vi=ov_info(&vf,-1);


	WAVEFORMATEX wave_format;
	memset(&wave_format, 0, sizeof(wave_format));
	DSBUFFERDESC buffer_desc;
	memset(&buffer_desc, 0, sizeof(buffer_desc));

	wave_format.wFormatTag = WAVE_FORMAT_PCM;
	wave_format.nChannels = vi->channels;
	wave_format.nSamplesPerSec = vi->rate;

	wave_format.wBitsPerSample = 16;
	wave_format.nBlockAlign = wave_format.nChannels * wave_format.wBitsPerSample / 8;
	wave_format.nAvgBytesPerSec = wave_format.nSamplesPerSec * wave_format.nBlockAlign;
	wave_format.cbSize = 0;

	buffer_desc.dwSize = sizeof(buffer_desc);
	buffer_desc.dwFlags = 0;
	buffer_desc.dwBufferBytes = 44100*2 * 2 * 2; // 1 second
	buffer_desc.lpwfxFormat = &wave_format;
	buffer_desc.dwInputMixBin = 0;

	DSSTREAMDESC stream_desc;
	memset(&stream_desc, 0, sizeof(stream_desc));
	stream_desc.dwMaxAttachedPackets = MP3_PACKETS;
	stream_desc.lpwfxFormat = &wave_format;

	GetSoundDevice()->CreateSoundBuffer( &buffer_desc, &m_pDSBuffer, NULL);
	GetSoundDevice()->CreateSoundStream( &stream_desc, &ds_stream, NULL );    

	ds_stream->SetVolume(DSBVOLUME_MAX);
	ds_stream->SetHeadroom(0);

	alreadyinhere = 1;
	timesincelaststart = timeGetTime2();

	input_socket = 0;

	RegisterThread(CreateThread(NULL, 128, (LPTHREAD_START_ROUTINE)OGGPlayer, this, 0, NULL )); 
	alreadyinhere = 0;
	return 1;
}


int	OGG::Play( void )
{
//	PlayThisone( PlaylistPointer );
	return  1;
}

int OGG::Pause( void )
{
	static int pausemode=0;

	pausemode = 1 - pausemode;

//	wma_engine->Pause(pausemode);
	return 1;
}

int OGG::Stop( void )
{
	userbreak = 1;
	while(music_playing)
	{
		KillSong  = 1;
		Sleep(200);
	}

	if( KillSong )
	{
		Sleep(500);
		KillSong = 0;
	}
//	KillSong  = 1;
	return 1;
}
/*	int		Pause( void )										{ return 0; }
	int		SkipBackward( void )								{ return 0; }
	struct PlaylistNode *GetNextSong( void )					{ return 0; }
	struct PlaylistNode *GetCurrentSong( void )					{ return 0; }

	int		Initialize( );
	int		KeepAlive( );
};*/

