#ifndef __PLAYER_H
#define	__PLAYER_H

#include "nxpmp3.h"
#include "ff.h"

#define	SLIDE_TIMER	5

typedef struct t_pcm_data {
    int rate;
    int samples;
    struct t_pcm_data *next;
    UH raw_buffer[PCM_BSIZE];
} pcm_data;

/* We have three taks modes - Clock, MP3 player and FM radio */
typedef enum {
  TMODE_CLOCK,
  TMODE_MP3,
  TMODE_FM,
} TMODE;

typedef enum {
    C_PLAY = 0,         /* 0 */
    C_STOP,
    C_NEXT,
    C_PREV,
    C_REWIND,
    C_NEXT_ALBUM,   /* 5 */
    C_PREV_ALBUM,
    C_PAUSE,
    C_DISC,
    C_OUTPUT,
    C_INSERT,       /* 10 */
    C_REMOVE,       /* 11 */
    C_READTOC,      /* 12 */
    C_SLIDE,
} player_cmd;

enum out_device {
    O_CODEC = 0,	/* Output to Codec */
    O_USB = 1,		/* Output to USB speaker */
};

#define	MAX_SONG_NAME	64
#define	MAX_PERFORMER_NAME	64
#define	MAX_ALBUM_NAME	64

enum player_state {
    S_NODISC = 0,	/* No disc inserted */
    S_LOADING,		/* 1: Loading TOC */
    S_READY,		/* TOC is available, waiting for control */
    S_PLAYING,		/* 3: Playing a track */
    S_PAUSING,		/* In pause */
};

/* Output device dependent functions */
typedef struct {
    void (*vol_set)(int volume);	/* set output volume */
    void (*rate_set)(int rate);	/* set sampling rate */
    void (*pcm_output)(pcm_data *pcm);
    void (*init_output)(void);
    void (*stop_output)(void);
    void (*restart_output)(void);
} devfunc;

typedef struct {
    UH  p_state;	/* Player status */
    UH  o_device;	/* Output device */
    UH  o_volume;	/* Volume level 0..10 */
    UH  cur_rate;	/* Current sampling rate */
    UH  max_album;
    UH  cur_album;
    UH  max_track;
    UH  cur_track;
    UH  tmode;
    UH  img_flag;	
    UH  file_type;	/* MP3, M4A, WAV */
    ID  decoder;	/* Associated decoder task */
    UW	title_length;	/* song length in ms */
    SYSTIM  play_start;	/* Play starting timestamp */
    SYSTIM  play_suspend;	/* Play suspended timestamp */
    FIL music_file;
    FIL img_file;
    DIR slide_dir;
    UH  slide_mode;
    UH  slide_no;
    int slide_timer;
    devfunc *pdevfuncs[2];
    char song_name[MAX_SONG_NAME+1];
    char performer_name[MAX_PERFORMER_NAME+1];
    char album_name[MAX_ALBUM_NAME+1];
} Player_Status;

/* Bit definition for slide_mode */
#define SLIDE_MANUAL    0   /* Manual paging */
#define SLIDE_SHOW      1   /* Side show mode paging */
#define SLIDE_CONTROL   2   /* Control bar is visible */

/* Bit definition for have_img */
#define	IMG_NONE	0	/* No image available */
#define	IMG_THERE	1	/* Image is there */
#define	IMG_SHOWN	2	/* Image has shown */

/* File types */
#define	TYPE_MP3	0	/* MP3 file */
#define	TYPE_M4A	1	/* MPEG4 Audio used in iTune */
#define	TYPE_WAV	2	/* 44.1K Stereo Raw WAV file */

extern Player_Status *get_player();

#define	MUSIC_BUFSIZE	2048

typedef struct {
    UB music_buffer[MUSIC_BUFSIZE];
    UB *read_ptr;
    int bytes_left;
    int nFrames;
    int offset;
} Music_Data;

extern Music_Data music_data;

extern devfunc *codec_func_init(), *usb_func_init();
#endif /* __PLAYER_H */
