/* replay.h */
/* Plays an ARMovie sound from file or memory */
#ifndef REPLAY_H
#define REPLAY_H

#include <stddef.h>

#include "kernel.h"

#ifndef FMSTREAM_H
#include "fmstream.h"
#endif

typedef int replay_handle;
typedef struct replay_codec replay_codec;
typedef struct replay_mute replay_mute;

/* Generates a handle */
_kernel_oserror *
replay_get_handle(replay_handle *);

_kernel_oserror *
replay_initialise(void *pw);

_kernel_oserror *
replay_finalise(void);

/* Returns pollword address if handle is Replay, otherwise NULL */
int *
replay_get_pollword(replay_handle);

/* file can be a filename or address of data in memory, depending
   on from_file. Size is only needed for in-memory */
_kernel_oserror *
replay_read_headers(const char *file, size_t, int track, int from_file,
                    replay_handle *handle, const char **codec,
                    const char **sndrep, int *fps, int *fpc,
                    int *channels, int *multiplier, int *chunk_size);

_kernel_oserror *
replay_remove(replay_handle);

_kernel_oserror *
replay_remove_current(void);

_kernel_oserror *
replay_prepare_codec(replay_handle, replay_codec *, replay_mute *,
                     int frequency_int, int frequency_frac, int quality);

_kernel_oserror *
replay_setup_buffers(replay_handle, char *samp_buf, int samp_size,
                     char *file_buf, int file_size);

_kernel_oserror *
replay_complete_timing_check(replay_handle, int *quality_hint);

_kernel_oserror *
replay_play(replay_handle, int quality);

_kernel_oserror *
replay_stop(replay_handle);

/* Callback handlers */
int
replay_tick_callback(_kernel_swi_regs *r, void *pw);

int
replay_finished_callback(_kernel_swi_regs *r, void *pw);

typedef struct {
  long int offset;
  size_t size;
} replay_chunk_data;

typedef enum {
  fill_AlreadyFull,
  fill_Filled,
  fill_EndOfBuffer,
  fill_OutOfData,
  fill_Finished,
  fill_Stalled,
  fill_Error
} fill_result;

typedef struct replay_data {
  replay_codec *codec;
  replay_mute *mute;
  fill_result sfr;          /* Result of last sample buffer fill */
  void *pw;
  char semaphore;
  char ticker_registered;
  char tick_callback_registered;
  char finished_callback_registered;
  char fill_needed, finished;
  fmstream fm;
  char *(*read_line)(fmstream);
  int (*close)(fmstream);
  int (*seek)(fmstream, long int offset);
  char *(*read_bytes)(fmstream, long int offset, size_t, char *buffer);
  char *sndrep;            /* Sound replay rate (floating point) */
  char *decomp;            /* Name of decompressor */
  char *file_buf;
  char *A_buf;
  char *B_buf;
  int A_size, B_size;
  int samp_offset;
  int samp_size;
  int file_size;
  int chunk_size;
  int nchunks;
  int chunk;
  replay_chunk_data *chunks;
  int time;                /* when timing check was started */
  int pollword;            /* Zero if sample is playing */
  char reversed;
  char fill_from_A;
  /* Whether certain blocks of memory are maintained by THSound */
  char my_codec, my_mute, my_samp, my_file;
} replay_data;

extern replay_data replay_master;

#endif
