#ifndef _module_h
#define _module_h

#include "kernel.h"
#include "a52.h"

typedef unsigned char byte;

typedef struct GlobHdr GlobHdr;

typedef struct
{
	byte*   start;
	byte*   free;
	byte*   data;
	byte*   last;
	int32_t size;
	int32_t count;
} bytebuf;

typedef struct
{
	int32_t         size;
	volatile int    real_start;
	volatile int    real_free;
	volatile int	finished;
	int32_t         dummy[12];
	byte            data[1];
} dinbuf;

typedef struct
{
	int32_t         size;
	volatile int    real_start;
	volatile int    real_free;
	volatile int    finished;
	int             dummy[12];
	int16_t         data[1];
} doutbuf;

typedef struct
{
	int16_t*  start;
	int16_t*  free;
	int16_t*  data;
	int16_t*  last;
	int       size;
} sndbuf;

typedef enum
{
	  Stream_Decode_Sync       = 0
	, Stream_Decode_Frame      = 1
	, Stream_Decode_Samples    = 2
	, Stream_Decode_Finished   = 3
	, Stream_Decode_FatalError = 4
} Stream_Decode;

typedef struct
{
	int32_t channels;
	int32_t samplerate;
	int32_t bitrate;
} stream_info;

typedef struct
{
	GlobHdr*        pGlobHdr;
	// dynamic area buffers
	dinbuf*         inb;
	doutbuf*        outb;
	int             inb_area;
	int             outb_area;
	bytebuf         bitb;
	// to check params changes on new serialno
	struct
	{
		int         channels;
		int         rate;
		int         foreground;
	}               conf;
	// for position past input buffer clear
	int             usedoutb;
	// output
	sndbuf          sndb;
	// main information
	Stream_Decode   decode;
	_kernel_oserror lasterr;
	// callback
	int             saved_freesndbuf;

	// work
	a52_state_t*    pvs;
	stream_info*    info;
	uint8_t         a52buf[3840];
	uint8_t*        a52bufptr;
	uint8_t*        a52bufpos;
} stream;

void bg_task(int arg);

#endif
