/*
 *
 *	objectdump.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	<time.h>

#include	<X11/StringDefs.h>
#include	<X11/Intrinsic.h>
#include	<X11/Shell.h>
#include	<X11/Core.h>
#include	<Xm/Xm.h>
#include	<Xm/Text.h>
#include	<Xm/Form.h>
#include	<Xm/ScrolledW.h>
#include	<Xm/List.h>
#include	<Xm/PanedW.h>

#include	"defines.h"
#include	"externs.h"
#include	"object.h"
#include	"variable.h"
#include	"viewpanel.h"
#include	"view.h"
#include	"objectdump.h"

typedef		struct statedata	{
		Widget		objtext;
		Widget		varnam;
		Widget		varval;
		Widget		varint;
		Widget		vartime;
		Widget		rellist;
		} SD;

static char	buf[BUFSIZ];

static char	*childstr[] = {
		"    (IPChild) ",
		"  (PhysChild) ",
		" (AdminChild) ",
		};
static char	*parentstr[] = {
		"   (IPParent) ",
		" (PhysParent) ",
		"(AdminParent) ",
		};
static int	hasparent[NUM_OBJCLASSES][NUM_PARENT] =
		{
		{0, 0, 0},
		{0, 0, 0},		/* agent */
		{0, 0, 0},		/* internet */
		{1, 0, 0},		/* network */
		{1, 0, 0},		/* subnet */
		{1, 1, 0},		/* ipaddr */
		{0, 1, 0},		/* site */
		{0, 1, 0},		/* processor */
		{0, 1, 0},		/* interface */
		{0, 1, 0},		/* equipment */
		{0, 1, 0},		/* administrator */
		{0, 0, 0},		/* module */
		};

static VIEW	objectdumpview;
static char	*requeststr[] = {"active", "passive"};


/*
 *	Add a child of the object to the dump.
 */
void
AddChildToObjectDump(view, obj1, obj2)
VIEW	*view;
OBJECT	*obj1, *obj2;
	{
	register	i;

	for (i=0; i<NUM_PARENT; i++)
		if (obj1->parent[i] == obj2)
			if (obj2->state)
				AddObjectDumpRelation(obj2->state, childstr[i],
					obj1);
	}


/*
 *	Add a relation to the dump.
 */
void
AddObjectDumpRelation(panel, rel, obj)
VIEWPANEL	*panel;
char		*rel;
OBJECT		*obj;
	{
	XmString	xs;
	SD		*d;

	strcpy(buf, rel);
	if (obj)
		strcat(buf, obj->uname);
	else
		strcat(buf, "(nil)");
	xs = X_STR(buf);
	d = (SD*)panel->wa;
	if (!XmListItemExists(d->rellist, xs))
		XmListAddItem(d->rellist, xs, 0);
	XmStringFree(xs);
	}


/*
 *	Create default view.
 */
void
CreateObjectDump(obj)
OBJECT	*obj;
	{
	Widget		f, w, l;
	XmString	xs;
	VIEWPANEL	*v;
	Widget		objvar, pw;
	SD		*d;

	if (!obj) return;
	if (obj->state) {
		OpenViewPanel(NULL, obj->state, NULL);
		LoadObjectDump(obj);
		return;
		}
	v = CreateViewPanel("DUMP:", obj->name, 700, 0, "objstate", 0, 0, 0);
	obj->state = (caddr_t)v;
	strcpy(buf, obj->name);
	XmTextSetString(v->titletext, buf);
	XtVaSetValues(v->titletext,
		XmNsensitive, False,
		NULL);
	v->wa = (caddr_t)myalloc(NULL, 1, sizeof(SD));
	d = (SD*)(v->wa);
	XtRemoveAllCallbacks(v->closebutton, XmNactivateCallback);
	XtAddCallback(v->closebutton, XmNactivateCallback,
		RemoveObjectDump, obj);

	d->objtext = XtVaCreateManagedWidget("objstate",
		xmTextWidgetClass,
		v->viewform,
		XmNtopAttachment, XmATTACH_FORM,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		XmNbottomAttachment, XmATTACH_NONE,
		XmNhighlightThickness, 0,
		XmNshadowThickness, 0,
		XmNeditable, False,
		XmNcursorPositionVisible, False,
		XmNsensitive, False,
		NULL);
	pw = XtVaCreateManagedWidget("objstate",
		xmPanedWindowWidgetClass,
		v->viewform,
		XmNtopAttachment, XmATTACH_WIDGET,
		XmNtopWidget, d->objtext,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		XmNbottomAttachment, XmATTACH_FORM,
		NULL);
	objvar = XtVaCreateManagedWidget("objstate",
		xmScrolledWindowWidgetClass,
		pw,
		XmNscrollingPolicy, XmAUTOMATIC,
		/*
		XmNhighlightThickness, 0,
		XmNshadowThickness, 0,
		*/
		XmNwidth, 400,
		XmNheight, 100,
		NULL);
	f = XtVaCreateManagedWidget("defaultview",
		xmFormWidgetClass,
		objvar,
		NULL);
	d->varnam = XtVaCreateManagedWidget("defaultview",
		xmTextWidgetClass,
		f,
		XmNtopAttachment, XmATTACH_FORM,
		XmNleftAttachment, XmATTACH_FORM,
		XmNbottomAttachment, XmATTACH_FORM,
		XmNcolumns, 16,
		XmNhighlightThickness, 0,
		XmNshadowThickness, 0,
		XmNeditable, False,
		XmNeditMode, XmMULTI_LINE_EDIT,
		XmNcursorPositionVisible, False,
		XmNresizeHeight, True,
		XmNresizeWidth, True,
		NULL);
	d->varval = XtVaCreateManagedWidget("objstate",
		xmTextWidgetClass,
		f,
		XmNtopAttachment, XmATTACH_FORM,
		XmNleftAttachment, XmATTACH_WIDGET,
		XmNleftWidget, d->varnam,
		XmNleftOffset, 4,
		XmNcolumns, 8,
		XmNbottomAttachment, XmATTACH_FORM,
		XmNhighlightThickness, 0,
		XmNshadowThickness, 0,
		XmNeditable, False,
		XmNeditMode, XmMULTI_LINE_EDIT,
		XmNcursorPositionVisible, False,
		XmNresizeHeight, True,
		XmNresizeWidth, True,
		NULL);
	d->varint = XtVaCreateManagedWidget("objstate",
		xmTextWidgetClass,
		f,
		XmNtopAttachment, XmATTACH_FORM,
		XmNleftAttachment, XmATTACH_WIDGET,
		XmNleftWidget, d->varval,
		XmNleftOffset, 4,
		XmNcolumns, 8,
		XmNbottomAttachment, XmATTACH_FORM,
		XmNhighlightThickness, 0,
		XmNshadowThickness, 0,
		XmNeditable, False,
		XmNeditMode, XmMULTI_LINE_EDIT,
		XmNcursorPositionVisible, False,
		XmNresizeHeight, True,
		XmNresizeWidth, True,
		NULL);
	d->vartime = XtVaCreateManagedWidget("objstate",
		xmTextWidgetClass,
		f,
		XmNtopAttachment, XmATTACH_FORM,
		XmNleftAttachment, XmATTACH_WIDGET,
		XmNleftWidget, d->varint,
		XmNleftOffset, 4,
		XmNbottomAttachment, XmATTACH_FORM,
		XmNhighlightThickness, 0,
		XmNshadowThickness, 0,
		XmNeditable, False,
		XmNeditMode, XmMULTI_LINE_EDIT,
		XmNcursorPositionVisible, False,
		XmNresizeHeight, True,
		XmNresizeWidth, True,
		NULL);

	d->rellist = XmCreateScrolledList(pw, "relations", NULL, 0);
	XtVaSetValues(d->rellist,
		XmNvisibleItemCount, 4,
		NULL);
	XtManageChild(d->rellist);

	GetHelp(v, 14);
	LoadObjectDump(obj);
	OpenViewPanel(NULL, v, NULL);
	}


/*
 *	Initialize the dump code.
 */
void
InitializeObjectDump()
	{
	bzero(&objectdumpview, sizeof(VIEW));
	objectdumpview.class = OBJECTDUMP;
	objectdumpview.recvonly = 1;
	}


/*
 *	Load object information into the dump panel.
 */
void
LoadObjectDump(obj)
OBJECT	*obj;
	{
	SD	*s;
	VIEWPANEL	*panel;

	panel = (VIEWPANEL*)(obj->state);
	s = (SD*)(panel->wa);
	sprintf(buf, "Name:%s  Class:%s  HID:%d", obj->name,
		obj_class_names[obj->class], obj->hid);
	panel->title = newstr(obj->name);
	XmTextSetString(s->objtext, buf);
	LoadObjectDumpVariables(obj, s);
	LoadObjectDumpRelations(obj, s);
	}


/*
 *	Load the object relations.
 */
void
LoadObjectDumpRelations(obj, d)
OBJECT	*obj;
SD	*d;
	{
	register	i;

	for (i=0; i<NUM_PARENT; i++)
		if (hasparent[obj->class][i])
			AddObjectDumpRelation(obj->state, parentstr[i],
				obj->parent[i]);
	ObjectWalk(&objectdumpview, AddChildToObjectDump, obj);
	}


/*
 *	Load the current object variables.
 */
void
LoadObjectDumpVariables(obj, d)
OBJECT	*obj;
SD	*d;
	{
	OBJVARENTRY	*ove;
	int	l;
	char	bufname[BUFSIZ], bufvalue[BUFSIZ], buftime[BUFSIZ];
	char	bufint[BUFSIZ];
	char	s[256];
	caddr_t	p, view;

	strcpy(bufname, "VARIABLE\n");
	strcpy(bufvalue, "VALUE\n");
	strcpy(bufint, "INTERVAL\n");
	strcpy(buftime, "TIME_CHANGED\n");
	p = obj->varlist;
	while (NextEntry(&p, &ove)) {
		strcat(bufname, VarOde(ove->var));
		if (IsVarString(ove->var)) {
			if (ove->value) {
				strcat(bufvalue, ove->value);
				l = strlen(bufvalue)-1;
				if (bufvalue[l] == '\n')
					bufvalue[l] = '\0';
				}
			}
		else {
			sprintf(s, "%d", (unsigned int)(ove->value));
			strcat(bufvalue, s);
			}
		sprintf(s, "%d", ove->interval);
		strcat(bufint, s);
		if (ove->tsc) strcat(buftime, get_time(ove->tsc));
		strcat(bufname, "\n");
		strcat(bufvalue, "\n");
		strcat(bufint, "\n");
		strcat(buftime, "\n");
		}
	strcat(bufname, "\nVIEW\n");
	strcat(bufvalue, "\nREQUEST\n");
	p = obj->viewlist;
	while (NextEntry(&p, &view)) {
		strcat(bufname, ViewTitle(view));
		strcat(bufname, "\n");
		strcat(bufvalue, requeststr[ViewRecvonly(view)]);
		strcat(bufvalue, "\n");
		}
	XmTextSetString(d->varnam, bufname);
	XmTextSetString(d->varval, bufvalue);
	XmTextSetString(d->varint, bufint);
	XmTextSetString(d->vartime, buftime);
	}


/*
 *	Remove an object dump panel.
 */
void
RemoveObjectDump(widg, obj, a)
Widget	widg;
OBJECT	*obj;
caddr_t	a;
	{
	VIEWPANEL	*v;

	v = (VIEWPANEL*)obj->state;
	free(v->wa);
	DestroyViewPanel(obj->state);
	obj->state = NULL;
	}
