#!/usr/local/bin/obmsh
#
# XIMTOOL.GUI -- Default GUI for the Ximtool image display server.
#
# Version 2.0 -- BETA VERSION


set Version	"NOAO/IRAF XImtool Version 2.0BETA"


reset-server

set Objects(ximtool) { \
	toplevel	Layout		display \
\
        display         Group           menuGroup\
        menuGroup       Layout          menubar\
	menubar		MenuButton	fileButton \
	menubar		MenuButton	viewButton \
	menubar		MenuButton	optionsButton \
	menubar		Label		imageTitle \
	menubar		Toggle		controlButton \
	menubar		Toggle		xflipButton \
	menubar		Toggle		yflipButton \
	menubar		Command		prevButton \
	menubar		MenuButton	frameButton \
	menubar		Command		nextButton \
	menubar		Toggle		helpButton \
\
	display		Frame		imageFrame\
	imageFrame	Gterm		imagewin\
	display		Frame		cbarFrame\
	cbarFrame	Gterm		colorbar\
	display		Toggle		hcut\
	display		Toggle		vcut\
	display		Frame		hcutFrame\
	hcutFrame	Gterm		hcutPlot\
	display		Frame		vcutFrame\
	vcutFrame	Gterm		vcutPlot\
	display		Slider2d	focusSlider\
\
	display		Group		plotOpts\
	plotOpts	Layout		poptsLayout\
	poptsLayout	TextToggle	plotSpeed\
	poptsLayout	TextToggle	plotAccurate\
	poptsLayout	TextToggle	plotImgPix\
	poptsLayout	Frame		optLine\
	poptsLayout	TextToggle	curJump\
	poptsLayout	TextToggle	curSmooth\
	poptsLayout	TextToggle	curTrack\
}


set Objects(panelShell) { \
	toplevel	TopLevelShell	panelShell\
	panelShell	Layout		panel\
\
	panel		Frame		panelMenuFrame\
	panelMenuFrame	Layout		panelMenuBar\
	panelMenuBar	Command		panelHelp\
	panelMenuBar	Command		panelClose\
\
	panel		Frame		tabFrame\
	tabFrame	Tabs		panelTabs\
	panelTabs	Frame		display_panel\
	panelTabs	Frame		print_panel\
	panelTabs	Frame		load_panel\
	panelTabs	Frame		save_panel\
	panelTabs	Frame		info_panel\
	panelTabs	Frame		tile_panel\
	panelTabs	Frame		wcs_panel\
\
\
	display_panel	Layout		controlPanel\
	controlPanel	Group		viewBox\
	controlPanel	Group		enhancementBox\
	controlPanel	Group		blinkBox\
	controlPanel	Group		optionsBox\
	controlPanel	Frame		controlBox\
\
	viewBox		Layout		view\
	view		Group		frameSelect\
	frameSelect	Layout		frameBox\
	frameBox	Box		frlistBox\
	frlistBox	Viewport	framePort\
	framePort	Layout		frameList\
	frameList	TextToggle	frame1\
	frameList	TextToggle	frame2\
	frameList	TextToggle	frame3\
	frameList	TextToggle	frame4\
	frameList	TextToggle	frame5\
	frameList	TextToggle	frame6\
	frameList	TextToggle	frame7\
	frameList	TextToggle	frame8\
	frameList	TextToggle	frame9\
	frameList	TextToggle	frame10\
	frameList	TextToggle	frame11\
	frameList	TextToggle	frame12\
	frameList	TextToggle	frame13\
	frameList	TextToggle	frame14\
	frameList	TextToggle	frame15\
	frameList	TextToggle	frame16\
	frameBox	Command		prevFrame\
	frameBox	Command		nextFrame\
	view		Frame		frameDataBox\
	frameDataBox	TextBox		frameData\
	view		Group		zoomBox\
	zoomBox		Layout		zoom\
	zoom		TextButton	toggleZoom\
	zoom		TextButton	zoomIn\
	zoom		Command		x1\
	zoom		Command		z2\
	zoom		Command		z3\
	zoom		Command		z4\
	zoom		Command		z5\
	zoom		Command		z8\
	zoom		TextButton	zoomOut\
	zoom		TextButton	centerFrame\
	zoom		Command		d2\
	zoom		Command		d3\
	zoom		Command		d4\
	zoom		Command		d5\
	zoom		Command		d8\
	view		Layout		viewButtons\
	viewButtons	Command		aspect\
	viewButtons	Command		flipX\
	viewButtons	Command		flipY\
	viewButtons	Command		flipXY\
	viewButtons	Command		clearFrame\
	viewButtons	Command		fitFrame\
\
	enhancementBox	Layout		enhance\
	enhance		Frame		colorlistFrame\
	colorlistFrame	Viewport	colorlistView\
	colorlistView	MultiList	colorlist\
	enhance		Frame		colordataFrame\
	colordataFrame	TextBox		colordata\
	enhance		Label		contrastLabel\
	enhance		Slider2d	contrastSlider\
	enhance		Label		brightnessLabel\
	enhance		Slider2d	brightnessSlider\
	enhance		Command		invertButton\
	enhance		Command		optimizeButton\
\
	blinkBox	Layout		blink\
	blink		Label		blinkFramesLabel\
	blink		Command		blinkFrame1\
	blink		Command		blinkFrame2\
	blink		Command		blinkFrame3\
	blink		Command		blinkFrame4\
	blink		Toggle		blinkPanel\
	blink		Command		blinkReset\
	blink		Label		blinkRateLabel\
	blink		Frame		BRframe\
	BRframe		Layout		BRlayout\
	BRlayout	Arrow		BRdecrease\
	BRlayout	TextBox		BRtext\
	BRlayout	Arrow		BRincrease\
	blink		Command		registerButton\
	blink		Command		matchButton\
	blink		TextToggle	blinkButton\
	blink		TextToggle	autoregButton\
\
	optionsBox	TextToggle	pannerButton\
	optionsBox	TextToggle	magnifierButton\
	optionsBox	TextToggle	coordsBoxButton\
	optionsBox	TextToggle	autoscaleButton\
	optionsBox	TextToggle	antialiasButton\
	optionsBox	TextToggle	tileFramesButton\
	optionsBox	TextToggle	warningsButton\
	optionsBox	TextToggle	peakupButton\
\
	controlBox	Layout		control\
	control		Command		initializeButton\
	control		Command		normalizeButton\
\
\
	print_panel	Layout		printLayout\
\
	printLayout	Group		printCmdGroup\
	printLayout	Group		optGroup\
	printLayout	Group		cmdGroup\
\
	printCmdGroup	Layout		printCmdLayout\
	printCmdLayout	Layout		labelLayout\
	labelLayout	Label		toLabel\
	labelLayout	Label		printerLabel\
	printCmdLayout	Layout		inputLayout\
	inputLayout	TextToggle	toPrinter\
	inputLayout	TextToggle	toFile\
	inputLayout	Frame		printcmdFrame\
	printcmdFrame	AsciiText	printcmd\
\
	optGroup	Layout		optLayout\
	optLayout	Group		epsPageGroup\
	optLayout	Group		optionsGroup\
	optLayout	Group		printColorGroup\
	optLayout	Group		printerGroup\
	optLayout	Group		annOptsGroup\
\
	epsPageGroup	Layout		epsPage\
	epsPage		Label		epsOrientLabel\
	epsPage		TextToggle	epsPortButton\
	epsPage		TextToggle	epsLandButton\
	epsPage		TextToggle	epsSquareButton\
	epsPage		Label		epsSizeLabel\
	epsPage		TextToggle	epsLetterButton\
	epsPage		TextToggle	epsLegalButton\
	epsPage		TextToggle	epsA4Button\
	epsPage		TextToggle	epsB5Button\
	epsPage		Label		epsScaleLabel\
	epsPage		Frame		ScaleFrame\
	ScaleFrame	Layout		ScaleLayout\
	ScaleLayout	Arrow		SCdecrease\
	ScaleLayout	TextBox		SCtext\
	ScaleLayout	Arrow		SCincrease\
\
	optionsGroup	Layout		options\
	options		TextToggle	epsscaleButton\
	options		TextToggle	autorotateButton\
	options		TextToggle	aspectButton\
	options		TextToggle	compressButton\
\
	annOptsGroup	Layout		annOpts\
	annOpts		TextToggle	annotateButton\
	annOpts		TextToggle	colorbarButton\
	annOpts		TextToggle	titleButton\
	annOpts		TextToggle	bordersButton\
	annOpts		Label		titleLabel\
	annOpts		Frame		titleFrame\
	titleFrame	AsciiText	titleString\
\
	printColorGroup	Layout		printColor\
	printColor	TextToggle	prGrayButton\
	printColor	TextToggle	prPseudoButton\
	printColor	TextToggle	prRGBButton\
\
	printerGroup	Layout		printers\
	printers	Frame		printlistFrame\
	printlistFrame	Viewport	printlistView\
	printlistView	MultiList	printlist\
\
	cmdGroup	Layout		cmdLayout\
	cmdLayout	Command		okayPrint\
	cmdLayout	Label		printStatus\
\
\
	load_panel	Layout		filesLayout\
	filesLayout	Group		imlistGroup\
	imlistGroup	Layout		imlistLayout\
	imlistLayout	Command		rootButton\
	imlistLayout	Command		homeButton\
	imlistLayout	Command		upButton\
	imlistLayout	Command		rescanButton\
	imlistLayout	Label		dirLabel\
	imlistLayout	Label		fnameLabel\
	imlistLayout	Frame		filnamFrame\
	filnamFrame	AsciiText	fnameText\
	imlistLayout	Label		imtemplateLabel\
	imlistLayout	Frame		imtemplateFrame\
	imtemplateFrame	AsciiText	imtemplateText\
	imlistLayout	Label		imlistLabel\
	imlistLayout	Frame		imlistFrame\
	imlistFrame	Viewport	imlistView\
	imlistView	MultiList	imageList\
\
	filesLayout	Group		imoptsGroup\
	imoptsGroup	Layout		imoptsLayout\
	imoptsLayout	TextToggle	grayscale\
	imoptsLayout	TextToggle	autoload\
	imoptsLayout	TextToggle	browseHdrs\
	imoptsLayout	TextToggle	zscale\
	imoptsLayout	TextToggle	zrange\
	imoptsLayout	Label		z1Label\
	imoptsLayout	Frame		z1Frame\
	z1Frame		AsciiText	z1Value\
	imoptsLayout	Label		z2Label\
	imoptsLayout	Frame		z2Frame\
	z2Frame		AsciiText	z2Value\
	imoptsLayout	Label		nsampLabel\
	imoptsLayout	Frame		nsampFrame\
	nsampFrame	AsciiText	nsampValue\
	imoptsLayout	Label		frameLabel\
	imoptsLayout	MenuButton	frameFrame\
\
	filesLayout	Group		loadCmdGroup\
	loadCmdGroup	Layout		loadCmdLayout\
	loadCmdLayout	Command		filesLoadButton\
	loadCmdLayout	Label		filesStatus\
\
\
	save_panel	Layout		saveLayout\
	saveLayout	Group		saveNameGroup\
	saveNameGroup	Layout		saveNameLayout\
	saveNameLayout	Label		saveLabel\
	saveNameLayout	Frame		fnameFrame\
	fnameFrame	AsciiText	saveFile\
\
	saveLayout	Group		saveOptGroup\
	saveOptGroup	Layout		saveOptLayout\
	saveOptLayout	Group		fmtGroup\
	saveOptLayout	Group		saveColorGroup\
	saveOptLayout	Frame		saveDataBox\
	saveDataBox	TextBox		saveData\
\
	fmtGroup	Layout		formats\
	formats		TextToggle	rasButton\
	formats		TextToggle	gifButton\
	formats		TextToggle	jpegButton\
	formats		TextToggle	tiffButton\
	formats		TextToggle	fitsButton\
	formats		TextToggle	epsButton\
	formats		TextToggle	x11Button\
	formats		TextToggle	rawButton\
\
	saveColorGroup	Layout		saveColor\
	saveColor	TextToggle	svGrayButton\
	saveColor	TextToggle	svPseudoButton\
	saveColor	TextToggle	svRGBButton\
\
	saveLayout	Group		saveCmdGroup\
	saveCmdGroup	Layout		saveCmdLayout\
	saveCmdLayout	Command		okaySave\
	saveCmdLayout	Label		saveStatus\
\
\
	info_panel	Layout		infoLayout\
	infoLayout	Group		infoBox\
	infoBox		Layout		infoBoxL\
	infoBoxL	Frame		infoFrame\
	infoFrame	AsciiText	infoText\
	infoBoxL	TextToggle	infoOptFr\
	infoBoxL	TextToggle	infoOptWCS\
	infoBoxL	TextToggle	infoOptSvr\
	infoBoxL	TextToggle	infoOptClients\
	infoBoxL	TextToggle	infoOptIsm\
	infoBoxL	TextToggle	infoOptFB\
\
\
	wcs_panel	Layout		wcsLayout\
	wcsLayout	Group		wcsGroup\
	wcsGroup	Layout		wcsBox\
\
	wcsBox		Frame		wcsFrame\
	wcsFrame	Layout		wcsText\
	wcsText		AsciiText	wtName\
	wcsText		AsciiText	wtTitle\
	wcsText		AsciiText	wtFBCfg\
	wcsText		AsciiText	wtIPixval\
	wcsText		AsciiText	wtSPixval\
	wcsText		AsciiText	wtBPixval\
	wcsText		AsciiText	wtWcs1\
	wcsText		AsciiText	wtWcs2\
	wcsText		AsciiText	wtWcs3\
	wcsText		AsciiText	wtWcs4\
\
	wcsBox		TextToggle	ismToggle\
	wcsBox		TextToggle	pixelTable\
	wcsBox		TextToggle	imageHeader\
	wcsBox		TextToggle	compass\
	wcsBox		TextToggle	wcsOptions\
\
\
        wcsLayout       Group           wcsOptGroup\
        wcsOptGroup     Layout          wcsOptLayout\
\
	wcsOptLayout	Group		wcsCoords\
	wcsCoords	Layout		wcLayout\
	wcLayout	Label		wcTitle\
	wcLayout	Frame		wcLine\
	wcLayout	Label		wlWcs1\
	wcLayout	Label		wlWcs2\
	wcLayout	Label		wlWcs3\
	wcLayout	Label		wlWcs4\
	wcLayout	MenuButton	sysWcs1\
	wcLayout	MenuButton	sysWcs2\
	wcLayout	MenuButton	sysWcs3\
	wcLayout	MenuButton	sysWcs4\
	wcLayout	MenuButton	fmtWcs1\
	wcLayout	MenuButton	fmtWcs2\
	wcLayout	MenuButton	fmtWcs3\
	wcLayout	MenuButton	fmtWcs4\
	wcLayout	TextToggle	wpWcs1\
	wcLayout	TextToggle	wpWcs2\
	wcLayout	TextToggle	wpWcs3\
	wcLayout	TextToggle	wpWcs4\
	wcLayout	TextToggle	wiWcs1\
	wcLayout	TextToggle	wiWcs2\
	wcLayout	TextToggle	wiWcs3\
	wcLayout	TextToggle	wiWcs4\
\
	wcsOptLayout	Group		wcsOpts\
	wcsOpts		Layout		woLayout\
	woLayout	TextToggle	woptLabels\
	woLayout	TextToggle	woptTitles\
	woLayout	TextToggle	woptFBinfo\
	woLayout	TextToggle	woptBPM\
\
	wcsOptLayout	Group		wcsIsmGroup\
	wcsIsmGroup	Layout		wcsIsmLayout\
	wcsIsmLayout	Label		wcsIsmLabel\
	wcsIsmLayout	Frame		wcsIsmFrame\
	wcsIsmFrame	AsciiText	wcsIsmCmd\
	wcsIsmLayout	Command		wcsIsmInit\
\
\
	tile_panel 	Frame	 	tileOpts\
	tileOpts	Layout	 	toptLayout\
	toptLayout 	Group	 	tFramesG\
	toptLayout 	Group	 	tileMode\
	tileMode	TextToggle	tileDisabled\
	tileMode	TextToggle	tileManual\
	tileMode	TextToggle	tileBest\
	tileMode	TextToggle	tileSquare\
	tileMode	TextToggle	tileHorizontal\
	tileMode	TextToggle	tileVertical\
	tileMode	TextToggle	tileRow\
	tileMode	TextToggle	tileCol\
	toptLayout 	Group	 	userOrientG\
	toptLayout	Group		fillStyle\
	fillStyle	TextToggle	byCols\
	fillStyle	TextToggle	bottomUp\
	toptLayout	Group		tileLabel\
	tileLabel	TextToggle	labelImname\
	tileLabel	TextToggle	labelTitles\
	tileLabel	TextToggle	labelFrames\
	toptLayout	Frame		geomFrame\
	geomFrame	Label		tileGeometry\
\
	userOrientG	Layout		userOrientL\
	userOrientL  	Label	 	nrowLab\
	userOrientL  	Frame	 	nrFrame\
	nrFrame	 	Layout	 	nrLayout\
	nrLayout	Arrow	 	nrdecrease\
	nrLayout	Label	 	nrtext\
	nrLayout	Arrow	 	nrincrease\
	userOrientL  	Label	 	ncolLab\
	userOrientL  	Frame	 	ncFrame\
	ncFrame	 	Layout	 	ncLayout\
	ncLayout	Arrow	 	ncdecrease\
	ncLayout	Label	 	nctext\
	ncLayout	Arrow	 	ncincrease\
\
	tFramesG  	Layout	 	tFrames\
	tFrames  	Command  	tAll\
	tFrames  	Command  	tNone\
	tFrames  	Toggle  	tFrame1\
	tFrames  	Toggle  	tFrame2\
	tFrames  	Toggle  	tFrame3\
	tFrames  	Toggle  	tFrame4\
	tFrames  	Toggle  	tFrame5\
	tFrames  	Toggle  	tFrame6\
	tFrames  	Toggle  	tFrame7\
	tFrames  	Toggle  	tFrame8\
	tFrames  	Toggle  	tFrame9\
	tFrames  	Toggle  	tFrame10\
	tFrames  	Toggle  	tFrame11\
	tFrames  	Toggle  	tFrame12\
	tFrames  	Toggle  	tFrame13\
	tFrames  	Toggle  	tFrame14\
	tFrames  	Toggle  	tFrame15\
	tFrames  	Toggle  	tFrame16\
}


set Objects(parameters) { \
	toplevel	Parameter	ximtool\
	ximtool		Parameter	alert\
	ximtool		Parameter	initialize\
	ximtool		Parameter	resize\
	ximtool		Parameter	frame\
	ximtool		Parameter	nframes\
	ximtool		Parameter	frameSize\
	ximtool		Parameter	frameRegion\
	ximtool		Parameter	frameView\
	ximtool		Parameter	frameTitle\
	ximtool		Parameter	frameFit\
	ximtool		Parameter	enhancement\
	ximtool		Parameter	colortables\
	ximtool		Parameter	cmfocus\
	ximtool		Parameter	autoscale\
	ximtool		Parameter	antialias\
	ximtool		Parameter	tileFrames\
	ximtool		Parameter	cursorMode\
	ximtool		Parameter	xflip\
	ximtool		Parameter	yflip\
	ximtool		Parameter	printerList\
	ximtool		Parameter	printOptions\
	ximtool		Parameter	loadOptions\
	ximtool		Parameter	saveOptions\
	ximtool		Parameter	tileOptions\
	ximtool		Parameter	filelist\
	ximtool		Parameter	help\
	ximtool		Parameter	info\
	ximtool		Parameter	ism_msg\
}


set Objects(help_panel) { \
	toplevel	TopLevelShell 	help_panel\
	help_panel  	Layout	 	helpLayout\
	helpLayout  	Group	 	helpMenuGroup\
	helpMenuGroup  	Layout	 	helpMenubar\
	helpLayout  	Layout	 	helpInfoLayout\
\
	helpMenubar	Command	 	helpClose\
\
	helpLayout	Command	 	helpBack\
	helpLayout	Command	 	helpForward\
	helpLayout	Command	 	helpHome\
        helpLayout      Frame           hfFrame\
        hfFrame         AsciiText       hfEntry\
        helpLayout      Command         hfFind\
        helpLayout      Command         hfClear\
	helpLayout  	Frame	 	helpTextFrame\
	helpTextFrame 	HTML	 	helpText\
\
	helpInfoLayout	Label	 	helpIRAFLogo\
	helpInfoLayout	Label	 	helpInfo1\
	helpInfoLayout	Label	 	helpInfo2\
	helpInfoLayout	Label	 	helpInfo3\
	helpInfoLayout	Label	 	helpNOAOLogo\
}


set Objects(blink_panel) { \
	toplevel	TopLevelShell 	blink_panel\
	blink_panel  	Layout	 	bpLayout\
\
	bpLayout  	Frame	 	brMenuFrame\
	brMenuFrame  	Layout	 	brMenuBar\
	brMenuBar  	Command	 	brClose\
\
	bpLayout	Frame		brFrame\
	brFrame		Layout		brLayout\
\
	brLayout	Group	 	brFramesG\
	brFramesG  	Layout	 	brFrames\
	brFrames	MenuButton  	brFrame1\
	brFrames	MenuButton  	brFrame2\
	brFrames	MenuButton  	brFrame3\
	brFrames	MenuButton  	brFrame4\
	brFrames	MenuButton  	brFrame5\
	brFrames	MenuButton  	brFrame6\
	brFrames	MenuButton  	brFrame7\
	brFrames	MenuButton  	brFrame8\
	brFrames	MenuButton  	brFrame9\
	brFrames	MenuButton  	brFrame10\
	brFrames	MenuButton  	brFrame11\
	brFrames	MenuButton  	brFrame12\
	brFrames	MenuButton  	brFrame13\
	brFrames	MenuButton  	brFrame14\
	brFrames	MenuButton  	brFrame15\
	brFrames	MenuButton  	brFrame16\
\
	brLayout	Group	 	brCmdG\
	brCmdG	 	Layout	 	brCmd\
	brCmd	 	Command	 	brReset\
	brCmd	 	Label	 	brRateLabel\
	brCmd	 	Frame	 	brBRframe\
	brBRframe  	Layout	 	brBRlayout\
	brBRlayout  	Arrow	 	brBRdecrease\
	brBRlayout  	TextBox	 	brBRtext\
	brBRlayout  	Arrow	 	brBRincrease\
	brCmd	 	Command	 	brRegButton\
	brCmd	 	Command	 	brMatchButton\
	brCmd	 	TextToggle  	brBlinkButton\
	brCmd	 	TextToggle  	brAregButton\
}


set Objects(hdr_panel) { \
	toplevel	TopLevelShell 	hdr_panel\
	hdr_panel	Layout		hdrLayout\
\
	hdrLayout	Frame		hdrMenuFrame\
	hdrMenuFrame	Layout		hdrMenuBar\
	hdrMenuBar	Command		hdrClose\
\
	hdrLayout  	Group	 	hdrObjGroup\
	hdrObjGroup  	Layout	 	hdrObjLayout\
	hdrObjLayout 	Label	 	hdrObjLabel\
	hdrObjLayout	MenuButton  	hdrObjMenu\
\
	hdrLayout  	Frame	 	hdrTabFrame\
	hdrTabFrame  	Tabs	 	hdrTabs\
	hdrTabs	 	Group	 	hdrHdrGroup\
	hdrTabs	 	Group	 	hdrWcsGroup\
\
	hdrHdrGroup  	Layout	 	hdrHdrLayout\
        hdrHdrLayout    Frame           hFindFrame\
        hFindFrame      AsciiText       hFindEntry\
        hdrHdrLayout    Command         hdrFilter\
        hdrHdrLayout    Command         hdrFind\
        hdrHdrLayout    Command         hdrClear\
	hdrHdrLayout 	HTML  		hdrText\
\
	hdrWcsGroup	Layout		hdrWcsLayout\
	hdrWcsLayout	Group		hdrInfoGroup\
	hdrInfoGroup	Frame		hdrIGFrame\
	hdrIGFrame	AsciiText	hdrIGText\
	hdrWcsLayout	Group		hdrKeywGroup\
	hdrKeywGroup	Frame		hdrKGFrame\
	hdrKGFrame	AsciiText	hdrKGText\
}


set Objects(pixel_table) { \
	toplevel	TopLevelShell	pixel_panel\
\
	pixel_panel	Layout		pixel_table\
	pixel_table	Frame		pixtabMenuFrame\
	pixtabMenuFrame	Layout		pixtabMenuBar\
	pixtabMenuBar	MenuButton	pixtabSize\
	pixtabMenuBar	Command		pixtabHelp\
	pixtabMenuBar	Command		pixtabClose\
\
	pixel_table	Frame		pixtabFrame\
	pixtabFrame  	Porthole	ptPort\
	ptPort	 	Layout	 	ptLayout\
	ptLayout	Frame	 	ptColFrame\
	ptColFrame  	MultiList  	ptColLabs\
	ptLayout  	Frame	 	ptRowFrame\
	ptRowFrame  	MultiList  	ptRowLabs\
	ptLayout	Frame		ptFrame\
	ptFrame		MultiList	pixtab\
\
	ptLayout	Label		meanLabel\
	ptLayout	Frame		meanFrame\
	meanFrame	Label		meanValue\
\
	ptLayout	Label		sigLabel\
	ptLayout	Frame		sigFrame\
	sigFrame	Label		sigValue\
}


set Objects(tcl_panel) { \
	toplevel	TopLevelShell tcl_panel\
	tcl_panel  	Layout		tclLayout\
	tclLayout  	Group		tclCmdGroup\
	tclCmdGroup  	Layout	 	tclCmd\
	tclCmd	 	Command	 	tclClear\
	tclCmd	 	Command	 	tclExecute\
	tclCmd	 	Command	 	tclDismiss\
	tclLayout  	Frame	 	tclFrame\
	tclFrame	AsciiText  	tclEntry\
}


set Objects(warning) { \
	toplevel	TransientShell	warning\
	warning		Layout		warn\
	warn		Frame		warnFrame\
	warnFrame	Layout		WFlayout\
	WFlayout	Icon		warnIcon\
	WFlayout	TextBox		warnText\
	warn		Command		warnOk\
	warn		Command		warnCancel\
}


set Resources(global) {	\

    !---------------------------------------------------------
    ! Define some global widget resources for the main panels.
    !---------------------------------------------------------
    *shadowWidth:			1
    *background:			#c4c4c4
!   *foreground:			black
    *Arrow.width:			16
    *Arrow.height:			25
    *Text*height:			21
    *Command.height:			21
    *Command.highlightThickness:	1
    *MenuButton.height:			21
    *MenuButton.highlightThickness:	1
    *Label.borderWidth:			0
    *Label.shadowWidth:			0
    *TextButton.shadowWidth:		0
    *TextButton.highlightThickness:	1
    *TextToggle*borderWidth:		0
    *TextToggle.highlightThickness:	0
    *Toggle.highlightThickness:		1
    *Group.shrinkToFit:			True

    *Arrow.foreground:			gray
    *Arrow.background:			#adadad
    *Text*background:			#adadad
    *AsciiText*background:		#adadad
    *TextBox.background:		#adadad
    *MultiList*background:		#adadad
    *Slider2d.thumbColor:		#c4c4c4


    !-------------------------------------------------------------
    ! Define resources to take advantage of the	3D scrollbar look.
    !-------------------------------------------------------------
    *Scrollbar*background:		#c4c4c4
    *Scrollbar*shadowWidth:		1
    *Scrollbar*width:			15
    *Scrollbar*height:			15
    *Scrollbar*cursorName:		top_left_arrow
    *Scrollbar*pushThumb:		true

    *HTML.Scrollbar.shadowWidth:	1
    *HTML*Scrollbar*width:		15
    *HTML*Scrollbar*height:		15


    !----------------------------------------
    ! Menu resources giving a shadow effect.
    !----------------------------------------
    *SmeBSB.leftMargin:			10
    *SmeBSB.rightMargin:		5
    *SmeBSB.shadowWidth:		2
    *SmeBSB.foreground:			#e5e5e5
    *SmeBSB.background:			SteelBlue
    *SimpleMenu.background:		#c4c4c4
    *SimpleMenu.borderWidth:		2
    *SimpleMenu.borderColor:		black
    *SimpleMenu.line1.foreground:	#9c9c9c
    *SimpleMenu.line2.foreground:	#e8e8e8
    *SimpleMenu.line3.foreground:	#9c9c9c
    *SimpleMenu.line4.foreground:	#e8e8e8
    *SimpleMenu.line5.foreground:	#9c9c9c
    *SimpleMenu.line6.foreground:	#e8e8e8
    *SimpleMenu.line7.foreground:	#9c9c9c
    *SimpleMenu.line8.foreground:	#e8e8e8
    *SimpleMenu.line9.foreground:	#9c9c9c
    *SimpleMenu.line10.foreground:	#e8e8e8
    *SimpleMenu.line11.foreground:	#9c9c9c
    *SimpleMenu.line12.foreground:	#e8e8e8
    *SimpleMenu.line13.foreground:	#9c9c9c
    *SimpleMenu.line14.foreground:	#e8e8e8
    *SimpleMenu.line15.foreground:	#9c9c9c
    *SimpleMenu.line16.foreground:	#e8e8e8
    *SimpleMenu.line17.foreground:	#9c9c9c
    *SimpleMenu.line18.foreground:	#e8e8e8
    *SimpleMenu.line19.foreground:	#9c9c9c
    *SimpleMenu.line20.foreground:	#e8e8e8
    *SimpleMenu.line21.foreground:	#9c9c9c
    *SimpleMenu.line22.foreground:	#e8e8e8
    *SimpleMenu.line23.foreground:	#9c9c9c
    *SimpleMenu.line24.foreground:	#e8e8e8
    *SimpleMenu.line25.foreground:	#9c9c9c
    *SimpleMenu.line26.foreground:	#e8e8e8
    *SimpleMenu.line27.foreground:	#9c9c9c
    *SimpleMenu.line28.foreground:	#e8e8e8
    *SimpleMenu.line29.foreground:	#9c9c9c
    *SimpleMenu.line30.foreground:	#e8e8e8
    *SimpleMenu.line31.foreground:	#9c9c9c
    *SimpleMenu.line32.foreground:	#e8e8e8
    *SimpleMenu.line33.foreground:	#9c9c9c
    *SimpleMenu.line34.foreground:	#e8e8e8
    *SimpleMenu.line35.foreground:	#9c9c9c
    *SimpleMenu.line36.foreground:	#e8e8e8
    *SimpleMenu.line37.foreground:	#9c9c9c
    *SimpleMenu.line38.foreground:	#e8e8e8
    *SimpleMenu.line39.foreground:	#9c9c9c
    *SimpleMenu.line40.foreground:	#e8e8e8


    !---------------------------------------------
    !  Fixups for 24-bit displays
    !---------------------------------------------
    *hFindEntry.background:		#adadad
    *hdrIGText.background:		#adadad
    *hdrKGText.background:		#adadad
    *hfEntry.background:		#adadad
    *printcmd.background:		#adadad
    *titleString.background:		#adadad
    *fnameText.background:		#adadad
    *imtemplateText.background:		#adadad
    *z1Value.background:		#adadad
    *z2Value.background:		#adadad
    *nsampValue.background:		#adadad
    *saveFile.background:		#adadad
    *infoText.background:		#adadad
    *wtName.background:			#adadad
    *wtTitle.background:		#adadad
    *wtFBCfg.background:		#adadad
    *wtIPixval.background:		#adadad
    *wtSPixval.background:		#adadad
    *wtBPixval.background:		#adadad
    *wtWcs1.background:			#adadad
    *wtWcs2.background:			#adadad
    *wtWcs3.background:			#adadad
    *wtWcs4.background:			#adadad
    *wcsIsmCmd.background:		#adadad
    *tclEntry.background:		#adadad

    *hFindEntry.foreground:		#000000
    *hdrIGText.foreground:		#000000
    *hdrKGText.foreground:		#000000
    *hfEntry.foreground:		#000000
    *printcmd.foreground:		#000000
    *titleString.foreground:		#000000
    *fnameText.foreground:		#000000
    *imtemplateText.foreground:		#000000
    *z1Value.foreground:		#000000
    *z2Value.foreground:		#000000
    *nsampValue.foreground:		#000000
    *saveFile.foreground:		#000000
    *infoText.foreground:		#000000
    *wtName.foreground:			#000000
    *wtTitle.foreground:		#000000
    *wtFBCfg.foreground:		#000000
    *wtIPixval.foreground:		#000000
    *wtSPixval.foreground:		#000000
    *wtBPixval.foreground:		#000000
    *wtWcs1.foreground:			#000000
    *wtWcs2.foreground:			#000000
    *wtWcs3.foreground:			#000000
    *wtWcs4.foreground:			#000000
    *wcsIsmCmd.foreground:		#000000
    *tclEntry.foreground:		#000000
}
    
    
    
    
 

set Resources(ximtool) { \

    ! Main image window resources.
    ! -------------------------------
    *allowShellResize:				True
    *beNiceToColormap:				False
    *menuLabel.foreground:			Gold
    *markerMenu.foreground:			Black
    *markerMenu.background:			SteelBlue
    *markerMenu*SimpleMenu.foreground:		Black
    *markerMenu*SimpleMenu.background:		SteelBlue
    *rulerMenu.foreground:			Black
    *rulerMenu.background:			SteelBlue
    *rulerMenu*SimpleMenu.foreground:		Black
    *rulerMenu*SimpleMenu.background:		SteelBlue
    *rulerMenu.SmeBSB.leftMargin:		16
    *magzoomMenu.foreground:                    Black
    *magzoomMenu.background:                    SteelBlue
    *magzoomMenu*SimpleMenu.foreground:         Black
    *magzoomMenu*SimpleMenu.background:         SteelBlue
    *markerColor.SmeBSB.leftMargin:		64
    *markerColor.SmeBSB.rightMargin:		0
    *markerColor.menuLabel.leftMargin:		5
    *markerColor.menuLabel.rightMargin:		5
    *rulerColor.SmeBSB.leftMargin:		64
    *rulerColor.SmeBSB.rightMargin:		0
    *rulerColor.menuLabel.leftMargin:		5
    *rulerColor.menuLabel.rightMargin:		5

    *ximtool.title:				XIMTOOL_VERSION

    *display.borderWidth:			0
    *display.layout: horizontal	{ \
	-0 \
	vertical { \
	    menuGroup  < +inf -inf * > \
	    -2 \
	    vertical { \
	        horizontal { \
	            imageFrame < +inf -inf * +inf -inf > \
	            vcutFrame  < * +inf -inf > \
	        } \
	        horizontal { \
	            hcutFrame  < +inf -inf * > 1 \
		    vertical { 4 plotOpts -4 } \
	        } \
	        horizontal { \
	            cbarFrame  < +inf -inf * > \
	            focusSlider 2 hcut 2 vcut 15 \
	        } \
	    } \
	} \
	-0 \
    }
    *hcut.label:				H
    *hcut.font:					*lucida-bold-r*10*
    *vcut.label:				V
    *vcut.font:					*lucida-bold-r*10*
    *focusSlider.location:			0 0 100 15

    *hcutFrame.frameType:                       sunken
    *hcutFrame.frameWidth:                      1
    *hcutFrame.innerOffset:                     0
    *hcutFrame.outerOffset:                     0
    *hcutPlot.color0:                           #c4c4c4
    *hcutPlot.color1:                           black
    *hcutPlot.color0:                           darkslategray
    *hcutPlot.color1:                           #eeeee0
    *hcutPlot.crosshairCursorColor:		red
    *hcutPlot.width:                            512
    *hcutPlot.height:                           6
    *hcutPlot.borderWidth:			0
    *hcutPlot.alphaFont1:			6x10
    *hcutPlot.alphaFont2:			6x10
    *hcutPlot.alphaFont3:			6x10
    *hcutPlot.alphaFont4:			6x10
    *hcutPlot.alphaFont5:			6x10
    *hcutPlot.alphaFont6:			6x10
    *hcutPlot.alphaFont7:			6x10
    *hcutPlot.alphaFont8:			6x10
    *hcutPlot.translations:	\
	 !Ctrl	<Key>1:	call(cpZoom,1,1,fixed) 		\n\
	 !Ctrl	<Key>2:	call(cpZoom,2,2,fixed) 		\n\
	 !Ctrl	<Key>3:	call(cpZoom,3,3,fixed) 		\n\
	 !Ctrl	<Key>4:	call(cpZoom,4,4,fixed) 		\n\
	 !Ctrl	<Key>5:	call(cpZoom,5,5,fixed) 		\n\
	 !Ctrl	<Key>6:	call(cpZoom,6,6,fixed) 		\n\
	 !Ctrl	<Key>7:	call(cpZoom,7,7,fixed) 		\n\
	 !Ctrl	<Key>8:	call(cpZoom,8,8,fixed) 		\n\
	 !Ctrl	<Key>9:	call(cpZoom,9,9,fixed) 		\n\
	 !Ctrl	<Key>b:	call(prevFrame,$name)		\n\
	 !Ctrl	<Key>f:	call(nextFrame,$name)		\n\
	 !Ctrl	<Key>i:	call(cpInvert)		       	\n\
	 !Ctrl	<Key>m:	call(toggleMagnifier)		\n\
	 !Ctrl	<Key>n:	call(normalize)			\n\
	 !Ctrl	<Key>p:	call(togglePanner)		\n\
      !Ctrl Alt <Key>q: call(Quit)			\n\
	 !Ctrl	<Key>r:	call(cpRegisterFrames)		\n\
	 !Ctrl	<Key>s:	call(cpMatchFrames)		\n\
	 !Ctrl	<Key>u:	call(cpZoom,1,1,fixed) 		\n\
	  Ctrl	<Key>+:	call(cpZoom,2.0,2.0,relative)	\n\
	  Ctrl	<Key>-:	call(cpZoom,0.5,0.5,relative)	\n\
	  Ctrl <Key>\<:	call(cpSetBlinkRate,BRdecrease)	\n\
	  Ctrl <Key>\>:	call(cpSetBlinkRate,BRincrease)	\n\
	  !Alt	<Key>b:	call(toggleBlink)	     	\n\
	  !Alt	<Key>c:	call(controlPanel)		\n\
	  !Alt	<Key>h:	call(Help)		 	\n\
	  !Alt	<Key>i:	call(infoPanel)		      	\n\
      !Ctrl Alt <Key>f: call(fitFrame)		 	\n\
	  !Alt	<Key>l:	call(loadPanel)		      	\n\
	  !Alt	<Key>p:	call(printPanel)	       	\n\
	  !Alt	<Key>s:	call(savePanel)		      	\n\
	  !Alt	<Key>t:	call(tclPanel)		     	\n\
	   !<Btn1Down>:	call(makeMarker,$name,$x,$y) m_create()	\n\
	 <EnterWindow>:	enter-window()			\n\
	 <LeaveWindow>:	leave-window()			\n\
	    <KeyPress>:	graphics-input()		\n\
         !Alt <Motion>:	call(curtrack_msg,$x,$y)	\n\
	      <Motion>:	track-cursor() call(hcutWCSUpdate,$x,$y)


    *vcutFrame.frameType:                       sunken
    *vcutFrame.frameWidth:                      1
    *vcutFrame.innerOffset:                     0
    *vcutFrame.outerOffset:                     0
    *vcutPlot.color0:                           #c4c4c4
    *vcutPlot.color1:                           black
    *vcutPlot.color0:                           darkslategray
    *vcutPlot.color1:                           #eeeee0
    *vcutPlot.crosshairCursorColor:		red
    *vcutPlot.width:                            6
    *vcutPlot.height:                           512
    *vcutPlot.borderWidth:			0
    *vcutPlot.alphaFont1:			6x10
    *vcutPlot.alphaFont2:			6x10
    *vcutPlot.alphaFont3:			6x10
    *vcutPlot.alphaFont4:			6x10
    *vcutPlot.alphaFont5:			6x10
    *vcutPlot.alphaFont6:			6x10
    *vcutPlot.alphaFont7:			6x10
    *vcutPlot.alphaFont8:			6x10
    *vcutPlot.translations:	\
	 !Ctrl	<Key>1:	call(cpZoom,1,1,fixed) 		\n\
	 !Ctrl	<Key>2:	call(cpZoom,2,2,fixed) 		\n\
	 !Ctrl	<Key>3:	call(cpZoom,3,3,fixed) 		\n\
	 !Ctrl	<Key>4:	call(cpZoom,4,4,fixed) 		\n\
	 !Ctrl	<Key>5:	call(cpZoom,5,5,fixed) 		\n\
	 !Ctrl	<Key>6:	call(cpZoom,6,6,fixed) 		\n\
	 !Ctrl	<Key>7:	call(cpZoom,7,7,fixed) 		\n\
	 !Ctrl	<Key>8:	call(cpZoom,8,8,fixed) 		\n\
	 !Ctrl	<Key>9:	call(cpZoom,9,9,fixed) 		\n\
	 !Ctrl	<Key>b:	call(prevFrame,$name)		\n\
	 !Ctrl	<Key>f:	call(nextFrame,$name)		\n\
	 !Ctrl	<Key>i:	call(cpInvert)		       	\n\
	 !Ctrl	<Key>m:	call(toggleMagnifier)		\n\
	 !Ctrl	<Key>n:	call(normalize)			\n\
	 !Ctrl	<Key>p:	call(togglePanner)		\n\
      !Ctrl Alt <Key>q: call(Quit)			\n\
	 !Ctrl	<Key>r:	call(cpRegisterFrames)		\n\
	 !Ctrl	<Key>s:	call(cpMatchFrames)		\n\
	 !Ctrl	<Key>u:	call(cpZoom,1,1,fixed) 		\n\
	  Ctrl	<Key>+:	call(cpZoom,2.0,2.0,relative)	\n\
	  Ctrl	<Key>-:	call(cpZoom,0.5,0.5,relative)	\n\
	  Ctrl <Key>\<:	call(cpSetBlinkRate,BRdecrease)	\n\
	  Ctrl <Key>\>:	call(cpSetBlinkRate,BRincrease)	\n\
	  !Alt	<Key>b:	call(toggleBlink)	     	\n\
	  !Alt	<Key>c:	call(controlPanel)		\n\
	  !Alt	<Key>h:	call(Help)		 	\n\
	  !Alt	<Key>i:	call(infoPanel)		      	\n\
      !Ctrl Alt <Key>f: call(fitFrame)		 	\n\
	  !Alt	<Key>l:	call(loadPanel)		      	\n\
	  !Alt	<Key>p:	call(printPanel)	       	\n\
	  !Alt	<Key>s:	call(savePanel)		      	\n\
	  !Alt	<Key>t:	call(tclPanel)		     	\n\
	   !<Btn1Down>:	call(makeMarker,$name,$x,$y) m_create()	\n\
	 <EnterWindow>:	enter-window()			\n\
	 <LeaveWindow>:	leave-window()			\n\
	    <KeyPress>:	graphics-input()		\n\
         !Alt <Motion>:	call(curtrack_msg,$x,$y)	\n\
	      <Motion>:	track-cursor() call(vcutWCSUpdate,$x,$y)


    *plotOpts.label:                            Options
    !*plotOpts*location:                         0 0 105 18
    *plotOpts*location:                         0 0 1 18
    *plotOpts.shrinkToFit:                      True
    *plotOpts.outerOffset:                      5
    *plotOpts.innerOffset:                      3
    *plotOpts.frameWidth:                       2
    *plotOpts*TextToggle.offIcon:               square0s
    *plotOpts*TextToggle.onIcon:                square1s
    *plotOpts*TextToggle.highlightColor:        yellow
    *plotOpts*TextToggle.outerOffset:           0
    *plotOpts*TextToggle.frameWidth:            0
    *plotOpts*TextToggle.selectionStyle:	multi
    *plotOpts*TextToggle.leftMargin:		3
    *plotOpts*TextToggle.alignment:		left

    *poptsLayout.borderWidth:			0
    *poptsLayout.layout: vertical { \
	-1 \
        plotSpeed plotAccurate plotImgPix \
	2 < -2 > \
        horizontal { -4 optLine < +inf -inf * > -4 } \
	2 < -2 > \
        curJump curSmooth curTrack \
	-1 \
     }
    *plotSpeed.label:				Better Speed
    *plotSpeed.on:			 	True
    *plotAccurate.label:			Better Accuracy
    *plotAccurate.on:				False
    *plotImgPix.label:				Image Pixels
    *plotImgPix.on:				False
    *plotImgPix.sensitive:			False
    *optLine.height:                            2
    *optLine.width:				120
    *optLine.outerOffset:			0
    *optLine.innerOffset:			0
    *optLine.frameWidth:                        2
    *optLine.frameType:                         chiseled
    *curJump.label:				Jump Cursor
    *curJump.on:				True
    *curSmooth.label:				Smooth Cursor
    *curSmooth.on:				False
    *curTrack.label:				Graphics Cursors
    *curTrack.on:				True


    *menuGroup.label:                           
    *menuGroup.height:                          40
    *menuGroup.width:                           518
    *menuGroup.frameType:                       raised
    *menuGroup.frameWidth:                      2
    *menubar.layout: horizontal { \
	1 < -1 > \
	fileButton 1 < -1 > viewButton 1 < -1 > optionsButton \
	1 < -1 > \
	imageTitle < +inff -inff * > \
	1 < -1 > \
	controlButton 1 < -1 > \
	1 < -1 > \
	xflipButton 1 < -1 > yflipButton \
	1 < -1 > \
	prevButton 1 < -1 > frameButton 1 < -1 > nextButton \
	1 < -1 > \
	helpButton \
	1 < -1 > \
    }

    *menubar*SimpleMenu.borderColor:		Black
    *menubar*SimpleMenu.borderWidth:		1
    *menubar*SimpleMenu.foreground:		white
    *menubar*SimpleMenu.background:		SteelBlue
    *SmeBSB.vertSpace:				10

    *SimpleMenu*font:	  -adobe-times-bold-r-normal-*-12-*-*-*-*-*-iso8859-1
    *fileButton.font:	  -adobe-times-bold-i-normal-*-12-*-*-*-*-*-iso8859-1
    *optionsButton.font:  -adobe-times-bold-i-normal-*-12-*-*-*-*-*-iso8859-1
    *viewButton.font:     -adobe-times-bold-i-normal-*-12-*-*-*-*-*-iso8859-1

    *menubar.width:				518
    *menubar*borderWidth:			0
    *menubar*Command.label:			x
    *menubar*Command.internalWidth:		0
    *menubar*Command.borderWidth:		0
    *menubar*Toggle.label:			x
    *menubar*Toggle.internalWidth:		0
    *menubar*Toggle.borderWidth:		0

    *fileButton.label:				File
    *fileButton.menuName:			fileMenu
    *viewButton.label:				View
    *viewButton.menuName:			viewMenu
    *optionsButton.label:			Options
    *optionsButton.menuName:			optionsMenu
    *imageTitle*font:				*times-bold-r*12*
    *imageTitle.width:				40
    *imageTitle.height:				20
    *frameButton.menuName:			frameMenu
    *frameButton.label:				1
    *frameButton.width:				20

    *Gterm.cmapName:				image
    *Gterm.basePixel:				64
    *imageFrame.frameType:                      sunken
    *imageFrame.frameWidth:                     1
    *imageFrame.outerOffset:                    0
    *imageFrame.innerOffset:                    0
    *imageFrame.width:				518
    *imageFrame.height:				518
    *cbarFrame.frameType:                       sunken
    *cbarFrame.frameWidth:                      1
    *cbarFrame.outerOffset:                     0
    *cbarFrame.innerOffset:                     0
    *cbarFrame.width:				518
    *imagewin.warpCursor:			true
    *imagewin.raiseWindow:			true
    *imagewin.deiconifyWindow:			true
    *imagewin.ginmodeCursor:			circle
    *imagewin.ginmodeBlinkInterval:		500
    *imagewin.resizable:			true
    *imagewin.copyOnResize:			false
    *imagewin.width:				512
    *imagewin.height:				512
    *imagewin.maxMappings:			64
    *imagewin.borderWidth:			0

    *imagewin.translations:     \
        None<Key>Left: call(move_cursor,-1,0)                   \n\
        None<Key>Down: call(move_cursor,0,1)                    \n\
          None<Key>Up: call(move_cursor,0,-1)                   \n\
       None<Key>Right: call(move_cursor,1,0)                    \n\
     !Shift <Key>Left: call(move_cursor,-10,0)                  \n\
     !Shift <Key>Down: call(move_cursor,0,10)                   \n\
       !Shift <Key>Up: call(move_cursor,0,-10)                  \n\
    !Shift <Key>Right: call(move_cursor,10,0)                   \n\
         !Ctrl <Key>h: call(move_cursor,-1,0)                   \n\
         !Ctrl <Key>j: call(move_cursor,0,1)                    \n\
         !Ctrl <Key>k: call(move_cursor,0,-1)                   \n\
         !Ctrl <Key>l: call(move_cursor,1,0)                    \n\
   !Ctrl Shift <Key>h: call(move_cursor,-10,0)                  \n\
   !Ctrl Shift <Key>j: call(move_cursor,0,10)                   \n\
   !Ctrl Shift <Key>k: call(move_cursor,0,-10)                  \n\
   !Ctrl Shift <Key>l: call(move_cursor,10,0)                   \n\
          !Alt <Key>1: call(cpSetFrame,frame1)               	\n\
          !Alt <Key>2: call(cpSetFrame,frame2)               	\n\
          !Alt <Key>3: call(cpSetFrame,frame3)               	\n\
          !Alt <Key>4: call(cpSetFrame,frame4)               	\n\
         !Ctrl <Key>1: call(cpZoom,1,1,fixed) 			\n\
         !Ctrl <Key>2: call(cpZoom,2,2,fixed) 			\n\
         !Ctrl <Key>3: call(cpZoom,3,3,fixed) 			\n\
         !Ctrl <Key>4: call(cpZoom,4,4,fixed) 			\n\
         !Ctrl <Key>5: call(cpZoom,5,5,fixed) 			\n\
         !Ctrl <Key>6: call(cpZoom,6,6,fixed) 			\n\
         !Ctrl <Key>7: call(cpZoom,7,7,fixed) 			\n\
         !Ctrl <Key>8: call(cpZoom,8,8,fixed) 			\n\
         !Ctrl <Key>9: call(cpZoom,9,9,fixed) 			\n\
      !Ctrl <Key>Left: call(moveFrame,-1,0)                     \n\
      !Ctrl <Key>Down: call(moveFrame,0,1)                      \n\
        !Ctrl <Key>Up: call(moveFrame,0,-1)                     \n\
     !Ctrl <Key>Right: call(moveFrame,1,0)                      \n\
  !Ctrl Alt <Key>Left: call(moveFrame,-0.5,0)                   \n\
  !Ctrl Alt <Key>Down: call(moveFrame,0,0.5)                    \n\
    !Ctrl Alt <Key>Up: call(moveFrame,0,-0.5)                   \n\
 !Ctrl Alt <Key>Right: call(moveFrame,0.5,0)                    \n\
         !Ctrl <Key>a: call(toggleAutoReg)                 	\n\
         !Ctrl <Key>b: call(prevFrame,$name)                 	\n\
         !Ctrl <Key>c: call(cpZoomAction,centerFrame)        	\n\
         !Ctrl <Key>f: call(nextFrame,$name)                 	\n\
         !Ctrl <Key>i: call(cpInvert)                 		\n\
         !Ctrl <Key>m: call(toggleMagnifier)                    \n\
         !Ctrl <Key>n: call(normalize)                       	\n\
         !Ctrl <Key>o: call(offset,$x,$y)                       \n\
         !Ctrl <Key>p: call(togglePanner)                       \n\
     !Ctrl Alt <Key>q: call(Quit)               		\n\
         !Ctrl <Key>r: call(cpRegisterFrames)                	\n\
         !Ctrl <Key>s: call(cpMatchFrames)                   	\n\
         !Ctrl <Key>t: call(tileFramesToggle)                  	\n\
         !Ctrl <Key>u: call(cpZoom,1,1,fixed) 			\n\
         !Ctrl <Key>x: call(cpFrameAction,flipX)               	\n\
         !Ctrl <Key>y: call(cpFrameAction,flipY)               	\n\
     !Ctrl Alt <Key>=: call(Print)            			\n\
          Ctrl <Key>+: call(cpZoom,2.0,2.0,relative)            \n\
          Ctrl <Key>-: call(cpZoom,0.5,0.5,relative)            \n\
         Ctrl <Key>\<: call(cpSetBlinkRate,BRdecrease)          \n\
         Ctrl <Key>\>: call(cpSetBlinkRate,BRincrease)          \n\
         Ctrl <Key>\[: call(setCtrBoxSize,$x,$y,-1)             \n\
         Ctrl <Key>\]: call(setCtrBoxSize,$x,$y,1)              \n\
         !Ctrl <Key>0: call(centroid,$x,$y,peak)            	\n\
     !Ctrl Alt <Key>0: call(centroid,$x,$y,min)            	\n\
          !Alt <Key>b: call(toggleBlink)            		\n\
          !Alt <Key>c: call(controlPanel)              		\n\
     !Ctrl Alt <Key>f: call(fitFrame)            		\n\
          !Alt <Key>h: call(Help)                 		\n\
          !Alt <Key>i: call(infoPanel)               		\n\
          !Alt <Key>l: call(loadPanel)               		\n\
          !Alt <Key>p: call(printPanel)               		\n\
          !Alt <Key>s: call(savePanel)               		\n\
          !Alt <Key>t: call(tclPanel)               		\n\
          !<Btn1Down>: call(makeMarker,$name,$x,$y) m_create()	\n\
    !Shift <Btn2Down>: crosshair(on)                         	\n\
  !Shift <Btn2Motion>: crosshair(on)                         	\n\
       !Shift<Btn2Up>: crosshair(off)                        	\n\
            !<Btn2Up>: crosshair(off)                        	\n\
          !<Btn2Down>: call(zoom,$x,$y)                      	\n\
          !<Btn3Down>: call(windowColormap,$x,$y)            	\n\
            !<Btn3Up>: call(updateColormap,$x,$y)            	\n\
        !<Btn3Motion>: call(windowColormap,$x,$y)            	\n\
     !Ctrl <Btn1Down>: call(makeRuler,$name,$x,$y)     		\n\
    !Ctrl <Btn1Motion>: track-cursor() call(wcsUpdate,$x,$y) call(magnifierMapImage,$x,$y) call(resizeRuler,$x,$y,0)      			\n\
        !Ctrl <Btn1Up>: call(deleteRuler,$x,$y)         	\n\
        <EnterWindow>: enter-window()                        	\n\
        <LeaveWindow>: leave-window()                        	\n\
           <KeyPress>: graphics-input()                      	\n\
         !Alt <Motion>: call(curtrack_msg,$x,$y)        	\n\
             <Motion>: track-cursor() call(wcsUpdate,$x,$y) call(magnifierMapImage,$x,$y)


! The following translations can be used to enable windowing of the
! individual RGB components of the colormap.  It's not very useful but
! included here for those that may wish to use it.
!--------------------------------------------------------------------------
!     !Ctrl <Btn1Down>: call(windowRGB,1,$x,$y,0)               	\n\
!   !Ctrl <Btn1Motion>: call(windowRGB,1,$x,$y,0)               	\n\
!       !Ctrl <Btn1Up>: call(windowRGB,1,$x,$y,1)               	\n\
!     !Ctrl <Btn2Down>: call(windowRGB,2,$x,$y,0)               	\n\
!   !Ctrl <Btn2Motion>: call(windowRGB,2,$x,$y,0)               	\n\
!       !Ctrl <Btn2Up>: call(windowRGB,2,$x,$y,1)               	\n\
!     !Ctrl <Btn3Down>: call(windowRGB,3,$x,$y,0)               	\n\
!   !Ctrl <Btn3Motion>: call(windowRGB,3,$x,$y,0)               	\n\
!       !Ctrl <Btn3Up>: call(windowRGB,3,$x,$y,1)               	\n\

    *colorbar.borderWidth:			0
    *colorbar.maxRasters:			1
    *colorbar.maxMappings:			1
    *colorbar.width:				50
    *colorbar.height:				17
}


set Resources(panelShell) { \

    !================================
    !  Main Integrated Control Panel
    !================================
    *panelShell.title:				XImtool Control Panel
    *panelShell.geometry:			480x630
    *panelShell.maxWidth:			480
    *panelShell.minWidth:			480
    *panelTabs.internalHeight:			3
    *panelTabs.internalWidth:			10

    *Text*font:	 	 -*-helvetica-medium-r-normal-*-12-*-iso8859-1
    *TextBox*font:	 -*-helvetica-medium-r-normal-*-12-*-iso8859-1
    *List.font:	 	 -*-helvetica-medium-r-normal-*-12-*-iso8859-1
    *MultiList.font:	 -*-helvetica-medium-r-normal-*-12-*-iso8859-1
    *TextButton.font: 	 -*-helvetica-medium-r-normal-*-12-*-iso8859-1
    *TextToggle.font: 	 -*-helvetica-medium-r-normal-*-12-*-iso8859-1

    *display_panel.tabLabel:			Display
    *display_panel.innerOffset:			5
    *print_panel.tabLabel:			Print
    *print_panel.innerOffset:			5
    *load_panel.tabLabel:			Load
    *load_panel.innerOffset:			5
    *save_panel.tabLabel:			Save
    *save_panel.innerOffset:			5
    *info_panel.tabLabel:			Info
    *info_panel.innerOffset:			5
    *tile_panel.tabLabel:			Tile
    *tile_panel.innerOffset:			5
    *wcs_panel.tabLabel:			Coords
    *wcs_panel.innerOffset:			5

    *panelMenuBar*borderWidth:			0
    *panelMenuBar*Command.internalHeight:	4
    *panelMenuBar*Command.internalWidth:	15
    *panelMenuBar.layout: vertical { \
	5 < -5	> \
	horizontal { \
	    10	< +inf -10> \
	    panelHelp \
	    3 < -3 > \
	    panelClose	\
	    7 < -7 > \
	} \
	5 < -5	> \
    }

    *panelHelp.label:				Help
    *panelClose.label:				Dismiss


    *tabFrame.outerOffset:			3
    *tabFrame.innerOffset:			0
    *tabFrame.frameWidth:			0
    *tabFrame.frameType:			chiseled
    *panelMenuFrame.outerOffset:		0
    *panelMenuFrame.innerOffset:		1
    *panelMenuFrame.frameType:			raised
    *panelMenuFrame.frameWidth:			2
    *panel.layout: vertical { \
	panelMenuFrame	 < +inf	-inf * > \
	3 \
	horizontal { tabFrame < +inf -inf * +inf -inf>	} \
    }
} 


set Resources(display_panel) { \

    !================================
    ! Main Display Control Panel.
    !================================
    *controlPanel*internalWidth:		0
    *controlPanel*borderWidth:			0

    *TextBox.font:	7x13bold
    *TextToggle.font:	-adobe-times-medium-r-normal-*-12-*-*-*-*-*-iso8859-1
    *Command.font:	-adobe-times-bold-i-normal-*-12-*-*-*-*-*-iso8859-1
    *Toggle.font:	-adobe-times-medium-r-normal-*-12-*-*-*-*-*-iso8859-1
    *Label.font:	-*-helvetica-medium-r-normal-*-12-*-iso8859-1
    *MultiList.font:	-adobe-times-medium-r-normal-*-12-*-*-*-*-*-iso8859-1
    *toggleZoom.font:	-*-helvetica-medium-r-normal-*-12-*-iso8859-1
    *centerFrame.font:	-*-helvetica-medium-r-normal-*-12-*-iso8859-1
    *zoom*Command.font:	7x13bold

    *blinkFrame1.font:		-adobe-times-medium-r-normal-*-12-*-iso8859-1
    *blinkFrame2.font:		-adobe-times-medium-r-normal-*-12-*-iso8859-1
    *blinkFrame3.font:		-adobe-times-medium-r-normal-*-12-*-iso8859-1
    *blinkFrame4.font:		-adobe-times-medium-r-normal-*-12-*-iso8859-1
    *matchButton.font:		-adobe-times-medium-r-normal-*-12-*-iso8859-1
    *registerButton.font:	-adobe-times-medium-r-normal-*-12-*-iso8859-1
    *blinkButton.font:		-adobe-times-medium-r-normal-*-12-*-iso8859-1
    *autoregButton.font: 	-adobe-times-medium-r-normal-*-12-*-iso8859-1

    *controlPanel.layout: vertical { \
	5 < -5	> \
	horizontal { \
	    -1	\
	    viewBox < +inf -inf * > \
	    -1	\
	} \
	5 < -5	> \
	horizontal { \
	    -1	\
	    enhancementBox < +inf -inf	* +inf -inf > \
	    -5	\
	    vertical {	\
		-1 \
		blinkBox < * +inf - inf > \
		 1 \
		optionsBox < * +inff -inff > \
		-1 \
	    } \
	    -1	\
	} \
	-5 \
	controlBox < +inf * > \
	-5 \
    }

    ! VIEW
    ! ------------------
    *viewBox.label:				View
    *viewBox.location:				0 0 410 0
    *viewBox.shrinkToFit:			True
    *viewBox.outerOffset:			7

    *view.layout: vertical { \
	5 < +inf -5 > \
	horizontal { \
	    -1	\
	    frameSelect \
	    vertical {	\
		3 < -3 > \
		frameDataBox < +inff -100% * +inff -100% > \
		3 < -3 > \
	    } \
	    zoomBox \
	    -1	\
	} \
	1 < +inf > \
	viewButtons < +inf -inf * +inf	-inf > \
	5 < +inf -5 > \
    }

    *frameDataBox.frameType:			sunken
    *frameDataBox.frameWidth:			1
    *frameData.width:				150
    *frameData.height:				50

    *frameSelect.location:			0 0 72 0
    *frameSelect.shrinkToFit:			True
    *frameSelect.outerOffset:			7
    *frameSelect.innerOffset:			2
    *frameSelect.frameWidth:			2
    *frameSelect*offIcon:			diamond0s
    *frameSelect*onIcon:			diamond1s
    *frameSelect*highlightColor:		blue
    *frameSelect.label:				Frame

    *frameBox.layout: vertical { \
	3 \
	horizontal { -2	frlistBox < * +inff -inff > } \
	3 < +inf -3 > \
	horizontal { prevFrame < +inf -inf * > 4 nextFrame < +inf -inf * > } \
    }
    *framePort.allowVert:			True
    *framePort.allowHoriz:			False
    *framePort.useRight:			True
    *framePort.height:				80

    *frameBox*alignment:			left
    *frameBox*frameWidth:			0
    *frameBox*frame1.label:			1\ \ 
    *frameBox*frame2.label:			2\ \ 
    *frameBox*frame3.label:			3\ \ 
    *frameBox*frame4.label:			4\ \ 

    *frameBox*frame5.label:			5\ \ 
    *frameBox*frame6.label:			6\ \ 
    *frameBox*frame7.label:			7\ \ 
    *frameBox*frame8.label:			8\ \ 
    *frameBox*frame9.label:			9\ \ 
    *frameBox*frame10.label:			10\ 
    *frameBox*frame11.label:			11\ 
    *frameBox*frame12.label:			12\ 
    *frameBox*frame13.label:			13\ 
    *frameBox*frame14.label:			14\ 
    *frameBox*frame15.label:			15\ 
    *frameBox*frame16.label:			16\ 
    *frameBox*Command.width:			24
    *frameBox*prevFrame.label:			xxx
    *frameBox*nextFrame.label:			xxx

    *frameList*location:			0 0 50 20
    *frameList.layout: vertical	{ \
	frame1	< +inf * >\
	frame2	< +inf * >\
	frame3	< +inf * >\
	frame4	< +inf * >\
	frame5	< +inf * >\
	frame6	< +inf * >\
	frame7	< +inf * >\
	frame8	< +inf * >\
	frame9	< +inf * >\
	frame10 < +inf * >\
	frame11 < +inf * >\
	frame12 < +inf * >\
	frame13 < +inf * >\
	frame14 < +inf * >\
	frame15 < +inf * >\
	frame16 < +inf * >\
    }


    *zoomBox.label:				Zoom:
    *zoomBox.location:				0 0 160 127
    *zoomBox.outerOffset:			7
    *zoomBox.shrinkToFit:			True
    *zoomBox*TextButton.frameWidth:		1
    *zoomBox*TextButton.outerOffset:		0

    *controlPanel*zoom*internalWidth:		4
    *zoom.layout: vertical { \
	space = ((50% of width	zoom) -	(50% of	width z5)) \
	1 < +inf > \
	horizontal { \
	    vertical { toggleZoom < +inf * +inf > 1 } \
	    1 \
	    vertical { 1 < +inf > z5 1 < +inf > z3 0 < +inf > } \
	    1 \
	    vertical { zoomIn < +inf	* +inf > 1 } \
	} \
	1 \
	horizontal { \
	    1 < +inf >	\
	    d8	1 d4 1 d2 1 x1 1 z2 1 z4 1 z8 \
	    1 < +inf >	\
	} \
	1 \
	horizontal { \
	    vertical { 1 zoomOut < +inf * +inf	> } \
	    1 \
	    vertical { 0 < +inf > d3 1 < +inf > d5 1 < +inf > } \
	    1 \
	    vertical { 1 centerFrame <	+inf * +inf > } \
	} \
	1 < +inf > \
    }

    *toggleZoom.label:				Toggle\nZoom
    *toggleZoom.outerOffset:			2
    *toggleZoom.width:				30
    *toggleZoom.height:				25

    *zoomIn.label:				Zoom\nIn
    *zoomIn.outerOffset:			2
    *zoomIn.width:				30
    *zoomIn.height:				25

    *x1.label:					1
    *z2.label:					2
    *z3.label:					3
    *z4.label:					4
    *z5.label:					5
    *z8.label:					8

    *controlPanel*zoomIn.foreground:		royalBlue3
    *controlPanel*z4.foreground:		royalBlue3
    *controlPanel*z5.foreground:		royalBlue3
    *controlPanel*z8.foreground:		royalBlue3
    *controlPanel*z2.foreground:		royalBlue3
    *controlPanel*z3.foreground:		royalBlue3

    *zoomOut.label:				Zoom\nOut
    *zoomOut.outerOffset:			2
    *zoomOut.width:				30
    *zoomOut.height:				25

    *centerFrame.label:				Center
    *centerFrame.outerOffset:			2
    *centerFrame.width:				30
    *centerFrame.height:			25

    *d2.label:					2
    *d3.label:					3
    *d4.label:					4
    *d5.label:					5
    *d8.label:					8

    *controlPanel*zoomOut.foreground:		mediumVioletRed
    *controlPanel*d2.foreground:		mediumVioletRed
    *controlPanel*d3.foreground:		mediumVioletRed
    *controlPanel*d4.foreground:		mediumVioletRed
    *controlPanel*d5.foreground:		mediumVioletRed
    *controlPanel*d8.foreground:		mediumVioletRed

    *viewButtons.location:			0 0 100 80
    *viewButtons.layout: horizontal { \
	2 < -2 > \
	aspect     < +inf * > 2 \
	flipX      < +inf * > 2 \
	flipY      < +inf * > 2 \
	flipXY     < +inf * > 2 \
	clearFrame < +inf * > 2 \
	fitFrame   < +inf * >   \
	2 < -2 > \
    }
    *nextFrame.label:				Next Frame
    *prevFrame.label:				Previous Frame
    *fitFrame.label:				Fit Frame
    *aspect.label:				Aspect
    *clearFrame.label:				Clear Frame
    *flipX.label:				Flip X
    *flipY.label:				Flip Y
    *flipXY.label:				Flip XY


    ! ENHANCEMENT
    ! ------------------
    *enhancementBox.label:			Enhancement
    *enhancementBox.location:			0 0 110	0
    *enhancementBox.shrinkToFit:		True
    *enhancementBox.outerOffset:		7

    *enhance*Viewport.allowVert:		True
    *enhance*Viewport.allowHoriz:		False
    *enhance*Viewport.useRight:			False
    *enhance*Viewport.resizeable:		True
    *enhance*Scrollbar.width:			17
    *enhance*Scrollbar.minimumThumb:		10
    *enhance.layout: vertical {	\
	3 < -3	> \
	horizontal { \
	    2 < -2 > \
	    colorlistFrame < +inf -inf	* +inff	-inff >	\
	    2 < -2 > \
	} \
	2 \
	horizontal { \
	    2 < -2 > \
	    colordataFrame < +inf -inf	* +inf -inf > \
	    2 < -2 > \
	} \
	5 < -5	> \
	horizontal { \
	    2 < -2 > \
	    vertical { -1 contrastLabel 3 < -3 > brightnessLabel -1 } \
	    3 < -3 > \
	    vertical {	\
		-1 \
		contrastSlider < +inf -inf * > \
		3 < -3 > \
		brightnessSlider < +inf -inf * > \
		-1 \
	    } \
	    2 < -2 > \
	} \
	5 < -5	> \
	horizontal { \
	    3 < -3 > \
	    invertButton < +inf -inf *	> \
	    5 < -5 > \
	    optimizeButton < +inf -inf	* > \
	    3 < -3 > \
	} \
	3 < -3	> \
    }

    *enhance*frameType:				sunken
    *enhance*frameWidth:			1
    *enhance*BorderWidth:			0
    *enhance*Label.ShadowWidth:			0

    *colorlist.width:				100
    *colorlist.height:				98
    *colordata.width:				100
    *colordata.height:				45
    *enhance*colordata.frameWidth:		0
    *contrastLabel.label:			x
    *contrastSlider.location:			0 0 100	17
    *brightnessLabel.label:			x
    *brightnessSlider.location:			0 0 100 17
    *invertButton.label:			Invert
    *optimizeButton.label:			Optimize


    ! ---------------------
    ! BLINK/REGISTER
    ! ---------------------
    *blinkBox.label:				Blink/Register
    *blinkBox.location:				0 0 235 0
    *blinkBox.shrinkToFit:			True
    *blinkBox.outerOffset:			7
    *blinkBox*TextToggle.frameWidth:		1

    *blink.layout: vertical { \
	space = (width	blinkFramesLabel - width blinkRateLabel) \
	3 < -3	> \
	horizontal { \
	    0 \
	    blinkFramesLabel \
	    3 < +inf >	\
	    blinkFrame1 < -50%	* > \
	    blinkFrame2 < -50%	* > \
	    blinkFrame3 < -50%	* > \
	    blinkFrame4 < -50%	* > \
	    4 < +inf >	\
	    blinkPanel	 < -50%	* > \
	    blinkReset	\
	    2 \
	} \
	5 < -5	> \
	horizontal { \
	    $space \
	    blinkRateLabel \
	    2	\
	    BRframe < +inf * >	\
	} \
	5 < +inf -100%	> \
	horizontal { \
	    vertical {	\
		2 matchButton	< +inf * > 4 < -4 > registerButton < +inf * > \
	    } \
	    5 < -5 > \
	    vertical {	\
		1 blinkButton	< +inf * > 4 < -4 > autoregButton < +inf * > \
	    } \
	} \
    }

    *BRlayout.layout: horizontal { \
	BRdecrease \
	BRtext	< +inf -100% * > \
	BRincrease \
    }

    *blink.Label.borderWidth:			0
    *blink.Label.shadowWidth:			0
    *controlPanel*blink*internalWidth:		4
    *blink.TextToggle.location:			0 0 102 23
    *blink.TextToggle.frameWidth:		1
    *blink*TextToggle.highlightColor:		yellow
    *blink*TextToggle.offIcon:			square0s
    *blink*TextToggle.onIcon:			square1s
    *blink*TextToggle.outerOffset:		1
    *blink*Command.height:			27
    *blink*Arrow.width:				16
    *blink*Arrow.height:			25


    *blinkFramesLabel.label:			Frames List:
    *blinkFrame1.label:				1
    *blinkFrame2.label:				2
    *blinkFrame3.label:				3
    *blinkFrame4.label:				4
    *blinkPanel.label:				x
    *blinkPanel.width:				20
    *blinkReset.label:				Reset

    *blinkRateLabel.label:			Blink Rate:
    *BRframe.frameType:				sunken
    *BRframe.frameWidth:			1
    *BRtext.width:				40
    *BRtext.height:				23
    *BRdecrease.direction:			left
    *BRincrease.direction:			right
    *registerButton.label:			Register
    *matchButton.label:				Match LUTs
    *blinkButton.label:				Blink
    *autoregButton.label:			Auto-Register

    ! OPTIONS
    ! ---------------------
    *optionsBox.label:				Options
    *optionsBox.location:			0 0 220 0
    *optionsBox.shrinkToFit:			False
    *optionsBox.outerOffset:			7
    *optionsBox*offIcon:			square0s
    *optionsBox*onIcon:				square1s
    *optionsBox*selectionStyle:			multi
    *optionsBox*highlightColor:			yellow
    *optionsBox.TextToggle.location:		0 0 102 20
    *optionsBox.TextToggle.frameWidth:		0
    *optionsBox.TextToggle.highlightThickness:	0
    *optionsBox*alignment:			left

    *pannerButton.label:			Panner
    *coordsBoxButton.label:			Coords Box
    *autoscaleButton.label:			Autoscale
    *antialiasButton.label:			Antialias
    *tileFramesButton.label:			Tile Frames
    *magnifierButton.label:			Magnifier
    *warningsButton.label:			Warnings
    *peakupButton.label:			Centroid Peaks
    *peakupButton.on:				True

    ! CONTROL
    ! ----------------------
    *controlBox.frameType:			chiseled
    *controlBox.frameWidth:			2
    *controlBox.outerOffset:			7
    *controlBox.innerOffset:			5
    *controlBox.height:				30

    *control.layout: horizontal	{ \
	1 \
	initializeButton < +inf * > \
	5 < -5	> \
	normalizeButton < +inf	* > \
	80 < +inf -100% > \
    }

    *initializeButton.label:			Initialize
    *normalizeButton.label:			Normalize
}


set Resources(print_panel) { \

    !=====================================
    !  Print Setup Panel resources.	!
    !=====================================
    *print_panel*TextToggle.alignment:		left
    *print_panel*Arrow.width:			16
    *print_panel*Arrow.height:			20
    *print_panel*TextToggle.frameWidth:		0
    *print_panel*TextToggle.height:		20
    *print_panel*Label.borderWidth:		0
    *print_panel*Label.shadowWidth:		0
    *print_panel*TextButton.width:		40
    *print_panel*TextButton.height:		25

    *printLayout.borderWidth:			0
    *printLayout.layout: vertical { \
	-1 \
	printCmdGroup < +inf *	> \
	-1 \
	optGroup < +inf -inf *	+inf -inf > \
	-3 \
	cmdGroup < +inf * > \
	-1\
    }


    ! Print Group resources.
    !----------------------------------
    *printCmdGroup.borderWidth:			0
    *printCmdGroup.outerOffset:			5
    *printCmdGroup.label:			
    *printCmdGroup.location:			0 0 400 80
    *printCmdGroup*offIcon:			diamond0s
    *printCmdGroup*onIcon:			diamond1s
    *printCmdGroup*highlightColor:		cyan
    *printCmdGroup*Frame.frameType:		sunken
    *printCmdGroup*Frame.frameWidth:		1
    *printCmdGroup*Frame.width:			300
    *printCmdGroup*Label.justify:		right
    *printCmdGroup*Text*editType:		edit
    *printCmdGroup*Text*height:			22
    *printCmdGroup*TextToggle.width:		70
    *printCmdGroup*shadowWidth:			0
    *printCmdGroup*borderWidth:			0
    *printCmdLayout.borderWidth:		0
    *printCmdLayout.layout: horizontal { \
	labelLayout 5 inputLayout < +inf -inf * > \
    }
    *labelLayout.borderWidth:			0
    *labelLayout.layout: vertical { 5 toLabel 7 printerLabel }
    *printerLabel.label:			Print Command:
    *toLabel.label:				Print To:
    *toPrinter.label:				Printer
    *toPrinter.on:				True
    *toFile.label:				File

    *inputLayout.borderWidth:			0
    *inputLayout.layout: horizontal { \
	3 \
	vertical { \
	    5 \
	    horizontal { 5 toPrinter 5 toFile 5 < +inf -inf > } \
	    5 \
	    printcmdFrame < +inf -inf * > \
	    5 \
	} \
	3 \
    }
    *printcmd*string:				lpr
    *printcmd*height:				22
    *printcmd*Text*editType:			edit


    !  Main options groups layout resources.
    !---------------------------------------
    *optGroup.frameWidth:			2
    *optGroup.frameType:			chiseled
    *optGroup.label:			
    *optGroup.location:				0 0 400 330
    *optGroup.outerOffset:			5
    *optGroup.innerOffset:			2
    *optLayout*borderWidth:			0
    *optLayout.layout: vertical	{ \
	-1 \
	horizontal { \
	    vertical {	\
		5 \
		epsPageGroup < +inf -inf * >	\
		optionsGroup < +inf -inf * +inf -inf > \
		-1 \
	    } \
	    vertical {	\
		5 \
		printColorGroup  < +inf -inf * > \
		printerGroup	< +inf -inf * >	\
		-1 \
	    } \
	    -1	\
	} \
	5 \
	horizontal { annOptsGroup < +inf * +inf	> -1 } \
	-1 \
    }


    ! Postscript Options group resources.
    ! -----------------------------------
    *epsPageGroup.label:			Postscript Options
    *epsPageGroup.outerOffset:			7
    *epsPageGroup.innerOffset:			5
    *epsPageGroup.location:			0 0 250 150
    *epsPageGroup*offIcon:			diamond0s
    *epsPageGroup*onIcon:			diamond1s
    *epsPageGroup*highlightColor:		cyan
    *epsPage*Label.justify:			left
    *epsPage.layout: vertical {	\
	-1 \
	epsOrientLabel	4 < -4 > \
	horizontal { 25 epsPortButton epsLandButton epsSquareButton -1 } \
	4 \
	epsSizeLabel -1 \
	horizontal { \
	    25 epsLetterButton epsLegalButton epsA4Button epsB5Button -1 \
	} \
	10 \
	horizontal { 5 epsScaleLabel 4 ScaleFrame < +inf -inf * > } \
	-1 \
    }


    ! Page Layout resources.
    ! -------------------------------
    *epsOrientLabel.label:			Orientation:
    *epsPortButton.label:			Portrait
    *epsPortButton.width:			65
    *epsLandButton.label:			Landscape
    *epsLandButton.width:			85
    *epsSquareButton.label:			Square
    *epsSquareButton.width:			70
    *epsSquareButton.sensitive:			False

    *epsSizeLabel.label:			Paper Size:
    *epsLetterButton.label:			Letter
    *epsLetterButton.width:			60
    *epsLegalButton.label:			Legal
    *epsLegalButton.width:			60
    *epsA4Button.label:				A4
    *epsA4Button.width:				50
    *epsB5Button.label:				B5
    *epsB5Button.width:				50

    ! Image scale box resources.
    ! -------------------------------
    *epsScaleLabel.label:			Output  Image  Scale:
    *epsScaleLabel.justify:			right
    *ScaleFrame.frameType:			sunken
    *ScaleFrame.frameWidth:			1
    *ScaleFrame*shadowWidth:			0
    *ScaleLayout.location:			0 0 100 35
    *ScaleLayout.label:			 
    *ScaleLayout.layout: horizontal { \
	SCdecrease SCtext < +inf -100% * > SCincrease \
    }
    *SCdecrease.direction:			left
    *SCtext.width:				75
    *SCtext.height:				22
    *SCtext.label:				100 %
    *SCincrease.direction:			right


    ! Miscellaneous print options box resources.
    ! ------------------------------------
    *optionsGroup.outerOffset:			7
    *optionsGroup.innerOffset:			5
    *optionsGroup*onIcon:			square1s
    *optionsGroup*offIcon:			square0s
    *optionsGroup.label:			Processing Options
    *optionsGroup*TextToggle.width:		125
    *optionsGroup*TextToggle.highlightColor:	yellow
    *options.location:				0 0 250 60
    *options.frameWidth:			2
    *options.layout: horizontal	{ \
	5 \
	vertical { -1 epsscaleButton 2	autorotateButton -1 } \
	3 \
	vertical { -1 aspectButton   2	compressButton	 -1 } \
	-1 \
    }
    *epsscaleButton.label:			Auto Scale
    *autorotateButton.label:			Auto Rotate
    *aspectButton.label:			Max Aspect
    *compressButton.label:			RLE Compress
    *compressButton.sensitive:			False


    ! Annotation options box resources.
    ! ------------------------------------
    *annOptsGroup.outerOffset:			7
    *annOptsGroup.innerOffset:			5
    *annOptsGroup*onIcon:			square1s
    *annOptsGroup*offIcon:			square0s
    *annOptsGroup.label:			Annotation Options
    *annOptsGroup*TextToggle.width:		90
    *annOptsGroup*TextToggle.highlightColor:	yellow
    *annOptsGroup*Frame.frameType:		sunken
    *annOptsGroup*Frame.frameWidth:		1
    *annOptsGroup*Frame.width:			300
    *annOptsGroup*Text*editType:		edit
    *annOpts.frameWidth:			2
    *annOpts.location:				0 0 400 70
    *annOpts.layout: vertical {	\
	2 \
	horizontal { \
	    5 annotateButton 2 titleButton 2 bordersButton 2 colorbarButton 5 \
	} \
	3 \
	horizontal { -1 titleLabel 2 titleFrame < +inf -inf * > -1 } \
	-1 \
    }
    *annotateButton.label:			\ Annotate
    *titleButton.label:				\ Title
    *bordersButton.label:			\ Borders
    *colorbarButton.label:			\ Colorbar
    *titleLabel.label:				Title String
    *titleString*string:			imtitle
    *titleString*height:			23
    *titleString*Text*editType:			edit


    ! Output color box resources.
    ! ------------------------------
    *printColorGroup.location:			0 0 150 90
    *printColorGroup.outerOffset:		7
    *printColorGroup.frameWidth:		2
    *printColorGroup*offIcon:			diamond0s
    *printColorGroup*onIcon:			diamond1s
    *printColorGroup*highlightColor:		cyan
    *printColorGroup.innerOffset:		5
    *printColorGroup.label:			Output Color
    *printColorGroup*TextToggle.width:		110
    *printColor.frameWidth:			2
    *printColor.location:			0 0 250 75
    *printColor.layout:	horizontal { \
	1 \
	vertical { -1 prGrayButton 2 prPseudoButton 2 prRGBButton -1 }	\
	-1 \
    }
    *prGrayButton.label:			Grayscale
    *prPseudoButton.label:			PseudoColor
    *prRGBButton.label:				RGB

    ! Printer Selection.
    ! --------------------------
    *printerGroup.label:			Printers
    *printerGroup.location:			0 0 110 130
    *printerGroup.shrinkToFit:			True
    *printerGroup.outerOffset:			7

    *printers*Viewport.allowVert:		True
    *printers*Viewport.allowHoriz:		False
    *printers*Viewport.useRight:		True
    *printers*Viewport.resizeable:		True
    *printers*Scrollbar.width:			17
    *printers*Scrollbar.minimumThumb:		10
    *printers.layout: vertical { \
	3 < -3	> \
	horizontal { \
	    2 < -2 > \
	    printlistFrame < +inf -inf	* +inff	-inff >	\
	    2 < -2 > \
	} \
	3 < -3	> \
    }

    *printers*frameType:			sunken
    *printers*frameWidth:			1
    *printers*BorderWidth:			0
    *printers*Label.ShadowWidth:		0

    *printlist.width:				100
    *printlist.height:				78


    ! Panel command resources.
    ! ------------------------------
    *cmdGroup.frameType:			chiseled
    *cmdGroup.frameWidth:			2
    *cmdGroup.outerOffset:			5
    *cmdGroup.innerOffset:			5
    *cmdGroup.label:
    *cmdGroup.location:				0 0 150 50
    *cmdLayout.borderWidth:			0
    *cmdLayout*Command.internalWidth:       	12
    *cmdLayout.layout: horizontal { \
	2 \
	okayPrint 1 < +inf > printStatus < +inf -inf *	+inf -inf > \
	2 \
    }
    *cmdGroup*TextButton*location:		0 0 80 0
    *okayPrint.label:				Print
}


set Resources(info_panel) { \

    !--------------------
    ! Information Panel
    !--------------------
    *infoLayout*borderWidth:			0
    *infoLayout*Frame.frameType:		sunken
    *infoLayout*Frame.frameWidth:		1
    *infoLayout*Command.internalWidth:		12
    *infoLayout*Text*editType:			read
    *infoLayout*Text*scrollVertical:		whenNeeded
    *infoLayout*Text*scrollHorizontal:		whenNeeded
    *infoLayout*Text*displayCaret:		False
    *infoLayout*Scrollbar.background:		#c4c4c4
    *infoLayout*Scrollbar.width:		17
    *infoLayout*Scrollbar.height:		17

    *infoText.height:				240
    *infoText*font:      			6x13
    *infoLayout.layout:	vertical { \
	infoBox  < +inf -inf * > \
    }

    *infoBox.label:
    *infoBox.outerOffset:			0
    *infoBox.innerOffset:			3
    *infoBoxL*TextToggle.frameType:		raised
    *infoBoxL*TextToggle.frameWidth:		1
    *infoBoxL*TextToggle*outerOffset:		0
    *infoBoxL*TextToggle*innerOffset:		1
    *infoBoxL*TextToggle.location:		0 0 100 25
    *infoBoxL*TextToggle*onIcon:		square1s
    *infoBoxL*TextToggle*offIcon:		square0s
    *infoBoxL*TextToggle*highlightColor:	cyan
    *infoBoxL.layout: vertical { \
	infoFrame < +inf -inf * +inf -inf > 1 \
	4 \
	horizontal { \
	    infoOptFr	< +inf -inf * > 1 \
	    infoOptSvr  < +inf -inf * > 1 \
	    infoOptClients  < +inf -inf * > 1 \
	    infoOptWCS  < +inf -inf * > 1 \
	    infoOptIsm  < +inf -inf * > 1 \
	    infoOptFB	< +inf -inf * >   \
	}\
 	2 \
    }
    *infoOptFr.label:				Frame
    *infoOptFr.on:				True
    *infoOptSvr.label:				Server
    *infoOptWCS.label:				WCS
    *infoOptIsm.label:				ISM
    *infoOptClients.label:			Clients
    *infoOptFB.label:				Imtoolrc
}



set Resources(load_panel) { \

    !-------------------------------
    ! File Load	Control	Panel.
    !-------------------------------
    *filesLayout*borderWidth:			0
    *filesLayout*Group.shrinkToFit:		True
    *filesLayout*Group.frameType:		chiseled
    *filesLayout*Frame*frameType:		sunken
    *filesLayout*Frame*frameWidth:		1
    *filesLayout*TextToggle.frameWidth:		0
    *filesLayout*TextToggle.height:		28
    *filesLayout*TextToggle.alignment:		left
    *filesLayout*TextToggle.ledtMargin:		3
    *filesLayout*SimpleMenu.borderWidth:        1
    *filesLayout*SimpleMenu.borderColor:        black
    *filesLayout*SimpleMenu.foreground:         White
    *filesLayout*SimpleMenu.background:         SteelBlue
    *filesLayout*Label.borderWidth:		0
    *filesLayout*Label.shadowWidth:		0
    *filesLayout.layout: vertical { \
	imlistGroup   < +inf -inf * > \
	3 \
	horizontal { -5 imoptsGroup < +inf -inf * > -5 } \
	-1 \
	loadCmdGroup < +inf -inf * > \
    }

    *imlistGroup.label:
    *imlistGroup.frameWidth:			2
    *imlistGroup.outerOffset:			2
    *imlistLayout*Label.shadowWidth:		0
    *imlistLayout*Label.justify:		left
    *imlistLayout*Command.width:		90
    *imlistLayout*Command.height:		23
    *imlistLayout*Command.shadowWidth:		1
    *imlistLayout*Viewport.allowVert:           True
    *imlistLayout*Viewport.allowHoriz           True
    *imlistLayout*Viewport.useRight:            True
    *imlistLayout*Viewport.useBottom:           True
    *imlistLayout*Viewport.resizeable:		True
    *imlistLayout*Scrollbar.height:		17
    *imlistLayout*Scrollbar.width:		17
    *imlistLayout.layout: vertical { \
	3 \
	horizontal { \
	    3 \
	    rootButton	 < +inf -inf * > 1 \
	    homeButton	 < +inf -inf * > 1 \
	    upButton     < +inf -inf * > 1 \
	    rescanButton < +inf -inf * >   \
	    3 \
	    imtemplateLabel 3 imtemplateFrame < +inf -inf  * > \
	    3 \
	} \
	5 \
	horizontal { 1 imlistLabel < +inf -inf * > 1 } \
	imlistFrame < +inf -inf * +inf -inf > \
	3 \
	dirLabel < +inf -inf * > \
	3 \
	horizontal { 5 fnameLabel 5 filnamFrame < +inf -inf * > } \
	3 \
    }
    *imtemplateLabel.label:			Filter:
    *imtemplateText*editType:			edit
    *imtemplateText*height:			23
    *imtemplateText*font:			7x13
    !*imageList.width:				100
    *imageList*height:				140
    *imageList.shadeSurplus:			False
    *imageList.defaultColumns:			3
    *imageList.font:				7x13
    *imlistView.resizeable:			True
    *imlistLabel.height:			0
    *imlistLabel.label:				xxx
    *imlistLabel.justify:			left
    *imlistLabel.font:				*lucida-bold-r*10*
    *upButton.label:				Up
    *rootButton.label:				Root
    *homeButton.label:				Home
    *rescanButton.label:			Rescan
    *dirLabel.label:				\ \ Directory:
    *dirLabel.alignment:			left
    *fnameLabel.label:				Load File:
    *fnameText*editType:			edit
    *fnameText.height:				22

    *imoptsGroup.label:				Options
    *imoptsGroup.frameWidth:			2
    *imoptsGroup.outerOffset:			7
    *imoptsGroup*offIcon:			square0s
    *imoptsGroup*onIcon:			square1s
    *imoptsGroup*highlightColor:		yellow
    *imoptsLayout*Label.shadowWidth:		0
    *imoptsLayout*Label.justify:		left
    *imoptsLayout.layout: vertical { \
	3 \
	horizontal { \
	    3 \
	    autoload 6 grayscale \
	    3 < +inf > \
	    browseHdrs \
	    3 < +inf > \
	    frameLabel 2 frameFrame \
	    3 \
	} \
	6 \
	horizontal { \
	    3 \
	    zscale 6 zrange \
	    3 \
	    z1Label z1Frame < +inf * >  2 \
	    z2Label z2Frame < +inf * >  2 \
	    nsampLabel nsampFrame < +inf * > \
	    3 \
	} \
	3 \
    }
    *grayscale.label:				Auto Grayscale
    *grayscale.location:			0 0 100 22
    *autoload.label:				Auto Load
    *autoload.location:				0 0 80 22
    *autoload.on:				True
    *browseHdrs.label:				List Image Headers
    *browseHdrs.location:			0 0 120 22
    *browseHdrs.on:				False
    *zscale.label:				Zscale
    *zscale.location:				0 0 60 22
    *zrange.label:				Zrange
    *zrange.location:				0 0 60 22
    *z1Label.label:				z1
    *z1Value*width:				60
    *z1Value*height:				22
    *z1Value*editType:				edit
    *z2Label.label:				z2
    *z2Value*width:				60
    *z2Value*height:				22
    *z2Value*editType:				edit
    *nsampLabel.label:				Nsample
    *nsampValue*width:				60
    *nsampValue*height:				22
    *nsampValue*editType:			edit
    *frameLabel.label:				Frame:\ 
    *frameFrame.width:				50
    *frameFrame.resize:				False
    *frameFrame.label:				Current
    *frameFrame.font:				6x13
    *frameFrame.menuName:			loadFrames


    *loadCmdGroup.label:
    *loadCmdGroup*frameWidth:			2
    *loadCmdGroup*outerOffset:			5
    *loadCmdGroup.outerOffset:			2
    *loadCmdGroup*innerOffset:			5
    *loadCmdGroup.frameType:			sunken
    *loadCmdGroup.label:
    *loadCmdGroup.location:                     0 0 400 45
    *loadCmdLayout*Command.internalWidth:	12
    *loadCmdLayout.layout: horizontal { \
	2 \
	filesLoadButton \
	1 < +inf > \
	filesStatus \
	2 \
    }
    *filesLoadButton.label:			Load
    *filesStatus.label:
}



set Resources(save_panel) { \

    !=====================================
    !  Save Setup Panel	resources.	!
    !=====================================
    *save_panel*TextToggle.alignment:		left
    *save_panel*TextToggle.frameWidth:		0
    *save_panel*TextToggle.height:		20
    *save_panel*Label.borderWidth:		0
    *save_panel*Label.shadowWidth:		0
    *save_panel*TextButton.width:		80

    *saveLayout.borderWidth:			0
    *saveLayout.layout:	vertical { \
	saveNameGroup < +inf *	> \
	saveOptGroup <	+inf -inf * > -3 \
	saveCmdGroup <	+inf * > \
    }

    ! Save Name	Group resources.
    !----------------------------------
    *saveNameGroup.borderWidth:			0
    *saveNameGroup.outerOffset:			5
    *saveNameGroup.label:
    *saveNameGroup.location:			0 0 400 50
    *saveNameGroup*offIcon:			diamond0s
    *saveNameGroup*onIcon:			diamond1s
    *saveNameGroup*highlightColor:		cyan
    *saveNameGroup*Frame.frameType:		sunken
    *saveNameGroup*Frame.frameWidth:		1
    *saveNameGroup*Label.justify:		right
    *saveNameGroup*Text*editType:		edit
    *saveNameGroup*shadowWidth:			0
    *saveNameGroup*borderWidth:			0
    *saveNameLayout.borderWidth:		0
    *saveNameLayout.layout: vertical { \
	2 \
	horizontal { 5 saveLabel 5 fnameFrame < +inf -inf * > 5 } \
	2 \
    }
    *saveLabel.label:				File Name:
    *saveFile.height:				22

    !  Main options groups layout resources.
    !---------------------------------------
    *saveOptGroup.frameWidth:			2
    *saveOptGroup.frameType:			chiseled
    *saveOptGroup.label:
    *saveOptGroup.location:			0 0 400 140
    *saveOptGroup.outerOffset:			5
    *saveOptGroup.innerOffset:			0
    *saveOptLayout*borderWidth:			0
    *saveOptLayout.layout: horizontal {	\
	-1 \
	vertical { 5 <	-5 > fmtGroup <	+inf * +inf > -1 } \
	-1 \
	vertical { \
	    10	< -10 >	\
	    saveDataBox < +inff -inff * +inff -inff > \
	    5 < -5 > \
	} \
	-1 \
	vertical { 5 <	-5 > saveColorGroup < +inf * +inf > -1 } \
	-1 \
    }

    ! Output color box resources.
    ! ------------------------------
    *saveColorGroup.location:			0 0 140	120
    *saveColorGroup.outerOffset:		7
    *saveColorGroup.frameWidth:			2
    *saveColorGroup*offIcon:			diamond0s
    *saveColorGroup*onIcon:			diamond1s
    *saveColorGroup*highlightColor:		cyan
    *saveColorGroup.innerOffset:		5
    *saveColorGroup.label:			Output Color
    *saveColorGroup*TextToggle.width:		110
    *saveColor.frameWidth:			2
    *saveColor.layout: horizontal { \
	3 \
	vertical { 5 svGrayButton 2 svPseudoButton 2 svRGBButton -1 } \
	-1 \
    }
    *svGrayButton.label:			Grayscale
    *svPseudoButton.label:			PseudoColor
    *svRGBButton.label:				RGB

    *saveDataBox.frameType:			sunken
    *saveDataBox.frameWidth:			1


    ! Output format box	resources.
    ! -----------------------------------
    *fmtGroup.location:				0 0 140 120
    *fmtGroup.outerOffset:			7
    *fmtGroup.frameWidth:			2
    *fmtGroup*offIcon:				diamond0s
    *fmtGroup*onIcon:				diamond1s
    *fmtGroup*TextToggle.width:			55
    *fmtGroup*highlightColor:			cyan
    *fmtGroup.label:				File Format
    *formats.layout: horizontal	{ \
	3 \
	vertical { 5 fitsButton 2 gifButton 2 tiffButton 2 rawButton  1 } \
	2 < -2	> \
	vertical { 5 epsButton	2 rasButton 2 x11Button  2 jpegButton 1 } \
	-1 \
    }
    *rasButton.label:				RAS
    *gifButton.label:				GIF
    *jpegButton.label:				JPEG
    *tiffButton.label:				TIFF
    *fitsButton.label:				FITS
    *x11Button.label:				X11
    *epsButton.label:				EPS
    *rawButton.label:				Raw

    ! Change the sensitivity once these	formats	are implemented. !
    !-------------------------------------------------------------
    *jpegButton.sensitive:			False
    *x11Button.sensitive:			False
    *rawButton.sensitive:			False


    ! Panel command resources.
    ! ------------------------------
    *saveCmdLayout.borderWidth:			0
    *saveCmdGroup.frameType:			chiseled
    *saveCmdGroup.frameWidth:			2
    *saveCmdGroup.outerOffset:			5
    *saveCmdGroup.innerOffset:			5
    *saveCmdGroup.label:
    *saveCmdGroup.location:			0 0 400 50
    *saveCmdLayout*Command.internalWidth:	12
    *saveCmdLayout.layout: horizontal {	\
	2 \
	okaySave 1 < +inf -1 >	saveStatus < +inf -inf * > \
	2 \
    }
    *okaySave.label:				Save
}


set Resources(tile_panel) { \

    *tileOpts.frameType:		    	chiseled
    *tileOpts.frameWidth:		    	2
    *tileOpts.outerOffset:			5
    *tileOpts.innerOffset:			7
    *tileOpts*shrinkToFit:			True
    *tileOpts*borderWidth:		      	0

    *toptLayout.layout:	vertical { \
	horizontal { -6 tFramesG < +inf -inf * > -6 } \
	horizontal { \
	    -1 \
	    horizontal { -6 tileMode < * +inf -inf > -6 } \
	    vertical { \
		horizontal { -3 userOrientG < +inf -inf * > -3 } \
		horizontal { -3 fillStyle   < +inf -inf * > -3 } \
		horizontal { -3 tileLabel   < +inf -inf * > -3 } \
		-7 \
		horizontal { -3 geomFrame   < +inf -inf * > -3 } \
	    } \
	    -1 \
	} \
	-4 \
    }
    *tileMode.label:				Tile Mode
    *tileMode.outerOffset:			7
    *tileMode.innerOffset:			5
    *tileMode*location:				0 0 150 20
    *tileMode*TextToggle.outerOffset:		2
    *tileMode*TextToggle.innerOffset:		1
    *tileMode*TextToggle.frameWidth:		0
    *tileMode*TextToggle.leftMargin:		10
    *tileMode*TextToggle.rightMargin:		20
    *tileMode*TextToggle.onIcon:		diamond1s
    *tileMode*TextToggle.offIcon:		diamond0s
    *tileMode*TextToggle.highlightColor:	yellow

    *tileDisabled.label:			Disabled
    *tileManual.label:				Manual
    *tileBest.label:				Best
    *tileSquare.label:				Square
    *tileHorizontal.label:			Horizontal
    *tileVertical.label:			Vertical
    *tileRow.label:				One Row
    *tileCol.label:				One Column

    *fillStyle.label:				Fill Style
    *fillStyle.location:			0 0 160 30
    *fillStyle.outerOffset:			7
    *fillStyle.innerOffset:			5
    *fillStyle.rows:				1
    *fillStyle*selectionStyle:			multi
    *fillStyle*outerOffset:			0
    *fillStyle*innerOffset:			1
    *fillStyle*leftMargin:			7
    *fillStyle*onIcon:				square1s
    *fillStyle*offIcon:				square0s
    *fillStyle*highlightColor:			yellow
    *fillStyle.TextToggle.frameWidth:		0
    *fillStyle.TextToggle.location:		0 0 85 23
    *byCols.label:				Fill by Columns
    *bottomUp.label:				Fill from Bottom

    *tileLabel.label:				Tile Labels
    *tileLabel.location:			0 0 175 30
    *tileLabel.outerOffset:			7
    *tileLabel.innerOffset:			5
    *tileLabel.rows:				1
    *tileLabel*selection:			-1
    *tileLabel*outerOffset:			0
    *tileLabel*innerOffset:			1
    *tileLabel*leftMargin:			7
    *tileLabel*onIcon:				square1s
    *tileLabel*offIcon:				square0s
    *tileLabel*highlightColor:			yellow
    *tileLabel.TextToggle.frameWidth:		0
    *tileLabel.TextToggle.location:		0 0 85 23
    *labelFrames.label:				Frameno
    *labelImname.label:				Img Name
    *labelTitles.label:				Img Title

    *geomFrame.frameWidth:			0
    *geomFrame.frameType:			sunken
    *geomFrame.outerOffset:			7
    *geomFrame.innerOffset:			4
    *tileGeometry.width:			220
    *tileGeometry.height;			37
    *tileGeometry.background:			#c4c4c4
    *tileGeometry.font:				7x13bold
    *tileGeometry.label:			Tile Geometry:  1 x 2

    *userOrientG.label:				Manual Configuration
    *userOrientG.height:			90
    *userOrientG.width:				220
    *userOrientG.outerOffset:			7
    *userOrientG.innerOffset:			5
    *userOrientG.shrinkToFit:			True
    *userOrientG*Frame.frameWidth:		1
    *userOrientG*Frame.frameType:		sunken
    *userOrientG*Text.height:			21
    *userOrientG*Text*editType:			edit
    *userOrientL.borderWidth:			0
    *userOrientL.layout: vertical { \
	1 \
	horizontal { 18 nrowLab < +50% -inf * >  nrFrame < +inf -inf * > 5 } \
	1 \
	horizontal { ncolLab < +50% -inf * > ncFrame < +inf -inf * > 5 } \
    }
    *nrowLab.justify:				right
    *ncolLab.justify:				right

    *nrLayout.layout: horizontal {nrdecrease nrtext < +inf -inf * > nrincrease}
    *nrdecrease.direction:			left
    *nrincrease.direction:			right
    *nrowLab.label:				Tile Rows:
    *nrtext.background:				#adadad
    *nrtext.justify:				center
    *nrtext.font:				7x13bold
    *nrtext.label:				1

    *ncLayout.layout: horizontal {ncdecrease nctext < +inf -inf * > ncincrease}
    *ncdecrease.direction:			left
    *ncincrease.direction:			right
    *ncolLab.label:				Tile Columns:
    *nctext.background:				#adadad
    *nctext.justify:				center
    *nctext.font:				7x13bold
    *nctext.label:				2

    *tFramesG.label:				Tile Frames
    *tFramesG.outerOffset:			7
    *tFramesG.innerOffset:			7
    *tFrames.borderWidth:			0
    *tFrames*Toggle.height:			17
    *tFrames.layout: horizontal	{ \
	tAll \
	2 \
	tFrame1  tFrame2  tFrame3  tFrame4  tFrame5  \
	tFrame6  tFrame7  tFrame8  tFrame9  tFrame10 \
	tFrame11 tFrame12 tFrame13 tFrame14 tFrame15 tFrame16 \
	2 \
	tNone \
    }
    *tAll.label:				All\ 
    *tNone.label:				None
}


set Resources(wcs_panel) { \

    !--------------------
    ! WCS Readout Panel
    !--------------------
    *wcsGroup*TextToggle.offIcon:               square0s
    *wcsGroup*TextToggle.onIcon:                square1s

    !*wcsLayout*TextToggle.location:             0 0 160 23
    *wcsLayout*TextToggle.height:		23
    *wcsLayout*TextToggle.outerOffset:          0
    *wcsLayout*Layout.borderWidth:		0
    *wcsLayout.borderWidth:			0
    *wcsLayout.layout: vertical { \
	0 < +0 -0 > \
	wcsGroup < +inf -inf * > \
	5 \
	horizontal { -1 wcsOptGroup < +inf -inf * > -1 } \
	-2 \
    }

    *wcsOptGroup.label:
    *wcsOptGroup.outerOffset:                   0
    *wcsOptGroup.innerOffset:                   5
    *wcsOptGroup.frameType:                     chiseled
    *wcsOptGroup.frameWidth:                    0
    *wcsOptLayout.layout: vertical { \
	horizontal { -9 wcsCoords   < +inf -inf * > -9 } \
	-3 \
	horizontal { -5 wcsOpts     < +inf -inf * > -5 } \
	horizontal { -5 wcsIsmGroup < +inf -inf * > -5 } \
	1 \
    }

    *wcsOpts.label:
    *wcsOpts.width:				265
    *wcsOpts.height:				40
    *wcsOpts.outerOffset:			3
    *wcsOpts.innerOffset:			3
    *woLayout*TextToggle.frameWidth:		0
    *woLayout*TextToggle.onIcon:		square1s
    *woLayout*TextToggle.offIcon:		square0s
    *woLayout*TextToggle.highlightColor:	cyan
    *woLayout*TextToggle.alignment:		left
    *woLayout*TextToggle.leftMargin:		5
    *woLayout.layout: horizontal { \
	3 \
	woptLabels < +inf -inf * > 2 \
	woptTitles < +inf -inf * > 2 \
	woptFBinfo < +inf -inf * > 2 \
	woptBPM    < +inf -inf * >   \
	3 \
    }
    *woptLabels.label:				WCS Labels
    *woptLabels.on:				True
    *woptTitles.label:				Image Titles
    *woptTitles.on:				True
    *woptFBinfo.label:				Frame Buffer Info
    *woptFBinfo.on:				True
    *woptBPM.label:				BPM Data
    *woptBPM.on:				False
    *woptLabels.location:			0 0 150 21
    *woptTitles.location:			0 0 150 21
    *woptFBinfo.location:			0 0 175 21
    *woptBPM.location:				0 0 120 21


    *wcsCoords.label:				Readout Values
    *wcsCoords.width:				265
    *wcsCoords.height:				135
    *wcsCoords.outerOffset:			7
    *wcsCoords.innerOffset:			3
    *wcLayout*TextToggle.offIcon:           	diamond0s
    *wcLayout*TextToggle.onIcon:            	diamond1s
    *wcLayout*TextToggle.highlightColor:    	yellow2
    *wcLayout*TextToggle.shrinkToFit:		True
    *wcLayout*TextToggle.frameWidth:		0
    *wcLayout*TextToggle.label:
    *wcLayout*TextToggle.on:			True
    *wcLayout*Label.justify:			right
    *wcLayout*Label.font:			7x13bold
    *wcLayout*SimpleMenu.borderColor:           black
    *wcLayout*SimpleMenu.borderWidth:           1
    *wcLayout*SimpleMenu.foreground:            White
    *wcLayout*SimpleMenu.background:            SteelBlue
    *wcLayout*MenuButton.shadowWidth:		1
    *wcLayout*MenuButton.resize:		False
    *wcLayout.layout: vertical {\
	1 \
	horizontal { 20 < -20 > wcTitle < +inf -inf * > 20 < -20 > }\
	1 \
	horizontal { 5 wcLine < +inf -inf * > 5 } \
	5 \
	horizontal { \
	    10 \
	    vertical { 2 wlWcs1  2 wlWcs2  2 wlWcs3  2 wlWcs4  2 }  5 \
	    vertical { 1 sysWcs1 1 sysWcs2 1 sysWcs3 1 sysWcs4 1 }  5 \
	    vertical { 1 fmtWcs1 1 fmtWcs2 1 fmtWcs3 1 fmtWcs4 1 } 20 \
	    vertical { 1 wpWcs1  3 wpWcs2  3 wpWcs3  3 wpWcs4  3 } 20 \
	    vertical { 1 wiWcs1  3 wiWcs2  3 wiWcs3  3 wiWcs4  3 } 15 \
	} \
	3 \
    }
    *wcTitle.label:    Type\ \ \ \ \ \ \ \ \ \ Format\ \ \ \ \ \ Panel\ ImgWin

    *wcLine.height:				2
    *wcLine.frameWidth:				2
    *wcLine.frameType:				ledged

    *wlWcs1.label:				First WCS
    *wlWcs2.label:				Second WCS
    *wlWcs3.label:				Third WCS
    *wlWcs4.label:				Fourth WCS
    *sysWcs1.label:				\ Image Display\ 
    *sysWcs1.menuName:				sysMenu1
    *sysWcs2.label:				None
    *sysWcs2.menuName:				sysMenu2
    *sysWcs3.label:				None
    *sysWcs3.menuName:				sysMenu3
    *sysWcs4.label:				None
    *sysWcs4.menuName:				sysMenu4
    *fmtWcs1.label:				\ Sexigesimal\ 
    *fmtWcs1.menuName:				fmtMenu1
    *fmtWcs2.label:				None
    *fmtWcs2.menuName:				fmtMenu2
    *fmtWcs3.label:				None
    *fmtWcs3.menuName:				fmtMenu3
    *fmtWcs4.label:				None
    *fmtWcs4.menuName:				fmtMenu4

    *editMenu fmtWcsMenu$i fmtWcs$i $items

    *wcsIsmGroup.label:
    *wcsIsmGroup.width:				395
    *wcsIsmGroup.height:			50
    *wcsIsmGroup.outerOffset:			3
    *wcsIsmGroup.innerOffset:			5
    *wcsIsmGroup*borderWidth:			0
    *wcsIsmLayout.layout: horizontal { \
	wcsIsmLabel 1 wcsIsmFrame < +inf -inf * > 3 wcsIsmInit 1 \
     }
    *wcsIsmLabel.label:				ISM Command
    *wcsIsmFrame.frameType:			sunken
    *wcsIsmFrame.frameWidth:			1
    *wcsIsmFrame.outerOffset:			1
    *wcsIsmFrame*height:			23
    *wcsIsmCmd*editType:			edit
    *wcsIsmCmd.displayCaret:			True
    *wcsIsmInit.label:				Initialize
    *wcsIsmInit.internalWidth:			7

    *wcsBox*borderWidth:			0
    *wcsBox*TextToggle.frameType:		raised
    *wcsBox*TextToggle.frameWidth:		1
    *wcsBox*TextToggle.leftMargin:		2
    *wcsBox*borderWidth:			0
    *wcsBox.layout: vertical { \
	wcsFrame < +inf -inf * > \
	2 \
	horizontal { \
	    2 \
	    ismToggle   < +inf -inf * > 2 \
	    pixelTable  < +inf -inf * > 2 \
	    imageHeader < +inf -inf * > 2 \
	    compass     < +inf -inf * > 2 \
	    wcsOptions  < +inf -inf * >   \
	    2 \
	} \
    }
    *ismToggle.label:				ISM Mod
    *ismToggle.label:				WCS/Pix
    *pixelTable.label:				Pix Table
    *imageHeader.label:				Header
    *imageHeader.sensitive:			False
    *compass.label:				Compass
    *wcsOptions.label:				Options

    *wcsGroup.label:
    *wcsGroup.outerOffset:                      0
    *wcsGroup.innerOffset:                      5
    *wcsGroup.frameType:                        chiseled
    *wcsGroup.frameWidth:                       2
    *wcsGroup*Text*width:			260
    *wcsGroup*Text*height:			17
    *wcsGroup*Text*font:			7x13
    *wcsGroup*Text*displayCaret:		False
    *wcsGroup*Text*editType:			read
    *wcsGroup*Text*background:			black
    *wcsGroup*Text*foreground:			yellow2
    *wcsGroup*TextToggle.highlightColor:        cyan
    *wcsFrame.frameType:			sunken
    *wcsFrame.frameWidth:			1
    *wcsText*background:			yellow4
    *wcsText.layout: vertical { \
	wtName    < +inf -inf * > -3 \
	wtTitle   < +inf -inf * > -3 \
	wtFBCfg   < +inf -inf * >    \
	1 < -1 > \
	wtWcs1  < +inf -inf * > -3 \
	wtWcs2  < +inf -inf * > -3 \
	wtWcs3  < +inf -inf * > -3 \
	wtWcs4  < +inf -inf * >    \
	1 < -1 > \
	horizontal { \
	    wtIPixval < +inf -inf * +inf > 1 \
	    wtSPixval < +inf -inf * +inf > 1 \
	    wtBPixval < +inf -inf * +inf > \
	} \
    }
}


set Resources(blink_panel) { \

    *blink_panel.geometry:			425x200
    *blink_panel.title:				Blink/Register Frames

    *brMenuBar*Command.internalHeight:	       	4
    *brMenuBar*Command.internalWidth:	       	12
    *brMenuBar*Command.height:			27
    *brMenuBar*borderWidth:			0

    *brMenuBar*Label.font:	  7x13bold
    *brLayout*Command.font:	  -*-helvetica-medium-r-normal-*-12-*-iso8859-1
    *brRegButton.font:		  -*-helvetica-medium-r-normal-*-12-*-iso8859-1
    *brReset.font:  		  -*-helvetica-medium-r-normal-*-12-*-iso8859-1
    *brMatchButton.font:  	  -*-helvetica-medium-r-normal-*-12-*-iso8859-1
    *brBlinkButton.font:  	  -*-helvetica-medium-r-normal-*-12-*-iso8859-1
    *brAregButton.font:		  -*-helvetica-medium-r-normal-*-12-*-iso8859-1


    *brMenuBar.layout: vertical	{ \
	5 < -5	> \
	horizontal { 10	< +inf -10> brClose 5 } \
	5 < -5	> \
    }
    *brClose.label:			       	Dismiss

    *brMenuFrame.frameType:		       	raised
    *brMenuFrame.frameWidth:		       	2
    *bpLayout.layout: vertical { \
	brMenuFrame  <	+inf -inf * > \
	1 < -1	> \
	brFrame < +inf	-inf * +inf -inf > \
    }

    *brFrame.frameType:			       	chiseled
    *brFrame.frameWidth:		       	2
    *brFrame.outerOffset:			4
    *brFrame.innerOffset:			4

    *brLayout.borderWidth:			0
    *brLayout.layout: vertical { \
	3 < -3	> \
	horizontal { -3 brFramesG < +inf -inf * > -3 } \
	-5  \
	horizontal { -3 brCmdG	< +inf -inf * +inf -inf	> -3 } \
	-5 \
    }

    *brCmdG.label:
    *brCmdG.outerOffset:			7
    *brCmdG.innerOffset:			7
    *brCmdG*borderWidth:			0
    *brCmd.layout: horizontal {	\
	2 \
	vertical { \
	    2 \
	    horizontal	{ \
		2 \
		brRateLabel \
		2 \
		brBRframe < +inf -inf	* >\
		4 \
		brReset \
		2 \
	    } \
	    8 < -8 > \
	    horizontal	{ \
		4 \
		brMatchButton	< +inf -inf * >	\
		5 < -5 > \
		brRegButton <	+inf -inf * > \
		2 \
	    } \
	    1 < +inf >	\
	} \
	10 \
	vertical { \
	    2 \
	    brBlinkButton < +inf * > \
	    10	< -10 >	\
	    brAregButton < +inf * > \
	    1 < +inf >	\
	} \
	2 \
    }

    *brFramesG.label:				Frames List
    *brFramesG.outerOffset:			7
    *brFramesG.innerOffset:			7
    *brFramesG*SimpleMenu.borderColor:		black
    *brFramesG*SimpleMenu.borderWidth:		1
    *brFramesG*SimpleMenu.foreground:           White
    *brFramesG*SimpleMenu.background:           SteelBlue

    *brFrames.borderWidth:			0
    *brFrames.layout: horizontal { \
	5 < +inf > \
	brFrame1  < +inf * > 1 \
	brFrame2  < +inf * > 1 \
	brFrame3  < +inf * > 1 \
	brFrame4  < +inf * > 1 \
	brFrame5  < +inf * > 1 \
	brFrame6  < +inf * > 1 \
	brFrame7  < +inf * > 1 \
	brFrame8  < +inf * > 1 \
	brFrame9  < +inf * > 1 \
	brFrame10 < +inf * > 1 \
	brFrame11 < +inf * > 1 \
	brFrame12 < +inf * > 1 \
	brFrame13 < +inf * > 1 \
	brFrame14 < +inf * > 1 \
	brFrame15 < +inf * > 1 \
	brFrame16 < +inf * >   \
	5 < +inf > \
    }

    *brBRlayout.layout:	horizontal { \
	brBRdecrease \
	brBRtext < +inf -100% * > \
	brBRincrease \
    }

    *blink_panel*TextToggle.location:		0 0 110	23
    *blink_panel*TextToggle.frameWidth:		1
    *blink_panel*TextToggle.highlightColor:	yellow
    *blink_panel*TextToggle.offIcon:		square0s
    *blink_panel*TextToggle.onIcon:		square1s
    *blink_panel*TextToggle.outerOffset:	0
    *blink_panel*TextToggle.innerOffset:	2
    *blink_panel*Command.height:		23
    *blink_panel*Arrow.width:			16
    *blink_panel*Arrow.height:			20


    *brFramesLabel.label:		     	Frames:
    *brFrame1.menuName:				frame1Menu
    *brFrame2.menuName:				frame2Menu
    *brFrame3.menuName:				frame3Menu
    *brFrame4.menuName:				frame4Menu
    *brFrame5.menuName:				frame5Menu
    *brFrame6.menuName:				frame6Menu
    *brFrame7.menuName:				frame7Menu
    *brFrame8.menuName:				frame8Menu
    *brFrame9.menuName:				frame9Menu
    *brFrame10.menuName:			frame10Menu
    *brFrame11.menuName:			frame11Menu
    *brFrame12.menuName:			frame12Menu
    *brFrame13.menuName:			frame13Menu
    *brFrame14.menuName:			frame14Menu
    *brFrame15.menuName:			frame15Menu
    *brFrame16.menuName:			frame16Menu
    *brReset.label:			     	Reset

    *brRateLabel.label:			     	Rate:
    *brBRframe.frameType:			sunken
    *brBRframe.frameWidth:			1
    *brBRtext.width:				40
    *brBRtext.height:				23
    *brBRdecrease.direction:			left
    *brBRincrease.direction:			right
    *brRegButton.label:			     	Register
    *brMatchButton.label:			Match LUTs
    *brBlinkButton.label:			Blink
    *brAregButton.label:		       	Auto-Register
}


set Resources(hdr_panel) { \

    *hdr_panel.geometry:			550x600
    *hdr_panel.title:				Image Header

    *hdr_panel*SimpleMenu.borderColor:          black
    *hdr_panel*SimpleMenu.borderWidth:          1
    *hdr_panel*SimpleMenu.foreground:           White
    *hdr_panel*SimpleMenu.background:           SteelBlue

    *hdrMenuFrame.frameType:			raised
    *hdrMenuFrame.frameWidth:			2
    *hdrLayout.layout: vertical	{ \
	hdrMenuFrame < +inf -inf * > \
	hdrObjGroup  < +inf -inf * > \
	hdrTabFrame  < +inf -inf * +inf	-inf> \
    }

    *hdrMenuBar*borderWidth:			0
    *hdrMenuBar*Command.internalHeight:		5
    *hdrMenuBar*Command.internalWidth:		12
    *hdrMenuBar.layout:	vertical { \
	5 < -5	> \
	horizontal { 10 < +inf -10> hdrClose 7 } \
	5 < -5	> \
    }
    *hdrClose.label:				Dismiss

    *hdrObjGroup.label:
    *hdrObjGroup.outerOffset:			7
    *hdrObjGroup.innerOffset:			4
    *hdrObjLayout.borderWidth:			0
    *hdrObjLayout.layout: vertical { \
	horizontal { hdrObjLabel 2 hdrObjMenu < +inf -inf * > 2 } \
    }
    *hdrObjLabel.label:				Image Name:
    *hdrObjMenu.label:
    *hdrObjMenu.justify:			left
    *hdrObjMenu.font:				7x13
    *hdrObjMenu.menuName:			objMenu
    *hdrObjMenu.internalWidth:			5
    *hdrObjMenu.internalHeight:			1
    *hdrObjMenu.shadowWidth:			1

    *hdrHdrGroup.tabLabel:			Image Header
    *hdrHdrGroup.label:
    *hdrHdrGroup.outerOffset:			7
    *hdrHdrGroup.innerOffset:			5
    *hdrHdrLayout.borderWidth:			0
    *hdrHdrLayout.layout: vertical { \
	horizontal { \
	    hdrFilter 2 hFindFrame < +inf -inf * > 2 hdrFind 1 hdrClear \
	} \
	5 \
	hdrText < +inf -inf * +inf -inf > \
    }
    *hFindEntry*editType:                       edit
    *hFindEntry*font:                           7x13
    *hFindEntry*displayCaret:                   True
    *hFindEntry*width:                          150
    *hFindFrame.frameWidth:                     1
    *hFindFrame*borderWidth:			0
    *hFindFrame.frameType:                      sunken
    *hFindFrame.width:                          150
    *hFindFrame.height:                         23
    *hdrFilter.label:                           Keyword Filter
    *hdrFind.label:                             Search
    *hdrClear.label:                            Clear

    ! Resources if the header text widget is AsciiText
!   *hdrText*scrollVertical:			Always
!   *hdrText*scrollHorizontal:			Always
!   *hdrText*editType:				edit
!   *hdrText*font:				7x13
!   *hdrText*background:			#c4c4c4
!   *hdrText*displayCaret:			False
!   *hdrText*bottomMargin:			10
!   *hdrText*Scrollbar.width:			15
!   *hdrText*Scrollbar.height:			15

    ! Resources if the header text widget is HTML
    *hdrText.width:                             600
    *hdrText.height:                            500
    *hdrText.anchorUnderlines:                  1
    *hdrText.visitedAnchorUnderlines:           1
    *hdrText.verticalScrollOnRight:             True
    *hdrText.plainFont:                         7x13
    *hdrText.marginWidth:			5
    *hdrText.marginHeight:			5


    *hdrWcsGroup.tabLabel:			Image WCS Info
    *hdrWcsGroup.label:
    *hdrWcsGroup.outerOffset:			5
    *hdrWcsGroup.innerOffset:			5
    *hdrWcsGroup*Text*scrollVertical:		whenNeeded
    *hdrWcsGroup*Text*scrollHorizontal:		whenNeeded
    *hdrWcsGroup*Text*editType:			edit
    *hdrWcsGroup*Text*displayCaret:		False
    *hdrWcsGroup*Text*borderWidth:		0
    *hdrWcsGroup*Text*editType:			edit
    *hdrWcsGroup*Text*font:			7x13
    *hdrWcsGroup*Text*Scrollbar.width:		15
    *hdrWcsGroup*Text*Scrollbar.height:		15
    *hdrWcsLayout.borderWidth:			0
    *hdrWcsLayout.layout: vertical { \
	2 < -2	> \
	hdrInfoGroup <	+inf -inf * > \
	2 < -2	> \
	hdrKeywGroup <	+inf -inf * +inf -inf >	\
	-4 \
    }
    *hdrInfoGroup.label:			Basic WCS Information
    *hdrInfoGroup.outerOffset:			7
    *hdrInfoGroup.innerOffset:			0
    *hdrIGFrame.frameType:			sunken
    *hdrIGFrame.frameWidth:			1
    *hdrIGText.height:				130
!   *hdrIGText*background:			black
!   *hdrIGText*foreground:			yellow2
    *hdrIGText*background:			#adadad
    *hdrIGText*foreground:			black
    *hdrWcsGroup*hdrIGText*scrollVertical:	never
    *hdrWcsGroup*hdrIGText*scrollHorizontal:	never
    *hdrWcsGroup*hdrIGText*font:  		7x13
    *hdrKeywGroup.label:			WCS Header Keywords
    *hdrKeywGroup.outerOffset:			7
    *hdrKeywGroup.innerOffset:			5
    *hdrKGFrame.frameType:			sunken
    *hdrKGFrame.frameWidth:			1
    *hdrKGText*background:			#c4c4c4
    *hdrKGText*bottomMargin:			10

    *hdrIGText*background:			#c4c4c4
    *hdrIGFrame.frameWidth:			0
}


set Resources(pixel_table) { \

    *pixel_panel.title:				Image Pixel Table
    *pixel_panel*SimpleMenu.borderWidth:	1
    *pixel_panel*SimpleMenu.borderColor:	black
    *pixel_panel*SimpleMenu.foreground:         White
    *pixel_panel*SimpleMenu.background:         SteelBlue

    *pixtabMenuBar*borderWidth:			0
    *pixtabMenuBar*Command.internalHeight:	4
    *pixtabMenuBar*Command.internalWidth:	12
    *pixtabMenuBar.layout: vertical { \
	5 \
	horizontal { \
	    5 \
	    pixtabSize 10 < +inf -10> pixtabHelp 5 pixtabClose \
	    7 \
	} \
	5 \
    }
    *pixtabSize.label:				Size
    *pixtabSize.menuName:			pixtabMenu
    *pixtabHelp.label:				Help
    *pixtabHelp.sensitive:			False
    *pixtabClose.label:				Dismiss

    *pixtabMenuFrame.frameType:			raised
    *pixtabMenuFrame.frameWidth:		2
    *pixel_table.layout: vertical { \
	1 \
	pixtabMenuFrame  < +inf -inf * > \
	1 \
	pixtabFrame < +inf -inf * +inf -inf > \
	1 \
    }
    

    *pixtabFrame.frameType:			raised
    *pixtabFrame.frameWidth:			0
    *pixtabFrame*borderWidth:			0
    *pixtabFrame*font:                          6x10
    *pixtabFrame*MultiList.font: 	-*-helvetica-medium-r-normal-*-10-*
    *pixtabFrame*Label.font: 		-*-helvetica-medium-r-normal-*-10-*
    *pixtabFrame*TextToggle.font: 	-*-helvetica-medium-r-normal-*-10-*

    *pixtabFrame*MultiList.forceColumns:	True
    *pixtabFrame*MultiList.defaultColumns:	5
    *pixtabFrame*MultiList.shadeSurplus:	False
    *pixtabFrame*MultiList.borderWidth:		0
    *pixtabFrame*MultiList.rowHeight:		25
    *pixtabFrame*MultiList.rowSpacing:		7
    *pixtabFrame*MultiList.internalWidth:	7
    *pixtabFrame*MultiList.internalHeight:	4
    *pixtabFrame*MultiList.width:		410
    *pixtabFrame*MultiList.height:		160
    *pixtabFrame*MultiList.columnWidth:		50
    *pixtabFrame*MultiList.columnSpacing:	2
    *pixtabFrame*MultiList.maxSelectable:	1
    *pixtabFrame*MultiList.highlightForeground:	red
    *pixtabFrame*MultiList.highlightBackground:	#c4c4c4
    *pixtabFrame*MultiList.background:		#c4c4c4
    *pixtabFrame*TextToggle.background:		#c4c4c4

    *pixtabFrame*Label.width:			00
    !*pixtabFrame*Label.resize:			False

    *meanFrame.frameWidth:			2
    *meanFrame.frameType:			chiseled
    *meanFrame.outerOffset:			0
    *meanFrame.width:				120
    *meanLabel.label:				Mean:
    *meanValue.label:
    *meanValue.resize:				False

    *sigFrame.frameWidth:			2
    *sigFrame.frameType:			chiseled
    *sigFrame.outerOffset:			0
    *sigFrame.width:				120
    *sigLabel.label:				Stdev:
    *sigValue.label:
    *sigValue.resize:				False

    *ptColFrame.frameWidth:			0
    *ptColFrame.outerOffset:			0
    *ptRowFrame.frameWidth:			0
    *ptRowFrame.outerOffset:			0

    *pixtabFrame*ptColLabs.width:		410
    *pixtabFrame*ptColLabs.height:		23
    *pixtabFrame*ptColLabs.defaultColumns:	5
    *pixtabFrame*ptColLabs.forceColumns:	True
    *pixtabFrame*ptColLabs.columnWidth:		50
    *pixtabFrame*ptColLabs.columnSpacing:	2
    *pixtabFrame*ptRowLabs.width:		60
    *pixtabFrame*ptRowLabs.height:		110
    *pixtabFrame*ptRowLabs.defaultColumns:	1
    *pixtabFrame*ptRowLabs.forceColumns:	True
    *pixtabFrame*ptRowLabs.verticalList:	True
    *pixtabFrame*ptRowLabs.columnWidth:		50
    *pixtabFrame*ptRowLabs.columnSpacing:	2
    *pixtabFrame*pixtab.verticalList:		True

    *ptFrame.outerOffset:           		0
    *ptFrame.innerOffset:           		0
    *ptFrame.borderWidth:			0
    *ptFrame.frameWidth:            		1
    *ptFrame.frameType:             		sunken
    *ptLayout.layout: vertical { \
        3 \
        horizontal { 65 ptColFrame < +inf -inf * > 5 } \
        1 \
        horizontal { \
          vertical { ptRowFrame< * +inf -inf > 5  } \
	  1 \
	  vertical { ptFrame } \
	  5 \
        } \
	1 \
        horizontal { \
	    2 < +inf > \
	    meanLabel meanFrame < +inf -inf * > 2 \
	    sigLabel  sigFrame  < +inf -inf * >   \
	    10 \
	} \
    }
}


set Resources(help_panel) { \

    !----------------------
    ! Help panel resources.
    !----------------------
    *help_panel.title:				XImtool	Help Summary
    *help_panel.width:				500
    *help_panel.height:				550
    *helpLayout*borderWidth:			0
    *helpLayout*Command.internalHeight:		4
    *helpLayout*Command.internalWidth:		12
    *helpLayout*HTML*shadowWidth:		1
    *helpLayout*helpText*Scrollbar.shadowWidth:		1

    *helpMenuGroup.label:               
    *helpMenuGroup.height:                      45
    *helpMenuGroup.outerOffset:                 0
    *helpMenuGroup.innerOffset:                 0
    *helpMenuGroup.frameType:			raised
    *helpMenubar.layout: vertical { \
	5 < -5 > \
	horizontal { 20 < +inf -20 > helpClose 7 } \
	5 < -5 > \
    }
    *helpBack.label:				Back
    *helpBack.sensitive:			False
    *helpForward.label:				Forward
    *helpForward.sensitive:			False
    *helpHome.label:				Home
    *helpClose.label:				Dismiss


    *hfEntry*editType:                          edit
    *hfEntry*font:                              7x13
    *hfEntry*displayCaret:                      True
    *hfFrame.frameWidth:			1
    *hfFrame.frameType:				sunken
    *hfFrame.width:				250
    *hfFind.label:                              Search
    *hfFind.shadowWidth:                        1
    *hfClear.label:                             Clear
    *hfClear.shadowWidth:                       1

    *helpLayout.layout:	vertical { \
	-1 \
	horizontal { helpMenuGroup < +inf -inf * > 	     } \
	5 \
        horizontal { \
            5 \
	    helpBack 2 helpForward 2 helpHome \
	    20 < +inf -20 > \
            hfFrame < +inf -inf * > 3 hfFind 1 hfClear \
            5 \
        } \
	5 \
	horizontal { helpTextFrame < +inf -inf * +inf -inf > } \
	horizontal { helpInfoLayout < +inf -inf	* > 	     } \
	-1 \
    }
    *helpTextFrame.frameWidth:			1
    *helpTextFrame.frameType:			sunken
    *helpText.width:				600
    *helpText.height:				500
    *helpText.anchorUnderlines:			1
    *helpText.visitedAnchorUnderlines:		1
    *helpText.verticalScrollOnRight:		true
    *helpText*Scrollbar.shadowWidth:		1
    *helpText.plainFont:       -adobe-courier-medium-r-normal-*-12-*-*-*-*-*-*-*
    *helpText.plainboldFont:   -adobe-courier-bold-r-normal-*-12-*-*-*-*-*-*-*
    *helpText.plainitalicFont: -adobe-courier-medium-o-normal-*-12-*-*-*-*-*-*-*
!   *helpText.boldFont:				6x12bold


    ! Contact info at the bottom of the panel.
    *helpInfoLayout*Label.justify:		center
    *helpInfoLayout*Label.internalHeight:	0
    *helpInfoLayout.layout: horizontal { \
	5 \
	vertical { 5 helpIRAFLogo 5 } \
	1 < +inf > \
	vertical { \
	    5 \
	    helpInfo1 < +inf -inf * +inf -inf > \
	    helpInfo2 < +inf -inf * +inf -inf > \
	    helpInfo3 < +inf -inf * +inf -inf > \
	    5 \
	} \
	1 < +inf > \
	vertical { 5 helpNOAOLogo 5 } \
	5 \
    }
    *helpInfo1.label:		XIMTOOL_VERSION
    *helpInfo2.label:		For help or questions:   http://iraf.net
    *helpInfo3.label: \
	NOAO is operated by AURA under cooperative agreement with the NSF

    *helpInfoLayout*helpInfo1.font: -*-helvetica-medium-r-normal-*-12-*-*-*
    *helpInfoLayout*helpInfo2.font: -*-helvetica-medium-r-normal-*-12-*-*-*
    *helpInfoLayout*helpInfo3.font: -*-helvetica-medium-r-normal-*-10-*-*-*

    *helpInfoLayout.helpIRAFLogo.internalWidth:		0
    *helpInfoLayout.helpIRAFLogo.internalHeight:	0
    *helpInfoLayout.helpIRAFLogo.foreground:		SteelBlue
    *helpInfoLayout.helpIRAFLogo.background:		white
    *helpInfoLayout.helpNOAOLogo.internalWidth:		0
    *helpInfoLayout.helpNOAOLogo.internalHeight:	0
    *helpInfoLayout.helpNOAOLogo.foreground:		SteelBlue
    *helpInfoLayout.helpNOAOLogo.background:		white
}

set Resources(tcl_panel) { \

    !--------------------------------
    ! Define a debug Tcl shell.
    !--------------------------------
    *tcl_panel.width:                           550
    *tcl_panel.height:                          180
    *tcl_panel.title:                           Debug TCL Command Entry
    *tclLayout*borderWidth:                     0
    *tclLayout*Frame.frameType:                 sunken
    *tclLayout*Frame.frameWidth:                2
    *tclLayout.layout:  vertical { \
        0 < +0 -0 > \
        tclCmdGroup   < +inf -inf * > \
        tclFrame < +inf -inf * +inf -inf> \
        0 < +0 -0 > \
    }
    *tclEntry*foreground:                       black
    *tclEntry*editType:                         edit
    *tclEntry*type:                             string
    *tclEntry*font:				7x13
    *tclEntry*scrollVertical:                   Always
    *tclEntry*scrollHorizontal:                 whenNeeded

    *tclCmdGroup.label:         
    *tclCmdGroup.outerOffset:                   0
    *tclCmdGroup.innerOffset:                   0
    *tclCmd.layout: vertical { \
        5 \
        horizontal { \
            5 \
            tclClear   3 \
            tclExecute   \
            10 < +inf -10>    \
            tclDismiss   \
            5 \
        } \
        5 \
    }
    *tclClear.label:                            Clear
    *tclExecute.label:                          Execute
    *tclDismiss.label:                          Dismiss
}


set Resources(warning) { \

    ! ---------------------
    ! WARNING dialog.
    ! ---------------------
    *warning.geometry:				+400+300
    *warning*borderWidth:			0
    *warning*TextBox.frameWidth:		0

    *warn.layout: vertical { \
	5 < -5	> \
	horizontal { 5 warnFrame < +inf * +inf > 5 } \
	5 < -5	> \
	horizontal { \
	    10 \
	    warnOk < +inf * > \
	    5 < +inf -5 > \
	    warnCancel < +inf * > \
	    10 \
	} \
	5 < -5	> \
    }
    *warnOk.label:				Okay
    *warnCancel.label:				Cancel

    *WFlayout.layout: horizontal { \
	5 < -5	> \
	vertical { 5 < +inf -5 > warnIcon 5 < +inf -5 > } \
	5 < -5	> \
	warnText < +inf -inf *	+inf -inf > \
	5 < -5	> \
    }

    *warnLabel.label:				Warning
    *warnLabel.width:				300
    *warnLabel.height:				20
    *warnFrame.frameType:			sunken
    *warnFrame.frameWidth:			2
    *warnIcon.location:				0 0 40 40
    *warnIcon.image:				WARNING
    *warnText.label:				generic warning text
    *warnText.width:				270
    *warnText.height:				60
    *warnText.background:			#c4c4c4
}




set Resources(gui) { \

    ! GUI resources.
    ! ------------------------------
    *autoscale:					True
    *zoomfactors:				1 2 4 8
    *displayCoords:				True
    *displayPanner:				True
    *displayMagnifier:				False
    *blinkRate:					1.0
    *pannerArea:				150*150
    *pannerGeom:				-5+5
    *magnifierArea:				100*100
    *magnifierGeom:				+5+5
    *wcsboxGeom:				-5-5
    *maxContrast:				5.0
    *showToolBar:				False
    *showPanelBar:				False
    *warnings:					True
    *centerBoxSize:				5
    *peakCentroid:				True
}





################################################################################
#  GUI Bootstrap Procedures
################################################################################

# Initialize the widget tree.
proc InitWidgetTree args \
{
    global Objects Resources Version


    # Add a new objects description for each of the panels found so we can
    # create them by name later rather that with the defaults.

    set guiResources ""
    foreach obj [array names Objects] {
	set guiResources \
		[ format "%s\n\n*%s_objects:%s\n" \
		    $guiResources $obj $Objects($obj) ]
    }

    # Now append all the Resource strings, changing any version strings as
    # needed.

    foreach res [array names Resources] {
	regsub -all XIMTOOL_VERSION $Resources($res) $Version ver
	set guiResources [ format "%s\n\n%s\n\n" $guiResources $ver ]
    }

    # Define all of the GUI objects and resources.
    appInitialize ximtool XImtool $guiResources
}


# Realize a window module, i.e. create it's objects.
proc Realize { module args } \
{
    global Objects

    # Create any widgets for the module.  We only do this once and set a
    # flag to indicate the objects have been created so we don't do it on
    # subsequent realizations.
    if { [info exists Objects($module)] } {
	createObjects [format "%s_objects" $module]
	reset-server
    }
}


# Bootstrap up the GUI.
InitWidgetTree
Realize ximtool
Realize parameters
Realize panelShell
Realize tcl_panel
Realize pixel_table
Realize hdr_panel
Realize blink_panel
Realize help_panel
Realize xpan_panel
Realize xmag_panel
Realize warning

reset-server

# Set the gterm widget focus.
send colorbar setGterm ; send colorbar activate
send imagewin setGterm ; send imagewin activate

# Crank it up.
activate




##############################################################################
#  Utility Procedures.
##############################################################################

# Utility procedure to test True/False strings in resources.
proc true {v} {expr {$v == "true" || $v == "True" || $v == "TRUE"}}

# Utility functions.
proc min {a b} { expr {($a < $b) ? $a : $b} }
proc max {a b} { expr {($a > $b) ? $a : $b} }

# Global variables.
set version	"NOAO/IRAF XImtool Version 2.0BETA"

set winWidth 	[send imagewin get width ]	;# display window width
set winHeight 	[send imagewin get height]	;# display window height
set appWidth 	[send display  get width ]	;# application window width
set appHeight 	[send display  get height]	;# application window height
set marker 		none			;# selected marker
set markno 		0			;# used to name new markers
set ruler 		none			;# selected ruler
set ruleno 		0			;# used to name new rulers
set blinkFrames 	"1 2"			;# list of blink frames
set auto_reg 		0

set panel_up 		0			;# control panel mapped
set help_up 		0			;# help panel mapped
set ism_enable		0			;# ISM is running
set ism_capable		1			;# Client is ISM capable
set frameCache(0)	""			;# ISM frame cache

set ctype		"equatorial"		;# default coord type
set eqtype		"fk5"			;# default equatorial type

# Global constants.
set MAX_FRAMES 		16			;# max frame buffers

# TCL constants
set tcl_precision 	8



# Window resize callbacks.
proc winResize {w width height} { 
    global winWidth winHeight

    if {$width <= 1 || $height <= 1} \
	return

    set winWidth  $width
    set winHeight $height 
} ; send imagewin addCallback winResize resize

proc appResize {w width height} \
{
    global doHcut doVcut cutXPos cutYPos
    global appWidth appHeight

    set appWidth $width
    set appHeight $height 

    catch {
        if {$doHcut} { 
	    send hcutPlot clearScreen
	    hcutInit
	    send hcutAxes1 redraw ; send hcutAxes2 redraw
	    cutPlots $cutXPos $cutYPos 
        }
        if {$doVcut} { 
	    send vcutPlot clearScreen
	    vcutInit
	    send vcutAxes1 redraw ; send vcutAxes2 redraw
	    cutPlots $cutXPos $cutYPos 
        }
    }
} ; #send imagewin addCallback appResize resize



# Additional global variables, taking default values from resources.
getResources {
    { zoomfactors }
    { displayCoords }
    { displayPanner }
    { displayMagnifier }
    { blinkRate }
    { pannerArea }
    { pannerGeom }
    { magnifierArea }
    { magnifierGeom }
    { wcsboxGeom }
    { maxContrast }
    { showToolBar }
    { showPanelBar }
    { warnings }
    { centerBoxSize }
    { peakCentroid }
    { highlight }
}

set warnings [true $warnings]
set defaultBlinkRate $blinkRate

# Client state variables (UI parameter objects).  Certain of these parameters
# we mirror in Tcl variables here, updating the values with a callback when
# the parameter value changes.  Others require special callbacks.

set frame       1		;# current display frame
set nframes     0		;# number of frame buffers
set frames {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16} ;# list of image frames
set frameWidth  0		;# frame buffer width, pixels
set frameHeight 0		;# frame buffer height, pixels
set frameDepth  8		;# frame buffer pixel size, bits
set cursorMode  0		;# true when cursor read pending

foreach i $frames {
    set frameZoomX($i) 0	;# X zoom factor
    set frameZoomY($i) 0	;# Y zoom factor
    set frameCenterX($i) 0	;# X center of field
    set frameCenterY($i) 0	;# Y center of field
    set frameScaleX($i) 0	;# X scale factor
    set frameScaleY($i) 0	;# Y scale factor
    set frameOffsetX($i) 0	;# X register offset
    set frameOffsetY($i) 0	;# Y register offset
    set enhancement($i) none	;# colortable enhancement
}


#trace variable frameOffsetX w debug_pvar	;# Debug stuff
#trace variable frameOffsetY w debug_pvar
#trace variable frameZoomX w debug_pvar
#trace variable frameZoomY w debug_pvar
#trace variable frameScaleX w debug_pvar
#trace variable frameScaleY w debug_pvar

proc debug_pvar { name element op } \
{
    if {$element != ""} {
	set name ${name}($element)
    }
    upvar $name x
    puts "Variable $name set to $x"
}




################################################################################
# Cut-plot handling routines.
################################################################################

set doHcut	0
set doVcut	0
set hstate	0
set vstate	0
set plotSpeed	1 ; send plotSpeed  set on True
set curJump	1 ; send curJump  set on True
set curTrack	1 ; send curTrack set on True

set cutXPos	[expr "$winWidth  / 2"]
set cutYPos	[expr "$winHeight / 2"]
set cutXScale 	1.0
set cutYScale 	1.0



# Change the cursor to the crosshair when in the plot
proc cutCursor { widget event args } \
{
    global doHcut doVcut curTrack

    if {! $curTrack} \
	return

    if { $event == "enterNotify" } {
	send $widget setCursorType ginMode

	# Disable the update of the graph we're in while in the plot window.
	if {$widget == "hcutPlot"} { set doHcut 0 } else { set doVcut 0 }
    } elseif { $event == "leaveNotify" } {
        send $widget setCursorType idle

	# Enable the update of the graph we're leaving.
	if {$widget == "hcutPlot"} { set doHcut 1 } else { set doVcut 1 }
    }
    cutPlotRefresh
}
foreach w {hcutPlot vcutPlot} {
    send $w addEventHandler cutCursor enterWindowMask
    send $w addEventHandler cutCursor leaveWindowMask
}

proc cutPlotRefresh args \
{
    global doHcut doVcut cutXPos cutYPos

    if {$doHcut} {
        send hcutPlot clearScreen
        hcutInit
        send hcutAxes1 redraw ; send hcutAxes2 redraw
        cutPlots $cutXPos $cutYPos
    }
    if {$doVcut} {
        send vcutPlot clearScreen
        vcutInit
        send vcutAxes1 redraw ; send vcutAxes2 redraw
        cutPlots $cutXPos $cutYPos
    }
} ; send imagewin addEventHandler cutPlotRefresh enterWindowMask

proc cutPlotRedraw args \
{
    global doHcut doVcut cutXPos cutYPos

    if {$doHcut} {
        send hcutAxes1 redraw ; send hcutAxes2 redraw
        cutPlots $cutXPos $cutYPos
    }
    if {$doVcut} {
        send vcutAxes1 redraw ; send vcutAxes2 redraw
        cutPlots $cutXPos $cutYPos
    }
}


# Disable the options when we first start up.
#send plotOpts "set height 1 ; set width 1 ; unmap"
foreach w {plotOpts hcutFrame vcutFrame} { send $w unmap }


# Cut-Plot options callback.
proc doPlotOpts { widget type state args } \
{
    global plotSpeed curJump curTrack doHcut doVcut
    global cutXPos cutYPos

    if {$state} { set not 0 } else { set not 1 }

    switch $widget {
    plotSpeed 	 { if {$state} {
    		       send plotAccurate set on 0 ; send plotImgPix set on 0
		   } else {
    		       send plotSpeed set on True ; 
		   }
		   set plotSpeed $not
		 }
    plotAccurate { if {$state} {
    		       send plotImgPix set on 0 ; send plotSpeed set on 0
		   } else {
    		       send plotSpeed set on True ; 
		   }
		   set plotSpeed $not
		 }
    plotImgPix   { if {$state} {
    		       send plotAccurate set on 0 ; send plotSpeed set on 0
		   } else {
    		       send plotSpeed set on True ; 
		   }
		   set plotSpeed $not
		 }
    curJump	 { send curSmooth set on $not    ; set curJump   $state }
    curSmooth	 { send curJump set on $not      ; set curJump   $not 	}
    curTrack	 { set curTrack $state 					}
    }

    # Redraw the plots right away.
    if {$widget == "plotSpeed" || $widget == "plotAccurate"} { 
	cutPlots $cutXPos $cutYPos
    }
}
foreach w { plotSpeed plotAccurate plotImgPix curJump curSmooth curTrack } {
    send $w addCallback doPlotOpts 
}


# Toggle the display of the horizontal or vertical cut plot windows.

proc cutPlotToggle { widget type state args } \
{
    global doHcut doVcut cutXPos cutYPos hstate vstate
    set    debug  0

    set hstate [send hcut get state]
    set vstate [send vcut get state]
    set w [send display get width]
    set h [send display get height]

    if {$debug} { print " " ; print [format "display: %d x %d\n" $w $h] }

    if {$widget == "hcut"} {
	set hfw [expr [send hcutFrame get width] - 4]
	set hpw [send hcutPlot  get width]
        if {$state} {
	    # Enable the plot and resize the main window
	    if {$vstate} { 
		send plotOpts set width 134 
	    }
	    send hcutFrame "set width $hpw ; set height 132; map"
	    send hcutPlot "set width $hfw ; set height 128"
	    send display "set height [ expr ($h + 132) ]; set width $w"
            drawHcutAxes  1
	    setHcutCursor 1
	    if {$vstate} { 
		send plotOpts "set height 134 ; map"
	        vcutInit
	    }
	    hcutInit 				;# Initialize the plot.
        } else {
	    # Disable the plot and resize the main window
	    setHcutCursor 0
            drawHcutAxes  0
	    send hcutPlot clearScreen
	    send plotOpts "unmap; set height 4"
	    send hcutFrame "unmap; set width $hfw; set height 4"
	    send plotOpts "set width 4"
	    send display "set height [ expr ($h - 128) ] ; set width $w"
	    if {$vstate} { 
	        vcutInit
	    }
        }
        set doHcut $state
    } else {
	set vfh  [expr [send vcutFrame get height] - 4]
	set vph  [send vcutPlot  get height]
        if {$state} {
	    # Enable the plot and resize the main window
	    if {$hstate} { 
		send plotOpts set height 134
	    }
	    send vcutFrame "set height $vph ; set width 132 ; map"
	    send vcutPlot "set height $vfh ; set width 128"
	    send display "set height $h; set width [ expr ($w + 132) ]"
            drawVcutAxes  1
	    setVcutCursor 1
	    if {$hstate} { 
		send plotOpts "set height 134 ; set width 134; map"
     	        hcutInit
	    }
     	    vcutInit 				;# Initialize the plot.
        } else {
	    # Disable the plot and resize the main window
	    setVcutCursor 0
            drawVcutAxes  0
	    send vcutPlot clearScreen
	    send plotOpts "unmap; set width 4"
	    send vcutFrame "unmap; set height $vfh; set width 4"
	    send plotOpts "set height 4"
	    send display "set width [ expr ($w - 128) ] ; set height $h"
	    if {$hstate} { 
	        hcutInit
	    }
        }
        set doVcut $state
    }
		
    if {$debug} {
	print [format " hFrame: %d x %d\n" \
		[send hcutFrame get width] [send hcutFrame get height] ]
	print [format "  hPlot: %d x %d\n" \
		[send hcutPlot get width] [send hcutPlot get height] ]
	print [format " vFrame: %d x %d\n" \
		[send vcutFrame get width] [send vcutFrame get height] ]
	print [format "  vPlot: %d x %d\n" \
		[send vcutPlot get width] [send vcutPlot get height] ]
	print [format "state: %d  %d\n" $hstate $vstate]
	print [format "display: %d x %d\n" $w $h]
    }

    cutPlots $cutXPos $cutYPos
} ; foreach w { hcut vcut } { send $w addCallback cutPlotToggle }


# Draw the cut plots.
proc cutPlots { xpos ypos args } \
{
    global doHcut doVcut cutXPos cutYPos hstate vstate

    catch {
        if {$doHcut} {
    	    drawHcutIndicator $xpos
	     if {$hstate} { plotHcut $xpos $ypos }
	}
        if {$doVcut} {
    	    drawVcutIndicator $xpos
            if {$vstate} { plotVcut $xpos $ypos }
	}
    }

    set cutXPos $xpos  ;  set cutYPos $ypos
}


################################################################################
# Horizontal Cut-Plot Routines
################################################################################

set hcutVec	{}

# Initiailize the horizontal cut-plot
proc hcutInit args \
{
    global logz cutXScale winWidth cutXPos cutYPos

    # Just get some dummy pixels, we only want the z1/z2 values so we can 
    # initialize the labels.
    set xp   [expr [send imagewin get width] / 2 ]
    set yp   [expr [send imagewin get height] / 2 ]
    set pix  [send client getPixels $xp $yp 2 2 ]
    set z1   [lindex $pix 0]
    set z2   [lindex $pix 1]

    send hcutPlot getPhysRes  xr  yr
    send hcutPlot setLogRes  $xr $yr

    set logx    [send imagewin get width]
    set logz    [expr ($z2 - $z1)]
    set cutXScale [expr ($xr * 1.0) / ($logx * 1.0)]

    # Initialize the labels.
    send vcutPlot "setColorIndex 6"
    drawHcutLabels $z1 $z2
}

# Draw the horizontal cut-plot.
proc plotHcut { xpos ypos } \
{
    global doHcut cutXScale
    global hcutVec cutXPos plotSpeed


    if { ($xpos == 0 && $ypos == 0) || ! $doHcut } \
	return

    # Do the horizontal cut plot.
    set width [send imagewin get width]
    if {$plotSpeed} {
        set pix  [send client getPixels 0 $ypos $width 1 2 5 $cutXScale]
    } else {
        set pix  [send client getPixels 0 $ypos $width 1 2 1 $cutXScale]
    }
    set z1   [lindex $pix 0]
    set z2   [lindex $pix 1]
    set vec  [lrange $pix 2 end]

    # Erase the last plot rather than clear the screen and redraw 
    # the new vector.
    send hcutPlot setColorIndex background
    send hcutPlot drawPolyline $hcutVec
    send hcutPlot setColorIndex foreground
    send hcutPlot drawPolyline $vec
    set  hcutVec $vec 			;# save for later erasure

    # Mark the cursor position.
    drawHcutIndicator $xpos

    # Minimize the screen refreshes to speed things up.
    if { [expr "$ypos % 3"] == 0} {
	catch {
            drawHcutLabels $z1 $z2	;# redraw the labels
	}
        send hcutAxes1 redraw		;# redraw the axes markers
        send hcutAxes2 redraw
    }
}


# Create markers to indicate axes on the horizontal cut-plot.
proc drawHcutAxes { state } \
{
    if {$state} {
        send hcutPlot createMarker hcutAxes1 \
            type            box \
            createMode      noninteractive \
            lineColor       gray60 \
            lineStyle       0 \
            x               1 \
            y               60 \
            height          30 \
	    width           4096 \
            activated       True \
            visible         True \
            sensitive       False
        send hcutPlot createMarker hcutAxes2 \
            type            box \
            createMode      noninteractive \
            lineColor       gray60 \
            lineStyle       0 \
            x               1 \
            y               1 \
            height          60 \
	    width           4096 \
            activated       True \
            visible         True \
            sensitive       False
    } else {
	send hcutAxes1 destroy ; send hcutAxes2 destroy
    }
}

# Create a marker to be used as the cursor indicator.
proc setHcutCursor { state } \
{
    if {$state} {
	set pts { {252 10} {260 10} {256 1} }

        send hcutPlot createMarker hcutCursor \
            type          polygon \
            createMode    noninteractive \
            lineColor     black \
            fill     	  True \
            fillColor     yellow \
            x             256 \
            y             12 \
            width         8 \
            height        10 \
            knotSize      0 \
            activated     True \
            visible       False \
            sensitive     False
        send hcutCursor setVertices $pts
        send hcutCursor set visible True

    } else {
	send hcutCursor destroy
    }
}

# Label the axes on the horizontal cut plot.
proc drawHcutLabels { z1 z2 } \
{
    set mid  [expr "($z2-$z1)/2.0+$z1"]
    set low [expr "($mid-$z1)/2.0+$z1"]
    set high  [expr "($z2-$mid)/2.0+$mid"]

    send hcutPlot "setColorIndex 6 ; \
	 drawAlphaText 2 10  [format "%.1f" $z2] ; \
         drawAlphaText 2 34  [format "%.1f" $high] ; \
         drawAlphaText 2 64  [format "%.1f" $mid] ; \
         drawAlphaText 2 94  [format "%.1f" $low] ; \
         drawAlphaText 2 120 [format "%.1f" $z1]"
}

# Draw the cursor position indicator on the horizontal cut plot.
proc drawHcutIndicator { xpos } \
{
    global cutXScale cutXPos

    send hcutCursor move [expr ($xpos * $cutXScale)] 12
    set cutXPos $xpos
}

# Track the cursor while in the cut-graph window.
proc hcutWCSUpdate { x y args } \
{
    global cutYPos curTrack
    if {$curTrack} { 
        wcsUpdate $x $cutYPos 
    }
    drawHcutIndicator $x
}




################################################################################
# Vertical Cut-Plot Routines
################################################################################

set vcutVec	{}

# Initiailize the vertical cut-plot
proc vcutInit args \
{
    global cutYScale winWidth cutXPos cutYPos

    # Just get some dummy pixels, we only want the z1/z2 values so we can 
    # initialize the labels.
    set xp   [expr [send imagewin get width] / 2 ]
    set yp   [expr [send imagewin get height] / 2 ]
    set pix  [send client getPixels $xp $yp 2 2 ]
    set z1   [lindex $pix 0]
    set z2   [lindex $pix 1]

    send vcutPlot getPhysRes  xr  yr
    send vcutPlot setLogRes  $xr $yr

    set logy    [send imagewin get height]
    set logz    [expr ($z2 - $z1)]
    set cutYScale [expr ($yr * 1.0) / ($logy * 1.0)]

    # Initialize the labels.
    send vcutPlot "setColorIndex 6; reset"
    drawVcutLabels $z1 $z2
}

# Draw the horizontal cut-plot.
proc plotVcut { xpos ypos } \
{
    global doVcut cutYScale
    global vcutVec cutXPos cutYPos plotSpeed


    if { ($xpos == 0 && $ypos == 0) || ! $doVcut } \
	return

    # Do the vertical cut plot.
    set height [send imagewin get height]
    if {$plotSpeed} {
        set pix  [send client getPixels $xpos 0 1 $height 3 5 $cutYScale]
    } else {
        set pix  [send client getPixels $xpos 0 1 $height 3 1 $cutYScale]
    }
    set z1   [lindex $pix 0]
    set z2   [lindex $pix 1]
    set vec  [lrange $pix 2 end]

    # Draw the vector.
    send vcutPlot setColorIndex background
    send vcutPlot drawPolyline $vcutVec
    send vcutPlot setColorIndex foreground
    send vcutPlot drawPolyline $vec
    set  vcutVec $vec 			;# save for later erasure

    # Mark the cursor position.
    drawVcutIndicator $ypos

    # Minimize the screen refreshes to speed things up.
    if { [expr "$xpos % 3"] == 0} {
	catch {
            drawVcutLabels $z1 $z2	;# redraw the labels
	}
        send vcutAxes1 redraw		;# redraw the axes markers
        send vcutAxes2 redraw
    }
}

# Erase the last plot rather than clear the screen and redraw it all. The
# erase is done by redrawing the last vector in the the background color.
proc eraseOldVcut args \
{
    global cutYPos vcutVec

    send vcutPlot setColorIndex background
    send vcutPlot drawPolyline $vcutVec
    send vcutPlot setColorIndex foreground
}

# Draw the horizontal cut-plot.
# Create markers to indicate axes on the vertical cut-plot.
proc drawVcutAxes { state } \
{
    if {$state} {
        send vcutPlot createMarker vcutAxes1 \
            type            box \
            createMode      noninteractive \
            lineColor       gray60 \
            lineStyle       0 \
            x               60 \
            y               1 \
            height          4096 \
            width           30 \
            activated       True \
            visible         True \
            sensitive       False
        send vcutPlot createMarker vcutAxes2 \
            type            box \
            createMode      noninteractive \
            lineColor       gray60 \
            lineStyle       0 \
            x               1 \
            y               1 \
            width           60 \
            height          4096 \
            activated       True \
            visible         True \
            sensitive       False
    } else {
	send vcutAxes1 destroy ; send vcutAxes2 destroy
    }
}

# Create a marker to be used as the cursor indicator.
proc setVcutCursor { state } \
{
    if {$state} {
	set pts { {10 252} {10 260} {1 256} }

        send vcutPlot createMarker vcutCursor \
            type          polygon \
            createMode    noninteractive \
            lineColor     black \
            fill     	  True \
            fillColor     yellow \
            x             12 \
            y             256 \
            width         10 \
            height        8 \
            knotSize      0 \
            activated     True \
            visible       False \
            sensitive     False
        send vcutCursor setVertices $pts
        send vcutCursor set visible True

    } else {
	send vcutCursor destroy
    }
}

# Label the axes on the vertical cut plot.
proc drawVcutLabels { z1 z2 } \
{
    set mid  [expr "($z2-$z1)/2.0+$z1"]
    set low  [expr "($mid-$z1)/2.0+$z1"]
    set high [expr "($z2-$mid)/2.0+$mid"]

    # Initialize the label strings and positions.
    set labels {}
    foreach i [list $z2 $high $mid $low $z1] {
	lappend labels  [ format "%.1f" $i ]
    }
    set xposns { 2 28 58 88 112 }

    send vcutPlot "setColorIndex 6"

    # Draw each label vertically down the position since we can't rotate
    # the text.
    set xp  0
    foreach lab $labels {
	set chars [split $lab {} ]
        set yp  12
	set xpos [lindex $xposns $xp]
        foreach ch $chars {
	    if {$ch == "."} { incr yp -4 }
    	    send vcutPlot drawAlphaText $xpos $yp $ch
	    incr yp 10
        }
	incr xp
    }
}


# Draw the cursor position indicator on the horizontal cut plot.
proc drawVcutIndicator { ypos } \
{
    global cutYScale cutYPos

    send vcutCursor move 12 [expr ($ypos * $cutYScale)]
    set cutYPos $ypos
}


# Track the cursor while in the cut-graph window.
proc vcutWCSUpdate { x y args } \
{
    global cutXPos curTrack
    if {$curTrack} { 
        wcsUpdate $cutXPos $y 
    }
    drawVcutIndicator $y
}



################################################################################
# UTILITY ROUTINES
################################################################################


# TICSTEP -- Utility routine to compute nice ticmark steps in plots.
# [ NOT CURRENTLY USED. ]

proc ticstep { range nsteps } \
{
    set t2 0.301029996
    set t5 0.698970004
    set df [ expr "$range / double($nsteps + 1)" ]
    if {$df > 0.0} {
        set p1 [ expr "log10(double($df))" ]
    } else {
        set p1 [ expr "log10(double(-$df))" ]
    }
    set p2 [ expr "int($p1)" ]
    set p3 [ expr "$p1 - $p2" ]

    if { $p3 < 0.0 } {
        set p3 [ expr "$p2 + 1.0" ]
        set p2 [ expr "$p2 - 1.0" ]
    }

    if { $p3 < 1.0e-10 } {
       set ticstep [ expr "pow(double(10.0),double($p2))" ]
    } elseif { $p3 > 0. &&  $p3 <=  $t2 } {
       set ticstep [ expr "pow(double(10.0),double($p2 + $t2))" ]
    } elseif { $p3 >  $t2 &&  $p3 <=  $t5 } {
       set ticstep [ expr "pow(double(10.0),double($p2 + $t5))" ]
    } elseif { $p3 >  $t5 &&  $p3 <= 1.0 } {
       set ticstep [ expr "pow(double(10.0),double($p2 + 1.))" ]
    } else {
       set ticstep $df
    }

    set logtic  [ expr "int(log10($ticstep)) - 1" ]
    set scale   [ expr "pow(double(10.0),double($logtic))" ]
    set ticstep [ expr "int( ($ticstep / $scale) * $scale)" ]

    if {$ticstep < 0.1} { set ticstep 0.10 }

    return $ticstep
}



# Cursor positioning routines
#----------------------------

proc move_cursor { xstep ystep args } \
{
    set raster 0
    send imagewin getCursorPos rx ry
    send imagewin setCursorPos [expr $rx + $xstep] [expr $ry + $ystep] $raster
}


# Called when the number of frames changes.
proc setNFrames {param old new} \
{
    global frameMenuDescription nframes frames

    set nframes $new
    if {$old != $new} {
	foreach i {prevButton nextButton} {
	    send $i set sensitive [expr "$nframes > 1"]
	}

	if {$nframes > 0} {

	    # Creates the Frames menu on the main image window.
	    set items { }
	    for {set i 1} {$i <= $nframes} {incr i} {
		set l [format "%2d" $i]
		lappend  items "$l f.exec \{send client setFrame $i\} sensitive \{[expr \"$nframes >= $i\"]\}"
	    }
	    editMenu frameMenu frameButton $items

	    # Create the menu for the blink frames list.
	    set items { }
	    for {set i 0} {$i <= $nframes} {incr i} {
		set j [expr ($i + 1)]
		if {$i == 0} {
	   	    set s "\"none\" f.exec \{send brFrameBTN set label \" \"\}"
		    lappend items $s
		} else {
		    set l [format "%2d" $i]
		    lappend items "$l f.exec \{send brFrameBTN set label $l\} sensitive \{[expr \"$nframes >= $i\"]\}"
		}
	    }
	    for {set i 1} {$i <= $nframes} {incr i} {
		send brFrame$i setSensitive True
		send tFrame$i  setSensitive True
	        regsub -all BTN $items $i nmenu
		editMenu frame${i}Menu brFrame$i $nmenu
	    }

	} else {
	    editMenu frameMenu frameButton $frameMenuDescription

	    for {set i 1} {$i <= $nframes} {incr i} {
		send brFrame$i setSensitive True
		send tFrame$i  setSensitive True
		editMenu frame${i}Menu brFrame$i $frameMenuDescription
	    }
	}
    }

    for {set i 1} {$i <= 16} {incr i} {
	if {$i <= $nframes} {
	    send frame$i map
	} else {
	    send frame$i unmap
	}
    }

    if {$nframes > 2} {
        setAllTileFrames
    }
}; send nframes addCallback setNFrames


# Set the default main window frame menu.
set frameMenuDescription {
    {" 1" f.exec "send client setFrame 1"  sensitive {[expr "$nframes >= 1"]} }
    {" 2" f.exec "send client setFrame 2"  sensitive {[expr "$nframes >= 2"]} }
    {" 3" f.exec "send client setFrame 3"  sensitive {[expr "$nframes >= 3"]} }
    {" 4" f.exec "send client setFrame 4"  sensitive {[expr "$nframes >= 4"]} }
}; createMenu frameMenu  frameButton  $frameMenuDescription




# Initialize the frame lists panels (blink panel and tile tab).
for {set i 1} {$i <= 16} {incr i} {
    send brFrame$i set label [format "%2d" $i]
    send tFrame$i  set label [format "%2d" $i]
    if {$i <= 4} {
	send brFrame$i setSensitive True
	send tFrame$i  "setSensitive True ; set state 1"
    } else {
	send brFrame$i setSensitive False
	send tFrame$i  "setSensitive False ; set state 0"
    }
    createMenu frame${i}Menu brFrame$i $frameMenuDescription
}


# Called when the frame being displayed changes.
proc frameChanged {param old new} \
{
    global frame

    set frame $new
    send frameButton set label [format "%2d" $frame]

    # The first time we request frame 5 or higher reset 
    # the extra frame buttons on the control panel to make
    # them visible.
    if {$new >= 5} {
	send frlistBox set width 49
    }
    wcsFmtFBConfig
    drawCompass
}; send frame addCallback frameChanged


# Called when the frame buffer configuration changes.
proc setFrameSize {param old new} \
{
    global frameWidth frameHeight frameDepth
    set frameWidth [lindex $new 0]
    set frameHeight [lindex $new 1]
    set frameDepth [lindex $new 2]

    wcsFmtFBConfig
}; send frameSize addCallback setFrameSize

# Called when the current frame is zoomed or panned.
proc setFrameView {param old new} \
{
    global frameZoomX frameZoomY frameCenterX frameCenterY
    global frameScaleX frameScaleY frameOffsetX frameOffsetY
    global frame auto_reg blinkFrames

    # Update the position.
    set frameZoomX($frame)   [lindex $new 0]
    set frameZoomY($frame)   [lindex $new 1]
    set frameCenterX($frame) [lindex $new 2]
    set frameCenterY($frame) [lindex $new 3]
    set frameScaleX($frame)  [lindex $new 4]
    set frameScaleY($frame)  [lindex $new 5]
    set frameOffsetX($frame) [lindex $new 6]
    set frameOffsetY($frame) [lindex $new 7]

    # If auto-registering is enabled, do it now, but only when we're updating
    # the current display frame, and only if that frame is in the framelist.

    if {$auto_reg == 1 && $frame == [send frameButton get label]} {
	if {[string first $frame $blinkFrames] != -1} {
	    send client offsetRegister \{$blinkFrames\}
	}

	foreach f $blinkFrames {
	    if {$f != $frame} {
    	        set frameZoomX($f)   $frameZoomX($frame)
    	        set frameZoomY($f)   $frameZoomY($frame)
    	        set frameCenterX($f) $frameCenterX($frame)
    	        set frameCenterY($f) $frameCenterY($frame)
    	        set frameScaleX($f)  $frameScaleX($frame)
    	        set frameScaleY($f)  $frameScaleY($frame)
	    }
	}
    }
    deleteAllRulers

}; send frameView addCallback setFrameView


# Called when the color enhancement for a frame changes.
proc setEnhancement {param old new} \
{
    global enhancement
    set enhancement([lindex $new 0]) [lrange $new 1 end]
}; send enhancement addCallback setEnhancement

# Called when the frame title changes (e.g. frame change or new frame loaded).
proc setTitle {param old new} \
{
    set lab  [string trimright $new]
    send imageTitle set label $lab

    set image [lindex [ split $lab '-'] 0 ]
    wcsFmtImname $image

    set title [lindex [ split $lab '-'] 1 ]
    wcsFmtImtitle $title
    deleteAllRulers
}; send frameTitle addCallback setTitle

# Called when the image is flipped in an axis.
proc setFlip {param old new} \
{
    if {$param == "xflip"} { 
	send xflipButton set state [true $new]
    } else {
	send yflipButton set state [true $new]
    }
    deleteAllRulers
}; foreach i {xflip yflip} { send $i addCallback setFlip }


# Various general callbacks.

proc Quit args \
{
    global ism_enable

    if {$ism_enable} {
        catch { send wcspix quit }
    }
    send client Quit 			  
}
proc nextFrame args	    { send client nextFrame 		  }
proc prevFrame args	    { send client prevFrame 		  }
proc setColormap { mapno }  { send client setColormap $mapno 	  }
proc xflip  args	    { send client flip x   ; flipRegister }
proc yflip  args	    { send client flip y   ; flipRegister }
proc xyflip args	    { send client flip x y ; flipRegister }
proc flipRegister args \
{
    global auto_reg frame blinkFrames

    if {$auto_reg == 1 && $frame == [send frameButton get label]} {
	if {[string first $frame $blinkFrames] != -1} {
	   send client offsetRegister \{$blinkFrames\}
	}
    }
}



# Initialize bitmaps.
createBitmap xflip 16 16 {
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x18, 0x18,
   0x1c, 0x38, 0xfe, 0x7f, 0xfe, 0x7f, 0x1c, 0x38, 0x18, 0x18, 0x10, 0x08,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}

createBitmap yflip 16 16 {
   0x00, 0x00, 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0xf0, 0x0f, 0x80, 0x01,
   0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0xf0, 0x0f,
   0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01, 0x00, 0x00}

createBitmap qmark 16 16 {
   0x00, 0x00, 0x00, 0x00, 0xf0, 0x07, 0xf8, 0x0f, 0x18, 0x0c, 0x18, 0x0c,
   0x18, 0x0e, 0x00, 0x07, 0x80, 0x03, 0x80, 0x01, 0x80, 0x01, 0x00, 0x00,
   0x80, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00}

createBitmap larrow 16 16 {
   0x00, 0x00, 0x00, 0x03, 0x80, 0x03, 0xc0, 0x03, 0xe0, 0x1e, 0x70, 0x1e,
   0x38, 0x18, 0x1c, 0x18, 0x1c, 0x18, 0x38, 0x18, 0x70, 0x1e, 0xe0, 0x1e,
   0xc0, 0x03, 0x80, 0x03, 0x00, 0x03, 0x00, 0x00}

createBitmap rarrow 16 16 {
   0x00, 0x00, 0xc0, 0x00, 0xc0, 0x01, 0xc0, 0x03, 0x78, 0x07, 0x78, 0x0e,
   0x18, 0x1c, 0x18, 0x38, 0x18, 0x38, 0x18, 0x1c, 0x78, 0x0e, 0x78, 0x07,
   0xc0, 0x03, 0xc0, 0x01, 0xc0, 0x00, 0x00, 0x00}

createBitmap panel 16 16 {
   0x00, 0x00, 0xf8, 0x1f, 0xf8, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
   0x98, 0x19, 0x98, 0x19, 0x98, 0x19, 0x98, 0x19, 0x98, 0x19, 0x18, 0x18,
   0x18, 0x18, 0x18, 0x18, 0xf8, 0x1f, 0xf8, 0x1f}

createBitmap brightness 15 15 {
   0x00, 0x00, 0x80, 0x00, 0x84, 0x10, 0xe8, 0x0b, 0x10, 0x04, 0x08, 0x08,
   0x08, 0x08, 0x0e, 0x38, 0x08, 0x08, 0x08, 0x08, 0x10, 0x04, 0xe8, 0x0b,
   0x84, 0x10, 0x80, 0x00, 0x00, 0x00}

createBitmap contrast 15 15 {
   0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x30, 0x07, 0x08, 0x0f, 0x08, 0x0f,
   0x04, 0x1f, 0x04, 0x1f, 0x04, 0x1f, 0x08, 0x0f, 0x08, 0x0f, 0x30, 0x07,
   0xc0, 0x01, 0x00, 0x00, 0x00, 0x00}

createBitmap bar 10 10 {
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x42, 0x00, 0x7e, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}

createBitmap dot 16 16 {
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01,
   0xe0, 0x03, 0xf0, 0x07, 0xf0, 0x07, 0xf0, 0x07, 0xe0, 0x03, 0xc0, 0x01,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}

createBitmap null 16 16 {
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}

createBitmap solid 64 24 {
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}

catch { send controlButton "set bitmap panel; addCallback panel" }
catch { send helpButton    "set bitmap qmark; addCallback Help"  }
send xflipButton "set bitmap xflip;	 addCallback xflip"
send yflipButton "set bitmap yflip;	 addCallback yflip"
send prevButton  "set bitmap larrow; addCallback prevFrame"
send nextButton  "set bitmap rarrow; addCallback nextFrame"
send blinkPanel  "set bitmap panel"



# WINDOW the current frame.
set old_cm_x	0
set old_cm_y	0

proc windowColormap {x y} \
{
    global winWidth winHeight maxContrast old_cm_x old_cm_y

    # For efficiency we won't compute the sqrt of the distance but instead
    # just compare the square.  Use a threshold of 6 pixels so when we
    # narrow in on the ROI we refine the colormap more precisely.

    set diff  [expr (($old_cm_x - $x) * ($old_cm_x - $x)) + \
                   (($old_cm_y - $y) * ($old_cm_y - $y))]

    # Keep the old position.
    set old_cm_x $x
    set old_cm_y $y
    if {$diff > 36} {
       return
    }

    send client windowColormap \
	[expr "double($x) / $winWidth"] \
	[expr "(double($y) - $winHeight / 2.0) / $winHeight * \
	    $maxContrast * 2.0"]
}

proc updateColormap {x y} \
{
    global winWidth winHeight maxContrast old_cm_x old_cm_y

    set old_cm_x $x
    set old_cm_y $y
    send client updateColormap \
	[expr "double($x) / $winWidth"] \
	[expr "(double($y) - $winHeight / 2.0) / $winHeight * \
	    $maxContrast * 2.0"]
}



# WINDOW the current frame, but only one color at a time.
proc windowRGB {color x y save_flag} \
{
    global winWidth winHeight maxContrast

    send client windowRGB $color \
	[expr "double($x) / $winWidth"] \
	[expr "(double($y) - $winHeight / 2.0) / $winHeight * \
	    $maxContrast * 2.0"] $save_flag
}


# ZOOM and PAN.
set xcen 0
set ycen 0
foreach i $frames {set zoomindex($i) 0}
set nzoomfactors 0
foreach i $zoomfactors {
    set zoomfactor($nzoomfactors) $i
    incr nzoomfactors
}

# Zoom or pan image at given center.
proc zoom {x y} \
{
    global xcen ycen frame
    global zoomindex zoomfactor
    global nzoomfactors

    set rx $x;  set ry $y
    set raster 0

    # Convert raw screen coordinates to frame buffer raster coordinates.
    send imagewin unmapPixel $x $y raster rx ry

    # Select a pixel.
    set rx [expr "int ($rx)"]
    set ry [expr "int ($ry)"]

    # If the pointer did not move (much) zoom the image, otherwise
    # pan it.

    send imagewin setCursorType busy
    if {sqrt(pow($x-$xcen, 2) + pow($y-$ycen, 2)) < 4} {
	set zoomindex($frame) [expr [incr zoomindex($frame)] % $nzoomfactors]
	set mag $zoomfactor($zoomindex($frame))
	send client zoom $mag $mag $rx $ry
    } else {
	send client pan $rx $ry
	set xcen $x
	set ycen $y
    }

    # Move the pointer so that it tracks the object feature the user
    # selected.

    send imagewin setCursorPos $rx $ry $raster
    send imagewin getCursorPos xcen ycen
    send imagewin setCursorType idle
}


# Zoom using a marker to indicate the region to be displayed.
proc zoomMarker {marker aspect} \
{
    global xcen ycen frame
    global winWidth winHeight
    global zoomindex nzoomfactors
    global auto_reg frame frameOffsetX frameOffsetY

    # getRegion returns: "rectangle raster x y width height rotangle".
    set region [send $marker getRegion unmap]

    set raster [lindex $region 1]
    set xcen [expr "int([lindex $region 2]) + 0.5"]
    set ycen [expr "int([lindex $region 3]) + 0.5"]
    set snx  [expr "[lindex $region 4] * 2"]
    set sny  [expr "[lindex $region 5] * 2"]

    # Compute the magnification ratio.
    set xmag [expr "$winWidth / $snx"]
    set ymag [expr "$winHeight / $sny"]
    if {$aspect == "equal"} {
	set mag [expr "($xmag < $ymag) ? $xmag : $ymag"]
	set xmag $mag;  set ymag $mag
    }

    # Zoom the image.
    send client zoomAbs \
	$xmag $ymag $xcen $ycen \
	$frameOffsetX($frame) $frameOffsetY($frame)

    # The following causes a button2 to redisplay the full image.
    send imagewin setCursorPos $xcen $ycen $raster
    send imagewin getCursorPos xcen ycen
    set zoomindex($frame) [expr "$nzoomfactors - 1"]
}

# Pan the display frame one width/height in a given direction.
proc moveFrame { xs ys args } \
{
    global winWidth winHeight frame
    global frameWidth frameHeight
    global frameZoomX frameZoomY frameCenterX frameCenterY
    global frameOffsetX frameOffsetY

    # Get the step size for the new position.
    set xstep_size [ expr "$xs * $winWidth / $frameZoomX($frame)" ]
    set ystep_size [ expr "$ys * $winHeight / $frameZoomY($frame)" ]

    # Set the boundaries so we only move up to the edges.
    set xl [ expr "($winWidth / $frameZoomX($frame)) / 2 + 1" ]
    set yl [ expr "($winHeight / $frameZoomY($frame)) / 2 + 1" ]
    set xu [ expr "$frameWidth - $xl" ]
    set yu [ expr "$frameHeight - $yl" ]

    # Set the new center position.
    set nxc [ expr "$frameCenterX($frame) + $xstep_size" ]
    set nyc [ expr "$frameCenterY($frame) + $ystep_size" ]
    if {$nxc < $xl} { set nxc $xl }
    if {$nxc > $xu} { set nxc $xu }
    if {$nyc < $yl} { set nyc $yl }
    if {$nyc > $yu} { set nyc $yu }

    # Finally, send the command to move the frame.
    send client zoomAbs \
	$frameZoomX($frame) $frameZoomY($frame) $nxc $nyc \
	$frameOffsetX($frame) $frameOffsetY($frame)
}

proc resetView {param old new} {
    global zoomindex xcen ycen frames
    global frameWidth frameHeight

    if {$new == "done"} {
	foreach i $frames {
	    send client setFrame $i
	    set xcen [expr $frameWidth / 2]
	    set ycen [expr $frameHeight / 2]
	    send client zoom 1 1 $xcen $ycen
	    set zoomindex($i) 0
	    send client setColormap Grayscale
	    normalize
	}
	send client setFrame 1
    }
}; #send initialize addCallback resetView


# CURSOR READ stuff.
proc setCursorMode {param old new} \
{
    global cursorMode

    if {$new == "on"} {
	send imagewin "activate; setCursorType ginMode"
	set cursorMode 1
    } elseif {$new == "off"} {
	send imagewin "setCursorType idle; deactivate"
	set cursorMode 0
    }
}

proc keyInput {widget event sx sy data} \
{
    global cursorMode frame

    if {!$cursorMode || $event != "keyPress"} \
	return
    if {[lindex $data 0] == "??"} \
	return

    # Convert raw screen coordinates to raster pixel coordinates.
    send imagewin unmapPixel $sx $sy raster rx ry

    # Return the cursor value and exit cursor mode.
    send client retCursorVal $rx $ry $frame 1 [lindex $data 0]
}

proc resetCursorMode args {
    global cursorMode frame
    if {$cursorMode} {
	send imagewin getCursorPos x y
	send client retCursorVal $x $y $frame 1 ^D
    }
}; send initialize addCallback resetCursorMode

send cursorMode addCallback setCursorMode
send imagewin   addCallback keyInput input


# MARKER stuff.  The active marker is determined by the global variable
# "marker", which is the marker the pointer is in, or which the pointer
# was most recently in.

# Translations when pointer is inside marker.
set markerTranslations { \
!Shift <Btn1Motion>:	m_rotateResize()
      <Btn1Motion>:	m_moveResize()
 !Shift <Btn1Down>:	m_raise()  m_markpos()
	<Btn1Down>:	m_raise()  m_markposAdd()
	  <Btn1Up>:	m_redraw() m_destroyNull()
	<Btn2Down>:	m_lower()
	<Btn3Down>:	popup(markerMenu)
	  <Btn3Up>:	popdown(markerMenu)
      !Ctrl <Key>b:     call(prevFrame,$name)
      !Ctrl <Key>f:     call(nextFrame,$name)
      !Ctrl <Key>h:     call(move_cursor,-1,0)
      !Ctrl <Key>j:     call(move_cursor,0,1)
      !Ctrl <Key>k:     call(move_cursor,0,-1)
      !Ctrl <Key>l:     call(move_cursor,1,0)
      !Ctrl <Key>n:     call(normalize)
      !Ctrl <Key>c:     call(cpZoomAction,centerFrame)
      !Ctrl <Key>i:     call(cpInvert)
      !Ctrl <Key>m:     call(cpMatchFrames)
      !Ctrl <Key>r:     call(cpRegisterFrames)
      !Ctrl <Key>p:     call(togglePanner)
       !Alt <Key>1: 	call(cpSetFrame,frame1)
       !Alt <Key>2: 	call(cpSetFrame,frame2)
       !Alt <Key>3: 	call(cpSetFrame,frame3)
       !Alt <Key>4: 	call(cpSetFrame,frame4)
      !Ctrl <Key>1: 	call(cpZoom,1,1,fixed)
      !Ctrl <Key>2: 	call(cpZoom,2,2,fixed)
      !Ctrl <Key>3: 	call(cpZoom,3,3,fixed)
      !Ctrl <Key>4: 	call(cpZoom,4,4,fixed)
      !Ctrl <Key>5: 	call(cpZoom,5,5,fixed)
      !Ctrl <Key>6: 	call(cpZoom,6,6,fixed)
      !Ctrl <Key>7: 	call(cpZoom,7,7,fixed)
      !Ctrl <Key>8: 	call(cpZoom,8,8,fixed)
      !Ctrl <Key>9: 	call(cpZoom,9,9,fixed)
    <Key>BackSpace:	m_deleteDestroy()
       <Key>Delete:	m_deleteDestroy()
	<KeyPress>:	m_input()
	  <Motion>:	track-cursor() call(wcsUpdate,$x,$y) call(magnifierMapImage,$x,$y)
}

# Popup menu in effect when inside marker.
createMenu markerMenu imagewin {
    {	Marker		f.title			}
    {			f.dblline		}
    {	Zoom		f.exec {
			    zoomMarker $marker equal
			    send $marker destroy
			}			}
    {	Fill		f.exec {
			    zoomMarker $marker fill
			    send $marker destroy
			}			}
    {	Print		f.exec {
			    send $marker getRect interior x0 y0 nx ny
		            setPrintCorners $x0 [expr $y0 + $ny -1] \
		                [expr $x0 + $nx -1] $y0
			    send client print $x0 $y0 $nx $ny
			}			}
    {	Save		f.exec {
		            send imagewin setCursorType busy
			    send $marker getRect interior x0 y0 nx ny
			    send client save $x0 $y0 $nx $ny
		            send imagewin setCursorType idle
			}			}
    {	Info		f.exec {
			    send infoText append \
				[format "%s\n" [send $marker getRegion unmap]]
			}			}
    {	Unrotate	f.exec {
			    send $marker setAttribute rotangle 0
			}			}
    {			f.dblline		}
    {	Color		f.menu markerColor	}
    {	Type		f.menu markerType	}
    {			f.dblline		}
    {	Destroy		f.exec {
			    send $marker destroy
			}			}
}

createMenu markerType markerMenu {
    {	Type		f.title			}
    {			f.dblline		}
    {	Rectangle	f.exec "m_setType $marker rectangle"	}
    {	Box		f.exec "m_setType $marker box"		}
    {	Circle		f.exec "m_setType $marker circle"	}
    {	Ellipse		f.exec "m_setType $marker ellipse"	}
    {	Polygon		f.exec "m_setType $marker polygon"	}
}

createMenu markerColor markerMenu {
    {	Color		f.title			}
    {			f.dblline		}
    {	""		f.exec "m_setColor $marker black"
			    bitmap solid foreground black }
    {	""		f.exec "m_setColor $marker white" 
			    bitmap solid foreground white }
    {	""		f.exec "m_setColor $marker red" 
			    bitmap solid foreground red }
    {	""		f.exec "m_setColor $marker green" 
			    bitmap solid foreground green }
    {	""		f.exec "m_setColor $marker blue" 
			    bitmap solid foreground blue }
    {	""		f.exec "m_setColor $marker magenta" 
			    bitmap solid foreground magenta }
    {	""		f.exec "m_setColor $marker cyan" 
			    bitmap solid foreground cyan }
    {	""		f.exec "m_setColor $marker yellow" 
			    bitmap solid foreground yellow }
}

proc m_setType {marker type}  {
    send $marker "markpos; set type $type; redraw"
}
proc m_setColor {marker color}  {
    send $marker "markpos;
	set lineColor $color;  set highlightColor $color; redraw"
}

# Callback executed when a marker gets or loses the focus.
proc selectMarker {active_marker event event_data} \
{
    global marker
    switch $event {
	focusIn		{ set marker $active_marker }
	focusOut	{  }
    }
}

# Create marker action.  Makes a new marker.
proc makeMarker {parent x y} \
{
    global markerTranslations markno
    set marker marker$markno;  incr markno

    send $parent createMarker $marker \
	type		rectangle \
	createMode	interactive \
	translations	$markerTranslations \
	x		$x \
	y		$y

    send $marker addCallback selectMarker focusIn focusOut
}


     
# WCSBOX -- Real time coordinate display.

set track_enable 	0
set last_x		0
set last_y		0

proc wcsUpdate {x y} \
{
    global track_enable frame pixtab_up tabTop
    global frameWidth frameHeight redraw_compass
    global ism_enable wcsLabels last_x last_y
    global ct_warn plotSpeed doHcut doVcut


    # If the cursor was frozen release it now.
    if {$ct_warn} {
	curtrack_destroy
    }

    # Convert screen coords to raster pixel.
    send imagewin unmapPixel $x $y raster rx ry rz

    # Set the current frame to the frame the pointer is within.
    if {$frame && $raster} {
	set track_frame [send client getFrame $raster]
	if {$frame != $track_frame} {
	    send client setFrame $track_frame
	}
    }

    # Update coords box.
    if {$raster} {
        set text [send client encodewcs $rx $ry $rz]
        scan $text "%g %g %g" nx ny nz
    } else {
        set text [format " %7.2f %7.2f %9.1f " $rx $ry $rz]
        set nx $rx ; set ny $ry ; set nz $rz
    }
	
    # Update the coords panel and pixel table.
    wcsFmtSValue $nz
    if {$pixtab_up} {
        updatePixelTable $x $y $nx $ny
    }

    # If the ISM is running update the coords box with all the selected
    # options, otherwise just write the one-line frame wcs coords.
    if {$ism_enable} {
        updateCoordsBox

    } else {
	# Update the on-screen marker.
        if {$track_enable} {
	    send wcsbox "set text \{$text\}; redraw noerase"
	}

	# Update the control panel readout (always done).
	if {$wcsLabels} {
	    set ln [format "   X: %12s     Y: %12s  WCS: Display" $nx $ny]
	} else {
	    set ln [format "      %12s        %12s       Display" $nx $ny]
	}
	send wtWcs1 set string $ln

	if {$redraw_compass} \
	    drawCompass
    }


    # Update the cut-plots if enabled.  If we're set for speed the don't 
    # track the really large cursor motions, wait till the differences are
    # small indicating a finer motion. 
    if {$doHcut || $doVcut} {
	set dist [ expr "sqrt(pow(($last_x - $x),2) + pow(($last_y - $y),2))" ]
	if {($plotSpeed && $dist < 30) || ! $plotSpeed} {
	    cutPlots $x $y
	}
    }

    # Save the position so we can track differences with last position.
    set last_x 	$x
    set last_y 	$y
}


proc setTrack {state} \
{
    global ism_enable track_enable wcsboxGeom
    global winWidth winHeight up_todo

    if {$state} {
	if {$track_enable} \
	    return

	send imagewin createMarker wcsbox {
	    type		text
	    createMode		noninteractive
	    width		27ch
	    height		1ch
	    lineWidth		0
	    imageText		true
	    textBgColor		black
	    textColor		yellow
	    visible		false
	}

	set box_width [send wcsbox get width]
	set box_height [send wcsbox get height]
	set defGeom [format "%sx%s-5-5" $box_width $box_height]
	send imagewin parseGeometry $wcsboxGeom $defGeom x y width height

	send wcsbox setAttributes    \
	    x			$x   \
	    y			$y   \
	    activated		true \
	    visible		true \
	    sensitive		true

	send wcsbox {
	    addCallback wcsboxDestroyCallback destroy
	    addCallback wcsboxMoved moveResize
	}

	send imagewin addCallback wcsboxWindowResize resize
	set track_enable 1
	send imagewin getCursorPos x y
	wcsUpdate $x $y
	magnifierMapImage $x $y

	# Turn on the option toggles on the control panel.
	foreach n {1 2 3 4} { 
	    if {[send sysWcs$n get label] != "None"} {
	        send wiWcs$n set on True
	    }
	}
	if {$ism_enable} {
	    resizeCoordsBox $up_todo
	}

    } elseif {$track_enable} {
	set track_enable 0
	send wcsbox destroy

	# Turn off the option toggles on the control panel.
	foreach w {wiWcs1 wiWcs2 wiWcs3 wiWcs4} { send $w set on False }
	resizeCoordsBox 0
    }
    updateCoordsBox
}

proc wcsboxDestroyCallback args \
{
    global track_enable
    send imagewin deleteCallback wcsboxWindowResize
    set track_enable 0
}

# If the window is resized make the wcsbox track the corner.
proc wcsboxWindowResize args \
{
    global track_enable
    global wcsboxGeom

    if {$track_enable} {
	# Get new location.
	set box_width [send wcsbox get width]
	set box_height [send wcsbox get height]
	set defGeom [format "%sx%s-5-5" $box_width $box_height]
	send imagewin parseGeometry $wcsboxGeom $defGeom x y width height

	# Move the marker.
	send wcsbox "\
	    deleteCallback wcsboxMoved; \
	    markpos; setAttributes x $x y $y; redraw; \
	    addCallback wcsboxMoved moveResize"
        set wcsboxGeom [send imagewin getGeometry $x $y $width $height]
    }
}

proc wcsboxMoved {marker event position} \
{
    global wcsboxGeom
    send wcsbox getRect boundary x y width height
    set wcsboxGeom [send imagewin getGeometry $x $y $width $height]
}

proc resetWcsbox {param old new} \
{
    global track_enable wcsboxGeom displayCoords
    if {$new == "done"} {
	setTrack [true $displayCoords]
    } elseif {$track_enable} {
	setTrack 0
	if {$new == "restart"} {
	    set wcsboxGeom -5-5
	}
    }
}; send initialize addCallback resetWcsbox



#---------------------
# FRAME BLINK.
#---------------------
set blinkId 0
set blinkIndex 0

proc toggleBlink args \
{
    global blinkId blinkRate blinkIndex
    global optionsMenuDescription

    if {$blinkId} {
	deleteTimedCallback $blinkId
	set blinkId 0
    } else {
	set blinkId [postTimedCallback blink [expr int($blinkRate * 1000)]]
    }

    set blinkIndex 0
    editMenu optionsMenu viewButton $optionsMenuDescription
}

proc blink args \
{
    global blinkId blinkRate blinkFrames blinkIndex

    send client setFrame [lindex $blinkFrames $blinkIndex]
    incr blinkIndex
    if {$blinkIndex >= [llength $blinkFrames]} {
	set blinkIndex 0
    }

    set blinkId [postTimedCallback blink [expr int($blinkRate * 1000)]]
}

proc resetBlink args \
{
    global blinkId
    if {$blinkId} \
	toggleBlink
}; send initialize addCallback resetBlink



# Normalize -- Reset the view parameters for the current frame.
proc normalize args \
{
    global zoomindex zoomfactor
    global frameWidth frameHeight
    global xcen ycen frame

    #set zoomindex($frame) 0
    #set xcen [expr $frameWidth / 2]
    #set ycen [expr $frameHeight / 2]
    #send client zoom 1 1 $xcen $ycen
    send client updateColormap 0.5 1.0
}


# Popdown menus.
createMenu fileMenu fileButton {
    {	"Info"		f.exec { panelTabToggle info_panel 	} }
    {	"Load"		f.exec {
			    panelTabToggle load_panel
	    		    set panel_up 1
			}					  }
    {	"Save"		f.exec { Save 				} }
    {	"Save As..."	f.exec { panelTabToggle save_panel 	} }
    {	"Print"		f.exec { 
			    send imagewin setCursorType busy
			    Print
			    send imagewin setCursorType idle
			}					  }
    {	"Print Setup"	f.exec { panelTabToggle print_panel 	} }
    {			f.dblline				  }
    {	"Reset"		f.exec {
			    # Do a hard reset.
			    send client Reset
			    #resetView initialize done done
			}					  }
    {	"Debug Panel"	f.exec { tclPanel 1			} }
    {	"Quit"		f.exec { Quit				} }
}

createMenu viewMenu viewButton {
    {	"Next frame"	f.exec nextFrame		}
    {	"Prev frame"	f.exec prevFrame		}
    {			f.dblline			}
    {	"Colormap"	f.menu cmapMenu			}
    {	"Flip"		f.menu flipMenu			}
    {			f.dblline			}
    {	"Equal aspect"	f.exec {
			    set xmag $frameZoomX($frame)
			    set ymag $frameZoomY($frame)
			    set zoom [expr ($xmag + $ymag) / 2.0]
			    cpZoom $zoom $zoom fixed
			}				}
    {	"Integer zoom"	f.exec {
			    set xmag [expr round ($frameZoomX($frame))]
			    set ymag [expr round ($frameZoomY($frame))]
			    cpZoom $xmag $ymag fixed
			}				}
    {	"Toggle zoom"	f.exec toggleZoom		}
    {	"Unzoom"	f.exec {
			    set zoomindex($frame) 0
			    set mag $zoomfactor($zoomindex($frame))
			    send client zoom $mag $mag $xcen $ycen
			}				}
}

createMenu cmapMenu viewMenu {
    {	"Normalize"	f.exec normalize	}
    {	"Invert"	f.exec cpInvert		}
    {	"Optimize"	f.exec cpOptimize	sensitive false }
    {			f.dblline		}
    {	"Grayscale"	f.exec "send client setColormap Grayscale" }
    {	"Color"		f.exec "send client setColormap Color" }
    {	"Heat"		f.exec "send client setColormap Heat" }
    {	"HSV"		f.exec "send client setColormap HSV" }
    {	"AIPS0"		f.exec "send client setColormap AIPS0" }
    {	"Halley"	f.exec "send client setColormap Halley" }
    {	"Ramp"		f.exec "send client setColormap Ramp" }
    {	"Standard"	f.exec "send client setColormap Standard" }
    {	"Staircase"	f.exec "send client setColormap Staircase" }
    {	"Rainbow1"	f.exec "send client setColormap Rainbow1" }
    {	"Rainbow2"	f.exec "send client setColormap Rainbow2" }
    {	"Random8"	f.exec "send client setColormap Random8" }
}

createMenu flipMenu viewMenu {
    {	"Flip X"	f.exec xflip		}
    {	"Flip Y"	f.exec yflip		}
    {	"Flip XY"	f.exec xyflip		}
}

set optionsMenuDescription {
    {	"Autoscale"	f.exec {
			    set value [send autoscaleButton get on]
			    send autoscaleButton set on [expr !$value]
			    cpSetAutoscale
			}			}
    {	"Antialias"	f.exec {
			    set value [send antialiasButton get on]
			    send antialiasButton set on [expr !$value]
			    cpSetAntialias
			}			}
    {	"Panner"	f.exec { setPanner [expr !$panner_enable] }	}
    {	"Magnifier"	f.exec { setMagnifier [expr !$magnifier_enable] }}
    {	"Coords box"	f.exec { setTrack [expr !$track_enable] }	}
    {	"Tile frames"	f.exec {
			    set value [send tileFramesButton get on]
			    send tileFramesButton set on [expr !$value]
			    cpSetTileFrames
			}			}
    {	"Clear frame"	f.exec clearFrame	}
    {	"Fit frame"	f.exec fitFrame		}
    {	"Match LUTs"	f.exec cpMatchFrames	}
    {	"Auto-Register"	f.exec cpAutoRegister	}
    {	"Register"	f.exec cpRegisterFrames	}
    {	{$blinkId ? "Stop blink" : "Blink frames"}
			f.exec toggleBlink	}
    {			f.dblline		}
    {   "Control Panel"	f.exec  { panelTabToggle display_panel	} }
    {   "Print Panel"	f.exec  { panelTabToggle print_panel	} }
    {   "Load Panel"	f.exec  { panelTabToggle load_panel	} }
    {   "Save Panel"	f.exec  { panelTabToggle save_panel	} }
}; createMenu optionsMenu optionsButton $optionsMenuDescription



#-------------------------------
# Frozen Cursor Warning Message
#-------------------------------

set ct_warn	0

proc curtrack_msg { x y args } \
{
    global ct_warn last_x last_y winHeight winWidth


    if {! $ct_warn == 0} {
	return
    }
        
    send imagewin createMarker curtrack_warn {
        type                text
        createMode          noninteractive
        width               25ch
        height              21
        lineWidth           0
        imageText           true
        textBgColor         red
        textColor           yellow
        visible             true
        sensitive           true
        activated           true
	x		    5
	y		    5
    }

    send curtrack_warn "set text \{  CURSOR READOUT FROZEN  \}"
    set ypos [ expr ($winHeight - 25) ]
    send curtrack_warn "markpos; setAttributes x 5 y $ypos; redraw"
    send curtrack_warn "redraw noerase"
    set ct_warn 1

    # Mark the position of the cursor.
    send imagewin createMarker x_curpos \
        type            box \
        createMode      noninteractive \
        lineColor       red \
        x               1 \
        y               $last_y \
        width           $winWidth \
        height          1 \
        activated       True \
        visible         True \
        sensitive       False

    send imagewin createMarker y_curpos \
        type            box \
        createMode      noninteractive \
        lineColor       red \
        x               $last_x \
        y               1 \
        width           1 \
        height          $winHeight \
        activated       True \
        visible         True \
        sensitive       False

    # Raise the coordinate marker so we can see where we are.
    send wcsbox raise
}


proc curtrack_destroy args \
{
    global ct_warn

    if {$ct_warn} {
	send curtrack_warn destroy
	send x_curpos destroy
	send y_curpos destroy
	set ct_warn 0
    }
}


################################################################################
# CURSOR CENTEROID AND AUTO-REGISTER FUNCTIONS.
################################################################################

# Set the centroiding box size.
set ctid	0
set cid		0

proc cbxDestroy args \
{
    global centerBoxSize cid ctid
    catch { 
	if {$ctid != 0} {
	    send cbm$cid destroy 
	    deleteTimedCallback $ctid
	    set ctid 0
	}
    }
}

proc setCtrBoxSize { x y delta args } \
{
    global centerBoxSize cid ctid
    global cpXscale cpYscale

    incr centerBoxSize $delta
    if {$centerBoxSize <= 1} { set centerBoxSize 1 }

    # Kill off any old markers before drawing the new one.
    catch { 
	if {$ctid != 0} {
	    send cbm$cid destroy 
	    deleteTimedCallback $ctid
	    set ctid 0
	}
    }

    # create a transient marker indicating the centering box and post a
    # callback to delete it in about a second.
    incr cid
    send imagewin createMarker cbm$cid \
	type            box \
	createMode      noninteractive \
	lineColor       red \
	x               $x \
	y               $y \
	width           [expr $cpXscale * $centerBoxSize] \
	height          [expr $cpXscale * $centerBoxSize] \
	activated       True \
	visible         True \
	sensitive       False

    set ctid [ postTimedCallback cbxDestroy 500]
}


# Box size is half-width of the marker size.  Value is the slider value.
set focusBoxSize	$winWidth			
set focusValue	       100.0
set fid			 0
set ftid		 0
set moving		 0

proc setFocusBoxSize { sz args } \
{
    global focusBoxSize fid ftid focusValue moving
    global winWidth winHeight


    if { $moving == 0 } {
        return done
    }

    if { $winWidth < $winHeight } {
	set max [expr $winWidth / 2 - 64]
    } else {
	set max [expr $winHeight / 2 - 64]
    }
    set focusBoxSize [expr 64 + ($sz * $max) - 1]
    #send client setOption cmfocus [expr ($focusBoxSize / 2)]
    send client setOption cmfocus $focusBoxSize

    # Destroy any existing markers.
    catch { 
        if {$ftid != 0} {
            send fm$fid destroy 
            set ftid 0
	}
    }

    # create a transient marker indicating the centering box and post a
    # callback to delete it in about a second.
    incr fid
    send imagewin createMarker fm$fid \
	type            box \
	createMode      noninteractive \
	lineColor       green \
	lineWidth       4 \
	x               [expr $winWidth / 2] \
	y               [expr $winHeight / 2] \
	width           $focusBoxSize \
	height          $focusBoxSize \
	activated       True \
	visible         True \
	sensitive       False

    set ftid [ postTimedCallback fbxDestroy 500]
    set moving  0
}

proc fbxDestroy args \
{
    global fid ftid moving
    catch { 
        if {$ftid != 0} {
            send fm$fid destroy 
            set ftid 0
        }
    }
}

proc setFocusSize { widget cbtype x y } \
{
    global focusValue ftid moving

    # Only update once we've stopped the movement.
    if { $x == $focusValue && $moving == 1 } {
	set ftid [ postWorkProc setFocusBoxSize $x ]
    } else {
        set moving  1
    }
    set focusValue $x
} ; send focusSlider addCallback setFocusSize scroll


# Compute a centroid offset for the current position to peak-up on the
# feature.

proc centroid { x y type args } \
{
    global centerBoxSize
    global cpXscale cpYscale

    # Convert to image coords.
    set sz [expr "int ($centerBoxSize * $cpXscale)"]

    # Get the centroid position.
    if {$type != "min"} {
        if {[send peakupButton get on]} {
            set center [ send client centroid $x $y $sz ]
        } else {
            set center [ send client centroid $x $y $sz max ]
        }
    } else {
        set center [ send client centroid $x $y $sz min ]
    }

    # Now reposition the cursor.
    set xoff [lindex $center 0 ]
    set yoff [lindex $center 1 ]
    move_cursor $xoff $yoff
}


# Set the auto-register center offset position
proc offset { x y args } \
{
    global frame blinkFrames auto_reg
    global frameCenterX frameCenterY
    global frameOffsetX frameOffsetY

    # No-op of auto-register isn't on.
    if { $auto_reg == 0 } {
	Wexec client "Auto-Register is not enabled!"
	return
    }

    # If we're not in the blink frames list ignore the request.
    if { [string first $frame $blinkFrames] == -1 } {
	Wexec client "Frame not in current\nregister list."
	return
    }

    set rx $x;  set ry $y
    set raster 0

    # Convert raw screen coordinates to frame buffer raster coordinates.
    send imagewin unmapPixel $x $y raster rx ry

    # Select a pixel.
    set xoff  [expr "int ($rx) - $frameCenterX($frame)" ]
    set yoff  [expr "int ($ry) - $frameCenterY($frame)" ]

    set frameOffsetX($frame)  $xoff
    set frameOffsetY($frame)  $yoff

    # Adjust the display.
    send client setOffset $xoff $yoff
}



################################################################################
# MAIN CONTROL PANEL
################################################################################


# Global control panel buttons.
# -------------------------------
proc cpInitialize args \
{
    send imagewin setCursorType busy
    send client initialize
    send imagewin setCursorType idle
}
send initializeButton 	addCallback cpInitialize
send normalizeButton 	addCallback normalize

# Temporarily deactivate some buttons.
send optimizeButton setSensitive false

#-----------------------------------------------------------------------------

foreach i $frames {set saveView($i) "1 1"}

send prevFrame 		set bitmap larrow
send nextFrame 		set bitmap rarrow
send contrastLabel	set bitmap contrast
send brightnessLabel	set bitmap brightness
send contrastSlider	resizeThumb 0.1 1.0
send brightnessSlider	resizeThumb 0.1 1.0
send focusSlider	"resizeThumb 0.1 1.0 ; moveThumb 1.0"


# panel -- Toggle control panel display.
proc panel args \
{
    global panel_up
    if {$panel_up} {
	send panelShell unmap
	set panel_up 0
    } else {
	send panelShell map
	set panel_up 1
    }
}

proc pbTracePanel {name element op} \
{
    catch {
        upvar $name panel_up
        send controlButton set state $panel_up
    }
} ; trace variable panel_up w pbTracePanel


# resetPanel -- Calling during startup or in an initialize, to reset things.
proc resetPanel {param old new} \
{
    global frame nframes frames
    global displayPanner displayMagnifier displayCoords
    global blinkFrames warnings peakCentroid

    switch $new {
    startup	{
		}
    restart	{   foreach i $frames {
			send frame$frame set on 0
		    }

		    # Initialize to hide the extra frames.
		    send frlistBox set width 30
		}
    done	{   if {$frame} {
			send frame$frame set on 1
		    }

		    cpResetBlink
		    set button 1
		    foreach i {1 2 3 4} {
			send blinkFrame$button set label $i
			incr button
		    }
		    for {set i 1} {$i <= 16} {incr i} {
			send brFrame$i set label $i
		    }

		    cpResetEnhance
		    send pannerButton set on [true $displayPanner]
		    send magnifierButton set on [true $displayMagnifier]
		    send coordsBoxButton set on [true $displayCoords]
		    send warningsButton set on $warnings
		    send peakupButton set on [true $peakCentroid]
		}
    }
}; send initialize addCallback resetPanel



#  Control Panel Tabs widget procedures.
#----------------------------------------

set cpTabs   { display_panel print_panel load_panel save_panel \
	       info_panel wcs_panel tile_panel}
set tabTop   "display_panel"


# Resize the control panel depending on the Tab selected.
proc cpResizeCB { widget event a b c d e args } \
{
    global tabTop fileList

    # Handle only the first exposure event generated.
    if { $a == 0 && $b == 0 && $c == 0 && $d == 0 && $e == 0 } {
	set tabTop $widget

	switch $widget {
	display_panel   { send panel set height 595 }
	print_panel     { send panel set height 545 }
	load_panel      { send panel set height 485 
			  if { [send browseHdrs get on] } {
			      send imageList setList $fileList resize
			  } else {
        		      send client setLoadOption rescan
			  }
        		}
	save_panel      { send panel set height 325 }
	info_panel      { send panel set height 380 }
	tile_panel      { send panel set height 405 }
	wcs_panel       { setCoordPanelHeight	    }
	}
    }
} ; foreach w $cpTabs {  send $w addEventHandler cpResizeCB exposureMask }


proc panelDismiss args \
{
    global panel_up
    send panelShell unmap
    set panel_up 0
} ; send panelClose addCallback panelDismiss


proc panelTabToggle { panel args } \
{
    global tabTop panel_up TabToWidget

    if {$tabTop == $panel && $panel_up} {
	send panelShell unmap
	send $TabToWidget($panel) set state 0
	set panel_up 0

    } else {
        # Special cases for each panel.
        if {$panel == "load_panel"} {
            send client setLoadOption rescan
        }

        send panelTabs setTop $panel
        set tabTop $panel

        # Now fire it up if it's not already open.
        if {$panel_up == 0} {
	    send panelShell map
	    set panel_up 1
        }

    }
}

proc displayPanel args  { panelTabToggle display_panel }
proc infoPanel args     { panelTabToggle info_panel    }
proc loadPanel args     { panelTabToggle load_panel    }
proc savePanel args     { panelTabToggle save_panel    }
proc printPanel args    { panelTabToggle print_panel   }
proc tilePanel args     { panelTabToggle tile_panel    }
proc wcsPanel args      { panelTabToggle wcs_panel     }




# Frame selection.
# -------------------------------
proc cpSetFrame {widget args} \
{
    send $widget set on 0
    send client setFrame [send $widget get label]
}

proc cpFrameChanged {param old new} \
{
    global frameCache

    if {$old > 0} {
	send frame$old set on 0
    }
    if {$new > 0} {
	send frame$new set on 1
    }

    # The first time we request frame 5 or higher reset 
    # the extra frame buttons on the control panel to make
    # them visible.
    if {$new >= 5} {
	send frlistBox set width 49
    }

    # Update the header panel object list.
    catch {
	# Only update when the header panel is open.
        if {[info exists frameCache($new)] && [send imageHeader get on]} {
            setHdrObjMenu $new
            getHeader [lindex $frameCache($new) 0] [lindex $frameCache($new) 1]
        }
    }
}

send prevFrame addCallback prevFrame
send nextFrame addCallback nextFrame
send frame addCallback cpFrameChanged
for {set i 1} {$i <= 16} {incr i} {send frame$i addCallback cpSetFrame}

# Initialize to hide the extra frames.
send frlistBox  set width 30

proc blinkPanelCB { widget type state args } \
{
    if {$state} {
	send blink_panel map
    } else {
	send blink_panel unmap
    }
} ; send blinkPanel addCallback blinkPanelCB

proc blinkPanelClose args \
{
    send blink_panel unmap
    send blinkPanel set state 0
} ; send brClose addCallback blinkPanelClose



# Frame buttons.
proc cpFrameAction {widget args} \
{
    global frameZoomX frameZoomY frame
    switch $widget {
    aspect	{   set xmag $frameZoomX($frame)
		    set ymag $frameZoomY($frame)
		    set zoom [expr round (($xmag + $ymag) / 2.0)]
		    cpZoom $zoom $zoom fixed
		}
    flipX	{   send client flip x }
    flipY	{   send client flip y }
    flipXY	{   send client flip x y }
    clearFrame	{   clearFrame }
    fitFrame	{   fitFrame }
    }
}
foreach widget {aspect flipX flipY flipXY clearFrame fitFrame} {
    send $widget addCallback cpFrameAction
}

# clearFrame -- Clear the current display frame.
proc clearFrame	args \
{
    global warnings
    if {$warnings} {
	Wexec client \
	    "Clearing the frame will destroy\n\
	    all data in the frame" \
	    clearFrame
    } else {
	send client clearFrame
    }
}

# fitFrame -- Resize the display window to fit the frame buffer.
proc fitFrame args \
{
    global frameWidth frameHeight winWidth winHeight
    set dw [expr [send display get width] - $winWidth]
    set dh [expr [send display get height] - $winHeight]
    send display "resize [expr $frameWidth + $dw] [expr $frameHeight + $dh]"
}

proc initFitFrame { param old new } \
{
    if { [lindex $new 0] == "resize"} {
	fitFrame
    }
    pannerMapImage init
}; send frameFit addCallback initFitFrame



# Zoom and pan buttons.
# -------------------------------
proc cpZoomAction {widget args} \
{
    global frameWidth frameHeight

    switch $widget {
    x1		{   cpZoom 1 1 fixed }
    z2		{   cpZoom 2 2 fixed }
    z3		{   cpZoom 3 3 fixed }
    z4		{   cpZoom 4 4 fixed }
    z5		{   cpZoom 5 5 fixed }
    z8		{   cpZoom 8 8 fixed }

    d2		{   cpZoom [expr 1.0/2] [expr 1.0/2] fixed }
    d3		{   cpZoom [expr 1.0/3] [expr 1.0/3] fixed }
    d4		{   cpZoom [expr 1.0/4] [expr 1.0/4] fixed }
    d5		{   cpZoom [expr 1.0/5] [expr 1.0/5] fixed }
    d8		{   cpZoom [expr 1.0/8] [expr 1.0/8] fixed }

    zoomIn	{   cpZoom 2.0 2.0 relative }
    zoomOut	{   cpZoom 0.5 0.5 relative }

    centerFrame	{   send client pan \
			[expr $frameWidth/2.0] \
			[expr $frameHeight/2.0]
		}
    toggleZoom	{   toggleZoom }
    }
}

proc cpZoom {zoom_x zoom_y mode} \
{
    global frameZoomX frameZoomY zoomindex frame
    global frameOffsetX frameOffsetY frameCenterX frameCenterY

    if {$mode == "fixed"} {
	#send client zoom $zoom_x $zoom_y
	send client zoomAbs $zoom_x $zoom_y \
	    $frameCenterX($frame) $frameCenterY($frame) \
	    $frameOffsetX($frame) $frameOffsetY($frame)
    } else {
	#send client zoom \
	#    [expr $frameZoomX($frame) * $zoom_x] \
	#    [expr $frameZoomY($frame) * $zoom_y]
	send client zoomAbs \
	    [expr $frameZoomX($frame) * $zoom_x] \
	    [expr $frameZoomY($frame) * $zoom_y] \
	    $frameCenterX($frame) $frameCenterY($frame) \
	    $frameOffsetX($frame) $frameOffsetY($frame)
    }

    set zoomindex($frame) 0
}

proc toggleZoom	args \
{
    global frameZoomX frameZoomY frameCenterX frameCenterY
    global frameWidth frameHeight saveView frame

    if {$frameZoomX($frame) != 1 && $frameZoomY($frame) != 1} {
	set saveView($frame) \
	    "$frameZoomX($frame) $frameZoomY($frame) \
	     $frameCenterX($frame) $frameCenterY($frame)"
	send client zoom 1 1 \
	    [expr $frameWidth/2.0] \
	    [expr $frameHeight/2.0]
    } else {
	send client zoom $saveView($frame)
    }
}

foreach widget { toggleZoom centerFrame zoomIn zoomOut \
	x1  z2 z3 z4 z5 z8  d2 d3 d4 d5 d8  } {
    send $widget addCallback cpZoomAction
}

# Frame data display.
# -------------------------------
set cpFrame  0
set cpXcen   0
set cpYcen   0
set cpXmag   0
set cpYmag   0
set cpXscale 0
set cpYscale 0
set cpXoff   0
set cpYoff   0

proc cpDisplayFrameData {name old new} \
{
    global cpFrame cpXcen cpYcen cpXoff cpYoff
    global cpXmag cpYmag cpXscale cpYscale

    set update 0
    switch $name {
    frame	{   if {$new != $cpFrame} {
			set cpFrame $new
			set update 1
		    }
		}
    frameView	{   # Parse the frameView input.
		    set xmag  [lindex $new 0]; set ymag  [lindex $new 1]
		    set xcen  [lindex $new 2]; set ycen  [lindex $new 3]
		    set xnorm [lindex $new 4]; set ynorm [lindex $new 5]
		    set xoff  [lindex $new 6]; set yoff  [lindex $new 7]

		    # We need client coords and the overall scale factors.
		    set text [send client encodewcs $xcen $ycen]
		    set xcen [lindex $text 0]
		    set ycen [lindex $text 1]
		    set xscale [expr $xmag * $xnorm]
		    set yscale [expr $ymag * $ynorm]

		    if {$xcen != $cpXcen || $ycen != $cpYcen ||
			$xmag != $cpXmag || $ymag != $cpYmag ||
			$xoff != $cpXoff || $yoff != $cpYoff ||
			$xscale != $cpXscale || $yscale != $cpYscale} {

			    set cpXcen $xcen;  set cpXscale $xscale
			    set cpYcen $ycen;  set cpYscale $yscale
			    set cpXmag $xmag;  set cpXoff   $xoff;  
			    set cpYmag $ymag;  set cpYoff   $yoff;
			    set update 1
		    }
		}
    }

    if {$update} {
	set header [format "-- Frame %d --" $cpFrame]
	set center [format "X center: %0.1f\nY center: %0.1f" $cpXcen $cpYcen]
	if {int($cpXmag) >= 10} {
	    set zoom1 [format " X zoom: %0.1f" $cpXmag]
	    set zoom2 [format " Y zoom: %0.1f" $cpYmag]
	} else {
	    set zoom1 [format "X zoom: %0.1f" $cpXmag]
	    set zoom2 [format "Y zoom: %0.1f" $cpYmag]
	}
	if {int($cpXscale) >= 10} {
	    set scale1 [format "X scale: %0.1f" $cpXscale]
	    set scale2 [format "Y scale: %0.1f" $cpYscale]
	} else {
	    set scale1 [format "X scale: %0.2f" $cpXscale]
	    set scale2 [format "Y scale: %0.2f" $cpYscale]
	}
	set offset [format "  Offset: (%0.1f,%0.1f)" $cpXoff $cpYoff]

	send frameData set label [format "%s\n%s\n%s\n%s\n%s\n%s\n%s" \
	    $header $center $scale1 $scale2 $zoom1 $zoom2 $offset \
	]
    }
}; foreach p {frame frameView} {send $p addCallback cpDisplayFrameData}


# Frame enhancement.
# -------------------------------
set cpEnhanceDisable 0
set cpEnhanceId 0
set cpEnhanceMode none
set cpEnhanceVal 0
set cpListItem none

# Windowing the colormap is slow when the mouse is not in the image window,
# so it is necessary to execute the windowColormap in a work procedure.
# This allows any number of slider motion events to be processed for each
# windowColormap, preventing slider events from queueing up.

proc cpResetEnhance args \
{
    global cpListItem cpEnhanceId
    set cpListItem none
    set cpEnhanceId 0
}

proc cpSetEnhancement {widget cbtype x y} \
{
    global cpEnhanceMode cpEnhanceVal cpEnhanceId cpEnhanceDisable
    set cpEnhanceMode $widget
    set cpEnhanceVal $x
    if {!$cpEnhanceId && !$cpEnhanceDisable} {
	set cpEnhanceId [postWorkProc cpEnhanceProc]
    }
}
proc cpEnhanceProc args \
{
    global cpEnhanceMode cpEnhanceVal cpEnhanceId
    global enhancement frame maxContrast
    set val $cpEnhanceVal

    if {$cpEnhanceMode == "contrastSlider"} {
	set contrast [lindex $enhancement($frame) 2]
	send client windowColormap [lindex $enhancement($frame) 1] \
	    [expr (($contrast < 0) ? -$val : $val) * $maxContrast] 
    } else {
	send client windowColormap $val
    }

    set cpEnhanceId 0
    return done
}

proc cpInvert args \
{
    global enhancement frame
    set contrast [lindex $enhancement($frame) 2]
    send client updateColormap [lindex $enhancement($frame) 1] \
	[expr -1.0 * $contrast]
}

proc cpDisplayEnhancement {param old new} \
{
    global cpEnhanceId maxContrast cpEnhanceDisable
    global cpListItem enhancement frame

    if {!$frame} \
	return
    set enhance $enhancement($frame)
    if {[llength $enhance] < 3} \
	return

    set colortable [lindex $enhance 0]
    set offset     [lindex $enhance 1]
    set scale      [lindex $enhance 2]

    send colordata set label [format "-- %s --\nCon %0.2f  Brt %0.2f" \
	$colortable $scale $offset]

    if {$colortable != $cpListItem} {
	send colorlist highlight $colortable
	set cpListItem $colortable
    }

    if {!$cpEnhanceId && !$cpEnhanceDisable} {
	set cpEnhanceDisable 1
	send contrastSlider moveThumb [expr abs($scale) / $maxContrast]
	send brightnessSlider moveThumb $offset
	set cpEnhanceDisable 0
    }
}

foreach i {enhancement frame} {
    send $i addCallback cpDisplayEnhancement
}
send contrastSlider addCallback cpSetEnhancement scroll
send brightnessSlider addCallback cpSetEnhancement scroll
send invertButton addCallback cpInvert


# Colortable display and selection.
# -------------------------------
set colorTables	   {}

proc cpSetColorList {param old new} \
{
    set colorTables $new
    send colorlist setList $new resize
}; send colortables addCallback cpSetColorList

proc colorlistResize args \
{
    global colorTables
    send colorlist setList $colorTables resize
}; send colorlist addEventHandler colorlistResize ResizeRedirectMask

proc cpSelectColor {widget cbtype selections indices} \
{
    global colortable
    foreach selection $selections {
	send client setColormap $selection
    }
}; send colorlist addCallback cpSelectColor
    

# Frame blink.
# -------------------------------
send BRtext   set label $blinkRate
send brBRtext set label $blinkRate

proc cpSetBlinkRate {w args} \
{
    global blinkRate
    if {$w == "BRincrease" || $w == "brBRincrease"} {
	if {$blinkRate < 0.01} {
	    set blinkRate 0.125
	} else {
	    set blinkRate [expr $blinkRate * 2.0]
	}
    } else {
	set blinkRate [expr $blinkRate / 2.0]
	if {$blinkRate < 0.01} {
	    set blinkRate 0
	}
    }
    send BRtext   set label $blinkRate
    send brBRtext set label $blinkRate
}
foreach w {BRincrease BRdecrease brBRincrease brBRdecrease} {
    send $w addCallback cpSetBlinkRate
}

proc cpSetBlinkFrame {widget args} \
{
    global blinkFrames frames nframes

    set frame [send $widget get label]
    if {$frame == " "} {
	set frame 1
    } else {
	incr frame
	if {$frame > $nframes} {
	    set frame " "
	}
    }
    send $widget set label $frame

    set blinkFrames {}
    foreach i {1 2 3 4} {
	set frame [send blinkFrame$i get label]
	if {$frame != " "} {
	    lappend blinkFrames $frame
	}
    }
}; foreach i {1 2 3 4} {send blinkFrame$i addCallback cpSetBlinkFrame}

proc cpBlink {widget args} \
{
    global blinkRate blinkId

    if {$blinkRate < 0.01} {
	send blinkButton set on False
	send brBlinkButton set on False
	blink
    } elseif {($blinkId != 0) != [send $widget get on]} {
	toggleBlink
    }
} ; foreach w {blinkButton brBlinkButton} {send $w addCallback cpBlink}


proc cpAutoRegister {widget type state args} \
{
    global auto_reg frame frames blinkFrames
    global frameZoomX frameZoomY frameOffsetX frameOffsetY

    set auto_reg $state
    if {$auto_reg == 1} {
	send autoregButton set on True
	send brAregButton set on True
    } else {
	send autoregButton set on False
	send brAregButton set on False
    }

    # Register the frames to zero the offsets.
    send client registerFrames \{$blinkFrames\}
    foreach f $frames {
	set frameOffsetX($f) 0
	set frameOffsetY($f) 0
    }
} ; foreach w {autoregButton brAregButton} {send $w addCallback cpAutoRegister}


proc toggleAutoReg args \
{
    global auto_reg
    if {$auto_reg} {
	cpAutoRegister autoregButton dummy 0 
	set auto_reg 0
    } else {
	cpAutoRegister autoregButton dummy 1 
	set auto_reg 1
    }
}

proc resetAutoReg args \
{
    global auto_reg
    if {$auto_reg} \
	toggleAutoReg
}; send initialize addCallback resetAutoReg


proc cpResetBlink args \
{
    global blinkRate blinkFrames blinkIndex frames
    global defaultBlinkRate

    foreach i {1 2 3 4} {
	send blinkFrame$i set label " "
    }
    for {set i 1} {$i <= 16} {incr i} {
	send brFrame$i set label $i
    }
    set blinkRate $defaultBlinkRate
    send BRtext   set label $blinkRate
    send brBRtext set label $blinkRate
    set blinkIndex 0
} 
send blinkReset addCallback cpResetBlink
send brReset    addCallback cpResetBlink

proc cpTraceBlink {name element op} \
{
    upvar $name blinkId
    send blinkButton set on [expr $blinkId != 0]
    send brBlinkButton set on [expr $blinkId != 0]
}; trace variable blinkId w cpTraceBlink

proc cpSetBlinkFrames {param old new} \
{
    global blinkFrames frames

    set blinkFrames {}
    foreach i $frames {
	if {$i <= $new} {
	    lappend blinkFrames $i
	}
    }
    cpResetBlink
    set button 1
    for {set i 1} {$i <= $new} {incr i} {
	if {$i <= 4} {
	    send blinkFrame$button set label $i
	}
	send brFrame$button set label $i
	incr button
    }
}; send nframes addCallback cpSetBlinkFrames

proc cpRegisterFrames args \
{
    global frames blinkFrames
    global frameOffsetX frameOffsetY

    foreach f $frames {
	set frameOffsetX($f)  0
	set frameOffsetY($f)  0
    }
    send client registerFrames \{$blinkFrames\}
}
send registerButton addCallback cpRegisterFrames
send brRegButton    addCallback cpRegisterFrames

proc cpMatchFrames args \
{
    global blinkFrames
    send client matchFrames \{$blinkFrames\}
}
send matchButton   addCallback cpMatchFrames
send brMatchButton addCallback cpMatchFrames


# Options buttons.
# -------------------------------
proc cpSetPanner {widget args} \
{
    setPanner [send $widget get on]
}; send pannerButton addCallback cpSetPanner

proc cpTracePanner {name element op} \
{
    upvar $name panner_enable
    send pannerButton set on $panner_enable
}; trace variable panner_enable w cpTracePanner

proc cpSetMagnifier {widget args} \
{
    setMagnifier [send $widget get on]
}; send magnifierButton addCallback cpSetMagnifier

proc cpTraceMagnifier {name element op} \
{
    upvar $name magnifier_enable
    send magnifierButton set on $magnifier_enable
}; trace variable magnifier_enable w cpTraceMagnifier

proc cpSetCoordsBox {widget args} \
{
    setTrack [send $widget get on]
}; send coordsBoxButton addCallback cpSetCoordsBox

proc cpTraceCoordsBox {name element op} \
{
    upvar $name track_enable
    send coordsBoxButton set on $track_enable
}; trace variable track_enable w cpTraceCoordsBox

proc cpSetWarnings args \
{
    global warnings
    set warnings [send warningsButton get on]
}; send warningsButton addCallback cpSetWarnings

proc cpSetAutoscale args \
{
    set value [send autoscaleButton get on]
    send client setOption autoscale [expr {$value ? "True" : "False"}]
}; send autoscaleButton addCallback cpSetAutoscale

proc cpTrackAutoscale {param old new} \
{
    send autoscaleButton set on [true $new]
}; send autoscale addCallback cpTrackAutoscale

proc cpSetAntialias args \
{
    set value [send antialiasButton get on]
    send client setOption antialias [expr {$value ? "True" : "False"}]
}; send antialiasButton addCallback cpSetAntialias

proc cpTrackAntialias {param old new} \
{
    send antialiasButton set on [true $new]
}; send antialias addCallback cpTrackAntialias

proc cpSetTileFrames { widget type state args } \
{
    global tile_frames tileOpt

    set value [send tileFramesButton get on]
    if {$value} {
        selectTileOrientation junk junk [tileSelToLabel $tileOpt]
    } else {
        selectTileOrientation junk junk Disabled
    }
   send client setOption tileFrames \
	[expr {$value ? "True" : "False"}] \{ $tile_frames \}
} ; send tileFramesButton addCallback cpSetTileFrames

proc cpTrackTileFrames {param old new} \
{
    send tileFramesButton set on [true $new]
}; send tileFrames addCallback cpTrackTileFrames

proc tileFramesToggle args \
{
    set value [send tileFramesButton get on]
    send tileFramesButton set on [expr !$value]
    cpSetTileFrames
}


################################################################################
# MAGNIFIER.  A subraster around the cursor in the main image window is
# displayed at a high resolution in a marker (known as the magnifier window)
# within the main image window.
################################################################################

set magnifier_x 0
set magnifier_y 0
set magnifier_width 0
set magnifier_height 0
set mrm_width 0
set mrm_height 0

set magnifier_enable 0
set magnifier_mag_enable 0
set magnifier_mapping 0

createMenu magzoomMenu imagewin {
    {   "Zoom Factors"        	f.title                         }
    {                           f.dblline                       }
    {   "Zoom 1"                f.exec "setMagnifierZoom 1"     }
    {   "Zoom 2"                f.exec "setMagnifierZoom 2"     }
    {   "Zoom 4"                f.exec "setMagnifierZoom 4"     }
    {   "Zoom 8"                f.exec "setMagnifierZoom 8"     }
    {   "Zoom 16"               f.exec "setMagnifierZoom 16"    }
} 

# Magnifier window translations.
set magnifierWinTranslations { \
       !Shift <Btn1Motion>:	m_rotateResize()
	      <Btn1Motion>:	m_moveResize()
	 !Shift <Btn1Down>:	m_raise() m_markpos()
		<Btn1Down>:	m_raise() m_markposAdd()
		  <Btn1Up>:	m_redraw() m_destroyNull()
		<Btn2Down>:	m_lower()
		<Btn3Down>:     popup(magzoomMenu)
		  <Btn3Up>:     popdown(magzoomMenu)
	      !Ctrl <Key>m:     call(toggleMagnifier)
	      !Ctrl <Key>p:     call(togglePanner)
	    <Key>BackSpace:	m_deleteDestroy()
	       <Key>Delete:	m_deleteDestroy()
		<KeyPress>:     graphics-input()
		  <Motion>:	track-cursor() call(wcsUpdate,$x,$y)
}


# setMagnifier -- Turn the magnifier on or off.

set magAlreadyOn	0

proc setDynamicMagnifier {state} \
{
    global magAlreadyOn magnifier_enable

    if {$state} {
	set magAlreadyOn $magnifier_enable
    }
    if {$magAlreadyOn} {
	return
    } else {
	setMagnifier $state
    }
}

proc toggleMagnifier args \
{
    global magnifier_enable
    if {$magnifier_enable} {
	setMagnifier 0
    } else {
	setMagnifier 1
    }
}


proc setMagnifier {state} \
{
    global winWidth winHeight frameWidth frameHeight
    global frame magnifier_mapping magnifierWinTranslations magnifierArea
    global magnifier_enable magnifier_height
    global magnifierGeom magnifier_x magnifier_y magnifier_width

    if {$state} {
	if {$magnifier_enable} \
	    return

	# Determine where to place the magnifier.
	set scale  [expr sqrt(double($magnifierArea) / (512 * 512))]
	set scaled_width [expr int(512 * $scale) / 2 * 2 + 1]
	set scaled_height [expr int(512 * $scale) / 2 * 2 + 1]
	set defGeom [format "%sx%s-5+5" $scaled_width $scaled_height]
	send imagewin parseGeometry $magnifierGeom $defGeom x y width height

	# Create the main magnifier window (marker).
	send imagewin createMarker magnifierWin \
	    type		rectangle \
	    createMode		noninteractive \
	    width		[expr $width / 2] \
	    height		[expr $height / 2] \
	    x			[expr $x + $width / 2] \
	    y			[expr $y + $height / 2] \
	    lineColor		8 \
	    highlightColor	8 \
	    translations	$magnifierWinTranslations \
	    visible		true \
	    sensitive		true \
	    activated		true

	# Update the magnifier window position variables so that it comes up
	# in the same place the next time.

	send magnifierWin getRect boundary \
	    magnifier_x magnifier_y magnifier_width magnifier_height
	set magnifierGeom [send imagewin getGeometry \
	    $magnifier_x $magnifier_y $magnifier_width $magnifier_height]

	# Register callbacks.
	send imagewin addCallback magnifierImagewinResized resize
	send resize addCallback magnifierImagewinResized
	send magnifierWin addCallback magnifierMovedMapImage moveResize

	send magnifierWin {
	    addCallback magnifierMoved moveResize;
	    addCallback magnifierDestroy destroy;
	    addCallback magnifierWinConstraint constraint;
	}

	# Map display frame to magnifier window.
	set magnifier_enable 1
	set magnifier_mapping [send imagewin nextMapping]
	send imagewin refreshMapping $magnifier_mapping

	# create cross-hair
	send imagewin createMarker magPointer \
		type                rectangle \
		createMode          noninteractive \
		width               3 \
		height              3 \
		lineWidth           3 \
		lineColor           green \
		highlightcolor      green \
		activated           true \
		visible             true

	# set its position and size
	setMagPointerPosition 
	magnifierMapImage [expr $winWidth / 2] [expr $winHeight / 2]

    } elseif {$magnifier_enable} {
	magnifierDestroy
    }
}


# magnifierDestroy -- Delete the magnifier.

proc magnifierDestroy args \
{
    global magnifier_enable 
    global magnifier_mapping

    if {$magnifier_enable} {
	set magnifier_enable 0

	send imagewin freeMapping $magnifier_mapping
	send imagewin deleteCallback magnifierImagewinResized
	send resize deleteCallback magnifierImagewinResized
	send frame deleteCallback magnifierMapImage

	if [send server queryObject magnifierWin] {
	    send magnifierWin destroy
	}
	if [send server queryObject magPointer] {
	    send magPointer destroy
	}  
    }
}


# magnifierMoved -- Called when the user moves the magnifier window.  We need to
# move the region marker to the new window location and record the new location
# so that the window will come up in the same place if closed and reopened.

proc magnifierMoved {marker event position} \
{
    global winWidth winHeight magnifierGeom frame 
    global magnifier_x magnifier_y magnifier_width magnifier_height

    # Move the region marker to the new location.
    send client getSource raster sx sy snx sny

    # Update the magnifier window position variables so that it comes up
    # in the same place the next time.

    send magnifierWin getRect boundary \
	magnifier_x magnifier_y magnifier_width magnifier_height
    set magnifierGeom [send imagewin getGeometry \
	$magnifier_x $magnifier_y $magnifier_width $magnifier_height]
}


# magnifierWinConstraint -- Called when the magnifier window is moved, resized,
# or rotated. Constrain the magnifier window to remain within the image window;
# rotation is not permitted.

proc magnifierWinConstraint {marker event attributes} \
{
    global winWidth winHeight
    global magnifier_width magnifier_height

    set width $magnifier_width
    set height $magnifier_height
    set constraints [list {}]

    # Check the width and height first as we need these below.
    foreach i $attributes {
	set new [lindex $i 2]
	switch [lindex $i 0] {
	    width	{   set ww [expr $winWidth / 2]
			    if {$new > $ww} {
				lappend constraints "width $ww"
				set width $ww
			    } else {
				set width $new
			    }
			}
	    height	{   set wh [expr $winHeight / 2]
			    if {$new > $wh} {
				lappend constraints "height $wh"
				set height $wh
			    } else {
				set height $new
			    }
			}
	    rotangle	{    lappend constraints "rotangle 0"
			}
	}
    }

    # Constrain X and Y.
    foreach i $attributes {
	set new [lindex $i 2]
	switch [lindex $i 0] {
	    x		{   set pw [expr $width / 2]
			    if {$new < $pw} {
				lappend constraints "x $pw"
			    } elseif {$new > $winWidth - $pw} {
				lappend constraints "x [expr $winWidth - $pw]"
			    }
			}
	    y		{   set ph [expr $height / 2]
			    if {$new < $ph} {
				lappend constraints "y $ph"
			    } elseif {$new > $winHeight - $ph} {
				lappend constraints "y [expr $winHeight - $ph]"
			    }
			}
	}
    }

    return $constraints
}


# magnifierRegionConstraint -- Called when the region marker in the magnifier
# window is moved, resized, or rotated.

proc magnifierRegionConstraint {marker event attributes} \
{
    global winWidth winHeight

    set constraints [list {}]
    send magnifierWin getRect interior p_x p_y p_width p_height

    # Since the magnifier region marker is a box marker x,y and width,height
    # will not both change in the same call, so we can process them all
    # independently.

    foreach i $attributes {
	set new [lindex $i 2]

	switch [lindex $i 0] {
	    x		{   set left [expr $p_x + $rwidth + 1]
			    set right [expr $p_x + $p_width - $rwidth - 1]
			    if {$new < $left} {
				lappend constraints "x $left"
			    } elseif {$new > $right} {
				lappend constraints "x $right"
			    }
			}
	    y		{   set top [expr $p_y + $rheight + 1]
			    set bottom [expr $p_y + $p_height - $rheight - 1]
			    if {$new < $top} {
				lappend constraints "y $top"
			    } elseif {$new > $bottom} {
				lappend constraints "y $bottom"
			    }
			}
	    width	{   set ww [expr $winWidth / 2]
			    if {$new > $ww / 2} {
				lappend constraints "width $ww"
			    }
			}
	    height	{   set wh [expr $winHeight / 2]
			    if {$new > $wh / 2} {
				lappend constraints "height $wh"
			    }
			}
	    rotangle	{    lappend constraints "rotangle 0"
			}
	}
    }

    return $constraints
}


# magnifierImagewinResized -- If the display window is resized make the
# magnifier track the corner.

proc magnifierImagewinResized args \
{
    global magnifier_enable magnifier_mapping magnifier_height
    global magnifierGeom magnifier_x magnifier_y magnifier_width

    if {$magnifier_enable} {
	set old_x $magnifier_x;  set old_width $magnifier_width
	set old_y $magnifier_y;  set old_height $magnifier_height

	# Get new location of magnifier window.
	set defGeom [format "%sx%s+5+5" $magnifier_width $magnifier_height]
	send imagewin parseGeometry $magnifierGeom $defGeom x y width height

	# Reposition the marker.
	send magnifierWin "\
	    markpos; \
	    setAttributes \
		x		[expr $x + $width / 2] \
		y		[expr $y + $height / 2] \
		width		[expr $width / 2] \
		height		[expr $height / 2]; \
	    redraw"

	# Update the magnifier window position variables so that it comes up
	# in the same place the next time.
	send magnifierWin getRect boundary \
	    magnifier_x magnifier_y magnifier_width magnifier_height
	set magnifierGeom [send imagewin getGeometry \
	    $magnifier_x $magnifier_y $magnifier_width $magnifier_height]

	# Make sure the magnifier window is on top.
	send imagewin raiseMapping $magnifier_mapping

	# Refresh the magnifier window if it did not move.
	if {$magnifier_x == $old_x && $magnifier_y == $old_y &&
	    $magnifier_width == $old_width && $magnifier_height == $old_height} {
	    send imagewin refreshMapping $magnifier_mapping
	}
    }
}


# resetMagnifier -- Reinitialize the magnifier.

proc resetMagnifier {param old new} \
{
    global magnifierGeom displayMagnifier

    if {$new == "done"} {
	setMagnifier [true $displayMagnifier]
    } else {
	setMagnifier 0
	if {$new != "startup"} {
	    set magnifierGeom +5+5
	}
    }
}; send initialize addCallback resetMagnifier


set last_mag_x [expr $winWidth / 2]
set last_mag_y [expr $winHeight / 2]

# magnifierMovedMapImage -- Front end to magnifierMapImage, called when 
# magnifier window is moved or resized.

proc magnifierMovedMapImage args \
{
    global last_mag_x last_mag_y

    magnifierMapImage $last_mag_x $last_mag_y
    setMagPointerPosition
}

# The following code was borrowed from the SAOtng GUI by Eric Mandel of SAO
#--------------------------------------------------------------------------

# globals for magnifier
set mag_w 0
set mag_h 0

#
# setMagnifierZoom -- set the zoom factor for the magnifier
#
proc setMagnifierZoom { zoom } \
{
    global mag_w mag_h

    send magnifierWin getRect boundary \
		magnifier_x magnifier_y magnifier_width magnifier_height
    set mag_w [expr int( ( $magnifier_width  + $zoom - 1 ) / $zoom) ]
    set mag_h [expr int( ( $magnifier_height + $zoom - 1 ) / $zoom) ]

    #set mw [expr int (($magnifier_width - 1) / ($mag_w * 2))]
    #if { $mw < 4 } { set mw 4 }
    #set mh [expr int (($magnifier_height - 1) / ($mag_h * 2))]
    #if { $mh < 4 } { set mh 4 }
    #send magPointer "setAttributes width $mw height $mh; redraw"
}

# magnifierMapImage -- Map the of the current display frame centered on the
# pointer into the magnifier window.  Called when the frame changes, the
# pointer moves in the main image window, or (via magnifierMovedMapImage)
# the magnifier window is moved or resized.

set magnifierROP 0

proc magnifierMapImage {x y} \
{
    global magnifier_enable frame
    global last_mag_x last_mag_y
    global magnifier_mapping
    global winWidth winHeight
    global mag_w mag_h
    global magnifierROP

    if {!$magnifier_enable || $frame == 0} \
	return

#    if {abs($last_mag_x-$x) != 1 && abs($last_mag_y-$y) != 1} {
#	# For efficiency we won't compute the sqrt of the distance but instead
#	# just compare the square.  Use a threshold of 6 pixels so when we
#	# narrow in on the ROI the magnifier is still (mostly) correct.
#        set diff  [expr (($last_mag_x-$x) * ($last_mag_x-$x)) + \
#			(($last_mag_y-$y) * ($last_mag_y-$y))]
#        if {$diff > 36} {
#    	    set last_mag_x $x
#    	    set last_mag_y $y
#	    return
#  	}
#    }

    set last_mag_x $x
    set last_mag_y $y

    send magnifierWin getRect interior dx dy dnx dny
    if [send imagewin activeMapping $magnifier_mapping] {
	send imagewin raiseMapping $magnifier_mapping
    }

    # initialize the magnifier zoom factor, if necessary
    if { !$mag_w || !$mag_h } {
	setMagnifierZoom 4
    }

    set sx [expr $x - $mag_w / 2 ]
    set sy [expr $y - $mag_h / 2 ]

    # Constrain the source rectangle within the main image window 
    # (not overlapping an edge or the magnifier window).

    if {$sx > [expr $dx - $mag_w] && $sx < [expr $dx + $dnx] && 
	$sy > [expr $dy - $mag_h] && $sy < [expr $dy + $dny]    } {

	# The source rectangle would overlap the magnifier window; fix that.

	set dist(l) [expr $sx - ($dx - $mag_w)]
	set dist(b) [expr $dy + $dny - $sy]
	set dist(r) [expr $dx + $dnx - $sx]
	set dist(t) [expr $sy - ($dy - $mag_h)]

	#  Put the distances in order.

	foreach j [array names dist] {
	    set alreadyset($j) 0
	}

	for {set i 0} {$i < 4} {incr i} {
	    set candidate ""
	    foreach j [array names dist] {
		if {!$alreadyset($j)} {
		    if {$candidate == ""} {
			set candidate $j
			set minsofar $dist($j)
		    } elseif {$dist($j) < $minsofar} {
			set candidate $j
			set minsofar $dist($j)
		    }
		}
	    }
	    set order($i) $candidate
	    set alreadyset($candidate) 1
	}

	# Try the sides in order, using the first one where there's room.

	for {set i 0} {$i < 4} {incr i} {
	    if {$order($i) == "l"} {
		if {$dx >= $mag_w} {
		    set sx [expr $dx - $mag_w]
		    break
		}
	    } elseif {$order($i) == "b"} {
		if {$winHeight >= $dy + $dny + $mag_h} {
		    set sy [expr $dy + $dny]
		    break
		}
	    } elseif {$order($i) == "r"} {
		if {$winWidth >= $dx + $dnx + $mag_w} {
		    set sx [expr $dx + $dnx]
		    break
		}
	    } elseif {$order($i) == "t"} {
		if {$dy >= $mag_h} {
		    set sy [expr $dy - $mag_h]
		    break
		}
	    }
	}
    }

    # Make sure we don't go beyond an edge of the main window.

    if {$sx < 0} {
	set sx 0
    } else {
	set sxmax [expr $winWidth - $mag_w]
	if {$sx > $sxmax} {
	    set sx $sxmax
	}
    }

    if {$sy < 0} {
	set sy 0
    } else {
	set symax [expr $winHeight - $mag_h]
	if {$sy > $symax} {
	    set sy $symax
	}
    }

    # Map 32 x 32 centered on pointer in main window.
    set err [catch {send imagewin setMapping $magnifier_mapping $magnifierROP \
	0 pixel $sx $sy $mag_w $mag_h \
	0 pixel $dx $dy $dnx   $dny}]
    if { $err != 0 } {
	Print "There was a problem setting up the magnifier ... recovering"
    }
}


# set the position of the magnifier marker in the center of the mag window
proc setMagPointerPosition args \
{
    global magnifier_enable

    if { !$magnifier_enable } \
	return

    send magnifierWin "getAttributes x x y y"
    set xpos [expr $x + 1]
    set ypos [expr $y + 1]

    send magPointer "setAttributes x $xpos y $ypos visible true; redraw"
}



################################################################################
# PANNER.  The full frame mapped into the main image window is displayed at a
# reduced resolution in a marker (known as the panner window) within the main
# image window.  The currently displayed region of the frame is indicated
# using a small marker within the panner window.  This small marker may be
# moved or resized to pan or zoom the image in the main display window.
################################################################################

set panner_x 0
set panner_y 0
set panner_width 0
set panner_height 0
set prm_width 0
set prm_height 0

set panner_enable 0
set panner_pan_enable 0
set panner_mag_enable 0
set panner_region_enable 0
set panner_mapping 0

# Panner window translations.
set pannerWinTranslations { \
       !Shift <Btn1Motion>:	m_rotateResize()
	      <Btn1Motion>:	m_moveResize()
	 !Shift <Btn1Down>:	m_raise() m_markpos()
		<Btn1Down>:	m_raise() m_markposAdd()
		  <Btn1Up>:	m_redraw() m_destroyNull()
		<Btn2Down>:	m_lower()
		  <Btn2Up>:	call(pannerPanXY,$x,$y)
	      !Ctrl <Key>b:     call(prevFrame,$name)
	      !Ctrl <Key>f:     call(nextFrame,$name)
	      !Ctrl <Key>h:     call(move_cursor,-1,0)
	      !Ctrl <Key>j:     call(move_cursor,0,1)
	      !Ctrl <Key>k:     call(move_cursor,0,-1)
	      !Ctrl <Key>l:     call(move_cursor,1,0)
	      !Ctrl <Key>n:     call(normalize)
	      !Ctrl <Key>c:     call(cpZoomAction,centerFrame)
	      !Ctrl <Key>i:     call(cpInvert)
	      !Ctrl <Key>m:     call(toggleMagnifier)
	      !Ctrl <Key>p:     call(togglePanner)
	      !Ctrl <Key>r:     call(cpRegisterFrames)
	      !Ctrl <Key>s:     call(cpMatchFrames)
	       !Alt <Key>1: 	call(cpSetFrame,frame1)
	       !Alt <Key>2: 	call(cpSetFrame,frame2)
	       !Alt <Key>3: 	call(cpSetFrame,frame3)
	       !Alt <Key>4: 	call(cpSetFrame,frame4)
	      !Ctrl <Key>1: 	call(cpZoom,1,1,fixed)
	      !Ctrl <Key>2: 	call(cpZoom,2,2,fixed)
	      !Ctrl <Key>3: 	call(cpZoom,3,3,fixed)
	      !Ctrl <Key>4: 	call(cpZoom,4,4,fixed)
	      !Ctrl <Key>5: 	call(cpZoom,5,5,fixed)
	      !Ctrl <Key>6: 	call(cpZoom,6,6,fixed)
	      !Ctrl <Key>7: 	call(cpZoom,7,7,fixed)
	      !Ctrl <Key>8: 	call(cpZoom,8,8,fixed)
	      !Ctrl <Key>9: 	call(cpZoom,9,9,fixed)
	    <Key>BackSpace:	m_deleteDestroy()
	       <Key>Delete:	m_deleteDestroy()
		<KeyPress>:     graphics-input()
		  <Motion>:	track-cursor() call(wcsUpdate,$x,$y)
}


# setPanner -- Turn the panner on or off.

proc togglePanner args \
{
    global panner_enable

    if {$panner_enable} {
	setPanner 0
    } else {
	setPanner 1
    }
}


proc setPanner {state} \
{
    global winWidth winHeight frameWidth frameHeight
    global frame panner_mapping pannerWinTranslations pannerArea
    global panner_enable panner_region_enable panner_pan_enable
    global pannerGeom panner_x panner_y panner_width panner_height
    global last_compass

    if {$state} {
	if {$panner_enable} \
	    return

	# Determine where to place the panner.
	set scale \
	    [expr sqrt(double($pannerArea) / ($frameWidth * $frameHeight))]
	set scaled_width [expr int($frameWidth * $scale) / 2 * 2 + 1]
	set scaled_height [expr int($frameHeight * $scale) / 2 * 2 + 1]
	set defGeom [format "%sx%s-5+5" $scaled_width $scaled_height]
	send imagewin parseGeometry $pannerGeom $defGeom x y width height

	# Create the main panner window (marker).
	send imagewin createMarker pannerWin \
	    type		rectangle \
	    createMode		noninteractive \
	    width		[expr $width / 2] \
	    height		[expr $height / 2] \
	    x			[expr $x + $width / 2] \
	    y			[expr $y + $height / 2] \
	    lineColor		8 \
	    highlightColor	8 \
	    translations	$pannerWinTranslations \
	    visible		true \
	    sensitive		true \
	    autoRedraw		true \
	    activated		true

	# Update the panner window position variables so that it comes up
	# in the same place the next time.

	send pannerWin getRect boundary \
	    panner_x panner_y panner_width panner_height
	set pannerGeom [send imagewin getGeometry \
	    $panner_x $panner_y $panner_width $panner_height]

	# Register callbacks.
	send frame addCallback pannerMapImage
	send frameRegion addCallback pannerSetRegion
	send imagewin addCallback pannerImagewinResized resize
	send resize addCallback pannerImagewinResized

	send pannerWin {
	    addCallback pannerMapImage moveResize;
	    addCallback pannerMoved moveResize;
	    addCallback pannerDestroy destroy;
	    addCallback pannerWinConstraint constraint;
	}

	# Map display frame to panner window.
	set panner_enable 1
	set panner_region_enable 1
	set panner_mapping [send imagewin nextMapping]
	pannerMapImage init; send imagewin refreshMapping $panner_mapping

	# Redraw the compass if necessary.
	send compass "setSensitive True ; set on $last_compass"
	if { $last_compass } \
	    drawCompass

	# Draw a marker in the panner window outlining displayed region.
	send imagewin createMarker pannerRegionMarker \
	    type		box \
	    createMode		noninteractive \
	    translations	$pannerWinTranslations \
	    lineColor		green \
	    highlightColor	green \
	    sensitive		true

	# Fire up the panner region marker.
	send client getSource raster sx sy snx sny
	pannerSetRegion dummy dummy [concat $frame $sx $sy $snx $sny]
	send pannerRegionMarker "\
	    addCallback pannerPanImage moveResize; \
	    addCallback pannerDestroy destroy; \
	    addCallback pannerRegionConstraint constraint; \
	    setAttributes visible true activated true; \
	    redraw"
	set panner_pan_enable 1

    } elseif {$panner_enable} {
	pannerDestroy
    }
}


# pannerDestroy -- Delete the panner.

proc pannerDestroy args \
{
    global panner_enable panner_region_enable panner_pan_enable
    global panner_mapping

    if {$panner_enable} {
	set panner_enable 0
	set panner_pan_enable 0
	set panner_region_enable 0

	send imagewin freeMapping $panner_mapping
	send imagewin deleteCallback pannerImagewinResized
	send resize deleteCallback pannerImagewinResized
	send frame deleteCallback pannerMapImage
	send frameRegion deleteCallback pannerSetRegion

	if [send server queryObject pannerRegionMarker] {
	    send pannerRegionMarker destroy
	}
	if [send server queryObject pannerWin] {
	    send pannerWin destroy
	}

	# Disable the compass.
	send compass "setSensitive False ; set on False"
    }
}


# pannerMapImage -- Map the current display frame into the panner window.
# Called when the frame changes or the panner window is moved or resized.
# The panner window displays a small dezoomed version of the full frame.

proc pannerMapImage args \
{
    global panner_enable frame
    global panner_mapping

    if {!$panner_enable || $frame == 0} \
	return

    set raster [send client getRaster]
    send pannerWin getRect interior dx dy dnx dny
    send imagewin queryRaster $raster width height

    if [send imagewin activeMapping $panner_mapping] {
	send imagewin raiseMapping $panner_mapping
    }
    send imagewin setMapping $panner_mapping 0 \
	$raster pixel 0 0 $width $height \
	0 pixel $dx $dy $dnx $dny
}


# pannerSetRegion -- Adjust the pannerWin region marker to outline the
# region displayed in the main display window.  This is called in response
# to a frameRegion event when the main display mapping changes, e.g. when
# the frame changes or the user zooms or pans the main window.  The region
# marker is moved and resized to reflect the new view.

proc pannerSetRegion {param old new} \
{
    global panner_enable panner_region_marker
    global panner_region_enable panner_pan_enable
    global frame frameWidth frameHeight prm_width prm_height

    if {!$panner_enable || !$panner_region_enable || $frame == 0} \
	return

    # new: frame sx sy snx sny
    set src_frame [lindex $new 0]
    set sx [lindex $new 1];  set snx [lindex $new 3]
    set sy [lindex $new 2];  set sny [lindex $new 4]

    if {$src_frame != $frame} \
	return

    send pannerWin getRect interior px py pnx pny

    set x [expr ($sx + $snx/2.0) / $frameWidth * $pnx + $px]
    set y [expr ($sy + $sny/2.0) / $frameHeight * $pny + $py]
    set width  [expr ($snx/2.0) / $frameWidth * $pnx + 1]
    set height [expr ($sny/2.0) / $frameHeight * $pny + 1]

    set pan_save $panner_pan_enable;  set panner_pan_enable 0
    set panner_region_enable 0

    send pannerRegionMarker "\
	markpos; \
	setAttributes x $x y $y width $width height $height; \
	redraw; raise"
    send pannerRegionMarker getAttributes width prm_width height prm_height

    set panner_region_enable 1
    set panner_pan_enable $pan_save
}


# pannerPanImage -- Pan or zoom the image in the main image window.  This is
# called when the user moves the region marker within the panner window.

proc pannerPanImage {marker event position} \
{
    global panner_pan_enable
    global winWidth winHeight
    global prm_width prm_height
    global frame auto_reg frameOffsetX frameOffsetY

    if {!$panner_pan_enable} \
	return

    # position: x y width height.
    set new_width [lindex $position 2]
    set new_height [lindex $position 3]

    # region: type raster x y width height.
    set region [send pannerRegionMarker getRegion unmap]
    set x [expr [lindex $region 2] + 1];  set width [lindex $region 4]
    set y [expr [lindex $region 3] + 1];  set height [lindex $region 5]

    set panner_pan_enable 0
    if {$new_width == $prm_width && $new_height == $prm_height} {
	send client pan $x $y
    } else {
	set xscale [expr ($winWidth / 2.0) / $width]
	set yscale [expr ($winHeight / 2.0) / $height]
	if {$auto_reg == 1} {
	    send client zoomAbs $xscale $yscale $x $y \
		$frameOffsetX($frame) $frameOffsetY($frame)
	} else {
	    send client zoom $xscale $yscale $x $y
	}
    }
    set panner_pan_enable 1
}


# pannerPanXY -- Pan to the point X,Y in the panner window coordinate
# system.  Called when the user clicks MB2 in the panner window.

proc pannerPanXY {x y} \
{
    send imagewin unmapPixel $x $y raster rx ry
    send client pan $rx $ry
}


# pannerMoved -- Called when the user moves the panner window.  We need to
# move the region marker to the new window location and record the new location
# so that the window will come up in the same place if closed and reopened.

proc pannerMoved {marker event position} \
{
    global winWidth winHeight
    global frame panner_pan_enable pannerGeom
    global panner_x panner_y panner_width panner_height

    # Move the region marker to the new location.
    set pan_save $panner_pan_enable;  set panner_pan_enable 0
    send client getSource raster sx sy snx sny
    pannerSetRegion dummy dummy [concat $frame $sx $sy $snx $sny]
    set panner_pan_enable $pan_save

    # Update the panner window position variables so that it comes up
    # in the same place the next time.

    send pannerWin getRect boundary \
	panner_x panner_y panner_width panner_height
    set pannerGeom [send imagewin getGeometry \
	$panner_x $panner_y $panner_width $panner_height]

    drawCompass

    send pannerRegionMarker raise
}


# pannerWinConstraint -- Called when the panner window is moved, resized, or
# rotated.  Constrain the panner window to remain within the image window;
# rotation is not permitted.

proc pannerWinConstraint {marker event attributes} \
{
    global winWidth winHeight
    global panner_width panner_height

    set width $panner_width
    set height $panner_height
    set constraints [list {}]

    # Check the width and height first as we need these below.
    foreach i $attributes {
	set new [lindex $i 2]
	switch [lindex $i 0] {
	    width	{   set ww [expr $winWidth / 2]
			    if {$new > $ww} {
				lappend constraints "width $ww"
				set width $ww
			    } else {
				set width $new
			    }
			}
	    height	{   set wh [expr $winHeight / 2]
			    if {$new > $wh} {
				lappend constraints "height $wh"
				set height $wh
			    } else {
				set height $new
			    }
			}
	    rotangle	{    lappend constraints "rotangle 0"
			}
	}
    }

    # Constrain X and Y.
    foreach i $attributes {
	set new [lindex $i 2]
	switch [lindex $i 0] {
	    x		{   set pw [expr $width / 2]
			    if {$new < $pw} {
				lappend constraints "x $pw"
			    } elseif {$new > $winWidth - $pw} {
				lappend constraints "x [expr $winWidth - $pw]"
			    }
			}
	    y		{   set ph [expr $height / 2]
			    if {$new < $ph} {
				lappend constraints "y $ph"
			    } elseif {$new > $winHeight - $ph} {
				lappend constraints "y [expr $winHeight - $ph]"
			    }
			}
	}
    }

    return $constraints
}


# pannerRegionConstraint -- Called when the region marker in the panner
# window is moved, resized, or rotated.

proc pannerRegionConstraint {marker event attributes} \
{
    global winWidth winHeight
    global frame

    set constraints [list {}]
    send pannerWin getRect interior p_x p_y p_width p_height
    send pannerRegionMarker getAttributes width rwidth height rheight

    # Since the panner region marker is a box marker x,y and width,height
    # will not both change in the same call, so we can process them all
    # independently.

    foreach i $attributes {
	set new [lindex $i 2]

	switch [lindex $i 0] {
	    x		{   set left [expr $p_x + $rwidth + 1]
			    set right [expr $p_x + $p_width - $rwidth - 1]
			    if {$new < $left} {
				lappend constraints "x $left"
			    } elseif {$new > $right} {
				lappend constraints "x $right"
			    }
			}
	    y		{   set top [expr $p_y + $rheight + 1]
			    set bottom [expr $p_y + $p_height - $rheight - 1]
			    if {$new < $top} {
				lappend constraints "y $top"
			    } elseif {$new > $bottom} {
				lappend constraints "y $bottom"
			    }
			}
	    width	{   set ww [expr $winWidth / 2]
			    if {$new > $ww / 2} {
				lappend constraints "width $ww"
			    }
			}
	    height	{   set wh [expr $winHeight / 2]
			    if {$new > $wh / 2} {
				lappend constraints "height $wh"
			    }
			}
	    rotangle	{    lappend constraints "rotangle 0"
			}
	}
    }
    drawCompass

    return $constraints
}


# pannerImagewinResized -- If the display window is resized make the panner
# track the corner.

proc pannerImagewinResized args \
{
    global panner_enable panner_mapping 
    global pannerGeom panner_x panner_y panner_width panner_height
    global frame

    if {$panner_enable} {
	set old_x $panner_x;  set old_width $panner_width
	set old_y $panner_y;  set old_height $panner_height

        eraseCompass

	# Get new location of panner window.
	set defGeom [format "%sx%s-5+5" $panner_width $panner_height]
	send imagewin parseGeometry $pannerGeom $defGeom x y width height

	# Reposition the marker.
	send pannerWin "\
	    markpos; \
	    setAttributes \
		x		[expr $x + $width / 2] \
		y		[expr $y + $height / 2] \
		width		[expr $width / 2] \
		height		[expr $height / 2]; \
	    redraw"

	# Update the panner window position variables so that it comes up
	# in the same place the next time.
	send pannerWin getRect boundary \
	    panner_x panner_y panner_width panner_height
	set pannerGeom [send imagewin getGeometry \
	    $panner_x $panner_y $panner_width $panner_height]

	# Make sure the panner window is on top.
	send imagewin raiseMapping $panner_mapping

	# Refresh the panner window if it did not move.
	if {$panner_x == $old_x && $panner_y == $old_y &&
	    $panner_width == $old_width && $panner_height == $old_height} {
	    send imagewin refreshMapping $panner_mapping
	}

        drawCompass
    }
}


# resetPanner -- Reinitialize the panner.

proc resetPanner {param old new} \
{
    global pannerGeom displayPanner
    if {$new == "done"} {
	setPanner [true $displayPanner]
    } else {
	setPanner 0
	if {$new != "startup"} {
	    set pannerGeom -5+5
	}
    }
}; send initialize addCallback resetPanner



################################################################################
# Print Panel Functions.
################################################################################

# Global variables needed for the print setup panel

set printColor	prGrayButton
set orientation	epsPortButton
set page_size	epsLetterButton
set imageScale	100

set epsWidgets { epsPageGroup epsOrientLabel epsSizeLabel 
	epsPortButton epsLandButton epsLetterButton epsLegalButton epsA4Button
	ScaleFrame SCdecrease SCtext SCincrease 
}


proc psetup_init args \
{
    global printColor orientation page_size imageScale #format

    set_printer toPrinter callback 1
    send SCtext set label [ format "%d %%" $imageScale ]
    send $printColor set on true
    send $orientation set on true
    send $page_size set on true
}


proc doPrintOptions { param old new } \
{
    global imageScale page_size orientation imageScale printColor
    global warnings

    send printStatus set label {}
    set val [join [lrange $new 1 end] " "]

    # print [format "doPrintOptions %s = %s" [lindex $new 0] $val]
    switch [lindex $new 0] {
    autoscale	    { 	if { $val == "True" } {
			    send epsscaleButton set on true
			} elseif { $val == "False" } {
			    send epsscaleButton set on false
			}
		    }
    autorotate	    { 	if { $val == "True" } {
			    send autorotateButton set on true
			} elseif { $val == "False" } {
			    send autorotateButton set on false
			}
		    }
    maxaspect	    { 	if { $val == "True" } {
			    send aspectButton set on true
			} elseif { $val == "False" } {
			    send aspectButton set on false
			}
		    }
    annotate	    { 	if { $val == "True" } {
			    send annotateButton set on true
		            send titleButton setSensitive true
		            send colorbarButton setSensitive true
		            send bordersButton setSensitive true
		            send titleLabel setSensitive true
		            send titleString setSensitive true
			} elseif { $val == "False" } {
			    send annotateButton set on false
		            send titleButton setSensitive false
		            send colorbarButton setSensitive false
		            send bordersButton setSensitive false
		            send titleLabel setSensitive false
		            send titleString setSensitive false
			}
		    }
    compress	    { 	if { $val == "True" } {
			    send compressButton set on true
			} elseif { $val == "False" } {
			    send compressButton set on false
			}
		    }
    orientation	    { 	send $orientation set on false
			if { $val == "portrait" } {
			    send epsPortButton set on true
			    set orientation epsPortButton
			} elseif { $val == "landscape" } {
			    send epsPortButton set on false
			    set orientation epsLandButton
			}
		    }
    papersize	    { 	send $page_size set on false
			if { $val == "letter" } {
			    send epsLetterButton set on true
			    set page_size epsLetterButton
			} elseif { $val == "legal" } {
			    send epsLegalButton set on true
			    set page_size epsLegalButton
			} elseif { $val == "A4" } {
			    send epsA4Button set on true
			    set page_size epsA4Button
			} elseif { $val == "B5" } {
			    send epsB5Button set on true
			    set page_size epsB5Button
			}
		    }
    imscale	    { 	set imageScale $val
    			send SCtext set label [ format "%d %%" $imageScale ]
		    }
    colortype	    { 	send $printColor set on false
			if { $val == "gray" } {
			    send prGrayButton set on true
			    set printColor prGrayButton
			} elseif { $val == "pseudo" } {
			    send prPseudoButton set on true
			    set printColor prPseudoButton
			} elseif { $val == "rgb" } {
			    send prRGBButton set on true
			    set printColor prRGBButton
			}
		    }
    printerName	    {	if [send toPrinter get on] {
			    send printlist highlight $val
			}
		    }
    printCmd	    {	if [send toPrinter get on] {
			    send printcmd set string $val
			}
		    }
    printFile	    {	if [send toFile get on] {
			    send printcmd set string $val
			}
		    }
    deviceType      {   if { $val == "Printer" } {
			    send printerLabel set label "Print Command:"
			    send toPrinter set on true
			    send toFile set on false
		        } elseif { $val == "File" } {
			    send printerLabel set label "File Name:"
			    send toPrinter set on false
			    send toFile set on true
			    send printlist unhighlight
		        }
		    }
    dotitle         {   if { $val == "True" } {
		            send titleButton set on true
		        } elseif { $val == "False" } {
		            send titleButton set on false
		        }
		    }
    doborders       {   if { $val == "True" } {
		            send bordersButton set on true
		        } elseif { $val == "False" } {
		            send bordersButton set on false
		        }
		    }
    docolorbar      {   if { $val == "True" } {
		            send colorbarButton set on true
		        } elseif { $val == "False" } {
		            send colorbarButton set on false
		        }
		    }
    title           {   send titleString set string $val
		    }

    status	    {   send printStatus set label $val
			send server synchronize
	 	    }
    warning	    {   if {$warnings} { Wexec server $val }
		    }
    }
}; send printOptions addCallback doPrintOptions


# Print options procedures.
# -------------------------------

set prOptsWidgets { 
    toPrinter toFile
    prGrayButton prPseudoButton prRGBButton
    epsLandButton epsPortButton
    epsLetterButton epsLegalButton epsA4Button epsB5Button
    SCincrease SCdecrease
}
set prSimpleOptions { 
    epsscaleButton autorotateButton aspectButton annotateButton compressButton 
    titleButton bordersButton colorbarButton
}

proc prPrintCommand { widget cbtype args } \
{
    if [send toFile get on] {
	send client setPrintOption printfile $args
	send printStatus set label [format "output file set to %s" $args]
    } else {
	send client setPrintOption printcmd $args
	send printStatus set label [format "print command set to %s" $args]
    }
}; send printcmd addCallback prPrintCommand

proc prTitleString { widget cbtype args } \
{
    send client setPrintOption title $args
}; send titleString addCallback prTitleString

proc prOptionToggle { widget cbtype args } \
{
    global imageScale

    # Handle the image scale widgets first.
    switch $widget {
    SCincrease	{ set scale [expr $imageScale + 5] 
  		  send client setPrintOption imscale $scale
		  return
		}
    SCdecrease	{ set scale [ expr $imageScale - 5 ]
		  send client setPrintOption imscale $scale
		  return
		}
    }

    # If it's not one of those it must be one of the radio toggles.
    set val [ send $widget get on ]
    #print [ format "prOptionToggle %s = %s" $widget $val ]
    if { $val == 1 } {
	switch $widget {
	toPrinter  	{ send client setPrintOption devicetype printer }
	toFile  	{ send client setPrintOption devicetype file }

	epsLandButton   { send client setPrintOption orientation landscape }
	epsPortButton   { send client setPrintOption orientation portrait }

	epsLetterButton { send client setPrintOption papersize letter }
	epsLegalButton  { send client setPrintOption papersize legal }
	epsA4Button     { send client setPrintOption papersize A4 }
	epsB5Button     { send client setPrintOption papersize B5 }

	prGrayButton    { send client setPrintOption colortype gray }
	prPseudoButton  { send client setPrintOption colortype pseudo }
	prRGBButton     { send client setPrintOption colortype rgb }
	}
    } else {
	send $widget set on true
    }

} ; foreach w $prOptsWidgets { send $w addCallback prOptionToggle }

proc prSimpleOptionToggle { widget args } \
{
    set val [ send $widget get on ]
    #print [ format "prSimpleOptionToggle %s = %s" $widget $val ]

    switch $widget {
    epsscaleButton   { send client setPrintOption autoscale  $val }
    autorotateButton { send client setPrintOption autorotate $val }
    aspectButton     { send client setPrintOption maxaspect  $val }
    annotateButton   { send client setPrintOption annotate   $val }
    compressButton   { send client setPrintOption compress   $val }

    titleButton      { send client setPrintOption dotitle    $val }
    bordersButton    { send client setPrintOption doborders  $val }
    colorbarButton   { send client setPrintOption docolorbar $val }
    }
} ; foreach w $prSimpleOptions { send $w addCallback prSimpleOptionToggle }



# Printer display and selection.
# -------------------------------
set lprList	{}

proc psSetPrintList {param old new} \
{
    global lprList
    set lprList $new
    send printlist setList $new resize
    send printlist highlight 0
}; send printerList addCallback psSetPrintList

proc lprResize args \
{
    global lprList
    send printlist setList $lprList resize
    send printlist highlight 0
}; send printlist addEventHandler lprResize ResizeRedirectMask

proc psSelectPrint {widget cbtype selections indices} \
{
    global printerlist
    foreach selection $selections {
	send client setPrintOption printername $selection
    }
}; send printlist addCallback psSelectPrint


proc Print args \
{
    global winWidth winHeight
    send imagewin setCursorType busy

    # Get the print command or file template if not previous reset.
    set val [ send printcmd get string ]
    if [send toFile get on] {
	send client setPrintOption printfile $val
    } else {
	send client setPrintOption printcmd $val
    }
    set val [ send titleString get string ]
    send client setPrintOption title $val
    setPrintCorners 0 [expr $winWidth - 1] [expr $winHeight - 1] 0

    send client print
    send imagewin setCursorType idle
} ; send okayPrint addCallback Print



# setPrintCorners -- Tell the client the WCS of the image being printed.

proc setPrintCorners { lx ly ux uy args } \
{
    global winWidth winHeight

    # Convert raw corner screen coordinates to frame buffer raster coords.
    send imagewin unmapPixel $lx $ly raster llx lly
    set llx [expr "int ($llx)"]
    set lly [expr "int ($lly)"]
    set str  [send client encodewcs $llx $lly]
    scan $str "%g %g %g" llx_r lly_r z
    set llx_i [expr "int ($llx_r)"]
    set lly_i [expr "int ($lly_r)"]

    send imagewin unmapPixel $ux $uy raster urx ury
    set urx [expr "int ($urx)"]
    set ury [expr "int ($ury)"]
    set str [send client encodewcs $urx $ury]
    scan $str "%g %g %g" urx_r ury_r z
    set urx_i [expr "int ($urx_r)"]
    set ury_i [expr "int ($ury_r)"]

    send client setPrintOption corners $llx_i $lly_i $urx_i $ury_i
}



################################################################################
# INFO box.
################################################################################

set	infoMode	infoOptFr


# Current Frame information.
proc infoFrameUpdate args \
{
    global version frame nframes
    global frameWidth frameHeight frameDepth
    global enhancement
    global cpXcen cpYcen cpXoff cpYoff
    global cpXmag cpYmag cpXscale cpYscale

    if { [send infoOptWCS get on] } {
	send client info wcs
	return
    } elseif {! [send infoOptFr get on]} \
	return


    if {$frame == 0} {
       send infoText set string "initializing display..."
    } else {
       set line1 $version
       set line2 [format "Image:\t\t%s" [send imageTitle get label]]
       set line3 [format "Frame %d of %d:\t%d x %d" \
	    		$frame $nframes $frameWidth $frameHeight]
       set cmap  [lindex $enhancement($frame) 0]
       set brt   [lindex $enhancement($frame) 1]
       set con   [lindex $enhancement($frame) 2]
       set line4 [format "Colormap:\t%s" $cmap]
       set line5 [format "Enhancement:\tBrt=%s  Cont=%s" $brt $con]

       set cntr  [format "X: %0.1f\n\t\tY: %0.1f" $cpXcen $cpYcen]
       set line6 [format "Center:\t\t%s" $cntr]

       set line7 [format "Zoom:\t\tX: %0.2f\n\t\tY: %0.2f" $cpXmag $cpYmag]
       set line8 [format "Scale:\t\tX: %0.2f\n\t\tY: %0.2f" $cpXscale $cpYscale]
       set line9 [format "Offset:\t\tX: %0.2f\n\t\tY: %0.2f" $cpXoff $cpYoff]

       send infoText set string [
	    format "%s\n\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n\n" \
		$line1 $line2 $line3 $line4 $line5 $line6 $line7 $line8 $line9
       ]
    }
}
set params {frame frameView nframes frameSize frameTitle enhancement}
foreach p $params { send $p addCallback infoFrameUpdate }


# Server Program State information.
proc infoOptToggle { widget type state args } \
{
    global infoMode ismInfoText

    if {$state} { set not False } else { set not True }

    send $infoMode set on $not
    set infoMode $widget

    switch $widget {
    infoOptFr	   { infoFrameUpdate				}
    infoOptSvr	   { set bp [send imagewin get basePixel] 
		     set mc [send imagewin get maxColors]
		     send client info server $bp $mc
		   }
    infoOptIsm     { send infoText set string $ismInfoText	}
    infoOptClients { send client info clients			}
    infoOptWCS     { send client info wcs			}
    infoOptFB	   { send client info imtoolrc			}
    }
}
set iopts {infoOptFr infoOptSvr infoOptIsm infoOptClients infoOptWCS infoOptFB }
foreach w $iopts { send $w addCallback infoOptToggle }


proc infoSetText { param old new } \
{
   send infoText set string $new
} ; send info addCallback infoSetText



################################################################################
# Image and objects list display and section
################################################################################

proc filesTextHighlight { widget event args } \
{
    if { $event == "enterNotify" } {
	send $widget set displayCaret True
    } elseif { $event == "leaveNotify" } {
	send $widget set displayCaret False
    }
}
foreach w {imtemplateText fnameText z1Value z2Value} {
    send $w addEventHandler filesTextHighlight enterWindowMask
    send $w addEventHandler filesTextHighlight leaveWindowMask
}

send rootButton     addCallback "send client setLoadOption root"
send homeButton     addCallback "send client setLoadOption home"
send upButton       addCallback "send client setLoadOption up"
send rescanButton   addCallback "send client setLoadOption rescan"

set label \
    [format "%-35.35s %6s   %12s  %12s"\
         "              Image" "Bitpix" "  Size" "          Title"]
send imlistLabel set label $label
send imlistLabel "set height 0 ; unmap"


# Create the Frames menu on the load panel window.
set loadItems { "Current f.exec \{send frameFrame set label Current\}"}
for {set i 1} {$i <= $MAX_FRAMES} {incr i} {
    lappend loadItems "\"\ \ $i\ \ \" f.exec \{send frameFrame set label $i\}"
}; createMenu loadFrames frameFrame $loadItems





# Filename pattern callback.
proc setPattern { widget mode pattern args } \
{
    send client setLoadOption pattern $pattern
} ; send imtemplateText addCallback setPattern


# Load options parameter callback.
proc doLoadOptions { param old new } \
{
    global warnings panel_up

    set val     [ join [lrange $new 1 end] " " ]

    switch [lindex $new 0] {
    pattern  	{ send imtemplateText set string [format "%s" $val ] }
    curdir   	{ send dirLabel set label [format "  Directory:    %s" $val ] }
    newfile  	{ send fnameText set string $val }
    status  	{ send filesStatus set label $val
	          if { ! $panel_up } { send imageTitle set label $val }
	          send server synchronize
	    	}
    warning 	{ if {$warnings} { Wexec server $val } 		}
    gray	{ send grayscale set on $val 			}
    zscale	{ send zscale set on $val
    		  if {$val} {
		      send zrange setSensitive False
		  } else {
		      send zrange setSensitive True
		  }
		}
    zrange	{ send zrange set on $val
    		  if {$val} {
		      foreach w {z1Label z1Value z2Label z2Value} {
		          send $w setSensitive False
		      }
		  } else {
		      foreach w {z1Label z1Value z2Label z2Value} {
		          send $w setSensitive True
		      }
		  }
		}
    z1		{ send z1Value    set string [format "%s" $val ] }
    z2		{ send z2Value    set string [format "%s" $val ] }
    nsample	{ send nsampValue set string [format "%s" $val ] }
    }
} ; send loadOptions addCallback doLoadOptions

# Option utility routines.
proc toggleGraymap args \
{
    send client setLoadOption gray [ send grayscale get on ]
} ; send grayscale addCallback toggleGraymap

proc toggleHeaders args \
{
    if { [send browseHdrs get on] } {
        send client setLoadOption headers 
	send rootButton   setSensitive False
	send homeButton   setSensitive False
	send upButton     setSensitive False
	send rescanButton setSensitive False
	send imlistLabel "set height 10 ; map"
    } else {
        send client setLoadOption rescan 
	send rootButton   setSensitive True
	send homeButton   setSensitive True
	send upButton     setSensitive True
	send rescanButton setSensitive True
	send imlistLabel "set height 0 ; unmap"
    }
} ; send browseHdrs addCallback toggleHeaders

proc toggleZscale args \
{
    send client setLoadOption zscale [send zscale get on]
} ; send zscale addCallback toggleZscale

proc toggleZrange args \
{
    send client setLoadOption zrange [send zrange get on]
} ; send zrange addCallback toggleZrange

proc setZ1 { widget mode pattern args } \
{
    send client setLoadOption z1 $pattern
} ; send z1Value addCallback setZ1

proc setZ2 { widget mode pattern args } \
{
    send client setLoadOption z2 $pattern
} ; send z2Value addCallback setZ2

proc setNsamp { widget mode pattern args } \
{
    send client setLoadOption nsample $pattern
} ; send nsampValue addCallback setNsamp

proc fileLoad { widget mode fname args } \
{
    loadImage $fname
} ; send fnameText addCallback fileLoad



# Image list selection routines.

set fileList	{}

proc setFileList { param old new } \
{
    global fileList
    set fileList $new

    # Get the max length of the strings so we can set
    # the list columns appropriately.
    set max 0
    foreach n $new {
	set len [string length $n]
	if {$len > $max} { set max $len }
    }

    # Optimize the number of columns for the file list.
    if {$max > 35}  { 
	send imageList set defaultColumns 1
    } elseif {$max > 21} { 
	send imageList set defaultColumns 2
    } elseif {$max > 12} { 
	send imageList set defaultColumns 3
    } elseif {$max > 5} { 
	send imageList set defaultColumns 4
    } else { 
	send imageList set defaultColumns 5
    }

    send imageList setList $new resize
}; send filelist addCallback setFileList

proc flResize args \
{
    global fileList
    send imageList setList $fileList resize
}; send imageList addEventHandler flResize ResizeRedirectMask

proc flSelectPrint { widget cbtype selections args } \
{
    if {! [send autoload get on]} \
	return

    foreach selection $selections { 
        if { [send zrange get on] } {
	    loadImage [lindex $selection 0]
        } else {
	    loadImage $selection
        }
    }
}; send imageList addCallback flSelectPrint


# Load the named image in the display.
proc loadImage { name } \
{
    global frame

    set fr [send frameFrame get label]

    if { $fr == "Current" } { set fr $frame }

    if { [fileSetOptions] >= 0 } {
        send imagewin setCursorType busy
        send client load $name $fr
        send imagewin setCursorType idle
        send fnameText set string $name
    }
}

# Load button callback.
proc fileLoadB args \
{
    set fname [send fnameText get string]
    if {$fname == ""} {
	Wexec client "No image name specified"
    } else {
	loadImage $fname
    }
} ; send filesLoadButton addCallback fileLoadB


# Send and selected options to the client before loading the image.
proc fileSetOptions args \
{
    if { ![send zscale get on] && ![send zrange get on] } {
        set z1 [send z1Value get string]
        set z2 [send z2Value get string]

        if {$z1 == $z2} {
	    Wexec client "z1/z2 values are not set properly"
	    return -1
	} else {
            send client setLoadOption z1 $z1
            send client setLoadOption z2 $z2
	}
    }

    return 0
}


################################################################################
# Save panel functions.
################################################################################

# Global variables needed for the save setup panel

set format	rasButton
set saveColor	svPseudoButton

set fileFmtButtons {
    rasButton gifButton jpegButton tiffButton 
    fitsButton x11Button epsButton rawButton 
}


# Format group procedures.
#---------------------------------

# Select a format.

proc set_format { widget func state args } \
{
    global format saveColor

    send $format set on false
    if {$widget == $format} {
	send $widget set on true
    } else {
	switch $widget  { 
	rasButton	{ send client setSaveOption format ras  } 
	gifButton	{ send client setSaveOption format gif  }
	jpegButton	{ send client setSaveOption format jpeg }
	tiffButton	{ send client setSaveOption format tiff }
	fitsButton	{ send client setSaveOption format fits }
	x11Button	{ send client setSaveOption format x11  }
	epsButton	{ send client setSaveOption format eps  }
	rawButton	{ send client setSaveOption format raw  }
	}
    }
} ; foreach fmt $fileFmtButtons { send $fmt addCallback set_format }

proc setSaveFile { widget cbtype args } \
{
	send client setSaveOption fname $args
	send saveStatus set label [format "output file set to %s" $args]
}; send saveFile addCallback setSaveFile


proc doSaveOptions { param old new } \
{
    global format saveColor
    global warnings

    send saveStatus set label {}
    set val [join [lrange $new 1 end] " "]

    #print [format "doSaveOptions %s = %s" [lindex $new 0] $val]
    switch [lindex $new 0] {
    format  {   
		# Now (de)sensitize the color options depending on the format,
		# force the color choice when needed.
    		send $format set on false
		switch [lindex $val 0] {
		ras       { #send svRGBButton setSensitive false
		            send svPseudoButton setSensitive true
			    set format rasButton
		          }
		gif       { send svRGBButton setSensitive false
		            send svPseudoButton setSensitive true
		            if {$saveColor == "svRGBButton"} {
		                send $saveColor set on false
		                send svPseudoButton set on true
		                set saveColor svPseudoButton
		            }
			    set format gifButton
		          }
		jpeg      { send svRGBButton setSensitive true
		            send svPseudoButton setSensitive true
			    set format jpegButton
		          }
		tiff      { send svRGBButton setSensitive false
		            send svPseudoButton setSensitive true
			    set format tiffButton
		          }
		fits      { send svRGBButton setSensitive false
		            send svPseudoButton setSensitive false
		            send $saveColor set on false
		            send svGrayButton set on true
		            set saveColor svGrayButton
			    set format fitsButton
		          }
		x11       { send svRGBButton setSensitive true
		            send svPseudoButton setSensitive true
			    set format x11Button
		          }
		eps       { send svRGBButton setSensitive true
		            send svPseudoButton setSensitive true
			    set format epsButton
		          }
		raw       { send svRGBButton setSensitive true
		       	    send svPseudoButton setSensitive true
			    set format rawButton
		          }
		}
    		send $format set on true
	    }
    color   { send $saveColor set on false
	      switch [lindex $val 0] {
	      grayscale   { send svGrayButton set on true
     			    set saveColor svGrayButton
			  }
	      pseudocolor { send svPseudoButton set on true
     			    set saveColor svPseudoButton
			  }
	      rgb	  { send svRGBButton set on true
     			    set saveColor svRGBButton
			  }
	      }
	    }
    fname   { send saveFile set string $val
	    }
    status  { send saveStatus set label $val
	      send server synchronize
	    }
    text    { send saveData set label $val
	    }
    warning { if {$warnings} { Wexec server $val }
	    }
    }
} ; send saveOptions addCallback doSaveOptions


# Color group procedures.
#---------------------------------
send svGrayButton   addCallback "send client setSaveOption color grayscale"
send svPseudoButton addCallback "send client setSaveOption color pseudocolor"
send svRGBButton    addCallback "send client setSaveOption color rgb"


proc Save args \
{
    global panel_up

    send imagewin setCursorType busy

    # Get the print command or file template if not previous reset.
    set val [ send saveFile get string ]
    send client setSaveOption fname $val
    send saveStatus set label [format "output file set to %s" $args]

    send client save
    send imagewin setCursorType idle
} ; send okaySave addCallback Save



################################################################################
# TILE GEOMETRY
################################################################################

set tileSel	2
set tileOpt	0
set tileNcols	2
set tileNrows	1
set tile_frames {}

proc selectTileOrientation { widget type select args } \
{
    global tileSel tileOpt

    set w { nrowLab ncolLab nrdecrease nrincrease ncdecrease ncincrease }
    if {$select == "Manual"} {
	foreach p $w { send $p setSensitive True }
    } elseif {$select != "none"} {
	foreach p $w { send $p setSensitive False }
    }

    set w { byCols bottomUp labelFrames labelImname labelTitles }
    if {$select == "Disabled"} {
	foreach p $w { send $p setSensitive False }
    } else {
	foreach p $w { send $p setSensitive True }
    }

    switch $select {
    Disabled	 { set tileSel 0 }
    Manual	 { set tileSel 1
		   set nx [send nctext get label]
    		   set ny [send nrtext get label]
		   set select [format "%dx%d" $nx $ny]
		 }
    Best	 { set tileSel 2 }
    Square	 { set tileSel 3 }
    Horizontal	 { set tileSel 4 }
    Vertical	 { set tileSel 5 }
    "One Row"	 { set tileSel 6 }
    "One Column" { set tileSel 7 }
    none	 { send tileMode set selection $tileSel	; return }
    }

    # Reset the button in case we're called directly from elsewhere.
    send tileMode set selection $tileSel

    # Send the option to the client.
    if {$tileSel > 0} {
        setTileFrames
        send client setOption tileFrames "True"
	set tileOpt $tileSel
    } else {
        send client setOption tileFrames "False"
    }

} ; send tileMode addCallback selectTileOrientation

proc tileSelToLabel { selection args } \
{
    switch $selection {
    0    { return "Disabled"	}
    1    { return "Manual"	}
    2    { return "Best"	}
    3    { return "Square"	}
    4    { return "Horizontal"	}
    5    { return "Vertical"	}
    6    { return "One Row"	}
    7    { return "One Column"	}
    }
    return "Best"
}

# Callback for the fill style options.
proc selectFillStyle { widget type state args } \
{
    if {$state} { set not False } else { set not True }

    switch $widget {
    byCols   	{ send client setOption tileByRows $not  }
    bottomUp 	{ send client setOption tileTopDown $not }
    }
} ; foreach w {byCols bottomUp} { send $w addCallback selectFillStyle }

# Callback for the tile labelling options.
proc selectTileLabels { widget type state args } \
{
    if {$state} { 
        switch $widget {
        labelFrames { send client setOption tileLabels 1 }
        labelImname { send client setOption tileLabels 2 }
        labelTitles { send client setOption tileLabels 3 }
        }
    } else {
	send client setOption tileLabels 0
    }
    send $widget set on $state
}
foreach w {labelFrames labelImname labelTitles} {
   send $w addCallback selectTileLabels
}

# Callback for the Tile Frame selection toggles.
proc setTileFrames args \
{
    global tile_frames tileSel tileNcols tileNrows

    # No-op if tiling isn't enabled.
    if {$tileSel == 0} \
	return

    # Get the new tile frames list.
    set tile_frames {}
    for {set i 1} {$i <= 16} {incr i} {
	if {[send tFrame$i get state]} {
	    lappend tile_frames $i
	}
    }

    # Reset the geometry.
    set geom [format "%dx%d" $tileNcols $tileNrows]
    switch $tileSel {
    1   { send client setOption tileGeom $geom      \{ $tile_frames \} }
    2   { send client setOption tileGeom Best       \{ $tile_frames \} }
    3   { send client setOption tileGeom Square     \{ $tile_frames \} }
    4   { send client setOption tileGeom Horizontal \{ $tile_frames \} }
    5   { send client setOption tileGeom Vertical   \{ $tile_frames \} }
    6   { send client setOption tileGeom Row        \{ $tile_frames \} }
    7   { send client setOption tileGeom Column     \{ $tile_frames \} }
    }
}; for {set i 1} {$i <= 16} {incr i} {send tFrame$i addCallback setTileFrames}

proc setAllTileFrames args \
{
    global tileNcols tileNrows
    for {set i 1} {$i <= 16} {incr i} {
	if {[send tFrame$i get sensitive]} {
	    send tFrame$i set state True
	}
    }
    setTileFrames
} ; send tAll addCallback setAllTileFrames

proc setNoTileFrames args \
{
    global tileNcols tileNrows
    for {set i 1} {$i <= 16} {incr i} {
	if {[send tFrame$i get sensitive]} {
	    send tFrame$i set state False
	}
    }
    setTileFrames
} ; send tNone addCallback setNoTileFrames

proc tileOptions { param old new } \
{
    global tileNcols tileNrows

    set tileNcols [lindex $new 0]
    set tileNrows [lindex $new 1]

    # Set the geometry.
    send nctext set label $tileNcols
    send nrtext set label $tileNrows
    send tileGeometry set label [format \
    	"Tile Geometry:  %-2dx%2d" $tileNcols $tileNrows]

} ; send tileOptions addCallback tileOptions


proc tileSetRows { widget args } \
{
    global nframes tile_frames

    set nx [send nctext get label]
    set ny [send nrtext get label]

    if {$widget == "nrdecrease" && [expr ($ny-1)] > 0} {
	incr ny -1
    } elseif {$widget == "nrincrease" && [expr ($ny+1)] <= $nframes} {
	incr ny 1
    } else {
	return
    }
    set geom [format "%dx%d" $nx $ny]
    send client setOption tileGeom $geom $tile_frames
} ; foreach w { nrdecrease nrincrease } { send $w addCallback tileSetRows }

proc tileSetCols { widget args } \
{
    global nframes tile_frames

    set nx [send nctext get label]
    set ny [send nrtext get label]

    if {$widget == "ncdecrease" && [expr ($nx-1)] > 0} {
	incr nx -1
    } elseif {$widget == "ncincrease" && [expr ($nx+1)] <= $nframes} {
	incr nx 1
    } else {
	return
    }
    set geom [format "%dx%d" $nx $ny]
    send client setOption tileGeom $geom $tile_frames
} ; foreach w { ncdecrease ncincrease } { send $w addCallback tileSetCols }


# Initialize the frame tiling.
setAllTileFrames
selectTileOrientation junk junk Disabled
selectFillStyle byRows  junk True
selectFillStyle topDown junk True
selectTileLabels labelImname junk False

################################################################################
#  Coords Panel Callbacks.
################################################################################

# In case we need to change the values....
#global wcsPHeight wcsPTxtHeight wcsPGrHeight wcsPOptHeight
#set wcsPHeight		267
#set wcsPTxtHeight	132
#set wcsPGrHeight	175
#set wcsPOptHeight	233
#setCoordPanelHeight

set wcsPHeight		267		;# full panel no options
set wcsPTxtHeight	132		;# size of text area box
set wcsPGrHeight	175		;# size of text area group
set wcsPOptHeight	233		;# extra height for opts boxes

# Set the WCS readout panel sensitivity depending on whether the ISM
# is currently enabled.
proc setCoordPanelSensitivity args \
{
    set widgets { 
	wpWcs2 wpWcs3 wpWcs4 
	wiWcs2 wiWcs3 wiWcs4 
	wlWcs2 wlWcs3 wlWcs4
	sysWcs2 sysWcs3 sysWcs4 
	fmtWcs2 fmtWcs3 fmtWcs4
    }

    send sysWcs1 set label "Display"
    send fmtWcs1 set label "Default"

    for {set i 2} {$i <= 4} {incr i} {
        send sysWcs$i set label "None" ; send fmtWcs$i set label "Default"
        send wpWcs$i  set on False     ; send wiWcs$i  set on False
        send wtWcs$i  set height 4
    }

    if {[send ismToggle get on]} {
        send sysWcs2 set label "World" ; send fmtWcs2 set label "Default"
	send wpWcs2  set on True       ; send wiWcs2  set on True
        send wtWcs2  set height 17

        foreach w $widgets { send $w setSensitive True }
    } else {
        foreach w $widgets { send $w setSensitive False }
    }
}


# Set the Coords Panel height  depending on the option settings.
proc setCoordPanelHeight args \
{
    global wcsPHeight wcsPOptHeight wcsPTxtHeight wcsPGrHeight
    global tabTop

    if {$tabTop != "wcs_panel"} \
	return

    # Get the height of the text area
    set panel_h $wcsPHeight
    set shrinkage 0
    foreach w { wpWcs1 wpWcs2 wpWcs3 wpWcs4 woptFBinfo } {
	if {[send $w get on] == 0} {
	    incr shrinkage 13
	}
    }
    if {[send woptTitles get on] == 0} {
	incr shrinkage 26
    }

    set ph [expr ($wcsPHeight - $shrinkage)]
    if {[send wcsOptions get on] == 1} {
	incr ph $wcsPOptHeight
    }

    send wcsGroup set height [ expr ($wcsPGrHeight - $shrinkage) ]
    send wcsFrame set height [ expr ($wcsPTxtHeight - $shrinkage) ]
    send panel    set height $ph
}

# Toggle the options display for the panel.
proc wcsOptToggle { widget type state args } \
{
    global wcsPOptHeight
    set h [ send panel get height ] 
    if {$state == 1} {
	send panel set height [ expr ($h + $wcsPOptHeight) ]
    } else { 
	send panel set height [ expr ($h - $wcsPOptHeight) ]
    }
} ; send wcsOptions addCallback wcsOptToggle

# Handle the panel display toggles.
proc wcsCoordsCB { widget type state args } \
{

    set hght [ expr (($state == 1) ? 17 : 4)]
    switch $widget {
    wpWcs1	{ send wtWcs1 set height $hght	}
    wpWcs2	{ send wtWcs2 set height $hght	}
    wpWcs3	{ send wtWcs3 set height $hght	}
    wpWcs4	{ send wtWcs4 set height $hght	}
    woptFBinfo	{ send wtFBCfg set height $hght }
    woptTitles	{ send wtName set height $hght ; send wtTitle set height $hght }
    }
    setCoordPanelHeight                 
}
set wcValues { wpWcs1 wpWcs2 wpWcs3 wpWcs4 woptFBinfo woptTitles }
foreach w $wcValues { send $w addCallback wcsCoordsCB }


# Handle WCS label string options.
set wcsLabels 1
proc wcsLabelsCB { widget type state args } \
{
    global up_todo wcsLabels
    set wcsLabels $state
    #resizeCoordsBox 0
    resizeCoordsBox $up_todo
    updateCoordsBox
} ; send woptLabels addCallback wcsLabelsCB


# Toggle the BPM tracking state.
proc wcsBPMCB { widget type state args } \
{
    global ism_enable
    if ($ism_enable) { catch { send wcspix set bpm $state } }
} ; send woptBPM addCallback wcsBPMCB


# Procedures to format lines in the wcsText box.
proc wcsFmtImname { name } \
{
    send wtName    set string [format "     Name:  %s" [string trimleft $name]]
}

proc wcsFmtImtitle { title } \
{
    send wtTitle   set string [format "    Title:  %s" [string trimleft $title]]
}

proc wcsFmtFBConfig args \
{
    global frameWidth frameHeight frame nframes
    set buf [ format "%5d x %-5d" $frameWidth $frameHeight ]
    set line [ format "Frame Buf:  %-13s             Frame:  %d of %d" \
	[string trimleft $buf] $frame $nframes ]
    send wtFBCfg set string $line
}

proc wcsFmtIValue { value } \
{
    global coord
    set line [ format " Pixel:  %.11s" $value ]
    send wtIPixval set string $line
    if {[info exists coord(ival)]} {
        set coord(ival) $value
        updateCoordsBox
    }
}

proc wcsFmtSValue { value } \
{
    global coord
    set line [ format " Scaled:  %.8s" $value ]
    send wtSPixval set string $line
    set coord(sval) [format "%s" $value]
}

proc wcsFmtBValue { value } \
{
    global coord

    if { [send woptBPM get on] } {
        set line [ format " BPM:  %s" $value ]
        set color [expr { ($value == 0) ? "black" : "red" } ]
        set msg [format "set string \{%s\}; set background %s" $line $color ]
        set coord(bval) [format "%s" $value]
    } else {
        set line [ format " BPM:  (off)" ]
        set msg [format "set string \{%s\}" $line]
    }
    send wtBPixval $msg
}

proc wcsFmtWcs { num wcsname x y xunit yunit args } \
{ 
    global coord coordLab wcsLabels

    if {$wcsLabels} {
        set line [ format "%4s: %12s  %4s: %12s  WCS: %s" \
            $xunit $x $yunit $y [string trimleft $wcsname] ]
    } else {
        set line [ format "%4s  %12s  %4s  %12s       %s" \
            "    " $x "    " $y [string trimleft $wcsname] ]
    }
    send wtWcs$num set string $line

    if {[info exists coord(wcs$num)]} {
	if {$num == 1} {
            set coord(wcs1) [ format "\{%s\} \{%s\} \{%s\}" $x $y $coord(sval) ]
	} elseif {$num == 2} {
            set coord(wcs2) [ format "\{%s\} \{%s\} \{%s\}" $x $y $coord(ival) ]
	} else {
	    set coord(wcs$num) [ format "\{%s\} \{%s\} \{%s\}" $x $y $wcsname  ]
	}

	set coordLab(wcs$num) [ format "\{%s\} \{%s\} \{%s\}" \
	    $xunit $yunit [string trimleft $wcsname ] ]
        updateCoordsBox
    }
}



# Handle the wcsbox readout.
#------------------------------
set  up_todo	  2
set  up_done	  0
set  coord(ival)  0.
set  coord(sval)  0.
set  coord(bval)  0
set  coord(wcs1)  { 0. 0. 0. }
set  coord(wcs2)  { 0. 0. 0. }
set  coord(wcs3)  { 0. 0. 0. }
set  coord(wcs4)  { 0. 0. 0. }

proc wcsCoordB { widget type state args } \
{
    global coord up_todo

    switch $widget {
    wiWcs1	{ set line wcs1  ;set coord($line) { 0. 0. "" } }
    wiWcs2	{ set line wcs2  ;set coord($line) { 0. 0. "" } }
    wiWcs3	{ set line wcs3  ;set coord($line) { 0. 0. "" } }
    wiWcs4	{ set line wcs4  ;set coord($line) { 0. 0. "" } }
    }

    if {$state} {
	incr up_todo
    } else {
	unset coord($line)
	incr up_todo -1
    }

    resizeCoordsBox $up_todo
    updateCoordsBox
}
set wiValues { wiWcs1 wiWcs2 wiWcs3 wiWcs4 }
foreach w $wiValues { send $w addCallback wcsCoordB }


# Resize the coords box depending on the panel options.
proc resizeCoordsBox { nlines } \
{
    global track_enable wcsLabels winWidth winHeight wcsboxGeom 

    if {! $track_enable} \
	return

    send wcsbox getAttributes width cur_w height cur_h 
    set defGeom [format "%sx%s-5-5" $cur_w $cur_h]
    send imagewin parseGeometry $wcsboxGeom $defGeom x y width height

    set ew [expr (($wcsLabels == 1) ? 125 : 65)]

    # Reset to the default geometry
    if {$nlines == 0} {
	set x [expr ($x + $ew)]
	set y [expr ($y + $height - 17 + 1)]
	set new_w  166
	set new_h  17

    } else {
	if {$width > 166} {			;# not using default wcsbox
	    set new_w $width
	} else {
	    set new_w [expr ($width + $ew)]
	    set x [expr ($x - $ew)]
	    if {$wcsLabels == 0} {
		incr x 60
	    }
	}
        set new_h [ expr ($nlines * 17) ]
	set y [expr ($y + $height - $new_h + 1)]
    }

    # Bounds checking.
    if {$x < 5} {
	set x 5
    } elseif {$x > [expr ($winWidth - $new_w - 5)]} {
        set x [expr ($winWidth - $new_w - 5)]
    }
    if {$y < 5} {
	set y 5
    } elseif {$y > [expr ($winHeight - $new_h - 5)]} {
        set y [expr ($winHeight - $new_h - 5)]
    }

    # Finally redraw the marker.
    send wcsbox "\
        setAttributes     \
	    width  $new_w \
	    height $new_h \
	    x	   $x     \
	    y	   $y;    \
	redraw"

    set wcsboxGeom [send imagewin getGeometry $x $y $new_w $new_h]
    send client encodewcs [expr ($winWidth / 2)] [expr ($winHeight / 2)]
    updateCoordsBox
}


# Shortcuts for known WCS labels.
set labels(display)		"TV"
set labels(logical)		"Log"
set labels(physical)		"Phys"
set labels(equatorial)		"Eq"
set labels(ecliptic)		"Ecl"
set labels(galactic)		"Gal"
set labels(supergalactic)	"SGal"
set labels(amplifier)		"Amp"
set labels(ccd)			"CCD"
set labels(detector)		"Det"


# Format the coords box marker with the selected output options.
proc updateCoordsBox args \
{
    global ism_enable coord coordLab wcsLabels
    global up_done up_todo labels track_enable
    global coord

    if {! $ism_enable} \
	return

    incr up_done

    set text ""
    foreach l {wcs1 wcs2 wcs3 wcs4} {
	if {[info exists coord($l)]} {
	    set x [lindex $coord($l) 0]
	    set y [lindex $coord($l) 1]
	    set z [string tolower [string trimleft [lindex $coord($l) 2] ] ]
	    if {[info exists labels($z)]} {
		set z $labels($z)
	    }

	    if {$wcsLabels && [info exists coordLab($l)]} {
	        set lx [lindex $coordLab($l) 0]
	        set ly [lindex $coordLab($l) 1]
	        append text [format " %4s %12.12s %4s %12.12s %9.9s \n" \
		    $lx $x $ly $y $z ]
	    } else {
	        append text [format " %12.12s %12.12s %9.9s \n" $x $y $z ]
	    }
	}
    }

    # Now send the string.
    if {$track_enable} {
	set color [expr { ($coord(bval) == 0) ? "black" : "red" } ]
        set txt [format "set text \{%s\}; set textBgColor %s; redraw noerase" \
		$text $color ]
        send wcsbox $txt
    }

    if {$up_done >= $up_todo} {
        set up_done	0			;# reset counter
    }
}


# Create the WCS format menus.
#------------------------------------
proc setWcsFmt { format line } \
{
    catch { send wcspix set format $format $line }
}

for {set i 1} {$i <= 4} {incr i} {
   set items {}
   lappend items "\"Default\"     f.exec \{setWcsFmt default $i\}"
   lappend items "\"Sexigesimal\" f.exec \{setWcsFmt hms     $i\}"
   lappend items "\"Degrees\"     f.exec \{setWcsFmt deg     $i\}"
   lappend items "\"Radians\"     f.exec \{setWcsFmt rad     $i\}"
   editMenu fmtMenu$i fmtWcs$i $items
}


# Create the default WCS type menus.
#------------------------------------

set defaultWcsMenu {
   { "None"		f.exec	{setWcsSys none     WCS_LINE } }
   { "Display"		f.exec	{setWcsSys display  WCS_LINE } }
   { "World"		f.exec	{setWcsSys world    WCS_LINE } }
   { "Logical"		f.exec	{setWcsSys logical  WCS_LINE } }
   { "Physical"		f.exec	{setWcsSys physical WCS_LINE } }
   { 			f.dblline	}
}

proc setWcsSys { sys line } \
{
    if {[string tolower $sys] == "none"} {
        wcsCoordB wiWcs$line junk 0
        send sysWcs$line set label "None"; send fmtWcs$line set label "Default"
        send wpWcs$line  set on False    ; send wiWcs$line  set on False
        send wtWcs$line  set height 4
	setCoordPanelHeight

    } else {
        catch { send wcspix set wcs $sys $line }
    }
}

proc resetDefaultWcsMenu args \
{
    global defaultWcsMenu

    for {set i 1} {$i <= 4} {incr i} {
        regsub -all WCS_LINE $defaultWcsMenu $i menu_def
        editMenu sysMenu$i sysWcs$i $menu_def
    }
} ; resetDefaultWcsMenu


# Initialize the coordinates panel.
#------------------------------------

proc initCoordsPanel args \
{
    #send wcLine set height 2		;# kludge for label widget

    # Initialize the display strings in the coords box.
    wcsFmtImname   ""
    wcsFmtImtitle  ""
    wcsFmtFBConfig
    wcsFmtIValue  "0." ; wcsFmtSValue "0." ; wcsFmtBValue "0"
    wcsFmtWcs      1 "" "" "" "   X" "   Y"
    wcsFmtWcs      2 "" "" "" "   X" "   Y"
    wcsFmtWcs      3 "" "" "" "   X" "   Y"
    wcsFmtWcs      4 "" "" "" "   X" "   Y"

    send fmtWcs1 set label Default
    send wpWcs1 set on True  ;send wiWcs1 set on True
    send wpWcs2 set on True  ;send wiWcs2 set on True
    send wpWcs3 set on False ;send wiWcs3 set on False ;send wtWcs3 set height 4
    send wpWcs4 set on False ;send wiWcs4 set on False ;send wtWcs4 set height 4

    # Set the Coords Panel height.
    set wcsPTxtHeight [send wcsText get height]
    setCoordPanelHeight

    # Set the WCS readout panel sensitivity.
    setCoordPanelSensitivity

} ; initCoordsPanel




################################################################################
# Compass indicator procedures.
################################################################################

set compassColor	207			;# normally this is yellow
set last_compass	[send compass get on]	;# save compass state

proc drawCompass args \
{
    global ism_enable frame frameCache compassColor Compass Orient
    global panner_x panner_y panner_width panner_height cur_objid
    global redraw_compass last_compass

	
    if {! [send compass get on]} \
	return

    eraseCompass 				;# erase the old compass

    if {! [info exists frameCache($frame)] } {
        set id -1
    } elseif {$cur_objid != [lindex $frameCache($frame) 1]} {
        set id [lindex $frameCache($frame) 1]
    } else {
        set id $cur_objid
    }

    if { [info exists Compass($id)] } {
        set angle     [lindex $Compass($id) 0]
        set north_x   [lindex $Compass($id) 1]
        set north_y   [lindex $Compass($id) 2]
        set east_x    [lindex $Compass($id) 3]
        set east_y    [lindex $Compass($id) 4]
        set transpose [lindex $Compass($id) 5]
        set xlab      [lindex $Compass($id) 6]
        set ylab      [lindex $Compass($id) 7]
    } else {
	set north_x  0.0   	; set north_y  1.0
	set east_x   1.0	; set east_y   0.0
	set xlab       X   	; set ylab       Y
        set angle    0.0   	; set transpose  0
	set Compass($id) { 0.0 1.0 0.0 1.0 0.0 0 X Y }
    }
    set xflip 1
    set yflip 1

    # Adjust the compass for the display orientation (e.g. image sections
    # used to flip an image during display).
    if { [info exists Orient($id)] } {
        set xflip [expr $xflip * [lindex $Orient($id) 1] ]
        set yflip [expr $yflip * [lindex $Orient($id) 2] ]
    }

    # Get the panner center position.
    set pcx [expr ($panner_x + $panner_width  / 2)]
    set pcy [expr ($panner_y + $panner_height / 2)]

    # Setup for the overlay.
    send imagewin getLogRes  sv_xl sv_yl
    send imagewin getPhysRes sv_xp sv_yp
    send imagewin setLogRes $sv_xp $sv_yp
    send imagewin setLineWidth 2

    set xflip [ expr ($xflip * ([send xflipButton get state] ?  -1 : 1))]
    set yflip [ expr ($yflip * ([send yflipButton get state] ?  -1 : 1))]

    # Normalized compass points.  The first row are the axes, second is
    # the pointer head, and last are the X/Y label coords.  Assumes a
    # zero rotation with North up and East left, or standard X/Y orientation.
    set cpoints {
	{-1 0} {0 0} {0 -1}
	{-0.07 -0.85} {0 -1} {0.07 -0.85} {-0.07 -0.85}
	{-1.2 0} {0 -1.2}
    }


    # Get rotation and scale factors.
    set angle [expr "atan2($north_y,$north_x)"]
    set coso  [expr "cos (-$angle)"]
    set sino  [expr "sin (-$angle)"]
    set scale [expr ([min $panner_width $panner_height] * 0.3)]

    # Initialize the drawing points.
    set pts {}

    set cpoints { }
    lappend cpoints [list $east_x  $east_y ]
    lappend cpoints [list 0 0]
    lappend cpoints [list $north_x $north_y]
    foreach p $cpoints {
	# Get the scaled position.
	set sx [expr ($scale * [lindex $p [expr "($transpose > 0) ? 1 : 0"]])]
	set sy [expr ($scale * [lindex $p [expr "($transpose > 0) ? 0 : 1"]])]

	# Translate to the scaled position.
	set rx [expr int($pcx + $sx + 0.5)]
	set ry [expr int($pcy - $sy + 0.5)]

	# Now handle the axis flip.
	set rx [expr (($xflip < 0) ? ($pcx + ($pcx - $rx)) : $rx)]
	set ry [expr (($yflip < 0) ? ($pcy + ($pcy - $ry)) : $ry)]
	lappend pts $rx $ry
    }


    set rpoints { }
    set hpoints { {0.0 0.0} {-0.1 -0.07} {-0.1 0.07} {0.0 0.0} }
    foreach p $hpoints {
	# Break out the position.
	set sx [lindex $p [expr "($transpose > 0) ? 1 : 0"]]
	set sy [lindex $p [expr "($transpose > 0) ? 0 : 1"]]

	# Do the rotation of the head at the origin.
	set rx [expr ($north_x + ($sx * $coso + $sy * $sino))]
	set ry [expr ($north_y - ($sx * $sino + $sy * $coso))]

	lappend rpoints [list $rx $ry]
    }
    foreach p $rpoints {
	# Get the scaled position.
	set sx [expr ($scale * [lindex $p [expr "($transpose > 0) ? 1 : 0"]])]
	set sy [expr ($scale * [lindex $p [expr "($transpose > 0) ? 0 : 1"]])]

	# Translate to the scaled position.
	set rx [expr int($pcx + $sx + 0.5)]
	set ry [expr int($pcy - $sy + 0.5)]

	# Now handle the axis flip.
	set rx [expr (($xflip < 0) ? ($pcx + ($pcx - $rx)) : $rx)]
	set ry [expr (($yflip < 0) ? ($pcy + ($pcy - $ry)) : $ry)]
	lappend pts $rx $ry
    }

    set lpoints { }
    lappend lpoints [list [expr "$east_x-0.2"] $east_y ]
    lappend lpoints [list $north_x [expr "$north_y+0.2"] ]
    foreach p $lpoints {
	# Get the scaled position.
	set sx [expr ($scale * [lindex $p [expr "($transpose > 0) ? 1 : 0"]])]
	set sy [expr ($scale * [lindex $p [expr "($transpose > 0) ? 0 : 1"]])]

	# Translate to the scaled position.
	set rx [expr int($pcx + $sx + 0.5)]
	set ry [expr int($pcy - $sy - 0.5)]

	# Now handle the axis flip.
	set rx [expr (($xflip < 0) ? ($pcx + ($pcx - $rx)) : $rx)]
	set ry [expr (($yflip < 0) ? ($pcy + ($pcy - $ry)) : $ry)]
	lappend pts $rx $ry
    }


    # Draw the compass axes.
    set compassPts [lrange $pts 0 5]
    send imagewin setColorIndex $compassColor
    send imagewin drawPolyline $compassPts

    
    # Draw the compass pointer.
    set head [lrange $pts 6 13]
    send imagewin setFillType solid
    send imagewin drawPolygon $head

    # Draw the labels.
    send imagewin drawAlphaText [lindex $pts 14] [lindex $pts 15] $xlab
    send imagewin drawAlphaText [lindex $pts 16] [lindex $pts 17] $ylab

    send imagewin setLogRes $sv_xl $sv_yl

    set redraw_compass 0

} ; foreach w {xflip yflip} { send $w addCallback drawCompass }


# This is a kludge to redraw the compass after it is erased when displaying
# a new image.  Once the user moves the mouse back into the main window we'll
# do the redraw.
send imagewin addEventHandler drawCompass enterWindowMask



proc createCompassMarker { pts args } \
{
    set cm_points { }
    lappend cm_points [lrange $pts 0 1]
    lappend cm_points [lrange $pts 2 3]
    lappend cm_points [lrange $pts 4 5]

    print [list $cm_points]

}


proc eraseCompass args \
{
    global panner_mapping
    send imagewin refreshMapping $panner_mapping
}

proc toggleCompass { widget type state args } \
{
    global last_compass

    if {$state} {
	drawCompass
	set last_compass True
    } else {
	eraseCompass
	set last_compass False
    }
} ; send compass addCallback toggleCompass



     
################################################################################
# RULER MARKERS
################################################################################

set rulerX	0			;# ruler start in screen coords
set rulerY	0
set rulerPts	{ {0 0} {0 0} {0 0} }	;# ruler vertices
set rulerList	{ }			;# ruler list

set rulerSticky	{ }			;# list of sticky rulers
set isSticky	"Sticky"		;# menu label

set rulerWCS	0			;# use WCS coords
set rulerXWCS	0			;# ruler start in WCS units
set rulerYWCS	0
set rulerXWCS2	0			;# ruler end in WCS units
set rulerYWCS2	0
set rulerFmt	pixel			;# ruler label format


# Translations when pointer is inside marker.
set rulerTranslations { \
      !Ctrl <Key>b: call(prevFrame,$name)
      !Ctrl <Key>b: call(prevFrame,$name)
      !Ctrl <Key>f: call(nextFrame,$name)
      !Ctrl <Key>h: call(move_cursor,-1,0)
      !Ctrl <Key>j: call(move_cursor,0,1)
      !Ctrl <Key>k: call(move_cursor,0,-1)
      !Ctrl <Key>l: call(move_cursor,1,0)
      !Ctrl <Key>n: call(normalize)
      !Ctrl <Key>c: call(cpZoomAction,centerFrame)
      !Ctrl <Key>i: call(cpInvert)
      !Ctrl <Key>m: call(cpMatchFrames)
      !Ctrl <Key>r: call(cpRegisterFrames)
      !Ctrl <Key>p: call(togglePanner)
       !Alt <Key>1: call(cpSetFrame,frame1)
       !Alt <Key>2: call(cpSetFrame,frame2)
       !Alt <Key>3: call(cpSetFrame,frame3)
       !Alt <Key>4: call(cpSetFrame,frame4)
      !Ctrl <Key>1: call(cpZoom,1,1,fixed)
      !Ctrl <Key>2: call(cpZoom,2,2,fixed)
      !Ctrl <Key>3: call(cpZoom,3,3,fixed)
      !Ctrl <Key>4: call(cpZoom,4,4,fixed)
      !Ctrl <Key>5: call(cpZoom,5,5,fixed)
      !Ctrl <Key>6: call(cpZoom,6,6,fixed)
      !Ctrl <Key>7: call(cpZoom,7,7,fixed)
      !Ctrl <Key>8: call(cpZoom,8,8,fixed)
      !Ctrl <Key>9: call(cpZoom,9,9,fixed)
    <Key>BackSpace: call(deleteNamedRuler,NAME,$x,$y)
       <Key>Delete: call(deleteNamedRuler,NAME,$x,$y)
	<KeyPress>: m_input()
	<Btn3Down>: call(setRulerMenu) popup(rulerMenu)
	  <Btn3Up>: popdown(rulerMenu)
!Ctrl <Btn1Motion>: track-cursor() call(wcsUpdate,$x,$y) call(resizeRuler,$x,$y,0)
    !Ctrl <Btn1Up>: call(deleteRuler,$x,$y)
	  <Motion>: track-cursor() call(wcsUpdate,$x,$y) call(magnifierMapImage,$x,$y)
}



# Popup menu in effect when inside marker.
set rulerMenuDescription {
    {	"Ruler"    	  f.title			}
    {		    	  f.dblline			}
    {	"$isSticky"	  f.exec { 
			      toggleSticky $ruler
			  }				}
    {		    	  f.line			}
    {	"Units"	  	  f.menu rulerUnits		}
    {	"Color"	  	  f.menu rulerColor		}
    {		    	  f.line			}
    {	"Draw into Frame" f.exec { 
			      writeRuler $ruler
			  } sensitive False		}
    {		    	  f.line			}
    {	"Destroy"	  f.exec { 
		              scan $ruler "ruler%d" num
		              deleteNamedRuler $num x y
		    	  }				}
} ; createMenu rulerMenu imagewin $rulerMenuDescription

set rulerUnitsDescription {
    {	Units		f.title				  }
    {			f.dblline			  }
    {	"Pixels"	f.exec { setUnits $ruler pixel  } }
    {	"Arc Seconds"  	f.exec { setUnits $ruler arcsec  
			} sensitive { ($rulerWCS > 0) ? "True" : "False"} }
    {	"Arc Minutes"   f.exec { setUnits $ruler arcmin  
			} sensitive { ($rulerWCS > 0) ? "True" : "False"} }
    {	"Degrees"   	f.exec { setUnits $ruler degrees 
			} sensitive { ($rulerWCS > 0) ? "True" : "False"} }
} ; createMenu rulerUnits rulerMenu $rulerUnitsDescription

set rulerColorDescription {
    {	Color	f.title					}
    {		f.dblline				}
    {	""	f.exec "r_setColor $ruler black yellow"
		    bitmap solid foreground black 	}
    {	""	f.exec "r_setColor $ruler white black" 
		    bitmap solid foreground white 	}
    {	""	f.exec "r_setColor $ruler red yellow" 
		    bitmap solid foreground red 	}
    {	""	f.exec "r_setColor $ruler green black" 
		    bitmap solid foreground green 	}
    {	""	f.exec "r_setColor $ruler blue white" 
		    bitmap solid foreground blue 	}
    {	""	f.exec "r_setColor $ruler magenta black" 
		    bitmap solid foreground magenta 	}
    {	""	f.exec "r_setColor $ruler cyan black" 
		    bitmap solid foreground cyan 	}
    {	""	f.exec "r_setColor $ruler yellow black" 
		    bitmap solid foreground yellow 	}
} ; createMenu rulerColor rulerMenu $rulerColorDescription


proc makeRuler {parent x y} \
{
    global rulerTranslations ruleno rulerWCS rulerXWCS rulerYWCS
    global rulerPts rulerX rulerY rulerList
    global isSticky rulerMenuDescription rulerUnitsDescription
    global coord coordLab


    incr ruleno ; set ruler ruler$ruleno

    # Substitute so the marker translation will delete the marker
    # by it's number rather than the default parent widget name.
    regsub -all NAME $rulerTranslations $ruleno translations

    # Create the polygon for the marker.
    send $parent createMarker $ruler \
	type		polygon\
	createMode	noninteractive\
	translations	$translations\
        lineColor       yellow\
        fill       	False\
        highlightWidth  1\
        highlightColor  yellow\
        knotSize        0\
        activated       True\
        visible         False\
        sensitive       True\
	x		$x\
	y		$y

    # Define a callback so we can identify the ruler.
    send $ruler addCallback selectRuler focusIn focusOut

    # Create the text markers for the labels.
    send $parent set markerTextFont 6x9
    makeLabelMarker $parent rulerXlab$ruleno 5ch 1ch
    makeLabelMarker $parent rulerYlab$ruleno 5ch 1ch
    makeLabelMarker $parent rulerHlab$ruleno 8ch 1ch
    send $parent set markerTextFont 6x13

    set rulerX	$x				;# save the reference point
    set rulerY	$y

    set ref [ list $x $y ]			;# initialize the polygon
    set rx [ list [expr "$x +1"] $y ]
    set ry [ list $x [expr "$y +1"] ]
    set rulerPts [list $ref $rx $ry ]

    send $ruler setVertices $rulerPts		;# set attributes
    send $ruler set visible True"
    send $ruler setAttribute autoRedraw True

    # See whether we have a WCS to use.
    set rulerWCS  0
    set rulerXWCS 0
    set rulerYWCS 0
    for {set num 1} {$num <= 4 && $rulerWCS == 0} {incr num} {
	if { [info exists coordLab(wcs$num)] } {
	    set xl  [string tolower [lindex $coordLab(wcs$num) 0]]
	    set yl  [string tolower [lindex $coordLab(wcs$num) 1]]
	    set fmt [string tolower [send fmtWcs$num get label] ]
	    if {$xl=="  ra" || $xl=="elon" || $xl=="glon" || $xl=="slon"} {
		set rulerWCS $num
        	set rulerXWCS [wcs2log [lindex $coord(wcs$num) 0] $xl $fmt]
        	set rulerYWCS [wcs2log [lindex $coord(wcs$num) 1] $yl $fmt]
	    }
	}
    }

    # Edit the menus.
    set isSticky "Sticky"
    editMenu rulerMenu  imagewin $rulerMenuDescription
    editMenu rulerUnits imagewin $rulerUnitsDescription


    lappend rulerList $ruleno
}

proc wcs2log { val label fmt} \
{
    set newval $val
    if {$fmt == "sexigesimal" || $fmt == "default"} {
	scan $val "%d:%d:%f"  h m s
	set newval [expr "double($h) + double($m) / 60.0 + double($s) / 3600.0"]
	if {$label == "  ra"} {
	    set newval [expr "double($newval * 15.0)"]
	}
    }
    return [expr "double($newval)" ]
}


proc resizeRuler {x y redraw} \
{
    global rulerPts rulerX rulerY ruleno coord coordLab
    global rulerWCS rulerXWCS rulerYWCS rulerFmt
    global rulerXWCS2 rulerYWCS2


    # Track the mouse.
    set ref [ list $rulerX $rulerY ]
    set rx  [ list $x      $rulerY ]
    set ry  [ list $x      $y      ]
    set rulerPts [list $ref $rx $ry ]

    # Compute the distances.
    if {$rulerWCS > 0} {
 	set num $rulerWCS
	set xl  [string tolower [lindex $coordLab(wcs$num) 0]]
	set yl  [string tolower [lindex $coordLab(wcs$num) 1]]
	set fmt [string tolower [send fmtWcs$num get label] ]

	# Save the cursor coords in WCS so we can convert labels.
	if {$redraw} {
            set nx $rulerXWCS2
            set ny $rulerYWCS2
	} else {
            set nx  [wcs2log [lindex $coord(wcs$num) 0] $xl $fmt]
       	    set ny  [wcs2log [lindex $coord(wcs$num) 1] $yl $fmt]
            set rulerXWCS2 $nx
            set rulerYWCS2 $ny
	}
    }

    if {$rulerFmt == "pixel"} {
        set xdist [ expr "abs($x - $rulerX)" ]
        set ydist [ expr "abs($y - $rulerY)" ]
        set hdist [ expr "sqrt($xdist * $xdist + $ydist * $ydist)" ]
    } else {
        set xdist [ expr "abs($nx - $rulerXWCS)" ]
        set ydist [ expr "abs($ny - $rulerYWCS)" ]
        set hdist [ expr "sqrt($xdist * $xdist + $ydist * $ydist)" ]
    }

    # Redraw the polygon.
    send ruler$ruleno setVertices $rulerPts

    # Label the distances.
    setXRulerLabel $x $y $xdist
    setYRulerLabel $x $y $ydist
    setHRulerLabel $x $y $hdist
}

# Create a label marker for the ruler.
proc makeLabelMarker { parent name width height } \
{
    send $parent createMarker $name \
        type            text \
        createMode      noninteractive \
        width           $width \
        height          $height \
        lineWidth       0 \
        imageText       true \
        textBgColor     yellow \
        textColor       black \
        activated       true \
        visible         false
}

proc setXRulerLabel { cx cy dist } \
{
    global rulerX rulerY ruleno winWidth winHeight
    global cpXscale rulerFmt

    send rulerXlab$ruleno set visible False

    if {[expr "abs($cx - $rulerX)"] > 30} {
	switch $rulerFmt {
	pixel	{ set text [format "%.1f" [expr "$dist / $cpXscale"] ]	}
	arcsec	{ set text [format "%.2f\"" [expr "$dist * 3600.0"] ] 	}
	arcmin	{ set text [format "%.2f\'" [expr "$dist * 60.0"] ] 	}
	degrees	{ set text [format "%.2fd" "$dist" ] 			}
	}
	set len [expr [string length $text] + 1]
	send rulerXlab$ruleno "set width ${len}ch"

	# Compute the placement of the label marker.
	if {$cy > $rulerY} {
	    set yp [expr "$rulerY - 14"]
	} else {
	    set yp [expr "$rulerY + 2"]
	}
	if {$cx > $rulerX} {
	    set xp [expr "$rulerX + abs($cx - $rulerX)/2 - 10"]
	} else {
	    set xp [expr "$rulerX - abs($cx - $rulerX)/2 - 10"]
	}

	# Bounds checking.
	if {$xp < 0} { set xp 1 }
	if {$yp < 0} { set yp 1 }
	if {$xp > $winWidth}  { set xp [expr "$winWidth - 20" }
	if {$yp > $winHeight} { set yp [expr "$winHeight - 20" }

	send rulerXlab$ruleno "setAttributes x $xp y $yp"
	send rulerXlab$ruleno "set text \{$text\}; redraw erase"

	send rulerXlab$ruleno set visible True
    }
}

proc setYRulerLabel { cx cy dist } \
{
    global rulerX rulerY ruleno winWidth winHeight
    global cpYscale rulerFmt

    send rulerYlab$ruleno set visible False

    if {[expr "abs($cy - $rulerY)"] > 20} {
	switch $rulerFmt {
	pixel	{ set text [format "%.1f" [expr "$dist / $cpYscale"] ]	}
	arcsec	{ set text [format "%.2f\"" [expr "$dist * 3600.0"] ] 	}
	arcmin	{ set text [format "%.2f\'" [expr "$dist * 60.0"] ] 	}
	degrees	{ set text [format "%.2fd" "$dist" ] 			}
	}
	set len [expr [string length $text] + 1]
	send rulerYlab$ruleno "set width ${len}ch"

	# Compute the placement of the label marker.
	if {$cx > $rulerX} {
	    set xp [expr "$cx + 2"]
	} else {
	    set xp [expr "$cx - $len * 6 - 5"]
	}
	if {$cy > $rulerY} {
	    set yp [expr "$rulerY + abs($cy - $rulerY)/2"]
	} else {
	    set yp [expr "$rulerY - abs($cy - $rulerY)/2"]
	}

	# Bounds checking.
	if {$xp < 0} { set xp 1 }
	if {$yp < 0} { set yp 1 }
	if {$xp > $winWidth}  { set xp [expr "$winWidth - 20" }
	if {$yp > $winHeight} { set yp [expr "$winHeight - 20" }

	send rulerYlab$ruleno "setAttributes x $xp y $yp"
	send rulerYlab$ruleno "set text \{$text\}; redraw erase"
	send rulerYlab$ruleno set visible True
    } 
}

proc setHRulerLabel { cx cy dist } \
{
    global rulerX rulerY ruleno winWidth winHeight
    global cpYscale cpXscale rulerFmt

    send rulerHlab$ruleno set visible False

    set xdist [ expr "abs($cx - $rulerX)" ]
    set ydist [ expr "abs($cy - $rulerY)" ]
    set hdist [ expr "sqrt($xdist * $xdist + $ydist * $ydist)" ]

    if {$hdist > 30} {
	switch $rulerFmt {
	pixel	{ set text [format "%.1f" [expr "$dist / $cpXscale"] ]	}
	arcsec	{ set text [format "%.2f\"" [expr "$dist * 3600.0"] ] 	}
	arcmin	{ set text [format "%.2f\'" [expr "$dist * 60.0"] ] 	}
	degrees	{ set text [format "%.2fd" "$dist" ] 			}
	}
	set len [expr [string length $text] + 1]
	send rulerHlab$ruleno "set width ${len}ch"

	# Compute the placement of the label marker.
	if {$cx > $rulerX} {
	    set xp [expr "$rulerX + abs($cx - $rulerX)/2 - $len * 6"]
	} else {
	    set xp [expr "$rulerX - abs($cx - $rulerX)/2 - $len * 3"]
	}
	if {$cy > $rulerY} {
	    set yp [expr "$rulerY + abs($cy - $rulerY)/2"]
	} else {
	    set yp [expr "$rulerY - abs($cy - $rulerY)/2"]
	}

	# Bounds checking.
	if {$xp < 0} { set xp 1 }
	if {$yp < 0} { set yp 1 }
	if {$xp > $winWidth}  { set xp [expr "$winWidth - 20" }
	if {$yp > $winHeight} { set yp [expr "$winHeight - 20" }

	send rulerHlab$ruleno "setAttributes x $xp y $yp"
	send rulerHlab$ruleno "set text \{$text\}; redraw erase"
	send rulerHlab$ruleno set visible True
    } else {
	send rulerHlab$ruleno set visible False
    }
}


# Callback executed when a marker gets or loses the focus.
proc selectRuler {active_ruler event event_data} \
{
    global ruler
    switch $event {
	focusIn		{ set ruler $active_ruler }
	focusOut	{  }
    }
}

# Reset the ruler format type.
proc setUnits { ruler units } \
{
    global rulerFmt rulerX rulerY

    send $ruler getVertices pts
    set rulerX [lindex [lindex [lindex $pts 0] 0] 0]
    set rulerY [lindex [lindex [lindex $pts 0] 0] 1]
    set cx [lindex [lindex [lindex $pts 0] 1] 0] ; incr cx -1
    set cy [lindex [lindex [lindex $pts 0] 2] 1] ; incr cy -1

    set rulerFmt $units
    resizeRuler $cx $cy 1
}

# Menu option toggle callbacks.
proc toggleSticky { ruler } \
{
    global isSticky rulerSticky rulerMenuDescription

    set index [ lsearch $rulerSticky $ruler]
    if { $index >= 0 } {
	# Remove it from the list.
    	set rulerSticky [lreplace $rulerSticky $index $index]
	set isSticky "Sticky"
    } else {
	# Add it to the list.
	lappend rulerSticky $ruler 
	set isSticky "UnSticky"
    }
    editMenu rulerMenu imagewin $rulerMenuDescription
}

proc setRulerMenu args \
{
    global ruler isSticky rulerSticky rulerMenuDescription

    if { [lsearch $rulerSticky $ruler] >= 0 } {
	set isSticky "UnSticky"
    } else {
	set isSticky "Sticky"
    }
    editMenu rulerMenu imagewin $rulerMenuDescription
}


# Draw the ruler to the frame buffer as a graphic.
proc writeRuler { ruler } \
{
}

# Change the color of the ruler.
proc r_setColor {ruler bgcolor fgcolor}  {
			    
    # Recolor the polygon.
    send $ruler \
	"markpos; set lineColor $bgcolor; set highlightColor $bgcolor; redraw"

    # Recolor the labels.
    scan $ruler "ruler%d" num
    send rulerXlab$num \
	"markpos; set textBgColor $bgcolor; set textColor $fgcolor; redraw"
    send rulerYlab$num \
	"markpos; set textBgColor $bgcolor; set textColor $fgcolor; redraw"
    send rulerHlab$num \
	"markpos; set textBgColor $bgcolor; set textColor $fgcolor; redraw"
}


# Delete the current ruler, called when we have a Btn1Up on the current ruler.
proc deleteRuler {x y} { global ruleno ; deleteNamedRuler $ruleno $x $y }

# Delete all rulers on the screen, usually called when the view changes.
# We preserve the rulers marked as 'sticky'.
proc deleteAllRulers args \
{
    global rulerList rulerSticky

    foreach r $rulerList { 
        # Delete the ruler if it's not in the sticky list.
        if { [lsearch $rulerSticky ruler$r] == -1 } {
	    deleteNamedRuler $r x y 
        }
    }
}

# Delete a particular ruler, usually called from the translation table on
# the marker itself.
proc deleteNamedRuler {name x y} \
{
    global rulerList

    catch {
	send ruler$name      destroy
	send rulerXlab$name  destroy
	send rulerYlab$name  destroy
	send rulerHlab$name  destroy
    }

    # Remove the ruler from the list.
    set index [lsearch $rulerList $name]
    set rulerList [lreplace $rulerList $index $index]
}





###############################################
# Define procedure for the help panel
###############################################

# Help Panel Bitmaps
#-------------------
createBitmap iraf_logo 45 45 {
0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff,
0xff, 0x3f, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xfc, 0xff, 0xff, 0xff,
0xff, 0x3f, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xf0, 0xff, 0xff, 0xff,
0xff, 0x3f, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xe0, 0xff, 0xff, 0xff,
0xff, 0x3f, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xc0, 0xff, 0xff, 0xff,
0xff, 0x3f, 0x80, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x80, 0xfc, 0xff, 0xff,
0xff, 0x3f, 0x84, 0xf8, 0xff, 0xff, 0xff, 0x1f, 0x84, 0xf4, 0xff, 0xff,
0xff, 0x1b, 0x04, 0x09, 0x00, 0xfc, 0xff, 0x11, 0x04, 0x11, 0xf8, 0xff,
0x7f, 0x10, 0x04, 0x21, 0xc0, 0xff, 0x1f, 0x10, 0x04, 0x41, 0xf0, 0xff,
0x00, 0x18, 0x04, 0x01, 0xe0, 0xff, 0x00, 0x18, 0x00, 0x81, 0xc0, 0xff,
0x00, 0x08, 0x00, 0x01, 0xe0, 0xff, 0x07, 0x08, 0x00, 0x01, 0xf1, 0xff,
0x1f, 0x08, 0x80, 0x21, 0xf0, 0xff, 0xff, 0x08, 0xc0, 0x41, 0xf4, 0xff,
0xff, 0x08, 0xc0, 0x41, 0xf8, 0xff, 0xff, 0x09, 0xc0, 0xc1, 0xf0, 0xff,
0xff, 0x0b, 0x80, 0xc1, 0xf1, 0xff, 0xff, 0x07, 0x80, 0x81, 0xe1, 0xff,
0xff, 0x07, 0x80, 0x01, 0xc1, 0xff, 0xff, 0x07, 0x00, 0x01, 0xc0, 0xff,
0xff, 0x07, 0xc2, 0x05, 0x81, 0xff, 0xff, 0x07, 0xf2, 0x07, 0x81, 0xff,
0xff, 0x07, 0xf2, 0x17, 0x03, 0xff, 0xff, 0x03, 0xfa, 0x7f, 0x02, 0xfe,
0xff, 0x03, 0xfe, 0xff, 0x02, 0xfe, 0xff, 0x03, 0xfe, 0xff, 0x03, 0xfc,
0xff, 0x03, 0xff, 0xff, 0x07, 0xfc, 0xff, 0x83, 0xff, 0xff, 0x0f, 0xf8,
0xff, 0xc1, 0xff, 0xff, 0x3f, 0xf0, 0xff, 0xe1, 0xff, 0xff, 0x7f, 0xf8,
0xff, 0xf1, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xe0,
0xff, 0xf8, 0xff, 0xff, 0xff, 0xe3, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xe7,
0xff, 0xfc, 0xff, 0xff, 0xff, 0xef}; send helpIRAFLogo "set bitmap iraf_logo"
 
createBitmap noao_logo 45 45 {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0xfe, 0xff, 0xff,
0xff, 0xff, 0x01, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x00, 0xf8, 0xff, 0xff,
0xff, 0xff, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x00, 0xf8, 0xff, 0xff,
0xff, 0x7f, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x00, 0xf8, 0xff, 0xff,
0xff, 0xff, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x00, 0xf8, 0xff, 0xff,
0xff, 0xff, 0x01, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x03, 0xfe, 0xff, 0xff,
0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff,
0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff,
0xff, 0xff, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff,
0xff, 0xff, 0x03, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x03, 0xfe, 0xff, 0xff,
0xff, 0xff, 0x01, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x01, 0xfc, 0xff, 0xff,
0xff, 0xff, 0x00, 0xf8, 0xff, 0xff, 0xff, 0x7f, 0x00, 0xf0, 0xff, 0xff,
0xff, 0x7f, 0x00, 0xf0, 0xff, 0xff, 0xff, 0x3f, 0x00, 0xe0, 0xff, 0xff,
0xff, 0x3f, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x1f, 0x00, 0xc0, 0xff, 0xff,
0xff, 0x1f, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x80, 0xff, 0xff,
0xff, 0x0f, 0x00, 0x80, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0xff, 0xff,
0xff, 0x03, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x03, 0x00, 0x00, 0xfe, 0xff,
0xff, 0x01, 0x00, 0x00, 0xfc, 0xff, 0xff, 0x01, 0x00, 0x00, 0xfc, 0xff,
0xff, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x00, 0x00, 0x00, 0xf8, 0xff,
0x7f, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x7f, 0x00, 0x00, 0x00, 0xf0, 0xff,
0x3f, 0x00, 0x00, 0x00, 0xe0, 0xff}; send helpNOAOLogo "set bitmap noao_logo"
  
send helpInfo1 set label $version

# Stuff for keeping track of visited anchors.
set links       { 0 }
set linkIndex     0
set visited(0)  empty

proc Help args \
{
    global help_up
    if {$help_up == 0} {
	send client help
    } else {
	send help_panel unmap
	set help_up 0
    } 
}

proc helpPanel args \
{
    global help_up
    if {$help_up} {
	send help_panel unmap
	set help_up 0
    } else {
	send help_panel map
	set help_up 1
    }
}

proc panelHelp args \
{
    Help
} ; send panelHelp addCallback panelHelp

proc helpQuit args \
{
    global help_up
    send help_panel unmap
    set help_up 0
}; send helpClose addCallback helpQuit

proc getHelpText { param old new } \
{
    send helpText setText $new
    helpPanel
}; send help addCallback getHelpText

proc anchorSelected {widget cbtype event text href args} \
{
    global visited links linkIndex
    set anchID [send helpText anchorToId $href]
    set visited($href) 1
    if {$linkIndex == 0} {
	send helpBack setSensitive True
	if {[lindex $links 1] != $anchID} {
	    set links { 0 }
	    send helpForward setSensitive False
	}
    }
    if {$linkIndex > 0 && [lindex $links [expr $linkIndex + 1]] != $anchID} {
	set links [lrange $links 0 $linkIndex]
    }
    if {[lindex $links [expr $linkIndex + 1]] != $anchID} {
	lappend links $anchID
	incr linkIndex
    } else {
	send helpForward setSensitive False
	incr linkIndex
    }
    if {$linkIndex == [expr [llength $links] - 1]} {
	send helpForward setSensitive False
    }
    send helpText gotoId $anchID
    send helpText retestAnchors
}; send helpText addCallback anchorSelected anchor     

proc testAnchor {widget cbtype href} \
{
    global visited
    return [info exists visited($href)]
}; send helpText addCallback testAnchor testAnchor


# Callbacks to position forwards and backwards in link list.
proc hlpForward args \
{
    global links linkIndex
    incr linkIndex
    if {$linkIndex <= [llength $links]} {
	set anchID [lindex $links $linkIndex]
	send helpText gotoId $anchID
	send helpText retestAnchors
	if {$linkIndex == [expr [llength $links] - 1]} {
	    send helpForward setSensitive False
	    send helpBack setSensitive True
	} else {
	    send helpBack setSensitive True
	}
    } else {
	incr linkIndex -1
    }
}; send helpForward addCallback hlpForward
       
proc hlpBack args \
{
    global links linkIndex
    incr linkIndex -1
    if {$linkIndex >= 0} {
	set anchID [lindex $links $linkIndex]
	send helpText gotoId $anchID
	send helpText retestAnchors
	if {$linkIndex == 0} { send helpBack setSensitive False   }
	if {$linkIndex >= 0} { send helpForward setSensitive True }
    } else {
	incr linkIndex 1
    }
}; send helpBack addCallback hlpBack

proc hlpHome args \
{
    global links linkIndex
    set links { 0 }
    set linkIndex  0
    send helpText gotoId 0
    send helpForward setSensitive False
    send helpBack setSensitive False
}; send helpHome addCallback hlpHome


proc helpFind args \
{
    set phrase  [send hfEntry get string]

    if { $phrase != "" } {
        if {[send helpText searchText $phrase start end forward caseless] > 0} {
            set elid [lindex [lindex $start 0] 0]
            set id   [max 1 [expr $elid - 10] ]
            send helpText gotoId $id
            send helpText setSelection $start $end
        } else {
            send warnText set label "Search string not found."
            send warning map
        }
    } else {
        send warnText set label "Warning: No search phrase entered."
        send warning map
    }
} ; foreach w { hfEntry hfFind } { send $w addCallback helpFind }

send hfClear addCallback { send hfEntry set string "" }


################################################################################
#  Header Display Callbacks.
################################################################################

set hdrImage		""
set hdrImageId		""
set hdrKeywords		"*"


proc fitsHdrClose args \
{
    global hdr_up

    send hdr_panel unmap
    send imageHeader set on False
    set hdr_up 0
} ; send hdrClose addCallback fitsHdrClose

proc ptFitsHeader {widget type state args} \
{
    global hdr_up

    set hdr_up $state
    if {$hdr_up == 1} {
	send imageHeader set on True
	send hdr_panel map
    } else {
	send imageHeader set on False
	send hdr_panel unmap
    }
}; send imageHeader addCallback ptFitsHeader

proc getHeader { name id } \
{
    global hdrImage hdrImageId hdrKeywords

    set hdrImage $name
    set hdrImageId $id
    send hdrObjMenu set label $name
    send hdrText   setText ""
    send hdrIGText set string ""
    send hdrKGText set string ""

    catch { send wcspix objinfo $hdrImageId $hdrKeywords }
}

proc hdrKeywFilter args \
{
    global hdrImageId hdrKeywords

    set str [ send hFindEntry get string ]
    if {$str != ""} {
	set hdrKeywords $str
	send hdrText setText ""
	catch { send wcspix objinfo $hdrImageId $hdrKeywords }
    }
} ; send hdrFilter addCallback hdrKeywFilter


# Set the image menu in the header panel.
proc setHdrObjMenu { frame args } \
{
    global frameCache ism_enable

    if {! $ism_enable} \
	return

    # Create the menu of images for the header panel.
    set items { }
    foreach i [list $frameCache($frame)] {
        set l [lindex $i 0]
        set lid [lindex $i 1]
        regsub -all {[\[]} $l  "\\\[" l2
	catch {
            lappend items [format "%s f.exec \{getHeader %s %d\}" $l $l2 $lid]
	}
    }
    editMenu objMenu hdrObjMenu $items
}


# Search box for the header.
proc hdrFind args \
{
    set phrase  [send hFindEntry get string]

    if { $phrase != "" } {
        if {[send hdrText searchText $phrase start end forward caseless] > 0} {
            set elid [lindex [lindex $start 0] 0]
            set id   [max 1 [expr $elid - 10] ]
            send hdrText gotoId $id
            send hdrText setSelection $start $end
        } else {
            send warnText set label "Search string not found."
            send warning map
        }
    } else {
        send warnText set label "Warning: No search phrase entered."
        send warning map
    }
} ; foreach w { hFindEntry hdrFind } { send $w addCallback hdrFind }

send hdrClear addCallback { send hFindEntry set string "" }


################################################################################
#  Pixel Table Callbacks.
################################################################################

set psize	5
set pixtab_up	0
set hdr_up	0

createMenu pixtabMenu pixtabSize {
    {   "3x3"          f.exec { pixtabSetSize 3 } }
    {   "5x5"          f.exec { pixtabSetSize 5 } }
    {   "7x7"          f.exec { pixtabSetSize 7 } }
    {   "9x9"          f.exec { pixtabSetSize 9 } }
}


proc updatePixelTable { cx cy wx wy args } \
{
    global psize pixtab_up ism_enable

    if {! $pixtab_up} \
	return
    if {$ism_enable} \
	return

    set delta [expr int($psize / 2) ]
    set x1 [expr ($wx - $delta) ]
    set x2 [expr ($wx + $delta) ]
    set y1 [expr ($wy - $delta) ]
    set y2 [expr ($wy + $delta) ]
    set c [ expr int($psize / 2) ]


    # Update the table labels.
    set x $x1 ;      set xl {}
    set y $y2 ;      set yl {}
    for {set i 0} {$i < $psize} {incr i} {
	lappend xl  [format " %10.1f " $x] ; set x [ expr ($x + 1.) ]
	lappend yl  [format " %10.1f " $y] ; set y [ expr ($y - 1.) ]
    }
    send ptColLabs setList $xl ; send ptColLabs highlight $c
    send ptRowLabs setList $yl ; send ptRowLabs highlight $c

    # Update the pixel table itself.
    #set pix [ send client getPixels $cx $cy $psize True ]

    set x0  [ expr int($cx - $psize / 2. + 0.5)]
    set y0  [ expr int($cy - $psize / 2. + 0.5)]
    set pix [ send client getPixels $x0 $y0 $psize $psize ]
    send pixtab setList [ lrange $pix 4 end ]
    set c [ expr int(($psize * $psize) / 2) ]
    send pixtab highlight $c

    # Update the pixtab stats.
    set sum   0.0
    set sum2  0.0
    set npix  [ expr ($psize * $psize) ]
    set nend  [ expr ($psize * $psize) + 4 ]
    for {set i 4} {$i < $nend} {incr i} {
	set val  [lindex $pix $i]
	catch {
	    set sum  [ expr ($sum + $val) ]
	    set sum2 [ expr ($sum2 + $val * $val) ]
	}
    }

    set mean [ expr ($sum / ($npix * 1.0)) ]
    set var  [ expr (($sum2 - $sum * $mean) / ($npix - 1)) ]
    if {$var <= 0.0} {
	set stdev 0.0
    } else {
	set stdev  [ expr sqrt ($var) ]
    }
    send meanValue set label [ format "%10.2f" $mean ]
    send sigValue set label  [ format "%10.4f" $stdev ]
}


proc pixtabClose args \
{
    global pixtab_up

    send pixel_panel unmap
    send pixelTable set on False
    set pixtab_up 0
    catch { send wcspix set psize 0 }
} ; send pixtabClose addCallback pixtabClose


proc pixtabSetSize { size args } \
{
    global psize ism_enable

    set c [ expr int(($psize * $psize) / 2) ]
    send pixtab highlight $c

    # Now reset the window size.
    switch $size {
    3	{ send pixel_panel "resize 265 175"
	  send pixtab "set width 180 ; set height 60"
	}
    5	{ send pixel_panel "resize 375 215"
	  send pixtab "set width 290 ; set height 105"
	}
    7	{ send pixel_panel "resize 495 265"
	  send pixtab "set width 410 ; set height 150"
	}
    9	{ send pixel_panel "resize 610 310"
	  send pixtab "set width 525 ; set height 195"
	}
    }

    send pixtab    set defaultColumns $size
    send ptColLabs set defaultColumns $size
    set psize $size

    # Notify the ISM we've changed size.
    if ($ism_enable) {
	catch { send wcspix set psize $psize }
    }

    send imagewin getCursorPos xc yc
    updatePixelTable $xc $yc $xc $yc

} ; pixtabSetSize $psize


proc ptPixelTable {widget type state args} \
{
    global pixtab_up psize

    set pixtab_up $state
    if {$pixtab_up == 1} {
	send pixelTable set on True
	send pixel_panel map
	catch { send wcspix set psize $psize }
    } else {
	send pixelTable set on False
	send pixel_panel unmap
	catch { send wcspix set psize 0 }
    }
}; send pixelTable addCallback ptPixelTable


################################################################################
# Warning dialog.  This pops up a dialog box with the given warning message,
# and executes the given command if the user pushes OK.
#
# Usage:	Wexec object message [ok_action [cancel_action]]
#
# The message text is displayed in a popup and the user hits the ok or
# cancel button to close the popup.  If an action has been posted for the
# button selected then it is sent to the named object.  Only one alert can
# be in effect at a time; posting another alert before the first has
# completed causes the new alert to override the first.
################################################################################

set W_object ""
set W_ok_cmd ""
set W_cancel_cmd ""

proc Wexec {object msg args} \
{
    global W_object W_ok_cmd W_cancel_cmd
    set W_object $object
    set W_ok_cmd [lindex $args 0]
    set W_cancel_cmd [lindex $args 1]
    send warnText set label $msg
    send warning map
}

proc Wbutton {widget args} \
{
    global W_object W_ok_cmd W_cancel_cmd
    switch $widget {
    warnOk	{ if [llength $W_ok_cmd] { send $W_object $W_ok_cmd }
		}
    warnCancel	{ if [llength $W_cancel_cmd] { send $W_object $W_cancel_cmd }
		}
    }
    send warning unmap
}
send warnOk     addCallback Wbutton
send warnCancel addCallback Wbutton

# The parameter "alert" is used to forward alerts from the client.
proc setAlert {param old new} \
{
    Wexec client [lindex $new 0] [lindex $new 1]
}; send alert addCallback setAlert



################################################
# Define some TCL debug procedures.
################################################

set tcl_up 0

proc tclCommandClear {widget args}   { send tclEntry set string "" }
proc tclCommandExecute {widget args} { send server [send tclEntry {get string}]
}
proc tclCommand {widget mode command args} { send server $command }
proc tclClose {widget args}                { tclPanel }
proc tclOpen args \
{ 
    global tcl_up
    send tcl_panel map 
    set tcl_up 1
}

proc tclPanel args \
{
    global tcl_up
    if {$tcl_up} {
	send tcl_panel unmap
	set tcl_up 0
    } else {
	send tcl_panel map
	set tcl_up 1
    }
}

send tclClear   addCallback tclCommandClear
send tclExecute addCallback tclCommandExecute
send tclEntry   addCallback tclCommand
send tclDismiss addCallback tclClose



################################################
# ISM Module support routines.
################################################


# Turn the ISM on or off.
proc ismToggle { widget type state args } \
{
    global ism_enable ism_capable psize

    set ism_enable $state

    # Set the coord-panel header option availability.
    if {$ism_enable == 1 && $ism_capable} {
	send imageHeader setSensitive True
	send woptBPM setSensitive True
	catch { send client ism_start wcspix }
    } else {
	send imageHeader setSensitive False
	send woptBPM set on False
	send woptBPM setSensitive False
	catch { send client ism_stop wcspix }
	send hdr_panel unmap
    }
    setCoordPanelSensitivity

} ; send ismToggle addCallback ismToggle



# Handle messages from ISM clients and pass them on to the appropriate
# callback.

proc ism_msg { param old new } \
{
    global ism_enable 

    set cmd  [lindex $new 0]				;# command name
    set ism  [lindex $new 1]				;# determine ISM name
    set argv [lrange $new 2 end]			;# get args
    set argc [llength $argv]

    switch  $cmd {
    source   { source [lindex $new 1]		}
    alert    { Wexec client [lindex $new 1]	}
    deliver  { ${ism}_msg $argc $argv		}
    info     { ism_info $ism			}
    }
} ; send ism_msg addCallback ism_msg



# Log a client message to the info panel
set ismInfoText " " 

proc ism_info { text } \
{
    global infoMode ismInfoText

    set ismInfoText [format "%s\n%s" $ismInfoText $text]
    if {$infoMode == "infoOptIsm"} {
	send infoText set string $ismInfoText
    }
}

# Initialize the text.
proc ismInitInfoText args \
{
    global ismInfoText

    set ismInfoText ""
    ism_info  "\t    ISM Client Message Logs"
    ism_info  "\t    -----------------------"
    ism_info  " "
} ; ismInitInfoText



################################################
# WPIX module support routines.
################################################

set cur_objid		0
set cur_regid		0
set redraw_compass	0
#set Compass(0)		{ 0.0 1 1 0 X Y }
set Compass(0)		{ 0.0 0.0 1.0 -1.0 0.0 0 X Y }
set Orient(0)		{ 1 1 1 }

set wcspix_debug	0

proc wcspix_msg { argc argv } \
{
    global wcspix_debug

    set arg [string trimleft [ string trimright [lindex $argv 0] ] ]
    set cmd [lindex $arg 0]

    if {$wcspix_debug} { print "wcspix_msg:  $cmd" }


    switch $cmd {
    startup	{ wcspix_startup					}
    shutdown	{ wcspix_shutdown					}
    disable	{ wcspix_disable					}
    capable	{ wcspix_capable					}

    cache	{ wcspix_cache   [lrange $arg 1 end]			}
    uncache	{ wcspix_uncache [lrange $arg 1 end]			}
    wcstran	{ wcspix_wcstran [lrange $arg 1 end]			}
    wcslist	{ wcspix_wcslist [lrange $arg 1 end] 			}

    imghdr	{ send hdrText \
			setText [format "<pre>%s\n%s</pre>" \
			[string trimright [send hdrText getText simple] "\n"]\
			[lindex $arg 1] ]
		}
    wcshdr	{ send hdrKGText append [lindex $arg 1]			}

    wcsinfo	{ send hdrIGText append [lindex $arg 1]		
		  send hdrText   gotoId 0
		  send hdrKGText set insertPosition 0
		}

    compass	{ wcspix_compass [lrange $arg 1 end] ; drawCompass 	}
    orient	{ wcspix_orient  [lrange $arg 1 end] 			}
    wcstype	{ wcspix_wcstype [lindex $arg 1] [lindex $arg 2]	}
    wcsfmt	{ set num [lindex $arg 2]
		  send fmtWcs$num set label [lindex $arg 1] 		}

    wcspix_cmd	{ send wcsIsmCmd set string [lindex $arg 1]		}

    pixtab	{ set tab  [lindex [lindex $arg 1] 0]
		  set col  [lindex [lindex $arg 1] 1]
		  set row  [lindex [lindex $arg 1] 2]
		  set stat [lindex [lindex $arg 1] 3]
		  wcspix_pixtab $tab $col $row $stat
		}
    }
}


# Startup and initialize the wcspix module with the GUI state.
proc wcspix_startup args \
{
    global ism_enable frame
    global up_todo psize pixtab_up frameCache

    set ism_enable 1
    send ismToggle set on True
    send imageHeader setSensitive True
    send woptBPM setSensitive True
    setCoordPanelSensitivity
    ismInitInfoText

    if {$up_todo < 3} {
        resizeCoordsBox $up_todo
    }
    updateCoordsBox
    drawCompass

    # Initialize the frame cache.
    foreach c [array names frameCache] {
	if {$c != "0"} { unset frameCache($c) }
    }

    catch { 
	if {$pixtab_up} { send wcspix set psize $psize }
	for {set i 1} {$i <= 4} {incr i} {
    	    send wcspix set wcs    [send sysWcs$i get label] $i
    	    send wcspix set format [send fmtWcs$i get label] $i
	}
    }

    if { [send infoOptClients get on] } {
	send client info clients
    }
}

# Shutdown the WPIX module.
proc wcspix_shutdown args \
{
    global ism_enable frame

    set ism_enable 0
    send ismToggle set on False
    send imageHeader setSensitive False
    send woptBPM set on False
    send woptBPM setSensitive False
    setCoordPanelSensitivity
    setCoordPanelHeight

    wcsFmtIValue "N/A"
    wcsFmtBValue "0"

    resizeCoordsBox 0
    drawCompass

    if { [send infoOptClients get on] } {
	send client info clients
    }
}


# Disable the WPIX module.  We are only called when a display client has
# indicated it doesn't use the new mapping facilities and having the WPIX
# ISM visible will only confuse the user.

proc wcspix_disable args \
{
    global ism_enable ism_capable rulerWCS

    if {$ism_enable} {
        send wcspix quit
    }
    set ism_capable 0
    set rulerWCS 0
    wcspix_shutdown
    send ismToggle setSensitive False
}


# Client connected is capable of using the ISM, but don't necessarily turn
# it on at this point.

proc wcspix_capable args \
{
    global ism_capable

    set ism_capable 1
    wcsFmtIValue "0"
    wcsFmtBValue "0"
    send ismToggle setSensitive True
}


# Cache an image in the GUI.
proc wcspix_cache { argv } \
{
    global frameCache redraw_compass cur_objid

    set name	[lindex $argv 0]
    set frame	[lindex $argv 1]
    set id	[lindex $argv 2]

    # Store the image name and id in a local cache.
    lappend frameCache($frame) $name $id
    send hdrObjMenu set label $name

    # Automatically get the header.
    regsub -all {[\[]} $name  "\\\[" image
    catch { getHeader $image $id }

    setHdrObjMenu $frame

    set cur_objid $id
    set redraw_compass 1
}

# Uncache an image in the GUI.
proc wcspix_uncache { argv } \
{
    global frameCache Compass

    set id [lindex $argv 0]
    foreach c [array names frameCache] {
	set i1 0
	set i2 1
	set new { }
	while { $i2 < [llength $frameCache($c)] } {
            if {[lindex $frameCache($c) $i2] != $id} { 
		lappend new [lindex $frameCache($c) $i1]
		lappend new [lindex $frameCache($c) $i2]
            }
	    incr i1 2
	    incr i2 2
        }
	set frameCache($c) $new
    }
    if [info exists Compass($id)] {
        unset Compass($id)
    }
}

# Format the results of the WCSTRAN method.
proc wcspix_wcstran { argv } \
{
    global frameCache cur_objid cur_regid redraw_compass

    set objid  [ lindex [lindex $argv 0] 1]
    set regid  [ lindex [lindex $argv 1] 1]
    set pixval [ lindex [lindex $argv 2] 1]
    set bpmval [ lindex [lindex $argv 3] 1]

    wcsFmtIValue $pixval
    wcsFmtBValue $bpmval

    set args [lrange $argv 4 end]
    set nargs [llength $args]
    for {set i 0} {$i < 4} {incr i} {
	set coord   [lindex $args $i]
	set wcsname [lindex $coord 1]
	set xval    [lindex $coord 2]
	set yval    [lindex $coord 3]
	set xunits  [lindex $coord 4]
	set yunits  [lindex $coord 5]
	wcsFmtWcs [expr ($i + 1)] $wcsname $xval $yval $xunits $yunits
    }

    set cur_objid $objid
    set cur_regid $regid

    if {$redraw_compass} \
	drawCompass
}

# Save the object compass information.
proc wcspix_compass { argv } \
{
    global Compass

    set objid     [lindex $argv 0]
    set angle     [lindex $argv 1]

    #set xflip     [lindex $argv 2]
    #set yflip     [lindex $argv 3]
    #set transpose [lindex $argv 4]
    #set xlab      [lindex $argv 5]
    #set ylab      [lindex $argv 6]

    set north_x   [lindex $argv 2]
    set north_y   [lindex $argv 3]
    set east_x    [lindex $argv 4]
    set east_y    [lindex $argv 5]
    set transpose [lindex $argv 6]
    set xlab      [lindex $argv 7]
    set ylab      [lindex $argv 8]

    #lappend Compass($objid) $angle $xflip $yflip $transpose $xlab $ylab
    #set Compass($objid) [list $angle $xflip $yflip $transpose $xlab $ylab]
    set Compass($objid) [list $angle $north_x $north_y $east_x $east_y \
	$transpose $xlab $ylab]
    drawCompass
}

# Save the image display orientation information.
proc wcspix_orient { argv } \
{
    global Orient

    set objid [lindex $argv 0]
    set frame [lindex $argv 1]
    set xflip [lindex $argv 2]
    set yflip [lindex $argv 3]

    set Orient($objid) [list $frame $xflip $yflip]
}


# Handle the list of WCSs available for the current image.
proc wcspix_wcslist { argv } \
{
    set wcslist [lindex $argv 0]

    for {set i 1} {$i <= 4} {incr i} {
        set items {}
	foreach nam $wcslist {
	    if {[string tolower $nam] == "line"} {
	        lappend items "f.dblline"
	    } else {
	        lappend items "\"$nam\" f.exec \{setWcsSys $nam $i\}"
	    }
	}
	editMenu sysMenu$i sysWcs$i $items
    }
}

# Set the type of the WCS.
proc wcspix_wcstype { label num } \
{
    global up_todo

    send sysWcs$num set label $label
    if {[string tolower $label] == "none"} {
	send wpWcs$num "set on False ; setSensitive False"
	send wiWcs$num "set on False ; setSensitive False"
	send fmtWcs$num setSensitive False
    	set hght 4
    } else {
        send wpWcs$num "set on True  ; setSensitive True"
        send wiWcs$num setSensitive True
	send fmtWcs$num setSensitive True
    	set hght 17
    }
    send wtWcs$num set height $hght
    setCoordPanelHeight

    #resizeCoordsBox $up_todo
    updateCoordsBox
}

# Display the pixel table.
proc wcspix_pixtab { tab col row stat } \
{
    global psize

    # Update the pixel table.
    send pixtab setList [lindex $tab 1]
    send pixtab highlight [expr int(($psize * $psize) / 2)]

    # Update the table labels.
    set c [ expr int($psize / 2) ]
    send ptColLabs setList $col ; send ptColLabs highlight $c
    send ptRowLabs setList $row ; send ptRowLabs highlight $c

    # Update the pixtab stats.
    send meanValue set label [ format "%10.2f" [lindex $stat 0] ]
    send sigValue  set label [ format "%10.4f" [lindex $stat 1] ]
}


