#! /bin/sh -f
# this shell script is used by NeWS.m to display graphics
# under NeWS from inside Mathematica.
#
# based on the original by WRI.
# Copyright 1989 by R. Maeder
# may be distributed freely, except for profit.
#
imagetitle="Mathematica Graphics"
nodistort=true		# default no-stretching: yes

while :; do
	case $# in
	0)
		break 2
		;;
	esac
	case "$1" in
	-T)
		shift
		imagetitle="$1"
		shift
		;;
	-h)
		shift
		# imageheight="$1"
		shift
		;;
	-w)
		shift
		# imagewidth="$1"
		shift
		;;
	-stretch)
		nodistort=false
		shift
		;;
	-*)
		echo 'Usage: NeWS.view [-T title] [-stretch] [file]' >&2
		exit 1
		;;
	*)
		break 2
		;;
	esac
done

# other defaults
# line quality, between 0 and 1; 1 is best (and slowest)
linequality=0.5

# save input in file
file=/tmp/NeWS.view$$
cat $@ > $file

(
	cat <<'!'
false setautobind % so that redefs work...
!
	psfix </dev/null
	cat <<'!'

pause % give it a chance to catch some breath

/MathPictureStart {
	gsave
	Mtransform		% possibly rotate to landscape mode
	Mlmarg			% left_margin
	Mbmarg			% bottom_margin
	translate		% -
	/Mtmatrix		% /Mtmatrix
	matrix currentmatrix	% /Mtmatrix text_matrix
	def			% -
	Plain			% default_font
	Mfontsize scalefont	% default_font (at default point size)
	setfont			% -
} bind def

% redraw after menu choice
/ReDraw {/paintclient win send} def

/realLinewidth /setlinewidth load def % save old value

/uselinewidth? true def
/speclinewidth 0 def

/setlinewidth { % redefine
	uselinewidth?
		{realLinewidth}
		{pop speclinewidth realLinewidth} ifelse
	} def

/thinlines {
	/speclinewidth 0 store
	/uselinewidth? false store
	} def

/thicklines {
	/speclinewidth 0.005 store
	/uselinewidth? false store
	} def

/defaultlines {
	/uselinewidth? true store
	} def

% define line quality
/linequality {
	/curlinequality exch store
	} def

/defaultlinequality {
	Mlinequality linequality
	} def

% stretching
/defaultstretch {
	/Mnodistort Defnodistort store
	Mnodistort {nostretchmsg} {stretchmsg} ifelse
		/searchkey getMenu send % wrong message displayed ?
	{Mnodistort {stretchmsg} {nostretchmsg} ifelse
		{stretchhandler} /changeitem getMenu send} if
	} def

/stretchmsg   (stretch to fill window) def
/nostretchmsg (preserve aspect ratio) def

/stretchhandler { % toggle flag and message
	/Mnodistort currentkey nostretchmsg eq store
	currentindex Mnodistort {stretchmsg} {nostretchmsg} ifelse
		{stretchhandler} /changeitem self send
	ReDraw
	} def

% switch meshes on and off
/MSetetra /Metetra load def	% save value
/MStetra /Mtetra load def	% save value
/Mshowmesh? true def

/Mswtetra {	% switch according to flag
	Mshowmesh? {MSetetra} {MStetra} ifelse
	} def

/defaultmesh {	% restore defaults
	/Metetra {MSetetra pause} store
	/Mtetra {MStetra pause} store
	meshmsg /searchkey getMenu send % wrong message displayed ?
	{nomeshmsg {meshhandler} /changeitem getMenu send} if
	} def

/meshmsg (draw mesh lines) def
/nomeshmsg (no mesh lines) def

/meshhandler { % toggle flag and message
	/Mshowmesh? currentkey meshmsg eq store
	/Metetra {Mswtetra pause} store
	/Mtetra {Mswtetra pause} store
	currentindex Mshowmesh? {nomeshmsg} {meshmsg} ifelse
		{meshhandler} /changeitem self send
	ReDraw
	} def

% filling on and off
/RealFill /fill load def
/fill {RealFill} def	% create new entry to be changed later

/defaultFill {
	dofill
	fillmsg /searchkey getMenu send % wrong message displayed ?
	{nofillmsg {fillhandler} /changeitem getMenu send} if
	} def
/dofill {
	/fill {RealFill pause} store
	} def
/nofill {
	/fill {newpath} store	% must destroy path!
	} def

/fillmsg   (fill polygons) def
/nofillmsg (do not fill polygons) def

/fillhandler { % toggle flag and message
	 currentkey fillmsg eq
	 	{dofill nofillmsg}
	 	{nofill fillmsg} ifelse % leaves msg on stack
	currentindex exch {fillhandler} /changeitem self send % set this msg
	ReDraw
	} def

/AllDefaults {
	defaultlines
	defaultlinequality
	defaultstretch
	defaultmesh
	defaultFill
	} def

!
	cat << !

/PSPaint {
	1 fillcanvas		% menu driven repaint does not work without
	clippath pathbbox	% lx ly hx hy
	exch			% lx ly hy hx
	4 -1 roll		% ly hy hx lx
	sub			% ly hy hx-lx
	3 1 roll		% hx-lx ly hy
	exch			% hx-lx hy ly
	sub			% hx-lx hy-ly
	/Mheight exch def	% total page height
	/Mwidth exch def	% total page width
	.1 72 mul		% left, right, top, and bottom margin
	dup dup dup		% bmarg tmarg rmarg lmarg
	/Mlmarg exch def	% left margin
	/Mrmarg exch def	% right margin
	/Mtmarg exch def	% top margin
	/Mbmarg exch def	% bottom margin
	0 setgray
	curlinequality setlinequality % allow menu driven changes
	pause
	filename (r) file cvx exec
} def

%defaults from shell variables
/Mlinequality $linequality def
% reset nodistort from psfix
/Defnodistort $nodistort def		% no-stretching flag
/filename ($file) def

/stretchdefmsg Defnodistort {stretchmsg} {nostretchmsg} ifelse def
/meshdefmsg nomeshmsg def
/filldefmsg nofillmsg def

/curlinequality Mlinequality def

% timeout?
statusdict begin 90 setjobtimeout end

pause

% our window
% values that need to be known outside the window context
/getMenu {{/ClientMenu load} win send} def

/win framebuffer /new DefaultWindow send def
{
	/PaintClient {PSPaint} def
	/FrameLabel ($imagetitle) def
	/IconLabel ($imagetitle) def
	/LineMenu [
		(default)	{defaultlines ReDraw}
		(thin)		{thinlines ReDraw}
		(thick)		{thicklines ReDraw}
	] /new DefaultMenu send def
	/QualityMenu [
		(default)	{defaultlinequality ReDraw}
		(fast)		{0 linequality ReDraw}
		(accurate)	{1 linequality ReDraw}
	] /new DefaultMenu send def
	% main menu
	/ClientMenu [
		(Reset to Defaults)	{AllDefaults ReDraw}
		(Line width =>)		LineMenu
		(Line quality =>)	QualityMenu
		stretchdefmsg		{stretchhandler}
		meshdefmsg		{meshhandler}
		filldefmsg		{fillhandler}
		%(redraw)	{ReDraw} % for debugging
	] /new DefaultMenu send store

} win send
/reshapefromuser win send

{AllDefaults} win send % set it up

/map win send

% remove file on destruction of window
{/SaveDestroy /DestroyFrame load def
 /DestroyFrame {
	(rm ) filename append forkunix
	SaveDestroy
 } def
} win send
!
) | sed -e 's/^bind //' -e 's/ bind / /' -e 's/ bind$//' | psh
