/*
file: hsh_genaric_kernel.c
version: $Id: hshgen_k.c,v 5.123 1995/01/18 01:24:58 hitman Exp $
purpose: Handle all main operations.
updates: All updates are handled by RCS
*/

#include <stdio.h>
#ifdef __MSDOS__
#include <conio.h>
#endif

#ifndef __MSDOS__
#	include "control.h"
#	include "hshgen_h.h"
#	include "hsh_glob.h"
#	include "statetbl.h"
#	include "bbs_director.h"
#	include "finite_kernel_version.h"
#else				/* not_MSDOS */
#	include "..\src\control.h"
#	include "..\src\hshgen_h.h"
#	include "..\src\hsh_glob.h"
#	include "..\src\statetbl.h"
#	include "..\src\bbs_director.h"
#	include "..\src\finite_kernel_version.h"
#endif				/* MSDOS */

/** Function Declarations **/
int             main(void);

int 
main(void)
{
/****************************************************************/
/*		TABLE OF CONTENTS */
/****************************************************************/
/* I want to make sure this information stays around so I am making it all static. */
	static _statetbl ProcessFile[] = {
/*                                      normal            error1          error2
Current             Function            Next              Next            Next
 state              to perform          state             state           state
 -----              -----------         ------            ------          ------*/
		{SHELL_DISPLAY, shell_display, CHECK_SPEED, SHOW_PROMPT, 0},
		{SHOW_PROMPT, show_prompt, GET_COMMAND, 0, 0},
		{LOGIN, login, SHELL_DISPLAY, 0, 0},
		{COMMAND_NOT_FOUND, command_not_found, SHOW_PROMPT, 0, 0},	/** bypass **/
		{GET_COMMAND, get_command, INTERPRETE, SHOW_PROMPT, 0},
		{INTERPRETE, interprete, INTERP_FROM_MENU, 0, 0},	/** bypass **/
		{INTERP_FROM_MENU, interp_from_menu, COMMAND_NOT_FOUND, 0, 0},	/** bypass **/
		{ERROR_HANDLE, error_handle, SHOW_PROMPT, 0, 0},
		{GOODBYE, goodbye, ERROR_HANDLE, 0, 0},
		{REDRAW_SCREEN, redraw_screen, SHOW_PROMPT, 0, 0},
		{CHECK_SPEED, check_speed, IS_BBS_RUNNING, 0, 0},
		{IS_BBS_RUNNING, is_bbs_running, DISPLAY_MENU, 0, 0},
		{DISPLAY_MENU, display_menu, SHOW_PROMPT, 0, 0},
		{DISPLAY_SCREEN, display_screen, LOGIN, 0, 0},
		{TABLEND, NULL, 0, 0, 0}
	};
/****************************************************************/


	int             idx = 0;/* The temporary hold for next state */
	int             cnt = 0;/* Loop counter. */

	static _character Channel;
	/* The Setup of all users. */
	/* Some information about the Kernel Structure. */
	fprintf(stderr, "%s, v%s, (c)%s\n\n", KPROGRAM, KVER, KCOPYRIGHT);

	/* Define where kernel starts. */
	ProcessFile[0].state = SHELL_DISPLAY;

	/*************************************************************/
	/* Send everyone to the employment agency, with an activity. */
	Channel.nextstate = DISPLAY_SCREEN;
	Channel.Activity = RUNNING;
	Channel.bypass = NO;
	/* assign the first menu */
	strcpy(Channel.Currmenu, FIRST_MENU);

	/****************************************************************/
	/****************************************************************/
	/* Main Loop and control cycle.                                 */
	while (Channel.nextstate)
		/* if state of the system player become */
		/* zero then the game has been ended   */
		/* by the system.                                          */
	{
#ifdef DEBUG
		fprintf(stderr, "** %s: while(%d) /* Channel.nextstate */ **\n", __FILE__, Channel.nextstate);
#endif
		/************************************************************/
		/* If you don't have any money don't look for things to buy! */
		if (Channel.Activity == IDLE)
		{
#ifdef DEBUG
			fprintf(stderr, "** %s(%d): I am IDLE! **\n", __FILE__, __LINE__);
#endif
			continue;
		}		/* if_channel_active */

		/************************************************************/
		/* scan the state table for the state to process            */
		for (cnt = 0; ProcessFile[cnt].state != TABLEND; cnt++)
		{
			/* find the right state? */
			if (ProcessFile[cnt].state == Channel.nextstate)
			{

				/* Zero out the idx to prevent some troubles. */
				idx = 0;

				/* call function */
				idx = (*ProcessFile[cnt].func) (&Channel);	/* this may cause
										   trouble */
#ifdef DEBUG
				fprintf(stderr, "** %s: Channel.nextstate = %d **\n", __FILE__, Channel.nextstate);
				fprintf(stderr, "** %s: Channel.bypass = %d **\n", __FILE__, Channel.bypass);
#endif
				/* Has the nextstate been bypassed? */
				switch (Channel.bypass)
				{
				case YES:
#ifdef DEBUG
					fprintf(stderr, "** %s: Case YES **\n", __FILE__);
#endif
					/* Define the nextstate with the
					   return of the above statement. */
					Channel.nextstate = idx;

					/* set the bypass switch back to
					   normal */
					Channel.bypass = NO;
					break;	/* case_YES */

				default:
#ifdef DEBUG
					fprintf(stderr, "** %s: Case Default **\n", __FILE__);
#endif
					/********************************************/
					/* Last players turn, next state is
					   defined. */
					Channel.nextstate = ProcessFile[cnt].nextstate[idx];
					break;	/* case_default */
				}	/* switch(Channel.bypass) */
				/****************************************************/
				/* break out of FOR loop                            */
				break;
			}	/* if_right_process */
		}		/* for_every_channel_in_process_table */
	}			/* while_looking_for_work */
#ifdef DEBUG
	fprintf(stderr, "** %s: while(%d) /* Out of loop */ **\n", __FILE__, Channel.nextstate);
#endif
	return (0);
}				/* hshgen_k:main */
