#ifndef MMIX_H
#define MMIX_H

#define VERSION "0.3"

#include "stddefs.h"
#include "params.h"

#include <linux/soundcard.h>

/* ****** */
/* mmix.c */
typedef struct {
 int left;   /* left volume   */
 int right;  /* right volume  */
 int m;      /* muted:    0/1 */
 int s;      /* stereo: 0/1/2 */
 int r;      /* recsrc: 0/1/2 */
} vol_t;
#define R_NO  0 /* not aviable */
#define R_OFF 1 /* aviable, and is off */
#define R_ON  2 /* aviable, and is on */

struct mmix {
 struct mmix *next;               /* provide me a single list */
 int fd;                          /* file descriptor */
 char fname[25]; /* file name -> /dev/sound/mixerXY ... */
 char *mname;    /* 'name - id' */
 int devmask;    /* devmask = valid devices     -> init once */
 int recmask;    /* recmask = devices for input -> init once */
 int stereo;     /* stereo  = stereo devices    -> init once */
 int nrdevs;     /* number of valid devices     -> init once */
 int recsrc;     /* current recording sources */
 bool cfg_okay;  /* config was read */

 /* 0..9 vol_t structs
  * 0    -> current volume
  * 1..9 -> volume of configuration 1..9 */
 vol_t v[10][SOUND_MIXER_NRDEVICES];
 char *rname[SOUND_MIXER_NRDEVICES];
 char *cname[9]; /* name of config */
};

#define U_MIXDEV  1 /* mixer device */
#define U_MIXVOL  2 /* volume has changed, via extern progs */
#define U_MIXRES  4 /* volume of current resource only has changed */
#define U_MIXCFG  8 /* configuration changed */
#define U_ALL    16 /* really ALL is updated */
extern int mmix_updates;  /* what has changed */
extern int mmix_found;    /* how much devices we have  */
extern char *mmix_config; /* the configurationfile */
extern int c_mix, c_res, r_res, c_cfg;  /* current settings */
extern bool _i, _q; /* params, we may need */

extern void mmix_quit(int unused); /* handler, normal exit */
extern void mmix_error(int nr);

#define ERR_NO     0
#define ERR_DEV    1
#define ERR_CONF   2
#define ERR_TERM   3

/* ****** */
/* misc.c */
#include "misc.h"

/* ***** */
/* tty.c */
void tty_mode_init(void);
void tty_mode_restore(void);
void tty_resize(int unused);
void tty_getsize(short *x, short *y);

/* ****** */
/* draw.c */
extern short maxx,maxy;
#define draw(fmt,args...)  do { xprintf((char*)fmt,##args); } while (0)
extern void draw_flush(void);
extern void draw_str(const unsigned char *msg);
extern void draw_exit(const unsigned char *msg, int i);
extern void draw_update(struct mmix *m);
extern void draw_update_mixvol(struct mmix *m);

/* ********* */
/* formats.c */
extern int xprintf(const char *format, ...);
extern int xsprintf(char *str, const char *format, ...);
extern int xsnprintf(char *str, size_t size, const char *format, ...);
extern int xvsnprintf(char *str, size_t size, const char *format, va_list ap);
extern int xltostr(char *s, int size, unsigned long i, int base, char UpCase);

/* ******* */
/* mixer.c */
extern struct mmix *mixer_init(void); /* init all aviable mixer devices */
extern void mixer_read(struct mmix *m); /* check for changes of the given mixer */
extern int mixer_realres(struct mmix *m, int searched);
extern void mixer_write(struct mmix *m, int res, int left, int right);
extern void mixer_write_it(struct mmix *m, int res, int left, int right);
extern void mixer_write_res(struct mmix *m, int res);

/* ********** */
/* defaults.c */
#include "defaults.h"

/* ******** */
/* alloc.c */
#include "alloc.h"

/* ****** */
/* str.c */
#include "str.h"

/* aliase */
#define gotoxy(x,y)    draw(T_GOTO_XY, y, x)
#define gotoxyw(x,y,t) draw(T_GOTO_XY "%s", y, x, t)

#define isset(x) ((mmix_updates&(x))==(x))
#define unset(x) mmix_updates&=~(x)
#define set(x)   mmix_updates|=(x)

#define CTRL_X(x) (x-96)

#endif
