/*****************************************************************************

        GRAOUMF TRACKER 2
        Author: Laurent de Soras, 1996-2016

--- Legal stuff ---

This program is free software. It comes without any warranty, to
the extent permitted by applicable law. You can redistribute it
and/or modify it under the terms of the Do What The Fuck You Want
To Public License, Version 2, as published by Sam Hocevar. See
http://sam.zoy.org/wtfpl/COPYING for more details.

*****************************************************************************/



#if defined (KEYB_CURRENT_HEADER)
	#error Inclusion recursive du header KEYB.
#endif
#define	KEYB_CURRENT_HEADER

#if ! defined (KEYB_HEADER_INCLUDED)
#define	KEYB_HEADER_INCLUDED



/*\\\ INCLUDES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/

#include	"archi.h"
#include	<list>

class ConfigKey;



/*\\\ CONSTANTES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/

#define	KEYB_NBR_KEYS_MAX_GROUP	32			/* Nombre maximum de touches dans un groupe */
#define	KEYB_MAX_SECTIONS			4			/* Nombre maximum de sections par groupe de touches */
#define	KEYB_NBR_GROUPS			8			/* Nombre de groupes de touches */
#define	KEYB_NBR_KEY_2_NOTE		64			/* Nombre de touches concernees par la conversion touche => note */

/* Touches */
#define	KEYB_ASCIICODE_RETURN	13
#define	KEYB_ASCIICODE_TAB		9

enum
{
	KEYB_SCANCODE_ESC = 1,
	KEYB_SCANCODE_BACKSPACE,
	KEYB_SCANCODE_TAB,
	KEYB_SCANCODE_RETURN,
	KEYB_SCANCODE_BCKQUOTE,
	KEYB_SCANCODE_SPACE,
	KEYB_SCANCODE_CLRHOME,
	KEYB_SCANCODE_UP,
	KEYB_SCANCODE_PAGEUP,
	KEYB_SCANCODE_PADMINUS,
	KEYB_SCANCODE_LEFT,
	KEYB_SCANCODE_RIGHT,
	KEYB_SCANCODE_PADPLUS,
	KEYB_SCANCODE_END,
	KEYB_SCANCODE_DOWN,
	KEYB_SCANCODE_PAGEDOWN,
	KEYB_SCANCODE_INSERT,
	KEYB_SCANCODE_DELETE,
	KEYB_SCANCODE_NUMLOCK,
	KEYB_SCANCODE_PADSLASH,
	KEYB_SCANCODE_PADSTAR,
	KEYB_SCANCODE_PAD7,
	KEYB_SCANCODE_PAD8,
	KEYB_SCANCODE_PAD9,
	KEYB_SCANCODE_PAD1,
	KEYB_SCANCODE_PAD2,
	KEYB_SCANCODE_PAD3,
	KEYB_SCANCODE_PAD0,
	KEYB_SCANCODE_PADPOINT,
	KEYB_SCANCODE_PADENTER,
	KEYB_SCANCODE_PAD4,
	KEYB_SCANCODE_PAD5,
	KEYB_SCANCODE_PAD6,
	KEYB_SCANCODE_ROW1,	/* Commence sur le 1 */
	KEYB_SCANCODE_ROW2 = KEYB_SCANCODE_ROW1 + 12,	/* A */
	KEYB_SCANCODE_ROW3 = KEYB_SCANCODE_ROW2 + 12,	/* Q */
	KEYB_SCANCODE_ROW4 = KEYB_SCANCODE_ROW3 + 12,	/* < */
	KEYB_SCANCODE_FUNC = KEYB_SCANCODE_ROW4 + 11,	/* F1 */
	KEYB_SCANCODE_NBR_KEYS	/* Nombre de touches */
};

/* Bits d'alteration des touches */
#define	KEYB_PURE_ASCII_MASK		0x000000FF
#define	KEYB_SHIFT					0x00000100
#define	KEYB_GROUP_MASK			0x00003C00
#define	KEYB_SECTION_MASK			0x0000C000
#define	KEYB_PURE_SCAN_MASK		0x00FF0000
#define	KEYB_RSHIFT					0x01000000
#define	KEYB_LSHIFT					0x02000000
#define	KEYB_CTRL					0x04000000
#define	KEYB_ALT						0x08000000
#define	KEYB_CAPSLOCK				0x10000000
#define	KEYB_SCROLLLOCK			0x40000000

/* Masques de touche predefinis */
#define	KEYB_SCAN_MASK				(KEYB_PURE_SCAN_MASK | KEYB_RSHIFT | KEYB_LSHIFT | KEYB_CTRL | KEYB_ALT)
#define	KEYB_SCAN_MASK_2SH		(KEYB_PURE_SCAN_MASK | KEYB_SHIFT | KEYB_CTRL | KEYB_ALT)
#define	KEYB_ASCII_MASK_2SH		(KEYB_PURE_ASCII_MASK | KEYB_SHIFT | KEYB_CTRL | KEYB_ALT)

/* Numeros de fonctions */
enum	KEYB_function_numbers
{
	KEYB_FNC_END = -1,		// Indicateur de fin des donnees
	KEYB_FNC_PREV_LINE = 0,
	KEYB_FNC_NEXT_LINE,
	KEYB_FNC_CURS_LEFT,
	KEYB_FNC_CURS_RIGHT,
	KEYB_FNC_PREV_INSTR,
	KEYB_FNC_NEXT_INSTR,
	KEYB_FNC_CUR_INSTR,
	KEYB_FNC_PREV_SAMPLE,
	KEYB_FNC_NEXT_SAMPLE,
	KEYB_FNC_PREV_OCTAVE,
	KEYB_FNC_NEXT_OCTAVE,
	KEYB_FNC_PREV_COLUMN,
	KEYB_FNC_NEXT_COLUMN,
	KEYB_FNC_PREV_BAR,
	KEYB_FNC_NEXT_BAR,
	KEYB_FNC_PREV_SONGPOS,
	KEYB_FNC_NEXT_SONGPOS,
	KEYB_FNC_PREV_PRESET,
	KEYB_FNC_NEXT_PRESET,
	KEYB_FNC_DEC_STEP,
	KEYB_FNC_INC_STEP,
	KEYB_FNC_STOP_EDIT,
	KEYB_FNC_PLAY_SONG,
	KEYB_FNC_CONT_SONG,
	KEYB_FNC_PLAY_PATTERN,
	KEYB_FNC_CONT_PATTERN,
	KEYB_FNC_DEL_FIELD,
	KEYB_FNC_DEL_NOTE,
	KEYB_FNC_DEL_FX,
	KEYB_FNC_DEL_VOL,
	KEYB_FNC_DEL_W_NOTE,
	KEYB_FNC_CHG_PAD_MODE,
	KEYB_FNC_CHG_DISP_TYPE,
	KEYB_FNC_INTERPOL_ONE,
	KEYB_FNC_INTERPOL_ALL,
	KEYB_FNC_BLOCK_START,
	KEYB_FNC_BLOCK_END,
	KEYB_FNC_INSERT_LINE_TRACK,
	KEYB_FNC_INSERT_LINE_PATTERN,
	KEYB_FNC_INSERT_LINE_PRESET,
	KEYB_FNC_DELETE_LINE_TRACK,
	KEYB_FNC_DELETE_LINE_PATTERN,
	KEYB_FNC_DELETE_LINE_PRESET,
	KEYB_FNC_CUT_BLOCK,
	KEYB_FNC_COPY_BLOCK,
	KEYB_FNC_PASTE_BLOCK,
	KEYB_FNC_FIRST_LINE,
	KEYB_FNC_LAST_LINE,
	KEYB_FNC_SELECT_TRACK_PAT,
	KEYB_FNC_SELECT_TOP_LEFT,
	KEYB_FNC_SELECT_BOT_RIGHT,
	KEYB_FNC_QUICK_SAVE_MOD,
	KEYB_FNC_QUICK_SAVE_SONG,
	KEYB_FNC_QUICK_LOAD_MOD,
	KEYB_FNC_QUICK_LOAD_SONG,
	KEYB_FNC_NEW_MOD,
	KEYB_FNC_UNDO,
	KEYB_FNC_REDO,
	KEYB_FNC_PLAY_LINE,
	KEYB_FNC_PLAY_CONTEXT,
	KEYB_FNC_CHANGE_REPLAY_FREQ,
	KEYB_FNC_TRANSPOSE_U1,
	KEYB_FNC_TRANSPOSE_D1,
	KEYB_FNC_TRANSPOSE_U12,
	KEYB_FNC_TRANSPOSE_D12
};



/*\\\ TYPES & STRUCTURES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/

typedef struct
{
	LWORD		function;	/* Numero de la fonction concernee */
	LWORD		mask1;		/* Masque la touche (valeur donnee par OS_get_key) */
	LWORD		val1;			/* Si <>0, comparer avec la touche masquee */
	LWORD		mask2;		/* 2eme possibilite de touche pour la fonction */
	LWORD		val2;
	LWORD		param;		/* Reserve a la fonction en question */
	const char	*pref_name_0;
} KEYB_KEY_FUNC;

typedef struct
{
	int		nbr_keys;		// Nombre de touches definies dans ce groupe
	int		nbr_sections;	// Nombre de sections differentes dans le groupe
	struct
	{
		void		(*fnc_ptr) (int group_nbr, LWORD key_code, LWORD param);	// Pointeur sur la fonction qui implemente ce groupe de touches
		LWORD		mask;			// And avec la touche frappee
		LWORD		modifier;	// Or avec la touche comparee
	}			section [KEYB_MAX_SECTIONS];
	struct
	{
		int		code;			// Code Scan de la touche
		int		parameter;	// Parametre allant avec cette touche
	}			key [KEYB_NBR_KEYS_MAX_GROUP];
} KEYB_KEY_GROUP;



/*\\\ PROTOTYPES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/

void	KEYB_flush_keyboard_buffer (void);
bool	KEYB_get_key_group (LWORD *key_ptr, LWORD *param_ptr);
void	KEYB_print_pad_mode (char *txt_0);

/*--------------------------------------------------------------------------*/
/*      Initialisations                                                     */
/*--------------------------------------------------------------------------*/

signed int	KEYB_init_keyboard (void);
void	KEYB_restore_keyboard (void);

signed int	KEYB_read_config_list (const std::list <ConfigKey> &key_list);

/*--------------------------------------------------------------------------*/
/*      Panneau principal                                                   */
/*--------------------------------------------------------------------------*/

void	KEYB_mp_keyboard (void);
void	KEYB_mp_edit_keys (LWORD key_code);



/*\\\ VARIABLES EXTERNES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/

extern KEYB_KEY_FUNC	KEYB_mp_key_functions [];
extern KEYB_KEY_GROUP	KEYB_key_group [KEYB_NBR_GROUPS];



/*\\\ FIN DU FICHIER \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/

#endif

#undef KEYB_CURRENT_HEADER
