/*
 * Copyright 1999 Silicon Graphics, Inc. All rights reserved.
 */
#include <lcrash.h>

/*
 * help_list() -- Print out the list of possible commands that have 'help'.
 *                This prints out duplicates as well (no little alias trick).
 */
int
help_list(command_t *cmd)
{
	int i, j, index, cur_count = 0;
	static int count = 0;
	static char **cmd_list = (char **)0;
	cmd_rec_t *cmd_rec;

	if ((cmd_rec = first_cmd_rec())) {
		do {
			cur_count++;
		} while ((cmd_rec = next_cmd_rec(cmd_rec)));
	}

	if (!count || (count < cur_count)) {
		if (cmd_list) {
			kl_free_block(cmd_list);
		}
		count = cur_count;
		cmd_list = kl_alloc_block(count * sizeof(char *), K_PERM); 
		cmd_rec = first_cmd_rec();
		for (i = 0; i < count; i++)  {
			cmd_list[i] = cmd_rec->cmd_name;
			cmd_rec = next_cmd_rec(cmd_rec);
		}
	}

	index = count / 4 + ( count % 4 ? 1 : 0);
	for (i = 0; i < index; i++) {
		fprintf(cmd->ofp, "%-17s", cmd_list[i]);
		if ((j = index + i) < count) {
			fprintf(cmd->ofp, "%-17s", cmd_list[j]);
		}
		if ((j = index * 2 + i) < count) {
			fprintf(cmd->ofp, "%-17s", cmd_list[j]);
		}
		if ((j = index * 3 + i) < count) {
			fprintf(cmd->ofp, "%-17s", cmd_list[j]);
		}
		fprintf(cmd->ofp, "\n");
	}
	return(0);
}

/*
 * help_all_list() -- Print out help on every command for 'help all'.
 */
void
help_all_list(command_t *cmd)
{
	cmd_rec_t *cmd_rec;

	cmd_rec = first_cmd_rec();
	while (cmd_rec) {
		if (!cmd_rec->real_cmd) {
			sprintf(cmd->command, "%s", cmd_rec->cmd_name);
			(*cmd_rec->cmdhelp)(cmd);
		}
		cmd_rec = next_cmd_rec(cmd_rec);
	}
}

/*
 * help_found() -- Find the index of the help item we are looking for.
 */
cmd_rec_t *
help_found(char *helpcmd)
{
	cmd_rec_t *cmd_rec;

	if ((cmd_rec = find_cmd_rec(helpcmd))) {
		if (cmd_rec->real_cmd) {
			return(cmd_rec->real_cmd);
		}
		else {
			return(cmd_rec);
		}
	}
	return((cmd_rec_t *)NULL);
}

/*
 * help_cmd() -- Run the 'help' command.
 */
int
help_cmd(command_t *cmd)
{
	int j;
	cmd_rec_t *cmd_rec; 

	/* First off, grab the command passed in.
	 */
	if (cmd->nargs < 1) {
		/* See if we didn't specify anything to get help on.
		 * If we didn't, just dump out all commands.
		 */
		help_list(cmd);
	} else {
		/* Print all help information out if 'all' is the first 
		 * argument.
		 */
		if (!strcmp(cmd->args[0], "all")) {
			help_all_list(cmd);
		}
		else {
			for (j = 0; j < cmd->nargs; j++) {
				if (!(cmd_rec = help_found(cmd->args[j]))) {
					fprintf(cmd->efp, "\nNo help exists on "
						"\"%s\".\n", cmd->args[j]);
				}
				else {
					sprintf(cmd->command, "%s", 
						cmd_rec->cmd_name);
					(*cmd_rec->cmdhelp)(cmd);
				}
			}
		}
	}
	return(0);
}

#define _HELP_USAGE "[-w outfile] [all | command_list]"

/*
 * help_usage() -- Print the usage string for the 'help' command.
 */
void
help_usage(command_t *cmd)
{
	CMD_USAGE(cmd, _HELP_USAGE);
}

/*
 * help_help() -- Print the help information for the 'help' command.
 */
void
help_help(command_t *cmd)
{
	CMD_HELP(cmd,_HELP_USAGE,
		"Display a description of the named functions, including "
		"syntax.  The 'all' option displays help information for every "
		"command.");
}

/*
 * help_parse() -- Parse the command line arguments for 'help'.
 */
int
help_parse(command_t *cmd)
{
	if (set_cmd_flags(cmd, (C_WRITE), 0)) {
		return(1);
	}
	return(0);
}

/*
 * help_complete() -- Complete arguments of 'help' command.
 */
char *
help_complete(command_t *cmd)
{
	char *ret;

	/* complete standard options (for example, -w option) arguments
	 */
	if ((ret = complete_standard_options(cmd)) != NOT_COMPLETED) {
		return(ret);
	}
	fprintf(cmd->ofp, "\n");
	help_usage(cmd);
	return(DRAW_NEW_ENTIRE_LINE);
}
