/*Scian.h
  Standard header for scian.
  Eric Pepke
  February 9, 1990
*/

#include "machine.h"

/*If it's computation only, no interaction or graphics.*/
#ifdef COMPONLY
#undef GRAPHICS
#undef INTERACTIVE
#endif

#define GODLIKE 

#ifdef RELEASE
#undef SOCKETS
#undef GODLIKE
#endif

#ifdef GODLIKE
#define PARANOID
#endif

#ifndef GRAPHICS
/*No graphics features at all*/
#undef WINDOWS4D
#undef MENUS4D
#undef FONTS4D
#undef CURSORS4D
#undef IRISNTSC
#undef GL4D
#undef INTERWINDRAG
#undef WINNOCLOSE
#undef NOHIDEFRAME
#undef MAKEOBJ
#endif

/*Yes, signals*/
#if 0
#define SIGNALS
#endif

#ifdef STDLIB
#include <stdlib.h>
#endif
#include <ctype.h>
#include <sys/types.h>
#ifdef INTERACTIVE
#include <device.h>
#include <fcntl.h>
#endif
#ifdef GRAPHICS
#ifdef FONTS4D
#include <fmclient.h>
#endif
#include <gl.h>
#if MACHINE == IRIS4D
#include <gl/addrs.h>
#include <gl/cg2vme.h>
#include <gl/get.h>
#endif
#else
typedef float Matrix[4][4];
#endif
#ifdef MALLOCH
#include <malloc.h>
#else
extern void *malloc();
#endif
#include <math.h>
#ifdef SOCKETS
#include <netdb.h>
#include <netinet/in.h>
#endif
#include <stdio.h>
#include <string.h>
#include <sys/dir.h>
#include <sys/file.h>
#include <sys/signal.h>
#if MACHINE == RS6000
#include <sys/machine.h>
#endif
#include <sys/param.h>
#ifdef SOCKETS
#include <sys/socket.h>
#endif
#include <sys/stat.h>
#include <sys/times.h>
#include <sys/time.h>
#if MACHINE == RS6000
#include <time.h>
#endif
#ifdef TERMIO
#include <termio.h>
#endif

#ifndef STDLIB
double strtod();
#endif

typedef int Bool;			/*Our boolean stuff*/
#define true 1
#define false 0

/*C Variable types*/
typedef float real;
typedef real Quaternion[4];

/*Bits for flags*/
#define PLAINOBJECT 	0		/*Plain object*/
#define REALARRAY	1		/*Array of real values*/
#define STRING		2		/*Single string value*/
#define INTEGER		3		/*Single integer value*/
#define REAL		4		/*Single real value*/
#define LIST		5		/*List of things*/
#define PALETTE		6		/*Palette of colors*/
#define MATRIX		7		/*Transformation matrix*/
#define WINDOW		8		/*Window*/
#define PICTURE		9		/*Picture of graphical objects*/
#define OBJECTARRAY	10		/*Array of objects*/
#define CONNECTION	11		/*Socket connection*/
#define SYMBOL		12		/*Symbol*/
#define OT_GEOMETRY	13		/*Geometry*/
#define HIGHESTFLAG	13		/*Highest flag*/

#define ISOBJECT	PLAINOBJECT	/*Kludge for backward compat.*/

#define OBJTYPEFLAGS	0xFF		/*Object type flags*/
#define OBJTYPE(flags)	((flags) & 0xFF)
#define SETOBJTYPE(flags, type)	(flags) = ((flags) & ~OBJTYPEFLAGS) | type

/*Object predicate, returns true iff theObj is an object*/
#define IsObject(theObj) ((theObj) && (OBJTYPE(((ThingPtr)(theObj)) -> flags) == PLAINOBJECT))
#define IsArray(theObj) ((theObj) && (OBJTYPE(((ThingPtr)(theObj)) -> flags) == REALARRAY))
#define IsRealArray(theObj) ((theObj) && (OBJTYPE(((ThingPtr)(theObj)) -> flags) == REALARRAY))
#define IsObjArray(theObj) ((theObj) && (OBJTYPE(((ThingPtr)(theObj)) -> flags) == OBJECTARRAY))
#define IsList(theObj) ((theObj) && (OBJTYPE(((ThingPtr)(theObj)) -> flags) == LIST))
#define IsReal(theObj) ((theObj) && (OBJTYPE(((ThingPtr)(theObj)) -> flags) == REAL))
#define IsString(theObj) ((theObj) && (OBJTYPE(((ThingPtr)(theObj)) -> flags) == STRING))
#define IsInt(theObj) ((theObj) && (OBJTYPE(((ThingPtr)(theObj)) -> flags) == INTEGER))
#define IsSymbol(theObj) ((theObj) && (OBJTYPE(((ThingPtr)(theObj)) -> flags) == SYMBOL))
#define IsPalette(theObj) ((theObj) && (OBJTYPE(((ThingPtr)(theObj)) -> flags) == PALETTE))
#define IsMatrix(theObj) ((theObj) && (OBJTYPE(((ThingPtr)(theObj)) -> flags) == MATRIX))
#define IsWindow(theObj) ((theObj) && (OBJTYPE(((ThingPtr)(theObj)) -> flags) == WINDOW))
#define IsPicture(theObj) ((theObj) && (OBJTYPE(((ThingPtr)(theObj)) -> flags) == PICTURE))
#define IsGeometry(theObj) ((theObj) && (OBJTYPE(((ThingPtr)(theObj)) -> flags) == OT_GEOMETRY))

/*NIL pointer, define so that it can cast to any pointer*/
#define NIL ((void *) 0)

#define CopyVar(d, s, v) SetVar(d, v, GetVar(s, v))

/*newp operator*/
#define newp(t)	((t *) malloc(sizeof(t)))

/*running variable, true iff running*/
extern int running;

/*running remote(ly) variable, true if running remotely*/
extern Bool runningRemote;

/*Demo mode, make text bigger and fatter*/
extern Bool demoP;

/*Use selects in scripts*/
extern Bool scriptSelectP;

/*Abort on script error*/
extern Bool abortScriptP;

/*Temporary string*/
#define TEMPSTRSIZE	400
extern char tempStr[TEMPSTRSIZE + 1];

/*Fonts*/
#define TITLEFONT	1		/*Font for big titles*/
#define SUBTITLEFONT	2		/*Subtitle font*/
#define ICONBEGFONTS	3		/*Beginning of icon fonts*/
#if 0
#define ICONFOREFONT	3		/*Font for icon foreground*/
#define ICONBACKFONT	4		/*Font for icon background*/
#define ICONSHADOWFONT	5		/*Font for icon shadow*/
#endif

/*Cursors*/
#define ARROWCURSOR	0		/*Arrow cursor*/
#define WATCHCURSOR	1		/*Watch cursor*/
#define IBEAMCURSOR	2		/*I-beam cursor*/
#define QUESTIONCURSOR	3		/*Question mark cursor*/
#define ICONCURSOR	4		/*Icon cursor*/

/*Class IDs*/
#define CLASS_ICON		1	/*Icon class*/
#define CLASS_CORRAL		2	/*Corral class*/
#define CLASS_VISWINDOW		4	/*Vis window class*/
#define CLASS_LIGHT		5	/*Class of a light*/
#define CLASS_CLOCK		6	/*Class of a clock*/
#define CLASS_OBSERVER		7	/*Class of an observer*/
#define CLASS_RENDERER		8	/*Class of a renderer*/
#define CLASS_TIMEDOBJ		9	/*Timed object class*/
#define CLASS_VISOBJ		10	/*Vis object class*/
#define CLASS_PANEL		11	/*Panel class*/
#define CLASS_DATASET		12	/*Dataset class*/
#define CLASS_FILE		13	/*File class*/
#define CLASS_TEXTBOX		14	/*Text box class*/
#define CLASS_SPACE		15	/*Space class*/
#define CLASS_DIALOG		16	/*Dialog class*/

/*Is icon predicate*/
#define IsIcon(icon) IntVarEql(icon, CLASSID, CLASS_ICON)


extern real missingData;		/*Missing data*/
extern real plusInf, minusInf;		/*Plus and minus infinity*/
#define PLUSINF		(plusInf)	/*Plus infinity*/
#define MINUSINF	(minusInf)	/*Minus infinity*/

#define SCIANDATE       "March 1, 1993" 
#define SCIANVERSION    "Version 0.742"
#define AUTOLOG				/*Automatically log for error tracking*/

/*Screen sizes*/
#ifdef XMAXSCREEN
#define CSCRWIDTH	XMAXSCREEN
#define CSCRHEIGHT	YMAXSCREEN
#define VSCRWIDTH	XMAX170
#define VSCRHEIGHT	YMAX170
#else
#define CSCRWIDTH	1280
#define CSCRHEIGHT	1024
#define VSCRWIDTH	649
#define VSCRHEIGHT	484
#endif

#define SCRWIDTH scrWidth
#define SCRHEIGHT scrHeight
extern int scrWidth, scrHeight;

#define WINBL		8
#define WINBR		8
#define WINBB		8
#define WINBT		32

#define SAFEFREE(p) if ((p)) {free((p)); (p) = 0;}

/*Handy macros*/
#ifndef MIN
#define MIN(x, y)  ((x) < (y) ? (x) : (y))
#endif
#ifndef MAX
#define MAX(x, y)  ((x) > (y) ? (x) : (y))
#endif
#ifndef ABS
#define ABS(x) ((x) < 0 ? (-(x)) : (x))
#endif
#define MAG3(m) (sqrt((m)[0] * (m)[0] + (m)[1] * (m)[1] + (m)[2] * (m)[2]));
#define NORM3(m) {float z7; z7 = 1.0 / MAG3(m); m[0] *= z7; m[1] *= z7; m[2] *= z7;}
#define MATCOPY(d, s) {int i, j; for (i = 0; i < 4; ++i) for (j = 0; j < 4; ++j) d[i][j] = s[i][j];}
#define CROSS(A, B, C) (C)[0]=(A)[1]*(B)[2]-(A)[2]*(B)[1]; (C)[1]=(A)[2]*(B)[0]-(A)[0]*(B)[2]; (C)[2]=(A)[0]*(B)[1]-(A)[1]*(B)[0];
#define DOT(A, B) ((A)[0] * (B)[0] + (A)[1] * (B)[1] + (A)[2] * (B)[2])
#define NORMALIZE(A) {register double f; f = 1.0 / sqrt((A)[0]*(A)[0] + (A)[1]*(A)[1] +(A)[2]*(A)[2]); (A)[0] *= f;(A)[1]*=f; (A)[2]*=f;}
#define REVERSE(A) (A)[0] = -(A)[0]; (A)[1] = -(A)[1]; (A)[2] = -(A)[2];
#define VECCOPY(d, s) d[0] = s[0], d[1] = s[1], d[2] = s[2]
#define BETWEENP(m, a, b) (((m) >= (a) && (m) <= (b)) || ((m) >= (b) && (m) <= (a)))
#define MULTMATRIX(a, b, r)			\
	(r)[0][0] = (a)[0][0]*(b)[0][0] + (a)[0][1]*(b)[1][0] + (a)[0][2]*(b)[2][0] + (a)[0][3]*(b)[3][0];\
	(r)[1][0] = (a)[1][0]*(b)[0][0] + (a)[1][1]*(b)[1][0] + (a)[1][2]*(b)[2][0] + (a)[1][3]*(b)[3][0];\
	(r)[2][0] = (a)[2][0]*(b)[0][0] + (a)[2][1]*(b)[1][0] + (a)[2][2]*(b)[2][0] + (a)[2][3]*(b)[3][0];\
	(r)[3][0] = (a)[3][0]*(b)[0][0] + (a)[3][1]*(b)[1][0] + (a)[3][2]*(b)[2][0] + (a)[3][3]*(b)[3][0];\
	(r)[0][1] = (a)[0][0]*(b)[0][1] + (a)[0][1]*(b)[1][1] + (a)[0][2]*(b)[2][1] + (a)[0][3]*(b)[3][1];\
	(r)[1][1] = (a)[1][0]*(b)[0][1] + (a)[1][1]*(b)[1][1] + (a)[1][2]*(b)[2][1] + (a)[1][3]*(b)[3][1];\
	(r)[2][1] = (a)[2][0]*(b)[0][1] + (a)[2][1]*(b)[1][1] + (a)[2][2]*(b)[2][1] + (a)[2][3]*(b)[3][1];\
	(r)[3][1] = (a)[3][0]*(b)[0][1] + (a)[3][1]*(b)[1][1] + (a)[3][2]*(b)[2][1] + (a)[3][3]*(b)[3][1];\
	(r)[0][2] = (a)[0][0]*(b)[0][2] + (a)[0][1]*(b)[1][2] + (a)[0][2]*(b)[2][2] + (a)[0][3]*(b)[3][2];\
	(r)[1][2] = (a)[1][0]*(b)[0][2] + (a)[1][1]*(b)[1][2] + (a)[1][2]*(b)[2][2] + (a)[1][3]*(b)[3][2];\
	(r)[2][2] = (a)[2][0]*(b)[0][2] + (a)[2][1]*(b)[1][2] + (a)[2][2]*(b)[2][2] + (a)[2][3]*(b)[3][2];\
	(r)[3][2] = (a)[3][0]*(b)[0][2] + (a)[3][1]*(b)[1][2] + (a)[3][2]*(b)[2][2] + (a)[3][3]*(b)[3][2];\
	(r)[0][3] = (a)[0][0]*(b)[0][3] + (a)[0][1]*(b)[1][3] + (a)[0][2]*(b)[2][3] + (a)[0][3]*(b)[3][3];\
	(r)[1][3] = (a)[1][0]*(b)[0][3] + (a)[1][1]*(b)[1][3] + (a)[1][2]*(b)[2][3] + (a)[1][3]*(b)[3][3];\
	(r)[2][3] = (a)[2][0]*(b)[0][3] + (a)[2][1]*(b)[1][3] + (a)[2][2]*(b)[2][3] + (a)[2][3]*(b)[3][3];\
	(r)[3][3] = (a)[3][0]*(b)[0][3] + (a)[3][1]*(b)[1][3] + (a)[3][2]*(b)[2][3] + (a)[3][3]*(b)[3][3];
#define MATBYVECTOR(a, b, r)			\
	(r)[0] = (a)[0][0]*(b)[0] + (a)[0][1]*(b)[1] + (a)[0][2]*(b)[2] + (a)[0][3];\
	(r)[1] = (a)[1][0]*(b)[0] + (a)[1][1]*(b)[1] + (a)[1][2]*(b)[2] + (a)[1][3];\
	(r)[2] = (a)[2][0]*(b)[0] + (a)[2][1]*(b)[1] + (a)[2][2]*(b)[2] + (a)[2][3];
#define SQUARE(x) ((x) * (x))
#define SKIPBLANKS(s) while (*(s) && isspace(*(s))) ++(s);
#define ZERO3(d) {(d)[0] = 0.0; (d)[1] = 0.0; (d)[2] = 0.0;}
#define COPY3(d, s) {(d)[0] = (s)[0]; (d)[1] = (s)[1]; (d)[2] = (s)[2];}
#define ADD3(d, s) {(d)[0] += (s)[0]; (d)[1] += (s)[1]; (d)[2] += (s)[2];}
#define DIV3SC(d, s) {(d)[0] /= (s); (d)[1] /= (s); (d)[2] /= (s);}

#ifdef FMATH
#define rsin(x) fsin(x)
#define rcos(x) fcos(x)
#define ratan2(x, y) fatan2(x, y)
#define rsqrt(x) fsqrt(x)
#else
#ifdef MATHF
#define rsin(x) sinf(x)
#define rcos(x) cosf(x)
#define ratan2(x, y) atan2f(x, y)
#define rsqrt(x) sqrtf(x)
#define fsin(x) sinf(x)
#define fcos(x) cosf(x)
#define fatan2(x, y) atan2f(x, y)
#define fsqrt(x) sqrtf(x)
#else
#define fsin(x) sin(x)
#define fcos(x) cos(x)
#define fatan2(x, y) atan2(x, y)
#define fsqrt(x) sqrt(x)
#define rsin(x) sin(x)
#define rcos(x) cos(x)
#define ratan2(x, y) atan2(x, y)
#define rsqrt(x) sqrt(x)
#endif
#endif

#ifndef M_PI
#define M_PI		3.14159265358979323846
#define M_PI_2		1.57079632679489661923
#define M_PI_4		0.78539816339744830962
#endif

#define SQ2     (1.414213562)
#define SQ22    (.707106)
#define SQ33	(.577735)

/*Have to define h_errno just in case*/
extern int h_errno;

/*Define heartbeat*/
#ifdef CLK_TCK
#define HEARTBEAT CLK_TCK
#else
#ifdef HZ
#define HEARTBEAT HZ
#else
#define HEARTBEAT 60
#endif
#endif

