
/*
 * Copyright 1993, 1994, 1995 by the Regents of the University of California
 * see the file "Copyright" in the distribution for conditions of use.
 */

#include <ctype.h>
#include <curses.h>
#include <stdio.h>

#include "getch7.h"
#include "menu.h"
#include "misc.h"
#include "node.h"

int   short_cut_index;
NODE *short_cut_ptr;
MENU *short_cut_menu;

static int short_cut_count;

/*	map to map short cut letters into node numbers	*/
int sc_map[128];
char menu_letter[MAX_MENU_ENTRIES];

init_short_cuts()
{
	int i;
	char *ptr;

	/*	find short cut node & set up pointer to it */
	short_cut_index = find_node( "Short_Cuts" );
	if( short_cut_index == -1 ) fatal( "*** missing short cut menu ***");
	short_cut_ptr = node[short_cut_index];

	/*	initialize - only letters matter	*/
	for( i = 'A' ; i <= 'Z' ; i++ ) sc_map[i] = -1;
	for( i = 'a' ; i <= 'z' ; i++ ) sc_map[i] = -1;
	/*	reserved: hjklmu: navigation, aAd: bookmarks, qQ: quitting */
	for( ptr = "hjklmuaAdvqQ"; *ptr != '\0'; ptr++ ) sc_map[ *ptr ] = -2;

	/*	initialize short cut count	*/
	short_cut_count = 0;
}


wants_short_cut( node_number )
int node_number;
{
	int ch;
	int letter = -1;
	int ok = 0;

	if( short_cut_ptr == NULL ) init_short_cuts();

	if( short_cut_count >= MAX_MENU_ENTRIES - 2 ) {
		ok = -1;
		mvaddstr( LINES - 4, 0, "" );
		clrtoeol();
		mvaddstr( LINES - 3, 0,
		    "You need to delete a short cut before creating another.");
		clrtoeol();
		mvaddstr( LINES - 2, 0, "" );
		clrtoeol();
		mvaddstr( LINES - 1, 0, "" );

		raw();
		goto done;
	}

	/*	get letter to use for this short cut */
	raw();
	mvaddstr( LINES - 1, 0, "" );
	clrtoeol();
	while( letter == -1 ) {
		ask_for_letter( node_number );
		GETCH7( ch );
		if( ch == '\r' ) {
			ok = 0;
			goto cleanup;
		} else if( ch == '?' ) {
			help_enter();
			mvaddstr( LINES-1, 0, "" );
			clrtoeol();
		} else if( !isalpha(ch) ) {
			mvaddstr( LINES-1, 0,
				"You must use a letter to represent the short cut. ");
			clrtoeol();
			refresh();
		} else if( sc_map[ ch ] == -2 ) {
			mvaddstr( LINES-1 , 0, "\"");
			addch( ch );
			addstr( "\" is a menu system command and cannot be used to label a short cut" );
			clrtoeol();
			refresh();
		} else if( sc_map[ ch ] >= 0 ) {
			mvaddstr( LINES-1 , 0, "\"");
			addch( ch );
			addstr( "\" is already defined as a short cut; you must delete it to redefine it" );
			clrtoeol();
			refresh();
		} else {
			/* tis ok - use it */
			letter = ch;
		}
	}
	add_short_cut( node_number, letter );
	ok = 1;

	update_short_cuts();
	save_status();

cleanup:
	/* clear messages, tell them it is done */
	mvaddstr( LINES -4, 0, "" );
	clrtoeol();
	mvaddstr( LINES -3, 0, "" );
	clrtoeol();
	mvaddstr( LINES -2, 0, "" );
	clrtoeol();
	mvaddstr( LINES-1, 0, "" );
	if( ok ) {
		addstr( "Short cut created, " );
	} else {
		addstr( "Short cut cancelled, " );
	}
done:
	addstr( "press any key to continue. " );
	clrtoeol();
	refresh();
	GETCH7( ch );
	if( ok = -1 ) {
		mvaddstr( LINES - 3, 0, "" );
		clrtoeol();
	}
	bottom_line();
	arrow_draw( cur_line_no );
	noraw();
}

ask_for_letter( node_number )
int node_number;
{
	mvaddstr( LINES - 4, 0, "Defining short cut for:" );
	clrtoeol();
	mvaddstr( LINES - 3, 0, "     " );
	addstr( node[node_number]->nd_title );
	clrtoeol();
	mvaddstr( LINES - 2, 0, "Enter letter to represent it or ? for help: ");
	clrtoeol();
	refresh();
}

#define L1 "> Enter Return if you want to cancel the short cut."
#define L2 "> Otherwise, enter a letter for the short cut symbol."
#define L3 "> Lower and uppercase are recognized separately."

help_enter()
{
	int ignore;

	mvaddstr( LINES - 4, 0, L1 ); clrtoeol();
	mvaddstr( LINES - 3, 0, L2 ); clrtoeol();
	mvaddstr( LINES - 2, 0, L3 ); clrtoeol();
	mvaddstr( LINES-1, 0, "> Press any key to continue. " );
	clrtoeol();
	refresh();
	GETCH7( ignore );
}

add_short_cut( node_number, letter )
int node_number;
char letter;
{
	if( short_cut_count >= MAX_MENU_ENTRIES - 2 ) {
		/* should never get here */
		fatal( "too many short cuts" );
	} else {
		short_cut_count++;
		sc_map[letter] = node_number;
	}
}

update_short_cuts()
{
	MENU *menu;
	char *malloc();
	char letter;
	int i;
	int nd;

	/*
	 *	collect pointers to titles for short cut menu
	 *	and make proper node
	 */

	menu = short_cut_ptr->nd_menu;
	if( menu == NULL ) {
		menu = (MENU *)malloc( sizeof( MENU ) );
		if( menu == NULL ) fatal("malloc() failure");
		short_cut_ptr->nd_menu = menu;
		short_cut_menu = menu;
	}

	/* get menu title from node */
	menu->mn_title = short_cut_ptr->nd_title;

	for ( i = 0 ; i < MAX_MENU_ENTRIES; i++ ) {
		menu->mn_line[i] = " ";
	}
	nd = short_cut_ptr->nd_nums[0];
	menu->mn_line[0] = node[nd]->nd_title;
	i = 0;
	for( letter = 'A' ; letter <= 'z' ; letter++ ) {
		if( isalpha( letter ) && sc_map[ letter ] >= 0 ) {
			if( i >= MAX_MENU_ENTRIES ) {
				fatal("*** too many short cuts ***");
			}
			i++;
			menu_letter[i] = letter;
			menu->mn_line[i] = node[sc_map[letter]]->nd_title;
			short_cut_ptr->nd_nums[i] = sc_map[letter];
			strcpy( short_cut_ptr->nd_labs[i],
					node[sc_map[letter]]->nd_label );
		}
	}

	menu->mn_nrows = i + 1;
	short_cut_ptr->nd_n = i + 1;
	short_cut_ptr->nd_menu = menu;

	return;
}

int
delete_short_cut( )
{
	MENU *menu;

	/* delete a short cut */
	sc_map[menu_letter[cur_line_no]] = -1;
	if( short_cut_count > 0 ) short_cut_count--;

	update_short_cuts();
	menu = short_cut_ptr->nd_menu;
	save_status();
	if( menu->mn_nrows > 0 ) {
		/* delete line from short cut menu */
		if( cur_line_no > 0 ) cur_line_no--;
		display_menu( menu );
		return 1;
	} else {
		/* short cut menu now empty */
		return( 0 );
	}
}
