static char rcsid[] = "@(#)$Id: help.c,v 1.34 2006/05/09 17:45:01 hurtta Exp $";

/******************************************************************************
 *  The Elm (ME+) Mail System  -  $Revision: 1.34 $   $State: Exp $
 *
 *  Modified by: Kari Hurtta <hurtta+elm@posti.FMI.FI> 
 *                           (was hurtta+elm@ozone.FMI.FI)
 ******************************************************************************
 *  The Elm Mail System 
 *
 *			Copyright (c) 1988-1992 USENET Community Trust
 *			Copyright (c) 1986,1987 Dave Taylor
 *****************************************************************************/

/*** help routine for ELM program 

***/

#include "def_elm.h"
#include "s_elm.h"

DEBUG_VAR(Debug,__FILE__,"misc");


static int display_file P_((char *file));

void help(pager_help,page, prompt_area)
     int pager_help;
     struct menu_context  *page;
     struct menu_context  *prompt_area;
{
	/** Process the request for help [section] from the user.
	    If pager_help is TRUE, then act a little differently from
	    if pager_help is FALSE (index screen)

	    If redraw is needed use menu_trigger_redraw()
	 **/

	int  ch;		/* character buffer for input */
	char *s;		/* string pointer...	      */
	int prompt_line, info_line;
	int delay_redraw = 0;

	static char *unknown_command = NULL;
	int LINES, COLUMNS;

	menu_get_sizes(page,&LINES, &COLUMNS);

	if (unknown_command == NULL) {
	    
	    unknown_command = 
		catgets(elm_msg_cat, ElmSet, 
			ElmHelpUnknownCommand,
			"Unknown command.  Use '?' for a list of commands.");
	}

 redraw:
	menu_ClearScreen(prompt_area);

	if(pager_help) {
	    print_format_center(LINES-1, 
				CATGETS(elm_msg_cat, ElmSet, ElmHelpMessage,
					"Press the key you want help for, '?' for a key list, or '.' to exit help"));
	    prompt_line = 0;
	} else {
	    menu_print_format_center(prompt_area,0,
				     CATGETS(elm_msg_cat, ElmSet, ElmHelpSystem,
					     "ELM Help System"));
	    menu_print_format_center(prompt_area,1,
				     CATGETS(elm_msg_cat, ElmSet, ElmHelpMessage,
					     "Press the key you want help for, '?' for a key list, or '.' to exit help"));
	    prompt_line = 2;
	}
	info_line = prompt_line + 1;

	do {
	    menu_PutLineX(prompt_area,
			  prompt_line, 0, 
			  CATGETS(elm_msg_cat, ElmSet, ElmHelpPrompt,
				  "Help for key: "));

	  ch = menu_ReadCh(prompt_area,REDRAW_MARK|READCH_CURSOR
			   |READCH_sig_char);
	  
	  if (ch == REDRAW_MARK) {
	      menu_ClearScreen(page);   /* clear possible redraw mark */

	      /* Call refresh routines of children */
	      menu_redraw_children(page);

	      delay_redraw++;

	      /* This clear redraw mark from prompt_area */	      
	      goto redraw;
	  }
	  if (ch == '.') 
	      break;

	  if (ch == TERMCH_interrupt_char) 
	      break;

	  s = unknown_command;

	  switch (ch) {

	  case HELP_MARK:
	    case '?': 
		display_helpfile(pager_help? PAGER_HELP : MAIN_HELP);
		menu_trigger_redraw(page);
		return;

	    case '$': if(!pager_help) s = catgets(elm_msg_cat, ElmSet, ElmHelpDollar,
"$ = Force resynchronization of the current folder. This will purge deleted mail.");
		      break;

	    case '!': s = catgets(elm_msg_cat, ElmSet, ElmHelpShell,
     "! = Escape to the UNIX shell of your choice, or just to enter commands.");
	              break;

	    case '@': if(!pager_help) s = catgets(elm_msg_cat, ElmSet, ElmHelpDebugSummary,
	   "@ = Debug - display a summary of the messages on the header page.");
		      break;

	    case '|': s = catgets(elm_msg_cat, ElmSet, ElmHelpPipe,
   "| = Pipe the current message or tagged messages to the command specified.");
		      break;

	    case '#': if(!pager_help) s = catgets(elm_msg_cat, ElmSet, ElmHelpDebugAll,
	    "# = Debug - display all information known about current message.");
		      break;

	    case '%': s = catgets(elm_msg_cat, ElmSet, ElmHelpDebugReturnAdd,
     "% = Debug - display the computed return address of the current message.");
		      break;

	    case '*': if(!pager_help)
		       s = catgets(elm_msg_cat, ElmSet, ElmHelpLastMessage,
				"* = Go to the last message in the current folder.");
		      break;

	  case LEFT_MARK:
	  case PAGEUP_MARK:
	    case '-': if(!pager_help) s = catgets(elm_msg_cat, ElmSet, ElmHelpPreviousPage,
"- = Go to the previous page of messages.  This is the same as the LEFT arrow.");
		      break;

	  case HOME_MARK:
	    case '=': if(!pager_help) s = catgets(elm_msg_cat, ElmSet, ElmHelpFirstMessage,
			"'=' = Go to the first message in the current folder.");
		      break;

	    case ' ': if(pager_help)
			s = catgets(elm_msg_cat, ElmSet, ElmHelpNextScreen,
  "<space> = Display next screen of current message (or first screen of next).");
		      else
			s = catgets(elm_msg_cat, ElmSet, ElmHelpDisplayCurrent,
				"<space> = Display the current message.");
		      break;

	  case RIGHT_MARK:
	  case PAGEDOWN_MARK:
	    case '+': if(!pager_help)
	    		s = catgets(elm_msg_cat, ElmSet, ElmHelpNextPage,
  "+ = Go to the next page of messages.  This is the same as the RIGHT arrow.");
		      break;

	  case FIND_MARK:
	    case '/': if(!pager_help)
			s = catgets(elm_msg_cat, ElmSet, ElmHelpSearchFolder,
				"/ = Search for specified pattern in folder.");
		      break;

#ifdef ENABLE_CALENDAR
	    case '<': s = catgets(elm_msg_cat, ElmSet, ElmHelpCalendar,
	       "< = Scan current message for calendar entries (if enabled).");
		      break;
#endif

	    case '>': s = catgets(elm_msg_cat, ElmSet, ElmHelpSave,
	       "> = Save current message or tagged messages to specified file.");
		      break;

	    case '^': if(!pager_help) s = catgets(elm_msg_cat, ElmSet, ElmHelpToggleStatus,
	       "^ = Toggle the Delete/Undelete status of the current message.");
		      break;

	    case 'a': if(!pager_help) s = catgets(elm_msg_cat, ElmSet, ElmHelpAliasSubmenu,
	   "a = Enter the alias sub-menu section.  Create and display aliases.");
		      break;

	    case 'b': s = catgets(elm_msg_cat, ElmSet, ElmHelpBounce,
      "b = Bounce (remail) a message to someone as if you have never seen it.");
		      break;

	    case 'C': s = catgets(elm_msg_cat, ElmSet, ElmHelpCopy,
               "C = Copy current message or tagged messages to specified file.");
		      break;

	    case 'c': if(!pager_help)
				s = catgets(elm_msg_cat, ElmSet, ElmHelpChangeFolder,
	 "c = Change folders, leaving the current folder as if 'quitting'.");
		      break;

	    case 'd': s = catgets(elm_msg_cat, ElmSet, ElmHelpDelete,
			"d = Mark the current message for future deletion.");
		      break;

	    case ctrl('D') : if(!pager_help) s = catgets(elm_msg_cat, ElmSet, ElmHelpDeletePattern,
	      "^D = Mark for deletion all messages with the specified pattern.");
		      break;

#ifdef ALLOW_MAILBOX_EDITING
	  case 'e': {
	      int ul = give_dt_enumerate_as_int(&user_level);

	      if (ul < 2)
		  break;
	      if(!pager_help) s = catgets(elm_msg_cat, ElmSet, ElmHelpEditor,
     "e = Invoke the editor on the entire folder, resynchronizing when done.");
	  }
	      break;
#endif

	  case 'E':
	      if(!pager_help) s = catgets(elm_msg_cat, ElmSet, ElmHelpExtendedCommand,
		  "E = Extended command prefix.");
	      break;

	    case 'f': s = catgets(elm_msg_cat, ElmSet, ElmHelpForward,
	"f = Forward the current message to someone, return address is yours.");
		      break;

	    case 'g': s = catgets(elm_msg_cat, ElmSet, ElmHelpGroupReply,
   "g = Group reply not only to the sender, but to everyone who received msg.");
		      break;

	    case 'h': s = catgets(elm_msg_cat, ElmSet, ElmHelpDisplayHeaders,
		 "h = Display message with all Headers (ignore weedout list).");
	              break;

	    case 'i': if(pager_help)
			s = catgets(elm_msg_cat, ElmSet, ElmHelpReturnToIndex,
				"i = Return to the index.");
		      break;
	  case 'I': s = catgets(elm_msg_cat, ElmSet, ElmHelpList,
"I = Display a mailing list information of current message.");
	              break;

	    case 'J': s = catgets(elm_msg_cat, ElmSet, ElmHelpNextMessage,
			"J = Go to the next message.");
		      break;

	  case DOWN_MARK:
	    case 'j': s = catgets(elm_msg_cat, ElmSet, ElmHelpNextUndeleted,
  "j = Go to the next undeleted message.  This is the same as the DOWN arrow.");
		      break;

	    case 'K': s = catgets(elm_msg_cat, ElmSet, ElmHelpPreviousMessage,
			"K = Go to the previous message.");
		      break;

	  case UP_MARK:
	    case 'k': s = catgets(elm_msg_cat, ElmSet, ElmHelpPreviousUndeleted,
"k = Go to the previous undeleted message.  This is the same as the UP arrow.");
		      break;

	    case 'l': if(!pager_help)
			s = catgets(elm_msg_cat, ElmSet, ElmHelpLimitDisplay,
               "l = Limit displayed messages based on the specified criteria.");
		      break;

	    case 'm': s = catgets(elm_msg_cat, ElmSet, ElmHelpSendMail,
		 "m = Create and send mail to the specified person or persons.");
		      break;

	    case 'n': if(pager_help)
		          s = catgets(elm_msg_cat, ElmSet, ElmHelpDisplayNext,
				"n = Display the next message.");
		      else
			s = catgets(elm_msg_cat, ElmSet, ElmHelpDisplayThenNext,
	   "n = Display the current message, then move current to next message.");
		      break;

	    case ctrl('N'): if(pager_help)
		                s = catgets(elm_msg_cat, ElmSet, 
					    ElmHelpDisplayNextU,
				"^N = Display the next unread message.");
	                    else
				s = catgets(elm_msg_cat, ElmSet, 
					    ElmHelpDisplayThenNextU,
	"^N = Display the message, then move current to next unread message.");
		      break;


	    case 'o': if(!pager_help)
			s = catgets(elm_msg_cat, ElmSet, ElmHelpOptionsMenu,
				"o = Go to the options submenu.");
	              break;

	    case 'p': s = catgets(elm_msg_cat, ElmSet, ElmHelpPrint,
		      "p = Print the current message or the tagged messages.");
	              break;

	    case 'P': s = catgets(elm_msg_cat, ElmSet, ElmHelpTextPrint,
		      "P = Print the text of current message or the tagged messages.");
	              break;


	    case 'q': if(pager_help)
			s = catgets(elm_msg_cat, ElmSet, ElmHelpQuitPager,
			  "q = Quit the pager and return to the index.");
		      else s = catgets(elm_msg_cat, ElmSet, ElmHelpQuitMailer,
		    "q = Quit the mailer, asking about deletion, saving, etc.");
		      break;

	    case 'r': s = catgets(elm_msg_cat, ElmSet, ElmHelpReplyMessage,
"r = Reply to the message.  This only sends to the originator of the message.");
	              break;

	  case 'R': s = catgets(elm_msg_cat, ElmSet, ElmHelpGenericReply,
"R = Generic Reply -command prefix. This includes sending mail to mailing list.");
	              break;


	    case 's': s = catgets(elm_msg_cat, ElmSet, ElmHelpSaveMessage,
               "s = Save current message or tagged messages to specified file.");
		      break;
	    case 'S': s = catgets(elm_msg_cat, ElmSet, ElmHelpSaveTextMessage,
               "S = Save text current message or tagged messages to specified file.");
		      break;

	    case 't': s = catgets(elm_msg_cat, ElmSet, ElmHelpTagMessage,
               "t = Tag a message for further operations (or untag if tagged).");
		      break;

	    case 'T': s = catgets(elm_msg_cat, ElmSet, ElmHelpTagAndNext,
               "T = Tag a message (or untag if tagged) and go to next message.");
		      break;

	    case ctrl('T') : if(!pager_help)
			s = catgets(elm_msg_cat, ElmSet, ElmHelpTagPattern,
			    "^T = Tag all messages with the specified pattern.");
		      break;

	    case 'u': s = catgets(elm_msg_cat, ElmSet, ElmHelpUndeleteMessage,
				  "u = Undelete - remove the deletion mark on the message.");
		      break;
            case 'U': s = catgets(elm_msg_cat, ElmSet, ElmHelpUnreadMessage,
				  "U = Unread - change status from read to unread.");
		      break;

	    case ctrl('U') : s = catgets(elm_msg_cat, ElmSet, ElmHelpUndeletePattern,
		      "^U = Undelete all messages with the specified pattern.");
		      break;
            case 'v':  s = catgets(elm_msg_cat, ElmSet, ElmHelpViewAttach,
				   "v = View Attachments in current message.");
		break;

	  case 'V': 
	      s = catgets(elm_msg_cat, ElmSet, ElmHelpViewDigest,
			  "v = View digest as mailbox.");
	      break;

	    case 'x': s = catgets(elm_msg_cat, ElmSet, ElmHelpExitFolder,
			"x = Exit leaving the folder untouched, ask permission if changed.");
		      break;

	    case 'X': s = catgets(elm_msg_cat, ElmSet, ElmHelpQuickExit,
			"X = Exit leaving the folder untouched, unconditionally.");
		      break;

	    case 'Q': if(!pager_help)
			s = catgets(elm_msg_cat, ElmSet, ElmHelpQuickQuit,
		"Q = Quick quit the mailer, save read, leave unread, delete deleted.");
		      break;

	    case '\n':
	    case '\r': if(pager_help)
			 s = catgets(elm_msg_cat, ElmSet, ElmHelpScrollForward,
  "<return> = Display current message, or (builtin pager only) scroll forward.");
		       else
			 s = catgets(elm_msg_cat, ElmSet, ElmHelpDisplayCurrentMessage,
				"<return> = Display the current message.");
		       break;

	    case ctrl('L'): if(!pager_help)
			s = catgets(elm_msg_cat, ElmSet, ElmHelpRewriteScreen,
				"^L = Rewrite the screen.");	
		       break;

            case ctrl('?'):					    /* DEL */
	    case ctrl('Q'): if(!pager_help)
				s = catgets(elm_msg_cat, ElmSet, ElmHelpExitQuickly,
					"Exit the mail system quickly.");
		       break;

	  case EOF: leave(0);   /* ????  global reference */
	      break;

	    default : if (isdigit(ch) && !pager_help) 
	            s = catgets(elm_msg_cat, ElmSet, ElmHelpMakeMessageCurrent,
			"<number> = Make specified number the current message.");
	  }

	  menu_ClearLine(prompt_area,info_line);
	  Centerline(info_line, s, prompt_area);

	} while (ch != '.');

	if (delay_redraw) 
	    menu_trigger_redraw(page);

	menu_trigger_redraw(prompt_area);
	return;
}

int display_helpfile(section)
     int section;
{
	/*** Help me!  Read file 'helpfile.<section>' and echo to screen ***/

	char buffer[SLEN];

	elm_sfprintf(buffer, sizeof buffer,
		     FRM("%s/%s.%d"), helphome, helpfile, section);
	return(display_file(buffer));
}

static int display_file(file)
     char *file;
{
    /*** Display file to screen ***/
    
    FILE *fileptr;
    int  lines=0;
    char buffer[SLEN];

    /* This routine is used to print helpfiles, which
       are not user writable directory, sho that is not actually
       problem */
    int err = can_open(file,"r");

    struct menu_context  *page = NULL;
    int LINES, COLUMNS;
    long oldpos = 0;

    if (err) {
	lib_error(CATGETS(elm_msg_cat, ElmSet, ElmHelpCouldntOpenFile,
			  "Couldn't open file %s."), 
		  file);
	return(FALSE);
    }

	if ((fileptr = fopen(file,"r")) == NULL) {
	  DPRINT(Debug,1,
		 (&Debug,
		  "Error: Couldn't open file %s (help)\n", file));
	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmHelpCouldntOpenFile,
			    "Couldn't open file %s."), 
		    file);
	  return(FALSE);
	}
	
	page = new_menu_context();

 redraw:
	menu_ClearScreen(page);

	menu_get_sizes(page,&LINES, &COLUMNS);

	while (fgets(buffer, SLEN, fileptr) != NULL) {
	    if (lines > LINES-4) {
		int X;
		menu_PutLineX(page,LINES-1, 0, 
			      CATGETS(elm_msg_cat, ElmSet, 
				      ElmHelpPressSpaceToContinue,
				      "Press <space> to continue, 'q' to return."));
		X = menu_ReadCh(page,READCH_sig_char|REDRAW_MARK);
		if(X == 'q' || X == 'Q' ||
		   X == TERMCH_interrupt_char) {
		    clear_error();
		    fclose(fileptr);
		    
		    goto OUT;
		}

		if (REDRAW_MARK == X) {
		    fseek(fileptr,oldpos,SEEK_SET);
		    lines = 0;
		    goto redraw;
		}

		lines = 0;
		menu_ClearScreen(page);
		oldpos = ftell(fileptr);
		Write_to_screen(FRM("%s\r"), buffer);
	    }
	    else 
		Write_to_screen(FRM("%s\r"), buffer);
	    
	    lines += strlen(buffer)/COLUMNS + 1;
	}
	
        PutLineX(LINES-1, 0, 
		 CATGETS(elm_msg_cat, ElmSet, 
			 ElmHelpPressAnyKeyToReturn,
			 "Press any key to return."));
	{ 
	    int X =  menu_ReadCh(page,REDRAW_MARK);
	    if (X == REDRAW_MARK) {
		fseek(fileptr,oldpos,SEEK_SET);
		lines = 0;
		goto redraw;
	    }

	}
	clear_error();

	fclose(fileptr);

 OUT:

	erase_menu_context(&page);
	return(TRUE);
}

/*
 * Local Variables:
 *  mode:c
 *  c-basic-offset:4
 *  buffer-file-coding-system: iso-8859-1
 * End:
 */


syntax highlighted by Code2HTML, v. 0.9.1