/**************************************************************************/
/**	File:  		Simu.C										                	 **/
/**	Author:  	Terry W. Jackson													 **/
/**	Company:		U. S. Nuclear Regulatory Comm.								 **/
/**	Date:			March 11, 1997													    **/
/**----------------------------------------------------------------------**/
/**	Description:  This file decodes the appropriate simulation code or **/
/**					  setpoint change and performs setpoint changes.		 **/
/**----------------------------------------------------------------------**/
/**	Functions Called:											                   **/
/**																							 **/
/**	display - displays messages on the message and command window		 **/
/**                                                                      **/
/**************************************************************************/
#include <alloc.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include "gwrps.h"

/********************* External Function Prototypes ***********************/
extern void display(message_type *message, char *command);
														/* Displays message and command */

/********************** External Global Variables *************************/
extern int SIMULATE;								/* Which variable to simulate   */
extern int RESET;									/* Reset variables				  */
extern int TRIP;									/* Enable simulation system	  */

/********************* External Setpoint Variables ************************/
extern SRNF_Type Source_Range_Setpoint;
extern int Intermed_Range_Setpoint;
extern int Low_Power_Range_Setpoint;
extern int High_Power_Range_Setpoint;
extern int Neg_Delta_Flux_Setpoint;
extern int Pos_Delta_Flux_Setpoint;
extern int OT_Delta_Setpoint;
extern int OP_Delta_Setpoint;
extern int Low_Press_Setpoint;
extern int High_Press_Setpoint;
extern int High_Press_Level_Setpoint;
extern int Cool_Flow_Setpoint;
extern int Low_Low_SG_Level_Setpoint;
extern int Low_SG_Level_Setpoint;
extern int Bus_UVolt_Setpoint;
extern int Bus_UFreq_Setpoint;
extern int Oil_Press_Setpoint;

/************************** Function Prototypes ***************************/
void simulate(int code);						/* Simulates various trips		  */
void setpoint(int code, char *char_val);	/* Changes setpoints				  */
void nuc_sim(void);								/* For testing purposes			  */


/**************************************************************************/
/********************************* Simu ***********************************/
/**************************************************************************/
/*  Inputs:  code - the type of simulation to perform  						  */
/*                                                                        */
/*  Outputs:  none                                                        */
/*                                                                        */
/*  Description:  Deciphers and presents the message for user selected    */
/*			simulations.																	  */
/**************************************************************************/

void simulate(int code)
{
	message_type *message;							/* Pointer to message struc. */
	char *command = "                    ";	/* Blank command line		  */

	message = calloc(1, sizeof(message_type));/* Mem. alloc. for messages  */
   RESET = TRUE;										/* Reset variables			  */
	switch (code)										/* Determine the simulation  */
	{
		case 0:
			strcpy(message->line_1, "Normal Operation");
			message->line_2[0] = '\0';
			message->line_3[0] = '\0';
			message->line_4[0] = '\0';
			display(message, command);
			SIMULATE = 0;
			TRIP = FALSE;
			break;
		case 1:
			strcpy(message->line_1, "Simulating Source");
			strcpy(message->line_2, "Range Hi Neutron");
			strcpy(message->line_3, "Flux Trip...");
			message->line_4[0] = '\0';
			display(message, command);
			SIMULATE = 1;
			RESET = TRUE;
			TRIP = FALSE;
			break;
		case 2:
			strcpy(message->line_1, "Simulating Inter-");
			strcpy(message->line_2, "mediate Range Hi");
			strcpy(message->line_3, "Neutron Flux Trip...");
			message->line_4[0] = '\0';
			display(message, command);
			SIMULATE = 2;
			RESET = TRUE;
			TRIP = FALSE;
			break;
		case 3:
			strcpy(message->line_1, "Simulating Power");
			strcpy(message->line_2, "Range Low Neutron");
			strcpy(message->line_3, "Flux Trip...");
			message->line_4[0] = '\0';
			display(message, command);
			SIMULATE = 3;
			RESET = TRUE;
			TRIP = FALSE;
			break;
		case 4:
			strcpy(message->line_1, "Simulating Power");
			strcpy(message->line_2, "Range Hi Neutron");
			strcpy(message->line_3, "Flux Trip...");
			message->line_4[0] = '\0';
			display(message, command);
			SIMULATE = 4;
			RESET = TRUE;
			TRIP = FALSE;
			break;
		case 5:
			strcpy(message->line_1, "Simulating High");
			strcpy(message->line_2, "Positive Neutron");
			strcpy(message->line_3, "Flux Rate Trip...");
			message->line_4[0] = '\0';
			display(message, command);
			SIMULATE = 5;
			RESET = TRUE;
			TRIP = FALSE;
			break;
		case 6:
			strcpy(message->line_1, "Simulating High");
			strcpy(message->line_2, "Negative Neutron");
			strcpy(message->line_3, "Flux Rate Trip...");
			message->line_4[0] = '\0';
			display(message, command);
			SIMULATE = 6;
			RESET = TRUE;
			TRIP = FALSE;
			break;
		case 7:
			strcpy(message->line_1, "Simulating Over");
			strcpy(message->line_2, "Temperature, Delta");
			strcpy(message->line_3, "T Trip...");
			message->line_4[0] = '\0';
			display(message, command);
			SIMULATE = 7;
			RESET = TRUE;
			TRIP = FALSE;
			break;
		case 8:
			strcpy(message->line_1, "Simulating Over");
			strcpy(message->line_2, "Power, Delta T");
			strcpy(message->line_3, "Trip...");
			message->line_4[0] = '\0';
			display(message, command);
			SIMULATE = 8;
			RESET = TRUE;
			TRIP = FALSE;
			break;
		case 9:
			strcpy(message->line_1, "Simulating Press-");
			strcpy(message->line_2, "urizer Low Pressure");
			strcpy(message->line_3, "Trip...");
			message->line_4[0] = '\0';
			display(message, command);
			SIMULATE = 9;
			RESET = TRUE;
			TRIP = FALSE;
			break;
		case 10:
			strcpy(message->line_1, "Simulating Press-");
			strcpy(message->line_2, "urzier High Pressure");
			strcpy(message->line_3, "Trip...");
			message->line_4[0] = '\0';
			display(message, command);
			SIMULATE = 10;
			RESET = TRUE;
			TRIP = FALSE;
			break;
		case 11:
			strcpy(message->line_1, "Simulating Press-");
			strcpy(message->line_2, "urizer High Level");
			strcpy(message->line_3, "Trip...");
			message->line_4[0] = '\0';
			display(message, command);
			SIMULATE = 11;
			RESET = TRUE;
			TRIP = FALSE;
			break;
		case 12:
			strcpy(message->line_1, "Simulating Low");
			strcpy(message->line_2, "Reactor Coolant");
			strcpy(message->line_3, "Flow Trip...");
			message->line_4[0] = '\0';
			display(message, command);
			SIMULATE = 12;
			RESET = TRUE;
			TRIP = FALSE;
			break;
		case 13:
			strcpy(message->line_1, "Simulating RCP Bus");
			strcpy(message->line_2, "Under Voltage Trip..");
			message->line_3[0] = '\0';
			message->line_4[0] = '\0';
			display(message, command);
			SIMULATE = 13;
			RESET = TRUE;
			TRIP = FALSE;
			break;
		case 14:
			strcpy(message->line_1, "Simulating RCP Bus");
			strcpy(message->line_2, "Under Frequency Trip");
			strcpy(message->line_3, "...");
			message->line_4[0] = '\0';
			display(message, command);
			SIMULATE = 14;
			RESET = TRUE;
			TRIP = FALSE;
			break;
		case 15:
			strcpy(message->line_1, "Simulating Low-Low");
			strcpy(message->line_2, "Steam Generator");
			strcpy(message->line_3, "Level Trip...");
			message->line_4[0] = '\0';
			display(message, command);
			SIMULATE = 15;
			RESET = TRUE;
			TRIP = FALSE;
			break;
		case 16:
			strcpy(message->line_1, "Simulating Low Steam");
			strcpy(message->line_2, "Generator Level Trip");
			strcpy(message->line_3, "...");
			message->line_4[0] = '\0';
			display(message, command);
			SIMULATE = 16;
			RESET = TRUE;
			TRIP = FALSE;
			break;
		case 17:
			strcpy(message->line_1, "Simulating Turbine");
			strcpy(message->line_2, "Oil Pressure Trip...");
			message->line_3[0] = '\0';
			message->line_4[0] = '\0';
			display(message, command);
			SIMULATE = 17;
			RESET = TRUE;
			TRIP = FALSE;
			break;
		case 18:
			strcpy(message->line_1, "Simulating");
			strcpy(message->line_2, "Turbine Stop Valve");
			strcpy(message->line_3, "Trip...");
			message->line_4[0] = '\0';
			display(message, command);
			SIMULATE = 18;
			RESET = TRUE;
			TRIP = FALSE;
			break;
		case 19:
			strcpy(message->line_1, "Simulating ESF");
			strcpy(message->line_2, "Trip...");
			message->line_3[0] = '\0';
			message->line_4[0] = '\0';
			display(message, command);
			SIMULATE = 19;
			RESET = TRUE;
			TRIP = FALSE;
			break;
		default:
			strcpy(message->line_1, "Invalid code");
			strcpy(message->line_2, "Try again...");
			message->line_3[0] = '\0';
			message->line_4[0] = '\0';
			display(message, command);
			nuc_sim();
         exit(1);
			break;
	}
	free(message);
}


/**************************************************************************/
/******************************* Setpoint *********************************/
/**************************************************************************/
/*  Inputs:  code - the type of setpoint to change		  						  */
/*				 char_val - the ascii representation of the new setpoint		  */
/*                                                                        */
/*  Outputs:  none                                                        */
/*                                                                        */
/*  Description:  Changes the setpoint according to the given code and    */
/*						the value given.													  */
/**************************************************************************/

void setpoint(int code, char *char_val)
{
message_type *message;				/* Pointer to a message structure	  */
char *command = "                    ";
char *endpointer;						/* Used in strtod							  */

message = malloc(sizeof(message_type));	/* Alloc. mem. to structure  */
switch(code)
{
case 1:
strcpy(message->line_1, "Changing setpoint");
strcpy(message->line_2, "for Source Range");
strcpy(message->line_3, "Neutron Flux");
message->line_4[0] = '\0';
display(message, command);
endpointer = strchr(char_val, 'e');
*endpointer = '\0';
Source_Range_Setpoint.mantissa = atof(char_val);
endpointer++;
Source_Range_Setpoint.exponent = atoi(endpointer);
break;
case 2:
strcpy(message->line_1, "Changing setpoint");
strcpy(message->line_2, "for Intermediate");
strcpy(message->line_3, "Range Neutron Flux");
message->line_4[0] = '\0';
display(message, command);
Intermed_Range_Setpoint = atoi(char_val);
break;
case 3:
strcpy(message->line_1, "Changing setpoint");
strcpy(message->line_2, "for Power Range");
strcpy(message->line_3, "Neutron Flux, Low");
strcpy(message->line_4, "Setpoint");
display(message, command);
Low_Power_Range_Setpoint = atoi(char_val);
break;
case 4:
strcpy(message->line_1, "Changing setpoint");
strcpy(message->line_2, "for Power Range");
strcpy(message->line_3, "Neutron Flux, High");
strcpy(message->line_4, "Setpoint");
display(message, command);
High_Power_Range_Setpoint = atoi(char_val);
break;
case 5:
strcpy(message->line_1, "Changing setpoint");
strcpy(message->line_2, "for Positive Neutron");
strcpy(message->line_3, "Flux Rate");
message->line_4[0] = '\0';
display(message, command);
Pos_Delta_Flux_Setpoint = atoi(char_val);
break;
case 6:
strcpy(message->line_1, "Changing setpoint");
strcpy(message->line_2, "for Negative Neutron");
strcpy(message->line_3, "Flux Rate");
message->line_4[0] = '\0';
display(message, command);
Neg_Delta_Flux_Setpoint = atoi(char_val);
break;
case 7:
strcpy(message->line_1, "Changing setpoint");
strcpy(message->line_2, "for Pressurizer");
strcpy(message->line_3, "Pressure, Low");
strcpy(message->line_4, "Setpoint");
display(message, command);
Low_Press_Setpoint = atoi(char_val);
break;
case 8:
strcpy(message->line_1, "Changing setpoint");
strcpy(message->line_2, "for Pressurizer");
strcpy(message->line_3, "Pressure, High");
strcpy(message->line_4, "Setpoint");
display(message, command);
High_Press_Setpoint = atoi(char_val);
break;
case 9:
strcpy(message->line_1, "Changing setpoint");
strcpy(message->line_2, "for Pressurizer");
strcpy(message->line_3, "Level");
message->line_4[0] = '\0';
display(message, command);
High_Press_Level_Setpoint = atoi(char_val);
break;
case 10:
strcpy(message->line_1, "Changing setpoint");
strcpy(message->line_2, "for Reactor Coolant");
strcpy(message->line_3, "Flow");
message->line_4[0] = '\0';
display(message, command);
Cool_Flow_Setpoint = atoi(char_val);
break;
case 11:
strcpy(message->line_1, "Changing setpoint");
strcpy(message->line_2, "for RCP Bus Voltage");
message->line_3[0] = '\0';
message->line_4[0] = '\0';
display(message, command);
Bus_UVolt_Setpoint = atoi(char_val);
break;
case 12:
strcpy(message->line_1, "Changing setpoint");
strcpy(message->line_2, "for RCP Bus Freq.");
message->line_3[0] = '\0';
message->line_4[0] = '\0';
display(message, command);
Bus_UFreq_Setpoint = atoi(char_val);
break;
case 13:
strcpy(message->line_1, "Changing setpoint");
strcpy(message->line_2, "for Low-Low Steam");
strcpy(message->line_3, "Generator Level");
message->line_4[0] = '\0';
display(message, command);
Low_Low_SG_Level_Setpoint = atoi(char_val);
break;
case 14:
strcpy(message->line_1, "Changing setpoint");
strcpy(message->line_2, "for Low Steam");
strcpy(message->line_3, "Generator Level");
message->line_4[0] = '\0';
display(message, command);
Low_SG_Level_Setpoint = atoi(char_val);
break;
case 15:
strcpy(message->line_1, "Changing setpoint");
strcpy(message->line_2, "for Turbine A/S Oil");
strcpy(message->line_3, "Pressure");
message->line_4[0] = '\0';
display(message, command);
Oil_Press_Setpoint = atoi(char_val);
break;
default:
strcpy(message->line_1, "Invalid setpoint");
strcpy(message->line_2, "change.  Try again...");
message->line_3[0] = '\0';
message->line_4[0] = '\0';
display(message, command);
break;
}
free(message);
}


/**************************************************************************/
/******************************** Nuc_Sim *********************************/
/**************************************************************************/
/*  Inputs:  none																			  */
/*                                                                        */
/*  Outputs:  none                                                        */
/*                                                                        */
/*  Description:  Covers some test cases for NUREG 6463.						  */
/**************************************************************************/

void nuc_sim(void)
{
	int i;
	int j;
	int sqr;
	char ch;

	#define square(x) x*x

	if (i & 0x01 == j | 0x02)			/* Parentheses for bitwise operations */
		i = j;
	if (ch = getch() == FALSE)			/* Parentheses for operations 		  */
		ch = 'a';
	sqr = square(3 + i);					/* Parentheses in macros				  */
	if (((ch = getch()) != 0x10) && (i < j))	/* Order of evaluation		  */
		ch = 'a';
	while(i = 0)							/* Assignment and evaluation			  */
		i == sqr;
//	thread();								/* Unix multitasking call	           */
}
