#include <gem.h>
#include <stdio.h>

#ifdef COLOR
#define MAX_X		639
#define MAX_Y		199
#define LAST_COL	15
#else
#define MAX_X		639
#define MAX_Y		399
#define LAST_COL	4
#endif

#define UNPACKED		0
#define UNPACKABLE		1
#define PACKED			2

#define S_SMALL		0
#define S_MID			1
#define S_BIG			2
#define NO_SIZE		3

typedef struct {
	unsigned	compare	: 2; /* 0 And	 1 Or   2 Xor */
	unsigned	wait 	: 1; /* 1 warten auf taste  0 zeit */
	unsigned	richtung	: 1; /* 0 vorwrts		1 vor und zurck */
	unsigned	repeat	: 1; /* 0 einmal		1 wiederholt */
} AO_FLAGS;

typedef struct {
	AO_FLAGS	flags;
	unsigned	wait_pic;
	unsigned	wait_end;
} SHOW_OPTS;

typedef struct {
	unsigned	dummy	: 1;	/* war mal kompakt/stad */
	unsigned	pic_type	: 2; /* 0 doodle	1 degas	2 stad		3 snapshot */
	unsigned	block	: 1; /* 0 maus 	0 fadenkreuz */
	unsigned	gong 	: 1; /* 0 aus		1 ein */
	unsigned	save 	: 1; /* 0 aus		1 ein */
	unsigned	save_war	: 1; /* 0 aus		1 ein */
	unsigned	abbruch	: 1; /* 0 aus		1 ein */
	unsigned	delete	: 2; /* 0 nie		1 neu	2 mehrere 3 immer */
	unsigned	quit 	: 2; /* 0 nie		1 neu	3 immer */
	unsigned	hc_size	: 2; /* 0 klein	1 gro	2 quer	3 doppel */
	unsigned	hc_leer	: 1; /* 0 nicht drucken 1 drucken */
	unsigned	hc_text	: 1; /* 0 nicht drucken 1 drucken */
	unsigned	hc_abst	: 1; /* 0 aus		1 ein */
	unsigned	hc_ff	: 8; /* bilder bis formfeed */
	unsigned	d_tos	: 1; /* 0 eigene pr_out	1 tos pr_out */
	unsigned  pack		: 1;	/* 0 bilder nicht packen  1 bilder packen */
#ifndef COLOR
	unsigned	col_flag	: 1; /* 0 normal	1 invers */
#endif
} FR_FLAGS;

#ifdef COLOR
typedef struct {
	unsigned	speed	: 16;
	unsigned	first	: 4;
	unsigned	last 	: 4;
	unsigned	dir		: 1; /* 0 links	1 rechts */
} CYCLE_OPT;
#endif

typedef struct
{
	FR_FLAGS	flags;
	char 	path[40];
	char 	ext;
	int		dummy;
	long 	mem_rest;
	SHOW_OPTS show;
	char 	d_code[8][10];
	char 	d_rand[9];
#ifdef COLOR
	int		col_tab[16];		/* farbtabelle fr desktop, mid_rez */
	CYCLE_OPT cycle;
	int		col_tabs[12][16];
#endif
} CHS_SET;

typedef struct
{
	long len;
	long *mother;
	char data[];
} PARAMETER;

typedef struct
{
	long len;
	long *mother;
	long data[];
} PIC_DATA;

typedef struct
{
	int		nr;			/* nummer */
	int		flag;		/* 0 film  1 pic  2... fractale */
	int		objc_flag;
	int		objc_state;
	int		icon_type;	/* flag + 256 fr checked */
	char		name[10];
	char		path[40];
	char		ext[4];
	char		pic_packed;	/* UNPACKED, UNPACKABLE, PACKED */
	char		size;		/* 0 small  1 mid	  2 big */
	PIC_DATA  *pic_data;
	long 	pic_len;
	PIC_DATA	*x_data;
	int		lastline;
	int       xor_offset;
	PARAMETER	*par;
#ifndef COLOR
	int       color;
#else
	int		col_tab[16];
#endif
} FR_OBJC;

/* ------------------------------------------------------------- */

/*	bei parametereingabe anzugebende parameter				*/
/* ------------------------------------------------------------- */
typedef struct
{
	int anzahl;
	int size;
#ifndef COLOR
	int color;
#else
	int col_tab[16];
#endif
	int xor_offset;
	char name[16];
	char path[64];
} X_PARAM;

typedef struct		/* fr info anzeigen */
{
	int		anz;
	double	points;
	double	time;
	double	iter;
} PIC_INFO;

typedef struct
{
	int size;
#ifndef COLOR
	int color;
#else
	int col_tab[16];
#endif
	int xor_offset;
	int lastline;
} L_PARAM;				/* fr load */

typedef struct
{
	char id[8];		/* kennung der routine,
						gedacht:	4 zeichen fr autor
								4 zeichen fr routine */

	char *menue;		/* meneintrag
						max. 16 zeichen */
	char *name;		/* name des autors fr programm-info anzeigen
						max. 24 zeichen */
	char *version;		/* versionsnummer (und datum) der routine
						max. 20 zeichen */
	char *text;		/* allg. beschreibung oder sonst. kommentar
						max. 64 zeichen */

	ICONBLK *icon;		/* zeiger auf icon fr nicht gespeicherte */
	ICONBLK *xicon;	/*					und gespeicherte bilder */

	long set_len;		/* lnge der voreinstellungen */
	void *set;		/* zeiger auf speicherbereich fr fr voreinstellungen,
						mu routine bereitstellen! */

	long par_len;		/* lnge der bild-parameter */

	long make_len;		/* lnge der eingabeparameter fr make bild(er) */
	long neu_len;		/* lnge fr parameter bei make_neu */
	void *neu_par;		/* zeiger auf make_neu-parameter, 
						von make_neu-routine zu setzen */
	int neu_flag;		/* flag fr make neu:
						0 not set, 1 neu ok, -1 nicht neu (abbruch in dialog) */

	int last_flag;		/* ==1 -> lastline (>0) entspricht ber. graph. zeilen
					   ==0 -> immer ganzen screen speichern */

		/* routinen */

	int (*do_init)(int nr);
				/*
					initialisiere routinen (zB. resourcen laden etc.)
					nr: nummer des fractal-types
					returns 	0 -> ok
							1 -> fehler
				*/

	int (*get_param)(void *param,X_PARAM *x_param);
				/*	parameter fr bild(er) eingeben
						param: bildparameter
						x_param: allg. parameter (gre, name...)
						RETURNS: 0/1 fr abbruch/ok
				*/

	void *(*get_picpar)(void *param_in,int nr,int anzahl);
				/* aus bild(er)parameter bildparameter machen
						param_in: bildparameter (wie in get_param)
						nr:		nummer des akt. bildes
						anzahl:	anzahl der bilder insg.
						RETURNS:	zeiger auf einzelbildparam.
				*/

	void (*set_param)(void);
				/* OPT */
				/*	parameter voreinstellen
						(aufruf von men mit shift)
				*/

	void (*extended)(void);
				/* OPT */
				/*	aufruf vom men aus mit control
				*/

	int (*get_neu_param)(void *param);
				/* OPT */
				/*	parameter fr 'neu berechnen' eingeben
						param: zeiger auf speicher fr parameter
						
						routine mu neu_par und neu_flag setzen
				*/

	void *(*make_neu_param)(FR_OBJC *objc,void *param,X_PARAM *x_par,int *change,int *redraw,int *size);
				/* OPT */
				/*
					aus parametern fr 'neu berechnen' und
					bildparameter neue bildparameter erzeugen
					und zurckgeben

					change,size und return
				*/

	void (*make_vier)(FR_OBJC *in,void *out,int nr);
				/* OPT */
				/*	erzeuge aus bildparametern parameter fr vier bilder
						in: zeiger auf input-object
						out: zeiger auf parameter des outputs
						nr: nummer des neuen bildes (0-3)
				*/

	int (*do_draw)(FR_OBJC *object,void *param,void *puffer);
				/* bild berechnen
						object:	zielobject
						param:	parameter
						puffer:	freier puffer (32k)
						RETURNS:	abbruchzustand
				*/
	void (*dont_draw)(FR_OBJC *object,void *param);

	int (*show_par)(FR_OBJC *object,long *buf);
				/* OPT */
				/* 	zeige parameter an
						return: 0 nichts gendert, 1 param. mgl. gendert */

	void (*show_info)(FR_OBJC *object,long *buf);
				/* OPT */
				/* 	zeige bildinfo an 
				*/

	void (*get_info)(FR_OBJC *object,PIC_INFO *info);
				/* OPT */
				/*	gebe bildinformationen zurck
				*/

	void (*get_objcblk)(FR_OBJC *object,double *x_min,double *x_max,double *y_min,double *y_max);
				/* OPT */
				/* 	koordinaten des bildrechteckes zurckgeben
					existenz der routine bedeutet auch, da bild koordinatenstruktur hat
						object	object
						x_min,x_max,y_min,y_max
				*/

	void (*get_xobjcblk)(FR_OBJC *object,double *x_min,double *x_max,double *y_min,double *y_max);
				/* OPT */
				/*	koordinaten des bildrechteckes zurckgeben
						object	object
						x_min,x_max,y_min,y_max

				*/
	void (*get_pkt)(FR_OBJC *object,double *x,double *y);
				/* OPT */
				/*	gebe konstante zurck, 
					nur sinnvoll wenn auch get_objcblk */

	void (*show_pktinfo)(FR_OBJC *object,int x,int y,long *scr,long *buf);
				/* OPT */
				/*	zeige punktinfo fr (raster)koordinaten x,y */
				/*		scr: aktueller bildschirm */
				/*		buf:	32k puffer zum sichern des bildschirms */

	void (*dr_param)(FR_OBJC *objc);
				/* OPT */
				/*	drucke parameter eines bildes unter hardcopy */

	int (*cnv_load)(int frac_typ,L_PARAM *par,PIC_DATA *xparam,PIC_DATA *param,PIC_DATA **x_par);
				/* OPT */
				/*	konvertiere parameter!, anpassen: offset, farben, 
									parameter von xparam nach param kopieren (und anpassen)
									x_par verwursten 
						return: 0 ok, 1 abbruch */
	long res1,res2,res3,res4,res5,res6,res7,res8; /* reserviert, mu 0 sein */
} CHAOS;

typedef struct
{
	long iter;
	long iter_done;
	long iter_left;
	long pkte_done;
	double time_done;
	double time_left;
} TIME_INFO;

typedef struct
{
	void (*draw_objc)(OBJECT *object,long *buffer);
	void (*xdraw_objc)(long *buf);
	void (*undraw_objc)(long *buf);

	void (*write_dbl)(char *s,double zahl,int l,int p);

	double (*ipol)(double anf,double end,int act_nr,int max_nr,int mode);
	void (*xipol)(double anf1,double end1,double anf2,double end2,double *anf,double *end,int act_nr,int max_nr);

#ifdef COLOR
	void (*plot_pixel)(int x,int y,int col,void *addr);
#else
	void (*plot_pixel)(int x,int y,void *addr);	/* nur punkte setzten (col==1), nicht lschen */
#endif
	void (*set_point)(int x,int y,int col,int flag);
	int (*get_pixel)(int x,int y,void *addr);

	void (*copy_screen)(long *s,long *d);
	void (*clr_screen)(long *s);
	void (*get_pic)(FR_OBJC *object,long *dest);

	PIC_DATA *(*pic_malloc)(long len,PIC_DATA **mother);
	void (*pic_mfree)(PIC_DATA *addr);
	int (*check_mem)(long len);

	long (*gettime)(void);

	FR_OBJC *(*get_objc)(int typfl);	/* typfl == TYP || -1 (-1 -> alle frac-typen) */
	int (*xget_obblk)(FR_OBJC *objc,double *x_min,double *x_max,double *y_min,double *y_max);
	FR_OBJC *(*get_konst)(int typflag,double *x,double *y);
	FR_OBJC *(*get_block)(int typflag,double *x_min,double *x_max,double *y_min,double *y_max);

	long (*irand)(long dummy);
	double (*xrand)(long dummy);

	void (*conv_time)(unsigned long ms,int *h,int *m,double *s);
	void (*conv_sc_mm)(double scale,double offset,int delta,double *min,double *max);
	void (*conv_mm_sc)(double min,double max,int delta,double *scale,double *offset);
	void (*time_info)(TIME_INFO *info,void *puffer);

	int (*fsel)(char *path,char *sel,int *button,char *label);

	void (*dr_string)(char *str);
	void (*set_unoutlined)(FR_OBJC *object);

	int  (*sprintf)( char *string, const char *format, ... );
	int  (*fprintf)( FILE *stream, const char *format, ... );
	int  (*sscanf)( const char *string, const char *format, ... );
	int  (*fscanf)( FILE *stream, const char *format, ... );
	
#ifdef COLOR
	int (*make_alert)(int button,int *coltab,char *alert);
	void (*make_drawobjc)(OBJECT *objc);
	void (*make_undraw)(int *coltab);
	void (*set_colors)(int *col_tab,long *scrn,FR_OBJC *object,int flag);
#endif

	int *fr_x0;
	int *fr_y0;
	int *fr_dx;
	int *fr_dy;
	int *pic_size;
	int *line_len;
	long *scr;
	CHS_SET *settings;

	long res1,res2,res3,res4,res5,res6,res7,res8;
	long res9,resA,resB,resC,resD,resE,resF,res0;
} COMMON;

typedef struct
{
	char id[8];
	int anz;
	int *flag;
	CHAOS *chs;
} XCHAOS;

