/*****************************************************************************
*   "Irit" - the 3d polygonal solid modeller.				     *
*									     *
* Written by:  Gershon Elber				Ver 0.2, Mar. 1990   *
******************************************************************************
* Test program of the InptPrsr.c module:				     *
* Note you can set DEBUG for InptPrsr preprocessor for intermidiate results: *
*****************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <setjmp.h>
#include <alloc.h>
#include "program.h"
#include "inptprsg.h"
#include "dosintrg.h"
#include "matherr.h"

char CurrentWorkingDir[LINE_LEN];      /* Save start CWD to recover on exit. */

struct ObjectStruct *GlblObjList = NULL;   /* All objects defined on system. */

int  WasCtrlBrk = FALSE; 	     /* True if control break/C was pressed. */
int  GlblFatalError = FALSE;	  /* True if disaster in system - must quit! */
int  LoadColor = 1, BoolColor = 2, ICrvColor = 14, PrimColor = 4;

char *HelpFileName = "irit.hlp";

jmp_buf LongJumpBuffer;			          /* Used in error recovery. */

extern unsigned int _stklen = 16384;	     /* Increase default stack size. */

static void PrintInptPrsrError(void);

/*****************************************************************************
* Simple main routine to emulate the needed parameters for InputParser:      *
*****************************************************************************/
void main(void)
{
    SetUpPredefObjects();		  /* Prepare the predefined objects. */
    fprintf(stderr, "Input Parser Test Program (type expression follows by ';'):\n");

    DosGetTime(1.0);				    /* Reset the time count. */
    AliasReset();

    /* If one long jumped to here with value 2, we must quit the program!    */
    if (setjmp(LongJumpBuffer) == 2)	          /* Used in error recovery. */
	exit(1);

    while (TRUE) {					      /* Do forever. */
	if (!InputParser())		     /* Error was found - handle it. */
	    PrintInptPrsrError();
	fprintf(stderr, "\nCurrent defined objects (Core left = %lx) :\n",
								coreleft());
	PrintObjectList(GlblObjList);
    }
}

/*****************************************************************************
* Routine to query (and print) the errors found in InputParser:		     *
*****************************************************************************/
static void PrintInptPrsrError(void)
{
    int ErrorNum;
    char *ErrorMsg;

    if ((ErrorNum = InptPrsrParseError(&ErrorMsg)) != 0) {/* Error in parse. */
	fprintf(stderr, "Parsing Error: ");
	switch(ErrorNum) {
	    case IP_ERR_WrongSyntax:
		fprintf(stderr, "Wrong syntax\n");
		break;
	    case IP_ERR_ParamExpect:
		fprintf(stderr, "Parameter Expected - %s\n", ErrorMsg);
		break;
	    case IP_ERR_OneOperand:
		fprintf(stderr, "Wrong Number of operands (1) - %s\n", ErrorMsg);
		break;
	    case IP_ERR_TwoOperand:
		fprintf(stderr, "Wrong Number of operands (2) - %s\n", ErrorMsg);
		break;
	    case IP_ERR_StackOV:
		fprintf(stderr, "Internal Stack OverFlow at - %s\n", ErrorMsg);
		break;
	    case IP_ERR_ParaMatch:
		fprintf(stderr, "Parenthesis mismatch - %s\n", ErrorMsg);
		break;
	    case IP_ERR_UndefToken:
		fprintf(stderr, "Undefined token - %s\n", ErrorMsg);
		break;
	    case IP_ERR_UndefFunc:
		fprintf(stderr, "Undefined function - %s\n", ErrorMsg);
		break;
	    case IP_ERR_NameTooLong:
		fprintf(stderr, "Object name too long - %s\n", ErrorMsg);
		break;
	    case IP_ERR_ParamFunc:
		fprintf(stderr, "Parameters expected in func %s\n", ErrorMsg);
		break;
	    case IP_ERR_NoParamFunc:
		fprintf(stderr, "No Parameters expected in func %s\n", ErrorMsg);
		break;
	}
	return;
    }

    if ((ErrorNum = InptPrsrEvalError(&ErrorMsg)) != 0) {  /* Error in eval. */
	fprintf(stderr, "Eval Error: ");
	switch(ErrorNum) {
	    case IE_ERR_FatalError:
		fprintf(stderr, "Fatal Error - %s\n", ErrorMsg);
		break;
	    case IE_ERR_DivByZero:
		fprintf(stderr, "Division by zero - %s\n", ErrorMsg);
		break;
	    case IE_ERR_NoObjMethod:
		fprintf(stderr, "No such method for object - %s\n", ErrorMsg);
		break;
	    case IE_ERR_TypeMismatch:
		fprintf(stderr, "Parameter type mismatch - %s\n", ErrorMsg);
		break;
	    case IE_ERR_AssignLeftOp:
		fprintf(stderr, "Lval is not a parameter - %s\n", ErrorMsg);
		break;
	    case IE_ERR_MixedObj:
		fprintf(stderr, "Mixed types in expression - %s\n", ErrorMsg);
		break;
	    case IE_ERR_UndefObject:
		fprintf(stderr, "No such object defined - %s\n", ErrorMsg);
		break;
	    case IE_ERR_NoAssignment:
		fprintf(stderr, "Assignment was expected\n");
		break;
	    case IE_ERR_FPError:
		fprintf(stderr, "Floating Point Error - %s\n", ErrorMsg);
		break;
	    case IE_ERR_NumPrmMismatch:
		fprintf(stderr, "Number of func. param. mismatch - %s\n", ErrorMsg);
		break;
	    case IE_ERR_MatPower:
		fprintf(stderr, "Wrong range or result exists, operator - %s\n", ErrorMsg);
		break;
	    case IE_ERR_FreeSimple:
		fprintf(stderr, "Free only Geometric Objects - %s\n", ErrorMsg);
		break;
	    case IE_ERR_ModifIterVar:
		fprintf(stderr,
		    "Iteration var. type modified or freed - %s\n", ErrorMsg);
		break;
	    case IE_ERR_BooleanErr:
		fprintf(stderr,
			"Geometric Boolean operation error - %s\n", ErrorMsg);
		break;
	    case IE_ERR_ListTooLong:
		fprintf(stderr,
			"List length too big - up to %d only.\n", MAX_OBJ_LIST);
		break;
	    case IE_ERR_NonParamInList:
		fprintf(stderr,
			"List element not an object (expression!?)\n");
		break;
	    case IE_ERR_FreeNoRefObj:
		fprintf(stderr,
			"Cannt free referenced (by others!) object %s\n", ErrorMsg);
		break;
	    case IE_ERR_DataPrsrError:
		fprintf(stderr, "%s", ErrorMsg);
		break;
	}
	return;
    }
}

/*****************************************************************************
* MyExit routine. 							     *
*****************************************************************************/
void MyExit(int ExitCode)
{
    exit(ExitCode);
}

/*****************************************************************************
* FatalEror routine. same as MyExit routine, but print error message	     *
* before it dies.							     *
*****************************************************************************/
void FatalError(char *ErrorMsg)
{
    fprintf(stderr, "%s\n", ErrorMsg);

    exit(99);
}

/*****************************************************************************
*   Routine that is called from the floating point package in case of fatal  *
* floating point error. Print error message, long jump to main loop. Default *
* FPE handler - must be reset after redirected to other module.		     *
*****************************************************************************/
void DefaultFPEHandler(int Sig, int Type, int *RegList)
{
    PrintFPError(Type);		     /* Print the floating point error type. */

    longjmp(LongJumpBuffer, 1);
}

/*****************************************************************************
*  And other emulations to the routines:				     *
*****************************************************************************/
void WndwPause()
{
    fprintf(stderr, "Pause was called, press anything:");
    getch();
}

void WndwInputWindowGetStr(char *Str, int Length)
{
    gets(Str);
}

void WndwLogPrint(RealType *R)
{
    fprintf(stderr, "Log file toggle - value = %lf\n", *R);
}

void WndwInputWindowPutStr(char *Str, int Color)
{
    printf("%s\n", Str);
}

void WndwInputWindowPutStrFS(char *Str, int Color, int Reset)
{
    printf("%s\n", Str);
}

void WndwViewGeomObject(ObjectStruct *PObj, RealType *ClearScreen)
{
    fprintf(stderr,
	"VIEW: object %s (Clear = %g)\n", PObj->Name, *ClearScreen);
}

void WndwStatusWindowUpdate()
{
    fprintf(stderr, "Core left = %lx\n", coreleft());
}

void DosChangeDir(char *s)
{
    fprintf(stderr, "CHDIR: to directory %s\n", s);
}

double DosGetTime(double ResetTime)
{
    fprintf(stderr, "Time invoked with reset = %lf\n", ResetTime);
    return 1234.5678;
}

void DosEditFile(char *s)
{
    fprintf(stderr, "Edit invoked with file \"%s\"\n", s);
}

void DosSystem()
{
    fprintf(stderr, "System invoked\n");
}

void DosPrintDir(char *s)
{
    fprintf(stderr, "Print Dir entered (%s)\n", s);
}

void InteractGeomObject(ObjectStruct *PObj, RealType *UpdateGlblMat)
{
    fprintf(stderr, "View Object entered, object %s, Update= %lf\n",
						PObj -> Name, *UpdateGlblMat);
}

void ViewGeomObject(ObjectStruct *PObj)
{
    fprintf(stderr, "View Object entered, object %s\n", PObj -> Name);
}

void ViewSetNormals(RealType *Active, RealType *Size, RealType *Color)
{
    fprintf(stderr,
	"View set normals entered, Active = %g Size = %g Color = %g\n",
		*Active, *Size, *Color);
}

void GGTone(int Freq, int Time)
{
    fprintf(stderr, "Beep invoked, Freq = %d, Time = %d\n", Freq, Time);
}
