/*
 *
 *	viewpanel.c
 *
 *	HNMS User Interface
 *	HNMS 2.0
 *
 *	February 1994
 *
 *	Leslie Schlecht
 *	Computer Sciences Corporation
 *	Numerical Aerodynamic Simulation Systems Division
 *	NASA Ames Research Center
 *
 *	Copyright (c) 1994 Leslie Schlecht
 *
 *	This program is free software; you can redistribute it and/or modify
 *	it under the terms of the GNU General Public License as published by
 *	the Free Software Foundation; either version 1, or (at your option)
 *	any later version.
 *
 *	This program is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *	GNU General Public License for more details.
 *
 *	You should have received a copy of the GNU General Public License
 *	along with this program; if not, write to the Free Software
 *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#include	<stdio.h>
#include	<string.h>

#include	<X11/StringDefs.h>
#include	<X11/Intrinsic.h>
#include	<X11/Shell.h>
#include	<X11/Core.h>
#include	<Xm/Xm.h>
#include	<Xm/PushB.h>
#include	<Xm/CascadeB.h>
#include	<Xm/RowColumn.h>
#include	<Xm/Form.h>
#include	<Xm/Frame.h>
#include	<Xm/Text.h>

#include	"defines.h"
#include	"externs.h"
#include	"xsupport.h"
#include	"viewpanel.h"
#include	"view.h"

static caddr_t	root=NULL;

void	OpenHelpPanel();

/*
 *	Close a view panel.
 */
void
CloseViewPanel(widg, vs, call_data)
Widget		widg;
VIEWPANEL	*vs;
caddr_t		call_data;
	{
	if (!XtIsRealized(vs->shell)) return;
	vs->open_me = False;
	GetShellDimensions(vs->shell, &(vs->x), &(vs->y), &(vs->w), &(vs->h));
	SetShellLocation(vs->shell, vs->x, vs->y, vs->geometry);
	XtUnrealizeWidget(vs->shell);
	if (vs->close) vs->close(vs);
	}


/*
 *	Get shell dimensions when it is configured.
 */
void
NotifyViewPanel(widg, vs, event)
Widget		widg;
VIEWPANEL	*vs;
XEvent		*event;
	{
	Dimension w, h;
	Position x, y;

	if (!vs) return;
	switch (event->type) {
	case ConfigureNotify:
		XtVaGetValues(widg,
			XmNx, &x,
			XmNy, &y,
			XmNwidth, &w,
			XmNheight, &h,
			NULL);
		vs->x = x;
		vs->y = y;
		vs->w = w;
		vs->h = h;
		break;
	default:;
		}
	}


/*
 *	Create a view panel struct and fill it.
 */
VIEWPANEL*
CreateViewPanel(titlelabel, namestring, w, h, classstring, ob, obpix, pnl)
char	*titlelabel, *namestring, *classstring;
int	w, h, ob, pnl;
int	obpix;
	{
	VIEWPANEL	*vs;
	XmString	xs;
	Widget		menubar, f, b, btnframe;

	vs = (VIEWPANEL*)myalloc(NULL, 1, sizeof(VIEWPANEL));
	AddEntry(&root, vs, NULL, 0);
	vs->shell = MakeShell(namestring, w, h);
	XtAddEventHandler(vs->shell, StructureNotifyMask, False,
		NotifyViewPanel, vs);
	vs->shellform = XtVaCreateManagedWidget(namestring,
		xmFormWidgetClass,
		vs->shell,
		NULL);
	vs->titleform = XtVaCreateManagedWidget("titleform",
		xmFormWidgetClass,
		vs->shellform,
		XmNtopAttachment, XmATTACH_FORM,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		NULL);
	btnframe = XtVaCreateManagedWidget("frame",
		xmFormWidgetClass,
		vs->titleform,
		XmNtopAttachment, XmATTACH_FORM,
		XmNleftAttachment, XmATTACH_NONE,
		XmNrightAttachment, XmATTACH_FORM,
		XmNbottomAttachment, XmATTACH_FORM,
		NULL);
	vs->name = newstr(namestring);
	vs->closebutton = XtVaCreateManagedWidget("closebutton",
		xmPushButtonWidgetClass,
		btnframe,
		XmNlabelType, XmPIXMAP,
		XmNlabelPixmap, GetPixmap(CLOSE_PIXMAP),
		XmNtopAttachment, XmATTACH_FORM,
		XmNleftAttachment, XmATTACH_NONE,
		XmNrightAttachment, XmATTACH_FORM,
		XmNbottomAttachment, XmATTACH_FORM,
		XmNhighlightThickness, 0,
		XmNwidth, 32,
		NULL);
	XtAddCallback(vs->closebutton, XmNactivateCallback, CloseViewPanel, vs);
	vs->helpbutton = XtVaCreateManagedWidget("helpbutton",
		xmPushButtonWidgetClass,
		btnframe,
		XmNlabelType, XmPIXMAP,
		XmNlabelPixmap, GetPixmap(HELP_PIXMAP),
		XmNtopAttachment, XmATTACH_FORM,
		XmNleftAttachment, XmATTACH_NONE,
		XmNrightAttachment, XmATTACH_WIDGET,
		XmNrightWidget, vs->closebutton,
		XmNbottomAttachment, XmATTACH_FORM,
		XmNhighlightThickness, 0,
		XmNwidth, 32,
		NULL);
	XtAddCallback(vs->helpbutton, XmNactivateCallback, OpenHelpPanel, vs);
	if (obpix && !ob) {
		vs->optionbutton = XtVaCreateManagedWidget("pb",
			xmPushButtonWidgetClass,
			btnframe,
			XmNlabelType, XmPIXMAP,
			XmNlabelPixmap, GetPixmap(obpix),
			XmNtopAttachment, XmATTACH_FORM,
			XmNleftAttachment, XmATTACH_FORM,
			XmNbottomAttachment, XmATTACH_FORM,
			XmNrightAttachment, XmATTACH_WIDGET,
			XmNrightWidget, vs->helpbutton,
			XmNwidth, 32,
			XmNhighlightThickness, 0,
			NULL);
		}
	else if (ob) {
		menubar = XmCreateMenuBar(btnframe, "hnms", NULL, 0);
		XtVaSetValues(menubar,
			XmNtopAttachment, XmATTACH_FORM,
			XmNleftAttachment, XmATTACH_NONE,
			XmNrightAttachment, XmATTACH_WIDGET,
			XmNrightWidget, vs->helpbutton,
			XmNbottomAttachment, XmATTACH_FORM,
			NULL);
		vs->optionmenu = XmCreatePulldownMenu(menubar, "menu",
			NULL, 0);
		if (obpix) {
			vs->optionbutton = XtVaCreateManagedWidget(
				"optionbutton",
				xmCascadeButtonWidgetClass,
				menubar,
				XmNlabelType, XmPIXMAP,
				XmNlabelPixmap, GetPixmap(obpix),
				XmNsubMenuId, vs->optionmenu,
				XmNwidth, 32,
				NULL);
			}
		else {
			vs->optionbutton = XtVaCreateManagedWidget(
				"optionbutton",
				xmCascadeButtonWidgetClass,
				menubar,
				XmNlabelType, XmPIXMAP,
				XmNlabelPixmap, GetPixmap(MORE_PIXMAP),
				XmNsubMenuId, vs->optionmenu,
				NULL);
			}
		XtManageChild(menubar);
		vs->menubar = menubar;
		}
	else
		XtVaSetValues(vs->helpbutton,
			XmNleftAttachment, XmATTACH_FORM,
			NULL);
	if (pnl) {
		if (ob)
			b = pbutton("pb", vs->optionmenu, "Panel");
		else if (obpix)
			b = vs->optionbutton;
		XtAddCallback(b, XmNactivateCallback, ShowExtraPanel, vs);
		vs->extrapanel = XtVaCreateWidget("frame",
			xmFrameWidgetClass,
			vs->shellform,
			XmNtopAttachment, XmATTACH_NONE,
			XmNleftAttachment, XmATTACH_FORM,
			XmNrightAttachment, XmATTACH_FORM,
			XmNbottomAttachment, XmATTACH_FORM,
			XmNshadowType, XmSHADOW_OUT,
			NULL);
		vs->extraform = XtVaCreateManagedWidget("form",
			xmFormWidgetClass,
			vs->extrapanel,
			NULL);
		}
	vs->titleframe = XtVaCreateManagedWidget("titleframe",
		xmFrameWidgetClass,
		vs->titleform,
		XmNtopAttachment, XmATTACH_FORM,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_WIDGET,
		XmNrightWidget, btnframe,
		XmNbottomAttachment, XmATTACH_FORM,
		XmNshadowType, XmSHADOW_OUT,
		XmNmarginWidth, 5,
		NULL);
	f = XtVaCreateManagedWidget("form",
		xmFormWidgetClass,
		vs->titleframe,
		NULL);
	vs->titlelabel = XtVaCreateManagedWidget("label",
		xmLabelWidgetClass,
		f,
		XmNtopAttachment, XmATTACH_NONE,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_NONE,
		XmNbottomAttachment, XmATTACH_FORM,
		XmNbottomOffset, 4,
		XmNlabelString, (xs=X_STR(titlelabel)),
		XmNalignment, XmALIGNMENT_BEGINNING,
		NULL);
	vs->titletext = XtVaCreateManagedWidget("title",
		xmTextWidgetClass,
		f,
		XmNtopAttachment, XmATTACH_NONE,
		XmNleftAttachment, XmATTACH_WIDGET,
		XmNleftWidget, vs->titlelabel,
		XmNrightAttachment, XmATTACH_FORM,
		XmNbottomAttachment, XmATTACH_FORM,
		XmNsensitive, False,
		XmNeditable, False,
		XmNcolumns, 16,
		XmNcursorPositionVisible, False,
		XmNhighlightThickness, 0,
		XmNshadowThickness, 0,
		XmNresizeWidth, True,
		XmNresizable, True,
		NULL);
	XtAddCallback(vs->titletext, XmNactivateCallback, SetViewPanelButton,
		vs);

	vs->viewform = XtVaCreateManagedWidget(classstring,
		xmFormWidgetClass,
		vs->shellform,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, vs->titleform,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		XmNbottomAttachment, XmATTACH_FORM,
		NULL);
	return(vs);
	}


void
HideShowViewPanels(hide)
int	hide;
	{
	caddr_t	n;
	VIEWPANEL	*vp;

	n = root;
	while (NextEntry(&n, &vp)) {
		if (hide) {
			if (XtIsRealized(vp->shell)) {
				vp->show = 1;
				CloseViewPanel(NULL, vp, NULL);
				}
			}
		else {
			if (vp->show) {
				if (!XtIsRealized(vp->shell))
					OpenViewPanel(NULL, vp, NULL);
				vp->show = 0;
				}
			}
		}
	}



/*
 *	Destroy a view panel.
 */
void
DestroyViewPanel(vs)
VIEWPANEL	*vs;
	{
	RemoveEntry(&root, vs, NULL);
	if (vs->button) XtDestroyWidget(vs->button);
	XtDestroyWidget(vs->shell);
	free(vs->name);
	free(vs->title);
	free(vs);
	}


/*
 *	Open a view panel.
 */
void
OpenViewPanel(widg, vs, a)
Widget		widg;
VIEWPANEL	*vs;
caddr_t		a;
	{
	if (!vs) return;
	if (XtIsRealized(vs->shell)) {
		RaiseWidget(vs->shell);
		RaiseWidget(vs->shellform);
		return;
		}
	XtRealizeWidget(vs->shell);
	vs->open_me = True;
	}


void
ShowExtraPanel(widg, vp, a)
Widget	widg;
VIEWPANEL	*vp;
caddr_t		a;
	{
	Dimension	h, w;
	int		off, wid;

	if (XtIsManaged(vp->extrapanel)) {
		XtVaSetValues(vp->shell,
			XmNallowShellResize, True,
			NULL);
		XtVaSetValues(vp->viewform,
			XmNbottomOffset, 0,
			NULL);
		XtUnmanageChild(vp->extrapanel);
		XtVaSetValues(vp->shell,
			XmNallowShellResize, False,
			NULL);
		}
	else {
		XtVaGetValues(vp->extrapanel,
			XmNheight, &h,
			NULL);
		XtVaGetValues(vp->viewform,
			XmNwidth, &w,
			NULL);
		off = h;
		wid = w;
		XtVaSetValues(vp->shell,
			XmNallowShellResize, True,
			NULL);
		XtVaSetValues(vp->viewform,
			XmNbottomOffset, off,
			NULL);
		XtVaSetValues(vp->extrapanel,
			XmNwidth, wid,
			NULL);
		XtManageChild(vp->extrapanel);
		XtVaSetValues(vp->shell,
			XmNallowShellResize, False,
			NULL);
		}
	}


void
AddRemoveButton(view, panel)
VIEW		*view;
VIEWPANEL	*panel;
	{
	Widget	b;

	b = pbutton("pb", panel->optionmenu, "Remove");
	XtAddCallback(b, XmNactivateCallback, RemoveView, view);
	}


void
SetViewPanelButton(widg, panel, a)
Widget	widg;
VIEWPANEL	*panel;
caddr_t	a;
	{
	char	*name, *label=NULL, buf[BUFSIZ];
	XmString	xs;

	XtVaGetValues(panel->titlelabel,
		XmNlabelString, &xs,
		NULL);
	label = exstr(xs);
	buf[0] = '\0';
	if (label) strcat(buf, label);
	XmStringFree(xs);
	strcat(buf, panel->title);
	if (strlen(buf)) {
		XtVaSetValues(panel->button,
			XmNlabelString, (xs=X_STR(buf)),
			NULL);
		XmStringFree(xs);
		}
	}


void
SetViewPanelTitle(panel, textstr)
VIEWPANEL	*panel;
char		*textstr;
	{
	XmTextSetString(panel->titletext, textstr);
	if (panel->title) free(panel->title);
	panel->title = newstr(textstr);
	SetViewPanelButton(NULL, panel, NULL);
	}


int
ConfigureViewPanel(panel, variable, value)
VIEWPANEL	*panel;
char		*variable;
char		*value;
	{
	if (strcmp(variable, "geometry") == 0) {
		XtVaSetValues(panel->shell,
			XmNgeometry, newstr(value),
			NULL);
		return(1);
		}
	else if (strcmp(variable, "width") == 0) {
		XtVaSetValues(panel->shell,
			XmNwidth, atoi(value),
			NULL);
		return(1);
		}
	else if (strcmp(variable, "height") == 0) {
		XtVaSetValues(panel->shell,
			XmNheight, atoi(value),
			NULL);
		return(1);
		}
	else if (strcmp(variable, "openme") == 0) {
		panel->open_me = atoi(value);
		panel->show = panel->open_me;
		return(1);
		}
	else if (strcmp(variable, "showextra") == 0) {
		if (atoi(value))
			ShowExtraPanel(NULL, panel, NULL);
		return(1);
		}
	else if (strcmp(variable, "title") == 0) {
		SetViewPanelTitle(panel, value);
		return(1);
		}
	else
		return(0);
	}


/*
 *	Save a view panel configuration.
 */
void
SaveViewPanel(vs, savetitle)
VIEWPANEL	*vs;
int		savetitle;
	{
	char	buf[BUFSIZ];

	if (!vs) return;
	PutConfiguration(vs->name, "openme", vs->open_me, 1);
	if (XtIsRealized(vs->shell))
		GetShellDimensions(vs->shell, &(vs->x), &(vs->y), &(vs->w),
			&(vs->h));
	if (!(vs->h) || !(vs->w)) return;
	sprintf(buf, "+%d+%d", vs->x, vs->y);
	PutConfiguration(vs->name, "geometry", buf, 2);
	PutConfiguration(vs->name, "width", vs->w, 1);
	PutConfiguration(vs->name, "height", vs->h, 1);
	if (vs->extrapanel)
		PutConfiguration(vs->name, "showextra",
			XtIsManaged(vs->extrapanel), 1);
	if (savetitle)
		PutConfiguration(vs->name, "title", vs->title, 2);
	}
