/*  MikMod example player
        (c) 2003 Raphael Assenat -- see file AUTHORS for complete list.
	(c) 1998, 1999 Miodrag Vallat and others - see file AUTHORS for
	complete list.

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at your option) any later version.
 
	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.
 
	You should have received a copy of the GNU General Public License
	along with this program; if not, write to the Free Software
	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
	02111-1307, USA.
*/

/*==============================================================================

  $Id: player.h,v 1.13 2003/10/08 02:08:48 raph Exp $

  Module player example of MikMod

==============================================================================*/

#ifndef PLAYER_H
#define PLAYER_H

#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
#if !defined(PATH_MAX) && defined(_POSIX_PATH_MAX)
#define PATH_MAX _POSIX_PATH_MAX
#endif
#ifndef PATH_MAX
#define PATH_MAX 256
#endif

#if defined(__OS2__)||defined(__EMX__)||defined(WIN32)
#define strcasecmp(s,t) stricmp(s,t)
#define filecmp strcasecmp
#else
#define filecmp strcmp
#endif

#define MIN(a,b) ((a)<(b)?(a):(b))
#define BTST(v,m) ((v)&(m)?1:0)

/*========== Messages */

#define version "3.2.1"

#if defined(__OS2__)||defined(__EMX__)
#define mikversion "-= MikMod/2 " version " =-"
#else
#define mikversion "-= MikMod " version " =-"
#endif

#define mikcopyr mikversion \
"\n(c) 2003, Raphael Assenat and others - see file AUTHORS for complete list"\
"\n(c) 1998, 1999 Miodrag Vallat and others - see file AUTHORS for complete list"

#define mikbanner mikcopyr "\n\n" \
" - MikMod authors and contributors are :\n"                                   \
"   Jean-Philippe Ajirent - Peter Amstutz - Anders Bjoerklund\n"               \
"   Dimitri Boldyrev - Peter Breitling - Arne de Bruijn - Douglas Carmichael\n"\
"   Chris Conn - Arnout Cosman - Shlomi Fish - Paul Fisher - Tobias Gloth\n"   \
"   Roine Gustaffson - Bjornar Henden - Stephan Kanthak - Alexander Kerkhove\n"\
"   ``Kodiak'' - Mario Koeppen - Mike Leibow - Andy Lo A Foe - Frank Loemker\n"\
"   Sylvain Marchand - Claudio Matsuoka - Jeremy McDonald - Steve McIntyre\n"  \
"   Brian McKinney - ``MenTaLguY'' - Jean-Paul Mikkers - Thomas Neumann\n"     \
"   C Ray C - Steffen Rusitschka - Jake Stine - Stefan Tibus - Tinic Urou\n"   \
"   Miodrag Vallat - Raphael Assenat - Kev Vance - Lutz Vieweg - Vince Vu\n"   \
"   Valtteri Vuorikoski\n"                                                     \
"\n"                                                                           \
" - This program is free software covered by the GNU General Public License\n" \
"   and comes with ABSOLUTELY NO WARRANTY.\n"                                  \
"\nType 'mikmod -h' for command line options!\n" 

#define pausebanner \
"'||''|.    |   '||'  '|' .|'''.| '||''''| '||''|.  \n" \
" ||   ||  |||   ||    |  ||..  '  ||  .    ||   || \n" \
" ||...|' |  ||  ||    |   ''|||.  ||''|    ||    ||\n" \
" ||     .''''|. ||    | .     '|| ||       ||    ||\n" \
".||.   .|.  .||. '|..'  |'....|' .||.....|.||...|' \n"

#define extractbanner \
"'||''''|          .                         .   ||               \n" \
" ||  .   ... ....||. ... ..  ....    .... .||. ... .. ...   ... .\n" \
" ||''|    '|..'  ||   ||' '''' .|| .|   '' ||   ||  ||  || || || \n" \
" ||        .|.   ||   ||    .|' || ||      ||   ||  ||  ||  |''  \n" \
".||.....|.|  ||. '|.'.||.   '|..'|' '|...' '|.'.||..||. ||.'||||.\n" \
"                                                          .|....'\n"
#define loadbanner \
"'||'                          '||   ||                 \n" \
" ||         ...    ....     .. ||  ...  .. ...    ... .\n" \
" ||       .|  '|. '' .||  .'  '||   ||   ||  ||  || || \n" \
" ||       ||   || .|' ||  |.   ||   ||   ||  ||   |''  \n" \
".||.....|  '|..|' '|..'|' '|..'||. .||. .||. || .'||||.\n" \
"                                                .|....'\n"

/*========== Playlist */

#define PL_CONT_NEXT (1)
#define PL_CONT_PREV (2)
#define PL_CONT_POS  (3)

#define PM_MODULE  (1)  /* Module repeatly */
#define PM_MULTI   (2)  /* PlayList repeatly */
#define PM_SHUFFLE (4)  /* shuffle PlayList */
#define PM_RANDOM  (8)  /* PlayList in random order */

#define PL_IDENT "MikMod playlist\n"

typedef struct {
	CHAR *file;
	CHAR *archive;
	int time;
	BOOL played;
} PLAYENTRY;

typedef struct {
	int current;
	int numused;
	PLAYENTRY* entry;
	int add_pos;
} PLAYLIST;

extern PLAYLIST playlist;

extern BOOL PL_isPlaylistFilename(CHAR*);
extern void PL_InitList(PLAYLIST*);
extern void PL_InitCurrent(PLAYLIST*);
extern void PL_ClearList(PLAYLIST*);

extern int PL_GetCurrentPos(PLAYLIST*);
extern PLAYENTRY *PL_GetCurrent(PLAYLIST*);
extern PLAYENTRY *PL_GetEntry(PLAYLIST*,int);
extern int PL_GetLength(PLAYLIST*);
extern void PL_SetTimeCurrent(PLAYLIST*,long);
extern void PL_SetPlayedCurrent(PLAYLIST*);

extern BOOL PL_DelEntry(PLAYLIST*,int);
extern BOOL PL_DelDouble(PLAYLIST*);
extern void PL_Add(PLAYLIST*,CHAR*,CHAR*,int,BOOL);
extern void PL_StartInsert(PLAYLIST*,int);
extern void PL_StopInsert(PLAYLIST*);

extern BOOL PL_Load(PLAYLIST*,CHAR*);
extern BOOL PL_Save(PLAYLIST*,CHAR*);
extern char* PL_GetFilename(void);
extern BOOL PL_LoadDefault(PLAYLIST*);
extern BOOL PL_SaveDefault(PLAYLIST*);

/* Get new playlist entry and change current accordingly */
extern BOOL PL_ContNext(PLAYLIST*,CHAR**,CHAR**,int);
extern BOOL PL_ContPrev(PLAYLIST*,CHAR**,CHAR**);
extern BOOL PL_ContPos(PLAYLIST*,CHAR**,CHAR**,int);

extern void PL_Sort(PLAYLIST*,int(*)(PLAYENTRY*,PLAYENTRY*));
extern void PL_Randomize(PLAYLIST*,BOOL);

/*========== Archive support */

extern CHAR *MA_dearchive(CHAR*,CHAR*);
extern void MA_FindFiles(PLAYLIST*,CHAR*);

#if defined(__OS2__)||defined(__EMX__)
#define PATH_SEP '\\'
#define PATH_SEP_STR "\\"
#else
#define PATH_SEP '/'
#define PATH_SEP_STR "/"
extern BOOL DropPrivileges(void);
#endif

/*========== Configuration file */

#define RENICE_NONE (0)
#define RENICE_PRI  (1)
#define RENICE_REAL (2)

typedef struct {
	int  driver;       /* nth driver for output */
#if LIBMIKMOD_VERSION >= 0x030107
	char *driveroptions;
#endif
	BOOL stereo;       /* mono/stereo output */
	BOOL mode_16bit;   /* 8/16 bit output */
	int  frequency;    /* mixing frequency */
	BOOL interpolate;  /* Use interpolate mixing */
	BOOL hqmixer;      /* Use high-quality (but slow) mixer */
	BOOL surround;     /* surround mixing */
	int  reverb;       /* reverb amount (0-15) */

	int  volume;       /* volume from 0% (silence) to 100% */
	BOOL volrestrict;  /* restrict playervolume to volume supplied by user */
	BOOL fade;         /* allow volume fade at the end of the module */
	BOOL loop;         /* allow in-module loops */
	BOOL panning;      /* process panning effects */
	BOOL extspd;       /* extended protracker effects */

	int playmode;      /* PM_MODULE | PM_MULTI | PM_SHUFFLE | PM_RANDOM*/
	BOOL exit_after;    /* Exit after reaching the end of the playlist */
	BOOL curious;      /* look for hidden patterns in module */
	BOOL tolerant;     /* don't halt on file access errors */
	int  renice;       /* RENICE_xxx */
	int statusbar;     /* size of statusbar */
	BOOL color;        /* use color in gui */
	BOOL xterm_title;  /* set the xterm(or equivalent title)? */
	BOOL save_config;  /* save config on exit */
	BOOL save_playlist;/* save playlist on exit */
	char *pl_name;     /* current playlist name */
	BOOL fullpaths;    /* display full path of the filenames */
} CONFIG;

extern CONFIG config;

extern char* CF_GetFilename(void);
extern void CF_set_string(char**,char*,int);
extern void CF_Init(CONFIG*);
extern BOOL CF_Save(CONFIG*);
extern BOOL CF_Load(CONFIG*);

/*========== Display */

/* maximum screen width we handle */
#define MAXWIDTH (200)

/* storage buffer length - used everywhere */
#define STORAGELEN MAXWIDTH+80+1

extern char storage[STORAGELEN];

#define DISPLAY_ROOT    (0)
#define DISPLAY_HELP    (1)
#define DISPLAY_SAMPLE  (2)
#define DISPLAY_INST    (3)
#define DISPLAY_COMMENT (4)
#define DISPLAY_LIST    (5)
#define DISPLAY_CONFIG  (6)

typedef enum {
	COM_NONE,
	MENU_ACTIVATE
} COMMAND;

extern void init_display(void);
extern void exit_display(void);

extern void display_message(char*);

extern void display_status(void);
extern void display_header(void);

extern void display_start(void);

extern void display_extractbanner(void);
extern void display_loadbanner(void);
extern void display_pausebanner(void);

extern void set_term_title(char *songname);

void display_init(void);

/*========== Player control */

extern void Player_SetNextMod(int);
extern void Player_SetConfig(CONFIG*);

/*========== Keycodes */

#define CTRL_A  1
#define CTRL_B  2
#define CTRL_D  4
#define CTRL_E  5
#define CTRL_F  6
#define CTRL_K 11
#define CTRL_L 12
#define CTRL_U 21
#define KEY_ASCII_DEL 127

#if defined(__OS2__)||defined(__EMX__)
#define KEY_UP (0x100|72)
#define KEY_DOWN (0x100|80)
#define KEY_LEFT (0x100|75)
#define KEY_RIGHT (0x100|77)
#define KEY_NPAGE (0x100|81)
#define KEY_PPAGE (0x100|73)
#define KEY_HOME (0x100|71)
#define KEY_END (0x100|79)
#define KEY_ENTER ('\n')
#define KEY_DC (127)
#define KEY_BACKSPACE (8)
#define KEY_F(x) (0x100|(58+(x)))
#define KEY_SF(x) (0x100|(83+(x)))
#endif

#endif
