/*
 * National Center for Supercomputing Applications, University of Illinois
 *
 * This NCSA software product is public domain software.  Permission
 * is hereby granted to do whatever you like with it. Should you wish
 * to make a contribution towards the production of this software, please
 * send us your comments about your experience with the software,  why
 * you liked or disliked it, how you use it, and most importantly, how it
 * helps your work. We will receive your comments at softdev@ncsa.uiuc.edu.
 *
 * Please send bug reports to bugs@ncsa.uiuc.edu
 *
 *	Author:		Brian Calvert, NCSA
 *			bcalvert@ncsa.uiuc.edu
 */

/*
 *      File:           pv.h
 *      Contents:       Constants, defines, global variables, and function
 *			prototypes for PolyView.
 */

/*
 *      Versions:
 *      1.00            90-07-02
 *                      Initial release.  No changes from beta version.
 *
 *	1.01		90-07-20
 *			Removed "beta notices" from code.
 *			Updated PV_STR string to 1.01.
 *
 *	1.02		90-08-13
 *			Changed "render" to "draw" in view window menu.
 *			Changed "labels" description in args table.
 *			Added check for turning on polygons at start up.
 */



/* INCLUDE FILES */
#include <stdio.h>
#include <gl.h>
#include <device.h>
#include <math.h>
#include "args.h"


/* CONSTANTS */
#define FAILURE 1
#define SUCCESS 0

#define	MIN_FLOAT	-1e126
#define	MAX_FLOAT	1e127
#define PI		3.1415926535897392384625433

#define	X	0
#define	Y	1
#define	Z	2
#define	DIMS	3

#define NCSA_STR	"National Center for Supercomputing Applications"
#define	UIUC_STR	"University of Illinois at Urbana-Champaign"
#define PV_STR		"PolyView 1.02"

/* Maxima */
#define	MAXLINELEN	1024
#define	MAXPATHLEN	256
#define MAXNAMELEN	80

#define PALETTE_X	120
#define PALETTE_Y	300

#define NTSC_XSIZ       480  /* Typcally 640 */
#define NTSC_YSIZ       480  /* Typcally 480 */
#define NTSC_ASPECT     NTSC_XSIZ / NTSC_YSIZ


/* COLOR SUPPORT CONSTANTS AND MACROS */
#define	SPEC_BASE	512
#define SPEC_SIZE	254
#define	LOGO_BASE	(SPEC_BASE+SPEC_SIZE+2)
#define LOGO_SIZE	64 /* 75 */
#define BACKGROUND	(SPEC_BASE)
#define FOREGROUND	(SPEC_BASE + SPEC_SIZE + 1)
#define	MAP_COLOR(min,v,max)	(1 + (int) SPEC_BASE + (unsigned int) \
				 ( ((v-min)/(max-min))*(SPEC_SIZE-1) + 0.99) )
#define	SPEC_BLUE	0
#define SPEC_GREEN	((SPEC_SIZE/2) - 1)
#define	SPEC_RED	(SPEC_SIZE)
#define SPEC_BLACK	0
#define SPEC_WHITE	(SPEC_SIZE)
#define RGB_INCREMENT	((float) 256) / (SPEC_SIZE / 2)
#define GRAY_INCREMENT	(((float) 256) / SPEC_SIZE)

#define R	0
#define G	1
#define B	2

/* Colormap types */
#define LOAD_SPEC	0
#define RBOW_SPEC	1
#define	RGB_SPEC	2
#define GRAY_SPEC	3
#define CNTR_SPEC	4
#define MAP_SPEC	5


/* MACROS */
#define MIN(a,b)	(((a)<(b))?(a):(b))
#define ABS(a)		(((a)>=0)?(a):(-(a)))
#define MAX(a,b)	(((a)>(b))?(a):(b))
#define SQR(a)		((a)*(a))
#define	VALINC(v)	(((v) == NULL) ? 0.0 : *((v)++))
#define	VALOFF(v,o)	(((v) == NULL) ? 0.0 : *(v+o))


/* DATA STRUCTURES */
/* Window information in-memory data structure */
typedef struct windat_s {
	int win_id;
	char * data;
	int (*redraw_fn)();
	int (*event_fn)();
	int redrawn;
	int animated;
	struct windat_s * next;
} windat_t;


/* Dataset in-memory structure */
typedef struct dataset_s {
	char fn[MAXPATHLEN];
	char group[MAXNAMELEN];
	char name[MAXNAMELEN];
	int used;
	int type;
	float min;
	float max;
	long size;
	char * value;
	struct dataset_s * next;
} dataset_t;


/* Data descriptor structure */
typedef struct datadesc_s {
	char name[MAXNAMELEN];
	dataset_t * ds;
} datadesc_t;


/* Image data structure */
typedef struct image_s {
	char fn[MAXPATHLEN];
	char palette[MAXPATHLEN];
	char ris8out[MAXPATHLEN];
	char group[MAXNAMELEN];
	datadesc_t p[DIMS];
	datadesc_t connect;
	datadesc_t color;
	struct image_s * next;
} image_t;


/* Current state of the system */
typedef struct state_s {
	windat_t * window;
	int active_id;
	int menu_id;

	int at_point;
	int at_mode;
	int axes;
	int box;
	int constant;
	int depth;
	int fly_mode;
	int from_mode;
	int instrumentation;
	int labels;
	int lines;
	int ortho;
	int outlines;
	int points;
	int polygons;
} state_t;


/* Animation status */
typedef struct animation_s {
        int     reverse;
        int     time_last_redraw;
        int     forward;
        int     speed;
} animation_t;


typedef struct parse_s {
	char * word;
	int (*parse_fn) ();
} parse_t;


/* Global variables */
extern int quit_m;		/* Menu ids for window menus */
extern int vrender_m;
extern int vshade_m;
extern int voverlay_m;
extern int vproject_m;
extern int vpalette_m;
extern int vview_m;
extern int vanimate_m;
extern int view_m;

extern int nvert;		/* Number of vertices per polygon (default 4) */
extern int quit;		/* Time to quit the program? */

extern float scaling;		/* Used for orthogonal scaling */
extern float max_width;		/* Maximum width of dataset */

extern float slope;		/* Slope and  ... */
extern float origin;		/* origin of color mapping function used by */
				/* "fiddling" feature in palette window */

extern short palette[256][3];		/* Active palette color values */
extern short master_palette[256][3];	/* Master palette color values */

extern Angle view_angle;	/* Azimuthal angle in x-y plane from y axis */
extern Angle twist;		/* Viewing twist angle */
extern float rho;		/* Distance from origin */
extern float theta;		/* Azimuthal angle in x-z plane from x axis */
extern float phi;		/* Incident angle measured from y axis */
extern Coord x_off;
extern Coord y_off;
extern Coord z_off;

extern float rotation[4][4];

extern float step;		/* Step size used for flights */

extern image_t main_image;	/* The only image in the program (for 0.3) */

extern state_t current;		/* State of view (only one in 0.60) */

extern image_t * cur_image;	/* Pointer to currently displayed image */
extern image_t * images;	/* Pointer to images */
extern dataset_t * datasets;	/* Pointer to list of common datasets */
extern windat_t * windows;	/* Pointer to list of windows */
extern windat_t * title;	/* Pointer to title window */

/* Start up parameters */
extern char	flyfile[MAXPATHLEN];	/* Name of flyfile */
extern float    from[3];			/* From point */
extern float    orig_from[3];		/* From point */
extern float    at[3];			/* At point */

/* Command line switch definitions */
extern args_t args[];

/* Command function definitions */
extern parse_t commands[];

/* Animation status */
extern animation_t animation;


/* FUNCTION DECALARTIONS */
void initialize(int);
void build_colormap(int);
windat_t * get_windat(windat_t *, int);
void handle_event(windat_t *);
void build_images(args_t [], image_t **, dataset_t **);
image_t * add_image(image_t **, char *);
void open_windows(image_t *, windat_t **);
void init_events(windat_t *);
void handle_events(windat_t *);
void add_set(dataset_t **, image_t *, datadesc_t *);
void fill_set(dataset_t *, datadesc_t *);
windat_t * create_window(char *, image_t *, windat_t **, int (*)(), int(*)());

int title_draw(windat_t *);
int image_draw(windat_t *);
int palette_draw(windat_t *);
int instrumentation_draw(windat_t *);

int do_event(windat_t *, long, short);
int title_event(windat_t *, long, short);
int image_event(windat_t *, long, short);
int palette_event(windat_t *, long, short);
void do_animation(windat_t *);

float facos2(float, float);
float fasin2(float, float);
void cart_to_sphere(float, float, float, float *, float *, float *);
void sphere_to_cart(float, float, float, float *, float *, float *);

void gprintf(long, long, char *, float);
int patmatch(char *, char *);

void init_menus();
int from_c(char *);
int at_c(char *);
int do_fly(int);
int ortho_mode(int);
int persp_mode(int);
int point_mode(int);
int lines_mode(int);
int polygon_mode(int);
int depth_mode(int);
int constant_mode(int);
int gouraud_mode(int);
int palette_pick(int);
int at_point_tgl(int);
int axes_tgl(int);
int box_tgl(int);
int labels_tgl(int);
int outlines_tgl(int);
int forward(int);
int forward1(int);
int stop(int);
int reverse1(int);
int reverse(int);
int do_redraw(int); 
int do_pop(int);
int do_reset(int);
int write_hdf(int);
int read_scr(long *, long *, unsigned char *);
