/*
 *
 *	objectlist.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/Label.h>
#include	<Xm/Text.h>
#include	<Xm/Form.h>
#include	<Xm/Frame.h>
#include	<Xm/ScrolledW.h>
#include	<Xm/List.h>
#include	<Xm/PushB.h>
#include	<Xm/ToggleB.h>
#include	<Xm/RowColumn.h>
#include	<Xm/Separator.h>
#include	<Xm/PanedW.h>

#include	"defines.h"
#include	"externs.h"
#include	"object.h"
#include	"viewpanel.h"
#include	"xsupport.h"
#include	"objectlist.h"

typedef		struct olist	{
		Widget		list, form, count;
		Dimension	w, h;
		caddr_t		*objs;
		int		cnt;
		} OLIST;

static OLIST		obj_list[NUM_OBJCLASSES];

static int		cclass, lastlist=0;
static VIEWPANEL	*objectpanel;

static char	buf[BUFSIZ];

static int	count=0;
static XmStringTable	obj_all[NUM_OBJCLASSES];
static int		obj_all_cnt[NUM_OBJCLASSES];


/*
 *	Add an object to a list.
 */
void
AddObjectToObjectList(obj)
OBJECT	*obj;
	{
	XmString	xs;
	int		pos;
	char		s[32];

	if ((obj->class < 1) || (obj->class >= NUM_OBJCLASSES))
		return;
	pos=AddEntry(&(obj_list[obj->class].objs), obj, CompareObjectName, 0);
	if (!pos) return;
	xs = X_STR(obj->name);
	XmListAddItem(obj_list[obj->class].list, xs, pos);
	obj_list[obj->class].cnt ++;
	XmStringFree(xs);
	count ++;
	sprintf(s, "%16d", count);
	XmTextSetString(objectpanel->titletext, s);
	sprintf(s, "%8d", obj_list[obj->class].cnt);
	XmTextSetString(obj_list[obj->class].count, s);
	}


/*
 *	Clear the object list panel.
 */
void
ClearObjectListPanel()
	{
	register	i;

	for (i=1; i<NUM_OBJCLASSES; i++) {
		XmListDeleteAllItems(obj_list[i].list);
		RemoveEntryList(obj_list[i].objs, NULL);
		obj_list[i].objs = NULL;
		obj_list[i].cnt = 0;
		XmTextSetString(obj_list[i].count, "");
		}
	count = 0;
	}


/*
 *	Apply a configuration file record.
 */
void
ConfigureObjectList(variable, value)
char	*variable;
char	*value;
	{
	char	*c;
	int	objectclass;

	if (ConfigureViewPanel(objectpanel, variable, value)) return;
	else if (c=strchr(variable, '.')) {
		*c = '\0';
		c ++;
		GetObjectClass(variable, &objectclass);
		if (!objectclass) return;
		if (strcmp(c, "height") == 0)
			XtVaSetValues(obj_list[objectclass].form,
				XmNheight, atoi(value),
				NULL);
		}
	}


/*
 *	Make the object list panel.
 */
void
CreateObjectListPanel(btn)
Widget	btn;
	{
	Widget		l, f, b, pw, m;
	XmString	xs;
	int		i;

	objectpanel = CreateViewPanel("OBJECTS:", "objectlist", 0, 0,
		"objectlist", 0, 0, 0);
	objectpanel->button = btn;
	XtAddCallback(btn, XmNactivateCallback, OpenViewPanel, objectpanel);
	XtVaSetValues(objectpanel->titletext,
		XmNleftAttachment, XmATTACH_NONE,
		NULL);
	/*
	for (i=1; i<NUM_OBJCLASSES; i++) {
		b = XtVaCreateManagedWidget("tb",
			xmToggleButtonWidgetClass,
			objectpanel->optionmenu,
			XmNlabelString, (xs=X_STR((char*)obj_class_names[i])),
			NULL);
		XmToggleButtonSetState(b, 1, False);
		XtAddCallback(b,XmNvalueChangedCallback,ShowObjectListClass,i);
		XmStringFree(xs);
		}
	*/
	pw = XtVaCreateManagedWidget("panedwindow",
		xmPanedWindowWidgetClass,
		objectpanel->viewform,
		XmNleftAttachment, XmATTACH_FORM,
		XmNleftOffset, 10,
		XmNrightAttachment, XmATTACH_FORM,
		XmNrightOffset, 10,
		XmNtopAttachment, XmATTACH_FORM,
		XmNtopOffset, 10,
		XmNbottomAttachment, XmATTACH_FORM,
		XmNbottomOffset, 10,
		NULL);
	for (i=1; i<NUM_OBJCLASSES; i++) {
		obj_all[i] = NULL;
		bzero(&(obj_list[i]), sizeof(OLIST));
		obj_list[i].form = XtVaCreateManagedWidget(obj_class_names[i],
			xmFormWidgetClass,
			pw,
			XmNallowResize, True,
			NULL);
		l = XtVaCreateManagedWidget("form",
			xmFormWidgetClass,
			obj_list[i].form,
			XmNleftAttachment, XmATTACH_FORM,
			XmNtopAttachment, XmATTACH_FORM,
			XmNrightAttachment, XmATTACH_FORM,
			XmNbottomAttachment, XmATTACH_NONE,
			NULL);
		obj_list[i].count = labeled_text("text", l, 8,
			(char*)obj_class_names[i]);
		XtVaSetValues(obj_list[i].count,
			XmNleftAttachment, XmATTACH_NONE,
			NULL);
		/* create list */
		obj_list[i].list = XtVaCreateManagedWidget("scrolledwindow",
			xmScrolledWindowWidgetClass,
			obj_list[i].form,
			XmNleftAttachment, XmATTACH_FORM,
			XmNtopAttachment, XmATTACH_WIDGET,
			XmNtopWidget, l,
			XmNrightAttachment, XmATTACH_FORM,
			XmNbottomAttachment, XmATTACH_FORM,
			NULL);
		obj_list[i].list = XtVaCreateManagedWidget("list",
			xmListWidgetClass,
			obj_list[i].list,
			NULL);
		XtAddCallback(obj_list[i].list, XmNbrowseSelectionCallback,
			SelectFromObjectList, (XtPointer)i);
		XtAddCallback(obj_list[i].list, XmNextendedSelectionCallback,
			SelectFromObjectList, (XtPointer)i);
		XtAddCallback(obj_list[i].list, XmNsingleSelectionCallback,
			SelectFromObjectList, (XtPointer)i);
		XtAddCallback(obj_list[i].list, XmNmultipleSelectionCallback,
			SelectFromObjectList, (XtPointer)i);
		}
	GetHelp(objectpanel, 6, 1);
	}


/*
 *	Get an object at a specific position from a list.
 */
OBJECT*
GetObjectFromObjectList(indx, pos)
int	indx, pos;
	{
	OBJECT		*obj;

	GetObjectPosition(obj_list[indx].objs, pos, &obj);
	return(obj);
	}


/*
 *	Get the current list of objects for a specific class.
 */
XmStringTable
GetObjectListItems(objclass)
int	objclass;
	{
	register	i, j;
	XmStringTable	items;

	if (obj_list[objclass].cnt != obj_all_cnt[objclass]) {
		if (obj_all[objclass]) {
			for (j=0; j<obj_all_cnt[objclass]; j++)
				XmStringFree(obj_all[objclass][j]);
			free(obj_all[objclass]);
			obj_all[objclass] = NULL;
			}
		XtVaGetValues(obj_list[objclass].list,
			XmNitems, &items,
			XmNitemCount, &(obj_all_cnt[objclass]),
			NULL);
		obj_all[objclass] = (XmStringTable)myalloc(NULL,
			obj_all_cnt[objclass], sizeof(XmString));
		for (j=0; j<obj_all_cnt[objclass]; j++)
			obj_all[objclass][j] = XmStringCopy(items[j]);
		}
	return(obj_all[objclass]);
	}


/*
 *	Get the current object list count for a specific class.
 */
int
GetObjectListItemCount(objclass)
int	objclass;
	{
	return(obj_all_cnt[objclass]);
	}


/*
 *	Remove an object from a list.
 */
void
RemoveObjectFromObjectList(obj)
OBJECT	*obj;
	{
	XmString	xs;
	int		class;

	if ((obj->class < 1) || (obj->class >= NUM_OBJCLASSES))
		return;
	xs = X_STR(obj->name);
	XmListDeleteItem(obj_list[obj->class].list, xs);
	XmStringFree(xs);
	class = obj->class;
	if (!RemoveEntry(&(obj_list[class].objs), obj, NULL)) return;
	obj_list[class].cnt --;
	}


/*
 *	Save the objectlist configuration.
 */
void
SaveObjectList()
	{
	register	i;
	char		buf[BUFSIZ];
	Dimension	w, h;

	SaveViewPanel(objectpanel, 0);
	for (i=1; i<NUM_OBJCLASSES; i++) {
		XtVaGetValues(obj_list[i].form,
			XmNheight, &h,
			NULL);
		strcpy(buf, obj_class_names[i]);
		strcat(buf, ".");
		strcat(buf, "height");
		PutConfiguration(objectpanel->name, buf, (int)h, 1);
		}
	}


/*
 *	Select an object from a list.
 */
void
SelectFromObjectList(w, indx, call_data)
Widget	w;
int	indx;
XmListCallbackStruct	*call_data;
	{
	OBJECT		*obj;

	GetObjectPosition(obj_list[indx].objs, call_data->item_position, &obj);
	SetCurrentObject(obj);
	if (lastlist)
		XmListDeselectAllItems(obj_list[lastlist].list);
	lastlist = indx;
	}


/*
void
ShowObjectListClass(widg, class, cb)
Widget	widg;
int	class;
XmToggleButtonCallbackStruct	*cb;
	{
	if (cb->set)
		XtManageChild(obj_list[class].form);
	else
		XtUnmanageChild(obj_list[class].form);
	}
*/
