// Emacs style mode select	 -*- C++ -*- 
//-----------------------------------------------------------------------------
//
// $Id:$
//
// Copyright (C) 1993-1996 by id Software, Inc.
//
// This source is available for distribution and/or modification
// only under the terms of the DOOM Source Code License as
// published by id Software. All rights reserved.
//
// The source is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
// for more details.
//
// DESCRIPTION:
//	 Menu widget stuff, episode selection and such.
//	  
//-----------------------------------------------------------------------------


#ifndef __M_MENU_H__
#define __M_MENU_H__

#include "d_event.h"
#include "c_cvars.h"

//
// MENUS
//
// Called by main loop,
// saves config file and calls I_Quit when user exits.
// Even when the menu is not displayed,
// this can resize the view and change game parameters.
// Does all the real work of the menu interaction.
BOOL M_Responder (event_t *ev);

// Called by main loop,
// only used for menu (skull cursor) animation.
void M_Ticker (void);

// Called by main loop,
// draws the menus directly into the screen buffer.
void M_Drawer (void);

// Called by D_DoomMain,
// loads the config file.
void M_Init (void);

// Called by intro code to force menu up upon a keypress,
// does nothing if menu is already up.
void M_StartControlPanel (void);

// [RH] Setup options menu
BOOL M_StartOptionsMenu (void);

// [BC] Setup multiplayer menu
BOOL M_StartMultiplayerMenu (void);

// [RH] Handle keys for options menu
void M_OptResponder (event_t *ev);

// [RH] Draw options menu
void M_OptDrawer (void);

// [RH] Initialize options menu
void M_OptInit (void);

struct menu_s;
void M_SwitchMenu (struct menu_s *menu);

void M_PopMenuStack (void);

// [RH] Called whenever the display mode changes
void M_RefreshModesList ();

void M_StartMessage(char *string,void (*routine)(int),BOOL input);	// [BC] You belong here, dammit

// [RH] For player setup menu.
void M_PlayerSetup (int choice);
void M_PlayerSetupDrawer (void);
void M_EditPlayerName (int choice);
void M_EditPlayerTeam (int choice);
void M_PlayerTeamChanged (int choice);
void M_PlayerNameChanged (int choice);
void M_SlidePlayerRed (int choice);
void M_SlidePlayerGreen (int choice);
void M_SlidePlayerBlue (int choice);
void M_ChangeGender (int choice);
void M_ChangeSkin (int choice);
void M_ChangeAutoAim (int choice);
void M_MoreOptions (int choice);	// [BC]

void SendNewColor (int red, int green, int blue);

// [BC] Player setup 2 menu
void M_PlayerSetupDrawer2 (void);
void M_EditTeamName (int choice);
void M_TeamNameChanged (int choice);
void M_ChangeTeam (int choice);
void M_ChangeLeader (int choice);
void M_SlideTeamRed (int choice);
void M_SlideTeamGreen (int choice);
void M_SlideTeamBlue (int choice);
void M_ChangeRocket (int choice);
void M_ChangePlasma (int choice);
void M_ChangeExpert (int choice);

// [BC] Menu flag definitions

#define MNF_ALIGNLEFT			1	// Align menu to the left
//#define MNF_
//#define MNF_
//#define MNF_

// [BC] Level flag defs for maplist
#define LV_NORMAL				1
#define LV_DEATHMATCH			2
#define LV_TEAMGAME				4

//
// MENU TYPEDEFS
//
typedef enum {
	whitetext,
	redtext,
	more,
	slider,
	discrete,
	cdiscrete,
	control,
	screenres,
	bitflag,
	listelement,
	nochoice,
	mapspot,	// [BC]
	string,
	skintype,
	number,
	maplist,
	botslot
} itemtype;

typedef struct menuitem_s {
	itemtype		  type;
	char			 *label;
	union {
		cvar_t			 *cvar;
		int				  selmode;
		int				  flagmask;
	} a;
	union {
		float			  min;		/* aka numvalues aka invflag */
		int				  key1;
		char			 *res1;
	} b;
	union {
		float			  max;
		int				  key2;
		char			 *res2;
	} c;
	union {
		float			  step;
		char			 *res3;
	} d;
	union {
		struct value_s	 *values;
		char			 *command;
		void			(*cfunc)(cvar_t *cvar, float newval);
		void			(*mfunc)(void);
		void			(*lfunc)(int);
		int				  highlight;
		int				 *flagint;
	} e;
} menuitem_t;

typedef struct menu_s {
	char			title[8];
	int				lastOn;
	int				numitems;
	int				indent;
	menuitem_t	   *items;
	void			(*routine)(void);	// [BC] These can have a draw routine now, too
	int				flags;				// [BC] Any special flags for the menu
} menu_t;

typedef struct value_s {
	float		value;
	char		*name;
	int			flags;		// [BC] Wheee...
} value_t;

typedef struct
{
	// -1 = no cursor here, 1 = ok, 2 = arrows ok
	short		status;
	
	char		name[10];
	
	// choice = menu item #.
	// if status = 2,
	//	 choice=0:leftarrow,1:rightarrow
	void		(*routine)(int choice);
	
	// hotkey in menu
	char		alphaKey;						
} oldmenuitem_t;

typedef struct oldmenu_s
{
	short				numitems;		// # of menu items
	oldmenuitem_t		*menuitems;		// menu items
	void				(*routine)(void);	// draw routine
	short				x;
	short				y;				// x,y of menu
	short				lastOn; 		// last item user was on in menu
} oldmenu_t;

typedef struct
{
	union {
		menu_t *newmenu;
		oldmenu_t *old;
	} menu;
	BOOL isNewStyle;
	BOOL drawSkull;
} menustack_t;

// [BC] Game modes
enum
{
	gm_normal,
	gm_deathmatch,
	gm_teamplay,
	gm_survival,
	gm_scoremode,
	gm_instagib,
	gm_terminator,
	gm_oldschool,
	gm_ctf
};


extern value_t YesNo[2];
extern value_t NoYes[2];
extern value_t OnOff[2];

extern menustack_t MenuStack[16];
extern int MenuStackDepth;

extern menu_t  *CurrentMenu;
extern int		CurrentItem;

extern short	 itemOn;
extern oldmenu_t *currentMenu;

#endif
