/* @(#)Copyright (c), 1987, 1992 StatSci, Inc.  All rights reserved. */
static char whatssi[] = "@(#)skeleton2.c version 3.17 created 10/30/92 ";
/* device driver that uses high-level routines */

#include "S.h"
#include "device.h"

extern float F77_COMDECL(bgrp)[];
#define am(i)		F77_COM(bgrp)[(i)-1]

/* note that all high-level device routines get user coordinates */
/* may need to transform them to rasters for plotting */
/* user-to-raster and raster-to-user conversions */
#define Xorigin		(am(36))
#define Yorigin		(am(38))
#define Xscale		(am(37))
#define Yscale		(am(39))
#define UxR(x)		((int)((x) * Xscale + Xorigin))
#define UyR(y)		((int)((y) * Yscale + Yorigin))
#define RxU(x)		(((x) - Xorigin) / Xscale)
#define RyU(y)		(((y) - Yorigin) / Yscale)

vector *highlevel(), *F77_NAME(brdpnz)(), *F77_NAME(bquxyz)();
void F77_NAME(dmarkz)(), F77_NAME(defltz)();
static vector *wrap(), *flush(), *signalled(), *points(), *lines(),
  		*polygon(), *text(), *segments(), *clear(), *mymenu();

static device d_highlevel = {
	FALSE,				/* active flag */
	0,				/* index in list of devices */
	(DisplayListHead *)NULL,
	(float *)NULL,			/* copy of bgrp array */
	0,				/* number of local parameters */
	(char *)NULL,			/* local parameters */
	{
		highlevel,		/* initialize */
		wrap,			/* wrap up */
		flush,			/* flush */
		signalled,		/* caught signal */
		points,			/* points */
		lines,			/* lines */
	 	polygon,		/* polygon */
		text,			/* text */
		segments,		/* segments */
		clear,			/* page eject */
		F77_CALL(brdpnz),	/* graphic input */
		mymenu,			/* menu */
		NULL,			/* hook */
		NULL,			/* seek (low level) */
		NULL,			/* point (low level) */
		NULL,			/* line (low level) */
		NULL,			/* width of string */
		F77_CALL(bquxyz),	/* graphic input (low level) */
		NULL,                   /* image <O> */
		NULL,                   /* printgraph <O> */
		NULL,                   /* redraw <O> */
		NULL,                   /* brush <O> */
		NULL,                   /* spin <O> */
		NULL,                   /* switchmode <O> */
		/* 6 unused slots, for total of NPRIMITIVES=30 */
		NULL,                   /* unused */
		NULL,                   /* unused */
		NULL,                   /* unused */
		NULL,                   /* unused */
		NULL,                   /* unused */
		NULL                    /* unused */
	}
};

vector
*highlevel()
{
	device *d, *new_device(); int i;

	/* initialize device structure and graphical parameters */
	set_device(new_device(&d_highlevel, 0L)->which);
	for(i = 1; i <= 39; i++)
		am(i) = 0;
	am(20) = 10;	/* character size */
	am(21) = am(20) * 1.2;
	am(22) = 0;				/* x limits */
	am(23) = 1000;
	am(24) = 0;				/* y limits */
	am(25) = 1000;
	am(28) = .001;			/* raster size in inches */
	am(29) = am(28);
	am(30) = -9876;			/* some magic negative number */
	am(31) = 1;				/* characters rotate */
	am(1) = 1;				/* characters scale */
	F77_CALL(defltz)();			/* set other parameters */
	printf("Initialize\n");
}

/*
 * flush() brings the output up to date
 * clear() prints the current page
 * wrap() wraps up the job
 * signalled() fixes up if interrupt or other signal occurs
 */
static vector *
flush()
{
	printf("Flush\n");
	return(S_void);
}

static vector *
clear()
{
	printf("Clear\n");
	return(S_void);
}

static vector *
wrap()
{
	printf("Wrapup\n");
	return(S_void);
}

static vector *
signalled()
{
	printf("Signalled\n");
	return(S_void);
}

static vector *
lines(x, y, n)
float *x, *y;
long *n;
{
	int nn = *n;
	
	printf("Move to %d %d\n", UxR(*x++), UyR(*y++)); 
	while(--nn) 
		printf("Line to %d %d\n", UxR(*x++), UyR(*y++));
	return(S_void);
}

static vector *
segments(x1, y1, x2, y2, n)
float *x1, *y1, *x2, *y2;
long *n;
{
	int nn = *n;
	
	while(nn--)
		printf("Segments %d %d %d %d S\n", UxR(*x1++), UyR(*y1++),
						 UxR(*x2++), UyR(*y2++));
	return(S_void);
}

static vector *
polygon(x, y, n)
float *x, *y;
long *n;
{
	int nn = *n;
	
	printf("Start Polygon %d %d\n", UxR(*x++), UyR(*y++)); 
	while(--nn)
		printf("Line to %d %d\n", UxR(*x++), UyR(*y++));
	printf("End Polygon\n");
	return(S_void);
}

static vector *
points(xx, yy, n)
float *xx, *yy;
long *n;
{
	long nn = *n, pch = (long)am(15); /* yuk */
	
	/* if plotting character is less than 32, then call special routine
		to draw plotting symbols rather than characters */
	if(pch < 32)
		F77_CALL(dmarkz)(xx, yy, n, &pch);
	else
		while(nn--)
			printf("Point %d %d\n", UxR(*xx++), UyR(*yy++));
	return(S_void);
}
	
static vector *
text(x, y, buf, n, pos)
float *x, *y, *pos;
char *buf;
long *n;
{
	printf("Text '%s' at %d %d (adjust %g)\n", buf, UxR(*x), UyR(*y),*pos);
	return(S_void);
}

static vector *
mymenu(ent,arglist)
vector *ent, *arglist;
{
	vector *value;
	int n, i;
	UNUSED(ent);
	value = coevec(*(arglist->value.tree),ANY,TRUE,CHECK_IT);
	if(value==NULL_ENTRY) return(S_void);
	value = coevec(value,CHAR,TRUE,CHECK_IT);

	printf("Menu with %d items:\n", value->length);
	for(i=0; i<value->length; i++)	/* the labels */
		printf("%d: %s\n",i+1,value->value.Char[i]);
	scanf("%d",&n);
	while(getchar()!='\n');	/* eat newline */
	if(n<0 || n>value->length) n = 0;  /* no selection */
	value=alcvec(INT,1L);
	*(value->value.Long) = n;
	return(value);
}
