/*
 * Copyright 1990 by Baylor College of Medicine ALL RIGHTS RESERVED. 
 *
 * This program is subject to a license agreement between 
 * Baylor College of Medicine and MIT. Any use inconsistent with
 * said license and any use by persons other than the faculty, 
 * students and staff at MIT or any use on a computer not operated 
 * as part of the Athena Computing Environment (ACE) is expressly 
 * prohibited.
 */
/****************************************************************
 * File: props.c
 * Date: 05/07/91
 *
 * Description:
 *   This file contains the functions to create and manage the
 *   property manager.
 *
 * Revisions:
 ****************************************************************/
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <pwd.h>
#include <Xm/Xm.h>
#include <Xm/PushB.h>
#include <Xm/PushBG.h>
#include <Xm/Label.h>
#include <Xm/ScrolledW.h>
#include <Xm/TextF.h>
#include <Xm/ToggleB.h>

#include <X11/IntrinsicP.h>
#include <X11/StringDefs.h>
#include <X11/CoreP.h>
#include <X11/Shell.h>

#include <VList.h>
#include <Color.h>

#include "VnsP.h"
#include "props.h"

static Boolean created = FALSE;

typedef struct _PropMgr
{
	Widget pop;               /* property manager popup shell */
	Widget type;              /* label widget for setting property type */
	Widget vp;                /* viewport for properties */
	Widget buttons;           /* buttons for selection property items */
	Widget last_vp;           /* last widget managed by vp */
	Widget last_buttons;      /* last button managed */
	Widget note_buttons;      /* notebook button panel */
	Widget note_info;         /* notebook info panel */
	Widget access;            /* notebook access panel */
	Widget page_buttons;      /* page button panel */
	Widget page_info;         /* page info panel */
	Widget object_info;       /* object info panel */
	Widget color;             /* color panel */
	Widget fonts;             /* font panel */

	int current;              /* current type */
	VnsNotebook *nl;          /* pointer to notebook */
	VnsPage *pl;              /* pointer to page */
	VnsObject *obj;           /* pointer to object */
	int visible;              /* True if PM is popped up */

	char color_name[256];     /* color name */
	char font_name[256];      /* font name */
	FontChooser font_chooser; /* font chooser structure */

	VnsProp page;             /* page property id */
	VnsProp list;             /* object property list */
} PropMgr;

/* local program context */
static struct _local_info
{
	Widget pop;               /* property manager popup shell */
	Widget type;              /* label widget for setting property type */
	Widget vp;                /* viewport for properties */
	Widget buttons;           /* buttons for selection property items */
	Widget last_vp;           /* last widget managed by vp */
	Widget last_buttons;      /* last button managed */
	Widget note_buttons;      /* notebook button panel */
	Widget note_info;         /* notebook info panel */
	Widget access;            /* notebook access panel */
	Widget page_buttons;      /* page button panel */
	Widget page_info;         /* page info panel */
	Widget object_info;       /* object info panel */
	Widget color;             /* color panel */
	Widget fonts;             /* font panel */

	int current;              /* current type */
	VnsNotebook *nl;          /* pointer to notebook */
	VnsPage *pl;              /* pointer to page */
	VnsObject *obj;           /* pointer to object */
	int visible;              /* True if PM is popped up */

	char color_name[256];     /* color name */
	char font_name[256];      /* font name */
	FontChooser font_chooser; /* font chooser structure */

	VnsProp page;             /* page property id */
	VnsProp list;             /* object property list */
} local;

/*
 * reset the main buttons so they are senesitive
 */
static
void
reset_main_buttons(nl)
	VnsNotebook *nl;
{
	Widget apply = XtNameToWidget(local.pop,"*MainButtons.Apply");
	Widget ok = XtNameToWidget(local.pop,"*MainButtons.Ok");
	Widget close = XtNameToWidget(local.pop,"*MainButtons.Close");

	if (nl == NULL) return;

	if (nl->info.can_write)
	{
		XtSetSensitive(apply,True);
		XtSetSensitive(ok,True);
		XtSetSensitive(close,True);
	}
	else
	{
		XtSetSensitive(apply,False);
		XtSetSensitive(ok,False);
		XtSetSensitive(close,True);
	}
}

/*
 * reset the main buttons so they are senesitive
 */
static
void
reset_notebook_buttons(nl)
	VnsNotebook *nl;
{
	Widget apply = XtNameToWidget(local.pop,"*MainButtons.Apply");
	Widget ok = XtNameToWidget(local.pop,"*MainButtons.Ok");
	Widget close = XtNameToWidget(local.pop,"*MainButtons.Close");
	int me = srv_uid(NoteToSrv(nl));

	if (nl == NULL) return;

	if (nl->info.aid == me)
	{
		XtSetSensitive(apply,True);
		XtSetSensitive(ok,True);
		XtSetSensitive(close,True);
	}
	else
	{
		XtSetSensitive(apply,False);
		XtSetSensitive(ok,False);
		XtSetSensitive(close,True);
	}
}

static
void
ClearButtons()
{
	if (local.last_buttons != (Widget)NULL)
	{
		XtUnmanageChild(local.last_buttons);
	}
}

static
void
ClearViewport()
{
	if (local.last_vp != (Widget)NULL)
	{
		XtUnmanageChild(local.last_vp);
	}
}

void
VnsPropDisplay(w)
	Widget w;
{
	if (w == (Widget)NULL) return;

	ClearViewport();
	XtManageChild(w);
	local.last_vp = w;
}

/*ARGSUSED*/
static
void
choose_color(wd)
	Widget wd;
{
	char *col;

	XtVaGetValues(wd,
		XtNcolorName,&col,
		NULL);

	strcpy(local.color_name,col);
}

static
void
choose_font(w,font_name)
	Widget w;
	char *font_name;
{
	strcpy(local.font_name,font_name);
}

static
VnsAuthor *
VnsFindAuthor(db,aid)
	VnsDatabase *db;
	int aid;
{
	VnsAuthor *al = db->first_author;

	while (al != NULL)
	{
		if (al->aid == aid)
		{
			return al;
		}
		al = al->next;
	}
	return NULL;
}

/*
 * update notebook access info
 */
update_notebook_access(nl)
	VnsNotebook *nl;
{
	VnsDatabase *db = NoteToDb(nl);
	Access_Item *acc;
	int me = srv_uid(NoteToSrv(nl));
	int orig_author = nl->info.aid;
	int i;
	int nacc;

	srv_get_author_access(NoteToSrv(nl),nl->nid,&nacc,&acc);

	for (i = 0; i < nacc; i++)
	{
		VnsAuthor *author = VnsFindAuthor(db,acc[i].aid);

		if (author != NULL)
		{
			struct passwd *pwd = getpwuid(acc[i].aid);
			int rd_sens = (acc[i].access == 1);
			int wr_sens = (acc[i].access == 2);
			int bw = 0;

			author->current_access = acc[i].access;
			if (acc[i].aid == orig_author)
			{
				bw = 2;
			}

			XtVaSetValues(author->name,
				XmNborderWidth,bw,
				NULL);
			XtVaSetValues(author->read_only,
				XmNset,rd_sens,
				NULL);
			XtVaSetValues(author->read_write,
				XmNset,wr_sens,
				NULL);
		}
	}
}

static
void
sel_read_only(w,al,info)
	Widget w;
	VnsAuthor *al;
	XmToggleButtonCallbackStruct *info;
{
	Boolean set;

	XtVaGetValues(al->read_write,
		XmNset,&set,
		NULL);

	if (set)
	{
		XtVaSetValues(al->read_write,
			XmNset,False,
			NULL);
	}
}

static
void
sel_read_write(w,al,info)
	Widget w;
	VnsAuthor *al;
	XmToggleButtonCallbackStruct *info;
{
	Boolean set;

	XtVaGetValues(al->read_only,
		XmNset,&set,
		NULL);

	if (set)
	{
		XtVaSetValues(al->read_only,
			XmNset,False,
			NULL);
	}
}

/*
 * creates the Page info panel
 */
static
Widget
make_notebook_access(vns,parent)
	VnsContext *vns;
	Widget parent;
{
	VnsDatabase *db = vns->current_db;
	Widget panel,sw,list;
	XmString xm_str;
	int i;

	Widget frm = XtVaCreateWidget("NotebookAccessForm",vListWidgetClass,parent,
		XtNborderWidth,0,
		XtNnumRows,2,
		XtNnumColumns,1,
		XtNvSpacing,2,
		XtNhSpacing,2,
		XtNstretchHoriz,True,
		XtNstretchVert,True,
		XtNrowPivot,2,
		NULL);

	panel = XtVaCreateManagedWidget("panel",vListWidgetClass,frm,
		XtNstretchHoriz,True,
		NULL);
	xm_str = XmStringCreateLtoR("Author | ReadOnly | ReadWrite",
		XmSTRING_DEFAULT_CHARSET);
	XtVaCreateManagedWidget("label",xmLabelWidgetClass,panel,
		XmNlabelString,xm_str,
		NULL);
	XmStringFree(xm_str);

	sw = XtVaCreateManagedWidget("Viewport",xmScrolledWindowWidgetClass,frm,
		XmNscrollingPolicy,XmAUTOMATIC,
		XmNvisualPolicy,XmVARIABLE,
		XtNstretchHoriz,True,
		XtNstretchVert,True,
		NULL);
	list = XtVaCreateManagedWidget("NotebookAccess",vListWidgetClass,sw,
		XtNborderWidth,0,
		XtNnumColumns,3,
		XtNvSpacing,2,
		XtNhSpacing,2,
		NULL);

	/* add authors */
	{
		VnsAuthor *al;
		long *authors;
		int nauth;
		int i;

		if (srv_get_author_list(db->srv,&authors,&nauth) < 0)
		{
			fprintf(stderr,"No author for current database\n");
			exit(-1);
		}

		al = (VnsAuthor *)malloc(nauth * sizeof(VnsAuthor));

		for (i = 0; i < nauth; i++)
		{
			int me = srv_uid(db->srv);
			struct passwd *pwd = getpwuid((int)authors[i]);
			int rd_sens = False;
			int wr_sens;
			char user_name[100];
			int bw = 0;

			al[i].aid = (int)authors[i];
			wr_sens = (authors[i] == me);

			if (wr_sens)
			{
				bw = 2;
			}

			if (pwd == NULL)
			{
				sprintf(user_name,"User %d",al[i].aid);
				xm_str = XmStringCreateLtoR(user_name,XmSTRING_DEFAULT_CHARSET);
				al[i].name = XtVaCreateManagedWidget("author",xmLabelWidgetClass,list,
					XmNlabelString,xm_str, 
					XmNborderWidth,bw,
					NULL);
				XmStringFree(xm_str);
			}
			else
			{
				xm_str = XmStringCreateLtoR(pwd->pw_name,XmSTRING_DEFAULT_CHARSET);
				al[i].name = XtVaCreateManagedWidget("author",xmLabelWidgetClass,list,
					XmNlabelString,xm_str, 
					XmNborderWidth,bw,
					NULL);
				XmStringFree(xm_str);
			}

			al[i].read_only = XtVaCreateManagedWidget("",xmToggleButtonWidgetClass,list,
				XmNset,rd_sens,
				NULL);
			XtAddCallback(al[i].read_only,XmNarmCallback,sel_read_only,(XtPointer)&al[i]);

			al[i].read_write = XtVaCreateManagedWidget("",xmToggleButtonWidgetClass,list,
				XmNset,wr_sens,
				NULL);
			XtAddCallback(al[i].read_write,XmNarmCallback,sel_read_write,(XtPointer)&al[i]);

			al[i].next = db->first_author;
			db->first_author = &al[i];
		}

		free((char *)authors);
	}

	return frm;
}

/*
 * creates the Page info panel
 */
static
Widget
make_notebook_info(parent)
	Widget parent;
{
	XmString xm_str;
	Widget sw = XtVaCreateWidget("Viewport",xmScrolledWindowWidgetClass,parent,
		XmNscrollingPolicy,XmAUTOMATIC,
		XmNvisualPolicy,XmVARIABLE,
		XtNstretchHoriz,True,
		XtNstretchVert,True,
		NULL);
	Widget vlist = XtVaCreateManagedWidget("NotebookInfo",vListWidgetClass,sw,
		XtNborderWidth,0,
		XtNnumColumns,2,
		XtNvSpacing,2,
		XtNhSpacing,2,
		NULL);

	xm_str = XmStringCreateLtoR("Notebook Name:",XmSTRING_DEFAULT_CHARSET);
	XtVaCreateManagedWidget("label",xmLabelWidgetClass,vlist,
		XmNlabelString,xm_str,
		NULL);
	XmStringFree(xm_str);

	XtVaCreateManagedWidget("NotebookName",xmTextFieldWidgetClass,vlist,
		NULL);

	xm_str = XmStringCreateLtoR("Notebook Id:",XmSTRING_DEFAULT_CHARSET);
	XtVaCreateManagedWidget("label",xmLabelWidgetClass,vlist,
		XmNlabelString,xm_str,
		NULL);
	XmStringFree(xm_str);

	xm_str = XmStringCreateLtoR(" ",XmSTRING_DEFAULT_CHARSET);
	XtVaCreateManagedWidget("NotebookId",xmLabelWidgetClass,vlist,
		XmNlabelString,xm_str,
		NULL);
	XmStringFree(xm_str);

	xm_str = XmStringCreateLtoR("Home Page Number:",XmSTRING_DEFAULT_CHARSET);
	XtVaCreateManagedWidget("label",xmLabelWidgetClass,vlist,
		XmNlabelString,xm_str,
		NULL);
	XmStringFree(xm_str);

	XtVaCreateManagedWidget("NotebookHomePage",xmTextFieldWidgetClass,vlist,
		NULL);

	return sw;
}

/*
 * creates the Page info panel
 */
static
Widget
make_page_info(parent)
	Widget parent;
{
	XmString xm_str;
	Widget sw = XtVaCreateWidget("Viewport",xmScrolledWindowWidgetClass,parent,
		XmNscrollingPolicy,XmAUTOMATIC,
		XmNvisualPolicy,XmVARIABLE,
		XtNstretchHoriz,True,
		XtNstretchVert,True,
		NULL);
	Widget vlist = XtVaCreateManagedWidget("PageInfo",vListWidgetClass,sw,
		XtNborderWidth,0,
		XtNnumColumns,2,
		XtNvSpacing,2,
		XtNhSpacing,2,
		NULL);

	xm_str = XmStringCreateLtoR("Page Name:",XmSTRING_DEFAULT_CHARSET);
	XtVaCreateManagedWidget("label",xmLabelWidgetClass,vlist,
		XmNlabelString,xm_str,
		NULL);
	XmStringFree(xm_str);

	XtVaCreateManagedWidget("PageName",xmTextFieldWidgetClass,vlist,
		NULL);

	xm_str = XmStringCreateLtoR("Owner:",XmSTRING_DEFAULT_CHARSET);
	XtVaCreateManagedWidget("label",xmLabelWidgetClass,vlist,
		XmNlabelString,xm_str,
		NULL);
	XmStringFree(xm_str);

	xm_str = XmStringCreateLtoR(" ",XmSTRING_DEFAULT_CHARSET);
	XtVaCreateManagedWidget("Owner",xmLabelWidgetClass,vlist,
		XmNlabelString,xm_str,
		NULL);
	XmStringFree(xm_str);

	xm_str = XmStringCreateLtoR("Notebook Name:",XmSTRING_DEFAULT_CHARSET);
	XtVaCreateManagedWidget("label",xmLabelWidgetClass,vlist,
		XmNlabelString,xm_str,
		NULL);
	XmStringFree(xm_str);

	xm_str = XmStringCreateLtoR(" ",XmSTRING_DEFAULT_CHARSET);
	XtVaCreateManagedWidget("NoteName",xmLabelWidgetClass,vlist,
		XmNlabelString,xm_str,
		NULL);
	XmStringFree(xm_str);

	xm_str = XmStringCreateLtoR("Creation Date:",XmSTRING_DEFAULT_CHARSET);
	XtVaCreateManagedWidget("label",xmLabelWidgetClass,vlist,
		XmNlabelString,xm_str,
		NULL);
	XmStringFree(xm_str);

	xm_str = XmStringCreateLtoR(" ",XmSTRING_DEFAULT_CHARSET);
	XtVaCreateManagedWidget("Created",xmLabelWidgetClass,vlist,
		XmNlabelString,xm_str,
		NULL);
	XmStringFree(xm_str);

	xm_str = XmStringCreateLtoR("Page Id:",XmSTRING_DEFAULT_CHARSET);
	XtVaCreateManagedWidget("label",xmLabelWidgetClass,vlist,
		XmNlabelString,xm_str,
		NULL);
	XmStringFree(xm_str);

	xm_str = XmStringCreateLtoR(" ",XmSTRING_DEFAULT_CHARSET);
	XtVaCreateManagedWidget("Id",xmLabelWidgetClass,vlist,
		XmNlabelString,xm_str,
		NULL);
	XmStringFree(xm_str);

	xm_str = XmStringCreateLtoR("Page Width:",XmSTRING_DEFAULT_CHARSET);
	XtVaCreateManagedWidget("label",xmLabelWidgetClass,vlist,
		XmNlabelString,xm_str,
		NULL);
	XmStringFree(xm_str);

	XtVaCreateManagedWidget("PageWidth",xmTextFieldWidgetClass,vlist,
		XtNstretchHoriz,True,
		NULL);

	xm_str = XmStringCreateLtoR("Page Height:",XmSTRING_DEFAULT_CHARSET);
	XtVaCreateManagedWidget("label",xmLabelWidgetClass,vlist,
		XmNlabelString,xm_str,
		NULL);
	XmStringFree(xm_str);

	XtVaCreateManagedWidget("PageHeight",xmTextFieldWidgetClass,vlist,
		XtNstretchHoriz,True,
		NULL);

	return sw;
}

/*
 * Update the information display for a page.
 */
static
void
update_note_info(nl)
	VnsNotebook *nl;
{
	Widget note_name = XtNameToWidget(local.note_info,"*NotebookName");
	Widget note_id = XtNameToWidget(local.note_info,"*NotebookId");
	Widget home_page = XtNameToWidget(local.note_info,"*NotebookHomePage");
	XmString xm_str;
	char buf[50];

	if (nl == NULL) return;

	XtVaSetValues(note_name,
		XmNvalue,nl->info.title,
		NULL);

	sprintf(buf,"%d",nl->nid);
	xm_str = XmStringCreateLtoR(buf,XmSTRING_DEFAULT_CHARSET);
	XtVaSetValues(note_id,
		XmNlabelString,xm_str,
		NULL);
	XmStringFree(xm_str);

	sprintf(buf,"%d",nl->info.home_page);
	XtVaSetValues(home_page,
		XmNvalue,buf,
		NULL);

	/* reset the text field to the beginning of the line */
	XmTextFieldShowPosition(note_name,0);
	XmTextFieldShowPosition(home_page,0);
}

/*
 * Update the information display for a page.
 */
static
void
update_page_info(pl)
	VnsPage *pl;
{
	Widget page_name = XtNameToWidget(local.page_info,"*PageName");
	Widget owner = XtNameToWidget(local.page_info,"*Owner");
	Widget note_name = XtNameToWidget(local.page_info,"*NoteName");
	Widget create_date = XtNameToWidget(local.page_info,"*Created");
	Widget id = XtNameToWidget(local.page_info,"*Id");
	Widget page_w = XtNameToWidget(local.page_info,"*PageWidth");
	Widget page_h = XtNameToWidget(local.page_info,"*PageHeight");
	VnsNotebook *nl;
	XmString xm_str;
	char buf[50];
	struct passwd *pwd;

	if (pl == NULL) return;

	nl = PageToNote(pl);

	XtVaSetValues(page_name,
		XmNvalue,pl->info.title,
		NULL);

	pwd = getpwuid(pl->info.aid);
	if (pwd == NULL)
	{
		sprintf(buf,"User %d",pl->info.aid);
		xm_str = XmStringCreateLtoR(buf,XmSTRING_DEFAULT_CHARSET);
		XtVaSetValues(owner,
			XmNlabelString,xm_str,
			NULL);
		XmStringFree(xm_str);
	}
	else
	{
		xm_str = XmStringCreateLtoR(pwd->pw_name,XmSTRING_DEFAULT_CHARSET);
		XtVaSetValues(owner,
			XmNlabelString,xm_str,
			NULL);
		XmStringFree(xm_str);
	}

	xm_str = XmStringCreateLtoR(nl->info.title,
		XmSTRING_DEFAULT_CHARSET);
	XtVaSetValues(note_name,
		XmNlabelString,xm_str,
		NULL);
	XmStringFree(xm_str);

	xm_str = XmStringCreateLtoR(pl->info.create_date,
		XmSTRING_DEFAULT_CHARSET);
	XtVaSetValues(create_date,
		XmNlabelString,xm_str,
		NULL);
	XmStringFree(xm_str);

	sprintf(buf,"%d",pl->pid);
	xm_str = XmStringCreateLtoR(buf,XmSTRING_DEFAULT_CHARSET);
	XtVaSetValues(id,
		XmNlabelString,xm_str,
		NULL);
	XmStringFree(xm_str);

	sprintf(buf,"%d",pl->info.width);
	XtVaSetValues(page_w,
		XmNvalue,buf,
		NULL);
	sprintf(buf,"%d",pl->info.height);
	XtVaSetValues(page_h,
		XmNvalue,buf,
		NULL);

	/* reset text fields */
	XmTextFieldShowPosition(page_name,0);
	XmTextFieldShowPosition(page_w,0);
	XmTextFieldShowPosition(page_h,0);
}

/*
 * Modify notebook
 */
static
void
modify_notebook()
{
	VnsNotebook *nl = local.nl;
	VnsDatabase *db;
	Widget note_name = XtNameToWidget(local.note_info,"*NotebookName");
	Widget note_id = XtNameToWidget(local.note_info,"*NotebookId");
	Widget home_page = XtNameToWidget(local.note_info,"*NotebookHomePage");
	XmString xm_str;
	char *name;
	char *home;
	int hid;

	if (nl == NULL) return;
	db = NoteToDb(nl);

	XtVaGetValues(note_name,
		XmNvalue,&name,
		NULL);
	XtVaGetValues(home_page,
		XmNvalue,&home,
		NULL);

	hid = atoi(home);

	if (srv_validate_page(NoteToSrv(nl),nl->nid,hid) != 1)
	{
		char msg[255];
		sprintf(msg,"Home page number %d is not a valid page number",hid);
		VtError(local.pop,msg);
		return;
	}

	/* update the notebook information */
	strcpy(nl->info.title,name);
	nl->info.home_page = hid;

	/* modify the notebook in the database */
	srv_modify_notebook(NoteToSrv(nl),nl->nid,&nl->info);

	/* activate notebook modify callbacks */
	VnsCallCallbacks(NoteToVns(nl),CB_NOTEBOOK_MODIFY,(VnsPointer)nl);

	/* update the notebook name on all displayed pages */
	{
		VnsPage *pl = nl->first_page;

		while (pl != NULL)
		{
			xm_str = XmStringCreateLtoR(nl->info.title,XmSTRING_DEFAULT_CHARSET);
			XtVaSetValues(pl->nname,
				XmNlabelString,xm_str,
				NULL);
			XmStringFree(xm_str);
			set_page_accesses(pl);
			pl = pl->next;
		}
	}

	/* update notebook access */
	{
		VnsAuthor *al = db->first_author;

		while (al != NULL)
		{
			Boolean ro, rw;
			int new_acc = 0;

			XtVaGetValues(al->read_only,
				XmNset,&ro,
				NULL);
			XtVaGetValues(al->read_write,
				XmNset,&rw,
				NULL);

			if (ro)
			{
				new_acc = 1;
			}

			if (rw)
			{
				new_acc = 2;
			}

			if (new_acc != al->current_access)
			{
				al->current_access = new_acc;
				switch(new_acc)
				{
					case 0:
						srv_disallow_author(NoteToSrv(nl),al->aid,local.nl->nid);
						if (al->aid == srv_uid(NoteToSrv(nl)))
						{
							local.nl->info.can_read = 0;
							local.nl->info.can_write = 0;
						}
						break;
					case 1:
						srv_allow_author(NoteToSrv(nl),al->aid,local.nl->nid,0);
						if (al->aid == srv_uid(NoteToSrv(nl)))
						{
							local.nl->info.can_read = 1;
							local.nl->info.can_write = 0;
						}
						break;
					case 2:
						srv_allow_author(NoteToSrv(nl),al->aid,local.nl->nid,1);
						if (al->aid == srv_uid(NoteToSrv(nl)))
						{
							local.nl->info.can_read = 1;
							local.nl->info.can_write = 1;
						}
						break;
				}
			}

			al = al->next;
		}
	}
}

/*
 * Modify page
 */
static
void
modify_page()
{
	VnsPage *pl = local.pl;
	VnsNotebook *nl = PageToNote(pl);
	Widget name = XtNameToWidget(local.page_info,"*PageName");
	Widget page_w = XtNameToWidget(local.page_info,"*PageWidth");
	Widget page_h = XtNameToWidget(local.page_info,"*PageHeight");
	char *title;
	char *s_w;
	char *s_h;

	/* get the current page name */
	XtVaGetValues(name,
		XmNvalue,&title,
		NULL);
	XtVaGetValues(page_w,
		XmNvalue,&s_w,
		NULL);
	XtVaGetValues(page_h,
		XmNvalue,&s_h,
		NULL);

	/* modifiy the page information and update the database */
	pl->info.width = atoi(s_w);
	pl->info.height = atoi(s_h);
	strcpy(pl->info.title,title);
	strcpy(pl->info.color,local.color_name);
	srv_modify_page(PageToSrv(pl),nl->nid,pl->pid,&pl->info);

	/* call page modify callbacks */
	VnsCallCallbacks(PageToVns(pl),CB_PAGE_MODIFY,(VnsPointer)pl);

	pl->col = VnsAllocNamedColor(PageToVns(pl),pl->info.color);
	VtSetBackColor(pl->comp,pl->col);

	/* modify the displayed page (this should be a callback!) */
	XtVaSetValues(pl->comp,
		XmNwidth,pl->info.width,
		XmNheight,pl->info.height,
		NULL);

	/* modify the page title and icon name for the page shell */
	XtVaSetValues(pl->pwd,
		XmNtitle,pl->info.title,
		XmNiconName,pl->info.title,
		NULL);
}

/*
 * creates the Object info panel
 */
static
Widget
make_object_info(parent)
	Widget parent;
{
	XmString xm_str;
	Widget sw = XtVaCreateWidget("Viewport",xmScrolledWindowWidgetClass,parent,
		XmNscrollingPolicy,XmAUTOMATIC,
		XmNvisualPolicy,XmVARIABLE,
		XtNstretchHoriz,True,
		XtNstretchVert,True,
		NULL);
	Widget vlist = XtVaCreateManagedWidget("ObjectInfo",vListWidgetClass,sw,
		XtNborderWidth,0,
		XtNnumColumns,2,
		XtNvSpacing,2,
		XtNhSpacing,2,
		NULL);

	xm_str = XmStringCreateLtoR("Object Type:",XmSTRING_DEFAULT_CHARSET);
	XtVaCreateManagedWidget("label",xmLabelWidgetClass,vlist,
		XmNlabelString,xm_str,
		NULL);
	XmStringFree(xm_str);

	xm_str = XmStringCreateLtoR(" ",XmSTRING_DEFAULT_CHARSET);
	XtVaCreateManagedWidget("Type",xmLabelWidgetClass,vlist,
		XmNlabelString,xm_str,
		NULL);
	XmStringFree(xm_str);

	xm_str = XmStringCreateLtoR("Owner:",XmSTRING_DEFAULT_CHARSET);
	XtVaCreateManagedWidget("label",xmLabelWidgetClass,vlist,
		XmNlabelString,xm_str,
		NULL);
	XmStringFree(xm_str);

	xm_str = XmStringCreateLtoR(" ",XmSTRING_DEFAULT_CHARSET);
	XtVaCreateManagedWidget("Owner",xmLabelWidgetClass,vlist,
		XmNlabelString,xm_str,
		NULL);
	XmStringFree(xm_str);

	xm_str = XmStringCreateLtoR("Parent Page:",XmSTRING_DEFAULT_CHARSET);
	XtVaCreateManagedWidget("label",xmLabelWidgetClass,vlist,
		XmNlabelString,xm_str,
		NULL);
	XmStringFree(xm_str);

	xm_str = XmStringCreateLtoR(" ",XmSTRING_DEFAULT_CHARSET);
	XtVaCreateManagedWidget("ParentPage",xmLabelWidgetClass,vlist,
		XmNlabelString,xm_str,
		NULL);
	XmStringFree(xm_str);

	xm_str = XmStringCreateLtoR("Parent Notebook:",XmSTRING_DEFAULT_CHARSET);
	XtVaCreateManagedWidget("label",xmLabelWidgetClass,vlist,
		XmNlabelString,xm_str,
		NULL);
	XmStringFree(xm_str);

	xm_str = XmStringCreateLtoR(" ",XmSTRING_DEFAULT_CHARSET);
	XtVaCreateManagedWidget("ParentNote",xmLabelWidgetClass,vlist,
		XmNlabelString,xm_str,
		NULL);
	XmStringFree(xm_str);

	xm_str = XmStringCreateLtoR("x:",XmSTRING_DEFAULT_CHARSET);
	XtVaCreateManagedWidget("label",xmLabelWidgetClass,vlist,
		XmNlabelString,xm_str,
		NULL);
	XmStringFree(xm_str);

	xm_str = XmStringCreateLtoR(" ",XmSTRING_DEFAULT_CHARSET);
	XtVaCreateManagedWidget("X",xmLabelWidgetClass,vlist,
		XmNlabelString,xm_str,
		XtNborderWidth,0,
		NULL);
	XmStringFree(xm_str);

	xm_str = XmStringCreateLtoR("y:",XmSTRING_DEFAULT_CHARSET);
	XtVaCreateManagedWidget("label",xmLabelWidgetClass,vlist,
		XmNlabelString,xm_str,
		NULL);
	XmStringFree(xm_str);

	xm_str = XmStringCreateLtoR(" ",XmSTRING_DEFAULT_CHARSET);
	XtVaCreateManagedWidget("Y",xmLabelWidgetClass,vlist,
		XmNlabelString,xm_str,
		XtNborderWidth,0,
		NULL);
	XmStringFree(xm_str);

	xm_str = XmStringCreateLtoR("Width:",XmSTRING_DEFAULT_CHARSET);
	XtVaCreateManagedWidget("label",xmLabelWidgetClass,vlist,
		XmNlabelString,xm_str,
		NULL);
	XmStringFree(xm_str);

	xm_str = XmStringCreateLtoR(" ",XmSTRING_DEFAULT_CHARSET);
	XtVaCreateManagedWidget("Width",xmLabelWidgetClass,vlist,
		XmNlabelString,xm_str,
		NULL);
	XmStringFree(xm_str);

	xm_str = XmStringCreateLtoR("Height:",XmSTRING_DEFAULT_CHARSET);
	XtVaCreateManagedWidget("label",xmLabelWidgetClass,vlist,
		XmNlabelString,xm_str,
		NULL);
	XmStringFree(xm_str);

	xm_str = XmStringCreateLtoR(" ",XmSTRING_DEFAULT_CHARSET);
	XtVaCreateManagedWidget("Height",xmLabelWidgetClass,vlist,
		XmNlabelString,xm_str,
		NULL);
	XmStringFree(xm_str);

	xm_str = XmStringCreateLtoR("Object Id:",XmSTRING_DEFAULT_CHARSET);
	XtVaCreateManagedWidget("label",xmLabelWidgetClass,vlist,
		XmNlabelString,xm_str,
		NULL);
	XmStringFree(xm_str);

	xm_str = XmStringCreateLtoR(" ",XmSTRING_DEFAULT_CHARSET);
	XtVaCreateManagedWidget("Id",xmLabelWidgetClass,vlist,
		XmNlabelString,xm_str,
		NULL);
	XmStringFree(xm_str);

	return sw;
}

/*
 * Callback for Notebook info
 */
/*ARGSUSED*/
static
void
sel_note_info(w)
	Widget w;
{
	ClearViewport();
	XtManageChild(local.note_info);
	local.last_vp = local.note_info;
}

/*
 * Callback for Notebook access
 */
/*ARGSUSED*/
static
void
sel_note_access(w)
	Widget w;
{
	ClearViewport();
	XtManageChild(local.access);
	local.last_vp = local.access;
}

/*
 * Callback for Page info
 */
/*ARGSUSED*/
static
void
sel_page_info(w)
	Widget w;
{
	ClearViewport();
	XtManageChild(local.page_info);
	local.last_vp = local.page_info;
}

/*
 * Callback for Object info
 */
/*ARGSUSED*/
static
void
sel_object_info(w)
	Widget w;
{
	ClearViewport();
	XtManageChild(local.object_info);
	local.last_vp = local.object_info;
}

/*
 * Callback for color
 */
/*ARGSUSED*/
static
void
sel_color(w)
	Widget w;
{
	VnsPropDisplay(local.color);
}

/*
 * Callback for fonts 
 */
/*ARGSUSED*/
static
void
sel_font(w)
	Widget w;
{
	VnsPropDisplay(local.fonts);
}

/*
 * Modify object
 */
/*ARGSUSED*/
static
void
modify_object()
{
	VnsObject *obj = local.obj;
	VnsProp prop;

	/* modify the object */
	prop = local.list;
	while (prop != NULL)
	{
		if (prop->type == VNS_OBJECT)
		{
			if (prop->sub_type == (int)obj->info.type)
			{
				/* update the object if it has an update callback */
				if (prop->modify)
				{
					(prop->modify)(prop,obj);
				}
			}
		}
		prop = prop->next;
	}
}

/*
 * Callback for Apply
 */
/*ARGSUSED*/
static
void
sel_apply(w)
	Widget w;
{
	switch(local.current)
	{
		case VNS_NOTEBOOK:
			modify_notebook();
			break;
		case VNS_PAGE:
			modify_page();
			break;
		case VNS_OBJECT:
			modify_object();
			break;
		default:
			break;	
	}
}

/*
 * Callback for Ok
 */
/*ARGSUSED*/
static
void
sel_ok(w,vns)
	Widget w;
	VnsContext *vns;
{
	/* apply the changes */
	sel_apply(w);

	/* popdown the property manager */
	XtPopdown(vns->prop_mgr);
}

/*
 * Callback for Close
 */
/*ARGSUSED*/
static
void
sel_close(w,vns)
	Widget w;
	VnsContext *vns;
{
	local.current = VNS_NULL;
	local.nl = (VnsNotebook *)NULL;
	local.pl = (VnsPage *)NULL;
	local.obj = (VnsObject *)NULL;

	XtPopdown(vns->prop_mgr);
}

/*
 * Callback when property manager is popped up
 */
static
void
pm_popup(w)
	Widget w;
{
	local.visible = TRUE;
}

/*
 * Callback when property manager is popped down
 */
static
void
pm_popdown(w)
	Widget w;
{
	local.visible = FALSE;
}

VnsPropWatchOn()
{
	if (local.visible)
	{
		VtWatchOn(local.pop);
	}
}

VnsPropWatchOff()
{
	if (local.visible)
	{
		VtWatchOff(local.pop);
	}
}

/*
 * Initialize the property manager. This function should
 * be called before all other VnsProp functions.
 */
void
VnsBuildPropertyManager(vns)
	VnsContext *vns;
{
	PropMgr *pm = (PropMgr *)malloc(sizeof(PropMgr));
	Widget form;
	XmString xm_str;

	local.list = (VnsProp)NULL;

	pm->pop = XtVaCreatePopupShell("PropertyManager",
		vendorShellWidgetClass,vns->toplevel,
		XmNtitle,"Property Manager",
		XmNwidth,370,
		XmNheight,420,
		NULL);
	XtAddCallback(pm->pop,XmNpopupCallback,pm_popup,(XtPointer)NULL);
	XtAddCallback(pm->pop,XmNpopdownCallback,pm_popdown,(XtPointer)NULL);

	local.pop = pm->pop;
	vns->prop_mgr = pm->pop;
	local.visible = FALSE;

	form = XtVaCreateManagedWidget("form",vListWidgetClass,pm->pop,
		XtNrowPivot,3,
		XtNvSpacing,2,
		XtNhSpacing,2,
		NULL);
	{
		Widget vlist = XtVaCreateManagedWidget("vlist",vListWidgetClass,form,
			XtNborderWidth,0,
			XtNnumRows,1,
			XtNvSpacing,2,
			XtNhSpacing,2,
			XtNstretchHoriz,True,
			NULL);

		xm_str = XmStringCreateLtoR("Properties:",XmSTRING_DEFAULT_CHARSET);
		XtVaCreateManagedWidget("PropertyLabel",xmLabelWidgetClass,vlist,
			XmNlabelString,xm_str,
			NULL);
		XmStringFree(xm_str);

		xm_str = XmStringCreateLtoR(" ",XmSTRING_DEFAULT_CHARSET);
		local.type = XtVaCreateManagedWidget("PropertyType",xmLabelWidgetClass,vlist,
			XmNlabelString,xm_str,
			NULL);
		XmStringFree(xm_str);
	}
	{
		Widget note_info, note_access;
		Widget page_info, page_color;
		local.buttons = XtVaCreateManagedWidget("ConfigButtonPanel",vListWidgetClass,form,
			XtNborderWidth,0,
			XtNnumRows,1,
			XtNvSpacing,2,
			XtNhSpacing,2,
			XtNheight,25,
			XtNstretchHoriz,True,
			NULL);

		local.note_buttons = XtVaCreateWidget("NoteButtons",vListWidgetClass,local.buttons,
			XtNborderWidth,0,
			XtNnumRows,1,
			XtNvSpacing,2,
			XtNhSpacing,2,
			XtNheight,25,
			XtNstretchHoriz,True,
			NULL);
		note_info = XtVaCreateManagedWidget("Info",xmPushButtonWidgetClass,local.note_buttons,
			NULL);
		XtAddCallback(note_info,XmNactivateCallback,sel_note_info,(XtPointer)NULL);
		note_access = XtVaCreateManagedWidget("Access",xmPushButtonWidgetClass,local.note_buttons,
			NULL);
		XtAddCallback(note_access,XmNactivateCallback,sel_note_access,(XtPointer)NULL);

		local.page_buttons = XtVaCreateWidget("PageButtons",vListWidgetClass,local.buttons,
			XtNborderWidth,0,
			XtNnumRows,1,
			XtNvSpacing,2,
			XtNhSpacing,2,
			XtNheight,25,
			XtNstretchHoriz,True,
			NULL);
		page_info = XtVaCreateManagedWidget("Info",xmPushButtonWidgetClass,local.page_buttons,
			NULL);
		XtAddCallback(page_info,XmNactivateCallback,sel_page_info,(XtPointer)NULL);
		page_color = XtVaCreateManagedWidget("Color",xmPushButtonWidgetClass,local.page_buttons,
			NULL);
		XtAddCallback(page_color,XmNactivateCallback,sel_color,(XtPointer)NULL);
	}
	{
		local.vp = XtVaCreateManagedWidget("vlist",vListWidgetClass,form,
			XtNnumRows,1,
			XtNvSpacing,2,
			XtNhSpacing,2,
			XtNwidth,330,
			XtNheight,350,
			XtNstretchHoriz,True,
			XtNstretchVert,True,
			NULL);

		/* construct various property items. each should be unmanaged */
		local.color = VtColorPanel(local.vp,choose_color);
		local.page_info = make_page_info(local.vp);
		local.object_info = make_object_info(local.vp);
		local.note_info = make_notebook_info(local.vp);
		local.access = make_notebook_access(vns,local.vp);
		local.fonts = VtFontPanel(local.vp,&local.font_chooser,choose_font,
			(XtPointer)local.vp);
	}
	{
		Widget vlist = XtVaCreateManagedWidget("MainButtons",vListWidgetClass,form,
			XtNborderWidth,0,
			XtNnumRows,1,
			XtNvSpacing,2,
			XtNhSpacing,2,
			XtNstretchHoriz,True,
			NULL);
		Widget apply = XtVaCreateManagedWidget("Apply",xmPushButtonWidgetClass,vlist,
			NULL);
		Widget ok = XtVaCreateManagedWidget("Ok",xmPushButtonWidgetClass,vlist,
			NULL);
		Widget close = XtVaCreateManagedWidget("Close",xmPushButtonWidgetClass,vlist,
			NULL);
		XtAddCallback(apply,XmNactivateCallback,sel_apply,(XtPointer)vns);
		XtAddCallback(ok,XmNactivateCallback,sel_ok,(XtPointer)vns);
		XtAddCallback(close,XmNactivateCallback,sel_close,(XtPointer)vns);
	}

	/* these should probably be moved to their perspective file 
	   and executed when the update function is first called */
	init_text_props(vns);
	init_image_props(vns);
	init_link_props(vns);
	init_action_props(vns);
}

/*
 * Update the property manager for a specific page
 */
void
VnsPropPage(pl)
	VnsPage *pl;
{
	VnsNotebook *nl;
	XmString xm_str;

	if (!created)
	{
		VnsBuildPropertyManager(PageToVns(pl));
		created = TRUE;
	}

	if (pl == NULL) return;

	nl = PageToNote(pl);

	if (!local.visible) return;

	/* reset the main control panel */
	reset_main_buttons(nl);

	/* update local parameters*/
	local.nl = nl;
	local.pl = pl;
	local.obj = (VnsObject *)NULL;

	/* update page information */
	update_page_info(pl);

	/* set the color in the color property sheet */
	{
		int len = strlen(pl->info.color);
		if (len == 0)
		{
			/* if no page color, then use white */
			VnsPropSetColor("white");
		}
		else
		{
			VnsPropSetColor(pl->info.color);
		}
	}

	if (local.current == VNS_PAGE) return;

	ClearViewport();
	local.current = VNS_PAGE;

	/* update property type label */
	xm_str = XmStringCreateLtoR("Page",XmSTRING_DEFAULT_CHARSET);
	XtVaSetValues(local.type,
		XmNlabelString,xm_str,
		NULL);
	XmStringFree(xm_str);

	ClearButtons();
	XtManageChild(local.page_buttons);
	local.last_buttons = local.page_buttons;

	XtManageChild(local.page_info);
	local.last_vp = local.page_info;
}

static
void
update_object_info(obj)
	VnsObject *obj;
{
	Widget type = XtNameToWidget(local.object_info,"*Type");
	Widget owner = XtNameToWidget(local.object_info,"*Owner");
	Widget parent_page = XtNameToWidget(local.object_info,"*ParentPage");
	Widget parent_note = XtNameToWidget(local.object_info,"*ParentNote");
	Widget x = XtNameToWidget(local.object_info,"*X");
	Widget y = XtNameToWidget(local.object_info,"*Y");
	Widget width = XtNameToWidget(local.object_info,"*Width");
	Widget height = XtNameToWidget(local.object_info,"*Height");
	Widget id = XtNameToWidget(local.object_info,"*Id");
	XmString xm_str;
	char buf[50];

	if (obj != NULL)
	{
		struct passwd *pwd = getpwuid(obj->info.aid);

		sprintf(buf,"%d",obj->info.type);
		xm_str = XmStringCreateLtoR(buf,XmSTRING_DEFAULT_CHARSET);
		XtVaSetValues(type,
			XmNlabelString,xm_str,
			NULL);
		XmStringFree(xm_str);

		if (pwd != NULL)
		{
			xm_str = XmStringCreateLtoR(pwd->pw_name,XmSTRING_DEFAULT_CHARSET);
			XtVaSetValues(owner,
				XmNlabelString,xm_str,
				NULL);
			XmStringFree(xm_str);
		}
		else
		{
			sprintf(buf,"User %d",obj->info.aid);
			xm_str = XmStringCreateLtoR(buf,XmSTRING_DEFAULT_CHARSET);
			XtVaSetValues(owner,
				XmNlabelString,xm_str,
				NULL);
			XmStringFree(xm_str);
		}

		xm_str = XmStringCreateLtoR(local.pl->info.title,XmSTRING_DEFAULT_CHARSET);
		XtVaSetValues(parent_page,
			XmNlabelString,xm_str,
			NULL);
		XmStringFree(xm_str);

		xm_str = XmStringCreateLtoR(local.nl->info.title,XmSTRING_DEFAULT_CHARSET);
		XtVaSetValues(parent_note,
			XmNlabelString,xm_str,
			NULL);
		XmStringFree(xm_str);

		sprintf(buf,"%d",obj->info.x);
		xm_str = XmStringCreateLtoR(buf,XmSTRING_DEFAULT_CHARSET);
		XtVaSetValues(x,
			XmNlabelString,xm_str,
			NULL);
		XmStringFree(xm_str);

		sprintf(buf,"%d",obj->info.y);
		xm_str = XmStringCreateLtoR(buf,XmSTRING_DEFAULT_CHARSET);
		XtVaSetValues(y,
			XmNlabelString,xm_str,
			NULL);
		XmStringFree(xm_str);

		sprintf(buf,"%d",obj->info.width);
		xm_str = XmStringCreateLtoR(buf,XmSTRING_DEFAULT_CHARSET);
		XtVaSetValues(width,
			XmNlabelString,xm_str,
			NULL);
		XmStringFree(xm_str);

		sprintf(buf,"%d",obj->info.height);
		xm_str = XmStringCreateLtoR(buf,XmSTRING_DEFAULT_CHARSET);
		XtVaSetValues(height,
			XmNlabelString,xm_str,
			NULL);
		XmStringFree(xm_str);

		sprintf(buf,"%d",obj->oid);
		xm_str = XmStringCreateLtoR(buf,XmSTRING_DEFAULT_CHARSET);
		XtVaSetValues(id,
			XmNlabelString,xm_str,
			NULL);
		XmStringFree(xm_str);
	}
}

/*
 * Update the property manager for a specific notebook
 */
void
VnsPropNotebook(nl)
	VnsNotebook *nl;
{
	VnsProp prop;
	XmString xm_str;

	if (!created)
	{
		VnsBuildPropertyManager(NoteToVns(nl));
		created = TRUE;
	}

	if (nl == NULL) return;

	if (!local.visible) return;

	/* reset the main control panel */
	reset_notebook_buttons(nl);

	/* update local parameters*/
	local.nl = nl;
	local.pl = (VnsPage *)NULL;
	local.obj = (VnsObject *)NULL;

	update_note_info(nl);
	update_notebook_access(nl);

	if (local.current == VNS_NOTEBOOK) return;

	ClearViewport();
	local.current = VNS_NOTEBOOK;

	/* update property type label */
	xm_str = XmStringCreateLtoR("Notebook",XmSTRING_DEFAULT_CHARSET);
	XtVaSetValues(local.type,
		XmNlabelString,xm_str,
		NULL);
	XmStringFree(xm_str);

	ClearButtons();
	XtManageChild(local.note_buttons);
	local.last_buttons = local.note_buttons;

	XtManageChild(local.note_info);
	local.last_vp = local.note_info;
}

/*
 * Update the property manager for a specific object
 */
void
VnsPropObject(obj)
	VnsObject *obj;
{
	VnsNotebook *nl;
	VnsProp prop;
	XmString xm_str;

	if (!created)
	{
		VnsBuildPropertyManager(ObjectToVns(obj));
		created = TRUE;
	}

	if (obj == NULL) return;

	nl = ObjectToNote(obj);

	if (!local.visible) return;

	/* reset the main control panel */
	reset_main_buttons(nl);

	if (local.current == VNS_OBJECT)
	{
		if (local.obj->info.type != obj->info.type)
		{
			ClearViewport();
			XtManageChild(local.object_info);
			local.last_vp = local.object_info;
		}
	}
	else
	{
		ClearViewport();
		XtManageChild(local.object_info);
		local.last_vp = local.object_info;
	}

	/* update local parameters*/
	local.current = VNS_OBJECT;
	local.nl = nl;
	local.pl = ObjectToPage(obj);
	local.obj = obj;

	update_object_info(obj);

	/* update property information */
	prop = local.list;
	while (prop != NULL)
	{
		if (prop->type == VNS_OBJECT)
		{
			if (prop->sub_type == (int)obj->info.type)
			{
				/* update the object if it has an update callback */
				if (prop->update)
				{
					(prop->update)(prop,obj);
				}

				xm_str = XmStringCreateLtoR(prop->name,XmSTRING_DEFAULT_CHARSET);
				XtVaSetValues(local.type,
					XmNlabelString,xm_str,
					NULL);
				XmStringFree(xm_str);

				ClearButtons();
				XtManageChild(prop->buttons);
                local.last_buttons = prop->buttons;
			}
		}
		prop = prop->next;
	}
}

/*
 * Popup the property manager
 */
void
VnsPopupPropertyManager(vns)
	VnsContext *vns;
{
	if (!created)
	{
		VnsBuildPropertyManager(vns);
		created = TRUE;
	}
	XtPopup(vns->prop_mgr,XtGrabNone);
	XtMapWidget(vns->prop_mgr);
	XRaiseWindow(XtDisplay(vns->prop_mgr),XtWindow(vns->prop_mgr));

	/* this could be a problem. we will have to store stuff in VNS */
	local.visible = TRUE;
}

/*
 * Reset the property manager
 */
void
VnsPropReset()
{
	XmString xm_str;

	xm_str = XmStringCreateLtoR(" ",XmSTRING_DEFAULT_CHARSET);
	XtVaSetValues(local.type,
		XmNlabelString,xm_str,
		NULL);
	XmStringFree(xm_str);

	ClearViewport();
	ClearButtons();
	local.current = VNS_NULL;
	local.nl = (VnsNotebook *)NULL;
	local.pl = (VnsPage *)NULL;
	local.obj = (VnsObject *)NULL;
}

/*
 * Public function for creating a property sheet
 */
VnsProp
VnsPropCreate(vns,prop_name,prop_type,sub_type)
	VnsContext *vns;
	char *prop_name;
	int prop_type;
	int sub_type;
{
	Widget info;
	VnsProp prop;

	if (vns->prop_mgr == NULL)
	{
		XtError("VnsPropCreate: VnsBuildPropertyManager has not been previously called");
	}

	prop = (VnsProp)XtMalloc(sizeof(VnsPropRec));

	prop->name = XtNewString(prop_name);
	prop->type = prop_type;
	prop->sub_type = sub_type;
	prop->vp = local.vp;
	prop->update = NULL;
	prop->modify = NULL;
	prop->buttons = XtVaCreateWidget("ObjectButtons",vListWidgetClass,local.buttons,
		XtNborderWidth,0,
		XtNnumRows,1,
		XtNvSpacing,2,
		XtNhSpacing,2,
		XtNheight,25,
		XtNstretchHoriz,True,
		NULL);
	info = XtVaCreateManagedWidget("Info",xmPushButtonWidgetClass,prop->buttons,
		NULL);
	XtAddCallback(info,XmNactivateCallback,sel_object_info,(XtPointer)NULL);

	/* add the new property sheet to the list */
	prop->next = local.list;
	local.list = prop;

	return prop;
}

void
VnsPropAddModify(prop,func)
	VnsProp prop;
	void (*func)();
{
	if (prop == NULL) return;

	prop->modify = func;
}

void
VnsPropAddUpdate(prop,func)
	VnsProp prop;
	void (*func)();
{
	if (prop == NULL) return;

	prop->update = func;
}

/*
 * Use Color as a property item
 */
void
VnsPropAddColor(prop)
	VnsProp prop;
{
	Widget color;

	if (prop == NULL)
	{
		XtWarning("VnsPropAddColor: Null property pointer passed");
		return;
	}

	/* add button for color */
	color = XtVaCreateManagedWidget("Color",xmPushButtonWidgetClass,prop->buttons,
		NULL);
	XtAddCallback(color,XmNactivateCallback,sel_color,(XtPointer)NULL);
}

/*
 * Use Font as a property item
 */
void
VnsPropAddFonts(prop)
	VnsProp prop;
{
	Widget font;

	if (prop == NULL)
	{
		XtWarning("VnsPropAddFonts: Null property pointer passed");
		return;
	}

	/* add button for fonts */
	font = XtVaCreateManagedWidget("Font",xmPushButtonWidgetClass,prop->buttons,
		NULL);
	XtAddCallback(font,XmNactivateCallback,sel_font,(XtPointer)NULL);
}

char *
VnsPropGetColor()
{
	char *color = strdup(local.color_name);
	return color;
}

void
VnsPropSetColor(color_name)
	char *color_name;
{
	Widget w_col,w_old;
	char buf[250];

	/* get the pointer to the old color widget */
	sprintf(buf,"*%s",local.color_name);
	w_old = XtNameToWidget(local.color,buf);

	/* set the new color */
	if (color_name == NULL)
	{
		strcpy(local.color_name,"white");
	}
	else
	{
		strcpy(local.color_name,color_name);
	}

	/* get the pointer to the new color widget */
	sprintf(buf,"*%s",local.color_name);
	w_col = XtNameToWidget(local.color,buf);

	/* deselect the old color */
	if (w_old != NULL)
	{
		XtVaSetValues(w_old,
			XtNcolorSet,False,
			NULL);
	}

	/* activate the selection of the new color */
	if (w_col != NULL)
	{
		XtVaSetValues(w_col,
			XtNcolorSet,True,
			NULL);
	}
}

char *
VnsPropGetFont()
{
	char *font_name = strdup(local.font_name);
	return font_name;
}

VnsPropSetFont(font_name)
	char *font_name;
{
	VtSetFont(&local.font_chooser,font_name);
	strcpy(local.font_name,font_name);
}

VnsPropResetNotebook(note)
	VnsNotebook *note;
{
	if (local.current == VNS_NOTEBOOK)
	{
		if (local.nl == note)
		{
			VnsPropReset();
		}
	}
}

VnsPropResetPage(page)
	VnsPage *page;
{
	if (local.current == VNS_PAGE)
	{
		if (local.pl == page)
		{
			VnsPropReset();
		}
	}
}

VnsPropResetObject(obj)
	VnsObject *obj;
{
	if (local.current == VNS_OBJECT)
	{
		if (local.obj == obj)
		{
			VnsPropReset();
		}
	}
}
