/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
////																					 ////
////																					 ////
////								  - SCOLmp3.cpp -									 ////
////																					 ////
////																					 ////
////				Implémentation des fonctions SCOL de la librairie sonore			 ////
////									 Version  1.0									 ////
////																					 ////
////								  Hilaire Verschuere								 ////
////																					 ////
////																					 ////
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////



#include "..\SCOL\ZooScol.h"
#include "..\SCOL\SCOLsound.h"


/////////////////////////////////////////////////////////////////////////////////////////////
// Static variables
/////////////////////////////////////////////////////////////////////////////////////////////
extern HSoundManager* pHSoundManager ;


/////////////////////////////////////////////////////////////////////////////////////////////
// Global variables
/////////////////////////////////////////////////////////////////////////////////////////////
int AsMp3 ;



//////////////////////////////////////////////////////////////////////////////////////////////
///		asMp3Create													
//////////////////////////////////////////////////////////////////////////////////////////////
//fun [Chn] AsMp3
int asMp3Create(mmachine m)
{
	HMp3* pHMp3 = new HMp3( false ) ;

	int mp3 = MMmalloc(m,1,TYPETAB) ;
	if ( mp3 == NIL ) { SAFE_DELETE( pHMp3 ) ; MMset(m,0,NIL) ; return MERRMEM ; }

	MMstore( m, mp3, 0, (int)pHMp3 ) ;
	
	MMpush(m, PTOM( mp3 )) ;
	return OBJcreate( m, AsMp3, (int)pHMp3, -1, 0 );
}


//////////////////////////////////////////////////////////////////////////////////////////////
///		asMp3Destroy													
//////////////////////////////////////////////////////////////////////////////////////////////
//fun [AsMp3] I
int asMp3Destroy(mmachine m)
{
	int	mp3 = MTOP(MMget(m,0)) ;
	if ( mp3 == NIL ) { MMset(m,0,NIL) ; return 0 ; }
	
	OBJdelTM( m, AsMp3, PTOM(mp3) ) ;
	MMset(m,0,0) ;

	return 0 ;
}





// Delete the AsMp3 ///////////////////////////////////////////////////////////////////////
int destroyAsMp3(mmachine m,int handsys,int mp3)
{
	HMp3* pHMp3 = (HMp3*)MMfetch(m, MTOP(mp3), 0) ;
	if( !pHMp3 ) { MMset(m,0,NIL) ; return 0 ; }

	SAFE_DELETE( pHMp3 ) ;
	
	MMstore( m, MTOP(mp3), 0, NULL ) ;
	MMechostr(1,"AsMp3 destroyed\n");

	return 0;
}



//////////////////////////////////////////////////////////////////////////////////////////////
///		asMp3GetFrameInfo													
//////////////////////////////////////////////////////////////////////////////////////////////
//fun [S] [I I I I]
int asMp3GetFrameInfo(mmachine m)
{
	int s = MTOP( MMget(m,0) ) ;
	if( s == NIL ) { MMset(m,0,NIL) ; return 0 ; }

	char* buffer = (char*)MMstartstr(m,s) ;
	int size = MMsizestr(m,s) ;

	HMp3 hmp3( NULL ) ;
	
	int frameSize = hmp3.GetFrameInfo( buffer, size ) ;
	if( frameSize <= 0 ) { MMechostr( 1, "Not a Mp3 frame" ) ; MMset(m,0,NIL) ; return 0 ; }

	int res = MMmalloc(m,4,TYPETAB) ;
	if ( res==NIL )	{ MMset(m,0,NIL) ;	return MERRMEM ; }

	MMstore(m, res, 0, ITOM( hmp3.cur_mp3info.nch ) ) ;
	MMstore(m, res, 1, ITOM( hmp3.cur_mp3info.freq ) ) ;
	MMstore(m, res, 2, ITOM( 16 ) ) ;
	MMstore(m, res, 3, ITOM( hmp3.cur_mp3info.bitrate ) ) ;

	MMset(m, 0, PTOM(res)) ;

	return 0 ;
}






//////////////////////////////////////////////////////////////////////////////////////////////
///		asMp3Decode													
//////////////////////////////////////////////////////////////////////////////////////////////
//fun [AsMp3 S] S
int asMp3Decode(mmachine m)
{
	int sizeOut, decodeState ;

	int s	= MTOP(MMpull(m));
	int mp3 = MTOP(MMget(m,0));
	if( mp3==NIL || s==NIL )  { MMset(m,0,NIL) ; return 0 ; }
	
	HMp3* pHMp3 = (HMp3*)MMfetch(m, mp3, 0) ;
	if( !pHMp3 ) { MMset(m,0,NIL) ; return 0 ; }

	char* in=(char *)MMstartstr(m,s);
	int inmemsize = MMsizestr(m,s);

	int buff = MMmalloc(m,STR_SIZE(OBSIZE),TYPEBUF);
	if (buff < 0) { MMset(m,0,NIL) ; return MERRMEM ; }
	char* out=(char*)MMstartstr(m,buff);

	decodeState = decodeMP3(pHMp3->m_mp3,in,inmemsize,out,OBSIZE,&sizeOut);

	if( decodeState == MP3_NEED_MORE ) { MMset(m,0,NIL) ; return 0 ; }
	if( decodeState == MP3_ERR ) 
	{
		MMechostr( 1, "Error in MP3 file." ) ;
		ExitMP3( pHMp3->m_mp3 ) ;
		InitMP3( pHMp3->m_mp3 ) ;
		MMset(m,0,NIL) ;
		return 0 ;
	}                    

	out[sizeOut] = 0 ;
	MMstore(m,buff,0,sizeOut);

	MMset(m,0,PTOM(buff));
	return 0 ;
}





/////////////////////////////////////////////////////// DEFINITIONS
#define NMP3PKG 5

char * MP3name [ NMP3PKG ] = 
{
	////// TYPES
	"AsMp3",                  //  AsMp3,                   

	////// AsMp3 I/O
	"asMp3Create",			// asMp3Create
	"asMp3Destroy",			// asMp3Destroy
	"asMp3GetFrameInfo",	// asMp3GetFrameInfo
	"asMp3Decode",			// asMp3Decode

} ;

char * MP3type [ NMP3PKG ] = 
{
	////// TYPES                          
	NULL,                   //  AsMp3,                           

	////// AsMp3 I/O
	"fun [Chn] AsMp3",		// asMp3Create,
	"fun [AsMp3] I",			// asMp3Destroy,
	"fun [S] [I I I I]",	// asMp3GetFrameInfo,
	"fun [AsMp3 S] S",		// asMp3Decode 

} ;



int MP3narg [ NMP3PKG ] = 
{
	////// TYPES      
	TYPTYPE,  //  AsMp3,                           

	////// AsMp3 I/O
	1,      // _CRMp3
	1,      // asMp3Destroy
	1,		// asMp3GetFrameInfo
	2,		// asMp3Decode 
} ;




int (*MP3fun[NMP3PKG])(mmachine m)= 
{
	////// TYPES
	NULL,				//  AsMp3,                          

	////// AsMp3 I/O
	asMp3Create,				// asMp3Create
	asMp3Destroy,				// asMp3Destroy
	asMp3GetFrameInfo,	// asMp3GetFrameInfo
	asMp3Decode,			// asMp3Decode

} ;


int SCOLloadMP3(mmachine m,cbmachine w)
{
	AsMp3 = OBJregister( 0, 1, destroyAsMp3, "AsMp3" ) ;

	return PKhardpak( m, "Mp3", NMP3PKG, MP3name, MP3fun, MP3narg, MP3type ) ;
}


int SCOLfreeMP3()
{
	return 0;
}