/*
 * 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: command_panel.c
 * Date: 05/08/91
 *
 * Description:
 *   This file contains a new version of the command panel.
 *
 * Revisions:
 ****************************************************************/
#include <stdio.h>
#include <malloc.h>
#include <Xm/Xm.h>
#include <X11/StringDefs.h>
#include <Xm/Label.h>
#include <Xm/PushBG.h>
#include <Xm/MessageB.h>
#include <Xm/RowColumn.h>
#include <Xm/CascadeB.h>
#include <Xm/ScrolledW.h>
#include <Xm/ToggleBG.h>
#include <Xm/ToggleB.h>
#include <Xm/SeparatoG.h>
#include <VList.h>

#include "VnsP.h"

typedef struct _Chooser
{
	VnsContext *vns;    /* vns context */
	Widget browser;     /* browser */
	Widget new;         /* new button */
	Widget open;        /* open button */
	Widget go_to;       /* goto button */
	Widget delete;      /* delete button */
	Widget props;       /* properties button */
	VnsNotebook *nl;    /* pointer to current notebook */
	int pid;            /* current page id */
} Chooser;

/****************************************************************
 *                  Private Functions
 ****************************************************************/

static
void
set_buttons(ch)
	Chooser *ch;
{
	if (ch != NULL)
	{
		if (ch->nl == NULL)
		{
			XtSetSensitive(ch->open,False);
			XtSetSensitive(ch->go_to,False);
			XtSetSensitive(ch->delete,False);
			XtSetSensitive(ch->props,False);
		}
		else
		{
			int me = srv_uid(NoteToSrv(ch->nl));
	
			XtSetSensitive(ch->open,True);
			XtSetSensitive(ch->go_to,True);

			/* only authors are allowed to delete notebooks */
			if (ch->nl->info.aid == me)
			{
				XtSetSensitive(ch->delete,True);
			}
			else
			{
				XtSetSensitive(ch->delete,False);
			}

			XtSetSensitive(ch->props,True);
		}
	}
}

/****************************************************************
 *              Button Callback Functions
 ****************************************************************/

static
void
sel_new(w,ch)
	Widget w;
	Chooser *ch;
{
	VnsNotebook *nl;
	VnsDatabase *db;
	Notebook_Info ninfo;
	Page_Info pinfo;
	int nid, pid;
	int uid;
	char buf[50];

	if (ch->vns->first_db == NULL) return;

	db = ch->vns->first_db;

	uid = srv_uid(db->srv);

	vns_watch_on(ch->vns);

	ninfo.home_page = 1;
	strcpy(ninfo.title,"Untitled");

	/* create the notebook in the database */
	nid = srv_create_notebook(db->srv,&ninfo);

	/* give the author read/write access to the new notebook */
	srv_allow_author(db->srv,uid,nid,1);

	/* now retrieve the notebook info */
	srv_inq_notebook(db->srv,nid,&ninfo);

	/* now rename the notebook */
	sprintf(buf,"Notebook %d",nid);
	strcpy(ninfo.title,buf);
	srv_modify_notebook(db->srv,nid,&ninfo);

	/* create the home page */
	strcpy(pinfo.title,"Home Page");
	strcpy(pinfo.color,"white");
	pinfo.width = 500;
	pinfo.height = 700;
	pid = srv_create_page(db->srv,nid,&pinfo);

	/* add the notebook to the linked list and the visual display */
	add_notebook(db,nid);

	vns_watch_off(ch->vns);
}

static
void
sel_open(w,ch)
	Widget w;
	Chooser *ch;
{
	if (ch->nl != NULL)
	{
		if (ch->pid > 0)
		{
			if (srv_validate_page(NoteToSrv(ch->nl),ch->nl->nid,ch->pid) == 1)
			{
				VnsAddPage(ch->nl,ch->pid,(struct return_page *)NULL,
					(char *)NULL,(VnsPage *)NULL);
			}
			else
			{
				VtError(ch->vns->toplevel,"Selected page is not valid for selected notebook");
			}
		}
		else
		{
			if (srv_validate_page(NoteToSrv(ch->nl),ch->nl->nid,ch->nl->info.home_page) == 1)
			{
				VnsAddPage(ch->nl,ch->nl->info.home_page,
					(struct return_page *)NULL,(char *)NULL,(VnsPage *)NULL);
			}
			else
			{
				VtError(ch->vns->toplevel,"Home page is not valid for selected notebook");
			}
		}
	}
	else
	{
		VtError(ch->vns->toplevel,"Notebook must be selected before opening");
	}
}

static
void
goto_callback(nid,pid,ch)
	int nid;
	int pid;
	Chooser *ch;
{
	VnsAddPage(ch->nl,pid,(struct return_page *)NULL,(char *)NULL,
		(VnsPage *)NULL);
}

static
void
sel_goto(w,ch)
	Widget w;
	Chooser *ch;
{
	if (ch->nl != NULL)
	{
		VtGotoPage(ch->vns->toplevel,NoteToSrv(ch->nl),ch->nl->nid,
			goto_callback,(XtPointer)ch);
	}
}

/* callback to confirm deletion of the notebook */
/*ARGSUSED*/
static
void
yes_delete_notebook(w,ch)
	Widget w;
	Chooser *ch;
{
	SrvContext *srv = NoteToSrv(ch->nl);
	int nid = ch->nl->nid;

	/* delete the notebook in the link list and call registered callbacks */
	del_notebook(ch->nl);

	/* delete the notebook in the database */
	srv_delete_notebook(srv,nid);

	ch->nl = NULL;

	set_buttons(ch);
}

static
void
sel_cancel(w,pop)
	Widget w;
	Widget pop;
{
	XtDestroyWidget(pop);
}

static
void
sel_delete(w,ch)
	Widget w;
	Chooser *ch;
{
	if (ch->nl != NULL)
	{
		Widget message_box;
		Widget yes,no,cancel;
		XmString xm_yes,xm_cancel,xm_msg;
		char msg[512];
		Arg args[10];
		int n = 0;

		sprintf(msg,"Delete '%s' and all of its pages?",ch->nl->info.title);
		xm_yes = XmStringCreateLtoR("Yes",XmSTRING_DEFAULT_CHARSET);
		xm_cancel = XmStringCreateLtoR("Cancel",XmSTRING_DEFAULT_CHARSET);
		xm_msg = XmStringCreateLtoR(msg,XmSTRING_DEFAULT_CHARSET);

		XtSetArg(args[n],XmNokLabelString,xm_yes); n++;
		XtSetArg(args[n],XmNhelpLabelString,xm_cancel); n++;
		XtSetArg(args[n],XmNmessageString,xm_msg); n++;
		XtSetArg(args[n],XmNdialogStyle,XmDIALOG_APPLICATION_MODAL); n++;
		XtSetArg(args[n],XmNdefaultButtonType,XmDIALOG_HELP_BUTTON); n++;
		message_box = XmCreateQuestionDialog(ch->vns->toplevel,"Delete Notebook",args,n);

		XmStringFree(xm_yes);
		XmStringFree(xm_cancel);
		XmStringFree(xm_msg);

		yes = XmMessageBoxGetChild(message_box,XmDIALOG_OK_BUTTON);
		no = XmMessageBoxGetChild(message_box,XmDIALOG_CANCEL_BUTTON);
		cancel = XmMessageBoxGetChild(message_box,XmDIALOG_HELP_BUTTON);

		XtAddCallback(yes,XmNactivateCallback,yes_delete_notebook,(XtPointer)ch);
		XtUnmanageChild(no);
		XtAddCallback(cancel,XmNactivateCallback,sel_cancel,(XtPointer)message_box);

		XtManageChild(message_box);
	}
}

static
void
sel_props(w,ch)
	Widget w;
	Chooser *ch;
{
	if (ch->nl != NULL)
	{
		if (ch->pid > 0)
		{
			VtMessage(ch->vns->toplevel,"Page properties must be accessed via the page");
		}
		else
		{
			VnsPopupPropertyManager(NoteToVns(ch->nl));
			VnsPropNotebook(ch->nl);
		}
	}
}

static
void
sel_yes(w,vns)
	Widget w;
	VnsContext *vns;
{
	VnsExit(vns);
	exit(0);
}

static
void
sel_quit(w,vns)
	Widget w;
	VnsContext *vns;
{
	Widget message_box;
	Widget yes,no,cancel;
	XmString xm_yes,xm_cancel,xm_msg;
	Arg args[10];
	int n = 0;

	xm_yes = XmStringCreateLtoR("Yes",XmSTRING_DEFAULT_CHARSET);
	xm_cancel = XmStringCreateLtoR("Cancel",XmSTRING_DEFAULT_CHARSET);
	xm_msg = XmStringCreateLtoR("Are you ready to Quit?",XmSTRING_DEFAULT_CHARSET);

	XtSetArg(args[n],XmNokLabelString,xm_yes); n++;
	XtSetArg(args[n],XmNhelpLabelString,xm_cancel); n++;
	XtSetArg(args[n],XmNmessageString,xm_msg); n++;
	XtSetArg(args[n],XmNdefaultButtonType,XmDIALOG_HELP_BUTTON); n++;
	XtSetArg(args[n],XmNdialogStyle,XmDIALOG_APPLICATION_MODAL); n++;
	message_box = XmCreateQuestionDialog(vns->toplevel,"Quit",args,n);

	XmStringFree(xm_yes);
	XmStringFree(xm_cancel);
	XmStringFree(xm_msg);

	yes = XmMessageBoxGetChild(message_box,XmDIALOG_OK_BUTTON);
	no = XmMessageBoxGetChild(message_box,XmDIALOG_CANCEL_BUTTON);
	cancel = XmMessageBoxGetChild(message_box,XmDIALOG_HELP_BUTTON);

	XtUnmanageChild(no);

	XtAddCallback(yes,XmNactivateCallback,sel_yes,(XtPointer)vns);
	XtAddCallback(cancel,XmNactivateCallback,sel_cancel,(XtPointer)message_box);

	XtManageChild(message_box);
}

/* Callback to set the outlines of all of the objects */
static
void
sel_outlines(wd,vns)
	Widget wd;
	VnsContext *vns;
{
	Boolean state;

	XtVaGetValues(wd,
		XmNset,&state,
		NULL);

	VnsSetOutlines(vns,state);
}

/* Callback to set snap to grid mode */
static
void
sel_snap(wd,vns)
	Widget wd;
	VnsContext *vns;
{
	Boolean state;

	XtVaGetValues(wd,
		XmNset,&state,
		NULL);

	VnsSetSnapToGrid(vns,state);
}

/* Callback to set show_grid mode */
static
void
sel_grid(wd,vns)
	Widget wd;
	VnsContext *vns;
{
	Boolean state;

	XtVaGetValues(wd,
		XmNset,&state,
		NULL);

	VnsSetGrid(vns,state);
}

/* Callback to set open page upon creation mode */
static
void
sel_open_page(wd,vns)
	Widget wd;
	VnsContext *vns;
{
	Boolean state;

	XtVaGetValues(wd,
		XmNset,&state,
		NULL);

	VnsSetAutoPageOpen(vns,state);
}

/* Callback to save session */
static
void
sel_save(w,vns)
	Widget w;
	VnsContext *vns;
{
	VnsSaveSession(vns);
}

/* Callback for browser when a notebook or page is selected */
static
void
sel_browser(ch,nid,pid)
	Chooser *ch;
	int nid;
	int pid;
{
	VnsDatabase *db = ch->vns->current_db;
	VnsNotebook *nl = *(VnsFindNotebook(db,nid));

	ch->nl = nl;
	set_buttons(ch);

	/* we only save the page id since the page may or
	 * may not be displayed.
	 */
	ch->pid = pid;

	if (pid > 0)
	{
		VnsPage *pl = *(VnsFindPage(nl,pid));
		if (pl == NULL)
		{
			VnsPropReset();
		}
		else
		{
			VnsPropPage(pl);
		}
	}
	else
	{
		VnsPropNotebook(ch->nl);
	}
}

PUBLIC
void
VnsBuildCommandPanel(vns,parent)
	VnsContext *vns;
	Widget parent;
{
	Widget com, menu_bar;
	XmString xm_str;
	Chooser *ch;
	Arg args[5];
	int n;

	/* allocate space for notebook chooser information */
	ch = (Chooser *)malloc(sizeof(Chooser));

	ch->nl = NULL;
	ch->pid = -1;
	ch->vns = vns;

	com = XtVaCreateManagedWidget("CommandPanel",vListWidgetClass,parent,
		XtNvSpacing,2,
		XtNhSpacing,2,
		XtNnumRows,2,
		XtNnumColumns,1,
		XtNrowPivot,2,
		XtNborderWidth,0,
		NULL);

	menu_bar = XtVaCreateManagedWidget("MenuBar",xmRowColumnWidgetClass,com,
		XmNrowColumnType,XmMENU_BAR,
		XmNorientation,XmHORIZONTAL,
		XtNstretchHoriz,True,
		NULL);

	{
		Widget menu,button,quit;

		n = 0;
		XtSetArg(args[n],XmNmarginWidth,2); n++;
		XtSetArg(args[n],XmNmarginHeight,2); n++;
		menu = XmCreatePulldownMenu(menu_bar,"Menu",args,n);

		n = 0;
		XtSetArg(args[n],XmNsubMenuId,menu); n++;
		XtSetArg(args[n],XmNmnemonic,'N'); n++;
		button = XmCreateCascadeButton(menu_bar,"Notebooks",args,n);
		XtManageChild(button);

		ch->new = XtVaCreateManagedWidget("New",xmPushButtonGadgetClass,menu,
			NULL);
		ch->open = XtVaCreateManagedWidget("Open",xmPushButtonGadgetClass,menu,
			NULL);
		xm_str = XmStringCreateLtoR("Goto ...",XmSTRING_DEFAULT_CHARSET);
		ch->go_to = XtVaCreateManagedWidget("Goto",xmPushButtonGadgetClass,menu,
			XmNlabelString,xm_str,
			NULL);
		XmStringFree(xm_str);
		xm_str = XmStringCreateLtoR("Delete ...",XmSTRING_DEFAULT_CHARSET);
		ch->delete = XtVaCreateManagedWidget("Delete",xmPushButtonGadgetClass,menu,
			XmNlabelString,xm_str,
			NULL);
		XmStringFree(xm_str);
		xm_str = XmStringCreateLtoR("Properties ...",XmSTRING_DEFAULT_CHARSET);
		ch->props = XtVaCreateManagedWidget("Properties",xmPushButtonGadgetClass,menu,
			XmNlabelString,xm_str,
			NULL);
		XmStringFree(xm_str);
		XtVaCreateManagedWidget("line",xmSeparatorGadgetClass,menu,
			NULL);
		xm_str = XmStringCreateLtoR("Quit ...",XmSTRING_DEFAULT_CHARSET);
		quit = XtVaCreateManagedWidget("Quit",xmPushButtonGadgetClass,menu,
			XmNlabelString,xm_str,
			NULL);
		XmStringFree(xm_str);

		XtAddCallback(ch->new,XmNactivateCallback,sel_new,(XtPointer)ch);
		XtAddCallback(ch->open,XmNactivateCallback,sel_open,(XtPointer)ch);
		XtAddCallback(ch->go_to,XmNactivateCallback,sel_goto,(XtPointer)ch);
		XtAddCallback(ch->delete,XmNactivateCallback,sel_delete,(XtPointer)ch);
		XtAddCallback(ch->props,XmNactivateCallback,sel_props,(XtPointer)ch);
		XtAddCallback(quit,XmNactivateCallback,sel_quit,(XtPointer)vns);
	}
	{
		Widget menu,button,grid,snap,outline,save,open_page;

		n = 0;
		XtSetArg(args[n],XmNmarginWidth,2); n++;
		XtSetArg(args[n],XmNmarginHeight,2); n++;
		menu = XmCreatePulldownMenu(menu_bar,"Menu",args,n);

		n = 0;
		XtSetArg(args[n],XmNsubMenuId,menu); n++;
		XtSetArg(args[n],XmNmnemonic,'S'); n++;
		button = XmCreateCascadeButton(menu_bar,"Session",args,n);
		XtManageChild(button);

		grid = XtVaCreateManagedWidget("Show Grid",xmToggleButtonGadgetClass,menu,
			XmNset,vns->session->show_grid,
			XmNvisibleWhenOff,True,
			NULL);
		snap = XtVaCreateManagedWidget("Snap To Grid",xmToggleButtonGadgetClass,menu,
			XmNset,vns->session->snap_to_grid,
			XmNvisibleWhenOff,True,
			NULL);
		outline = XtVaCreateManagedWidget("Show Outlines",xmToggleButtonGadgetClass,menu,
			XmNset,vns->session->show_outlines,
			XmNvisibleWhenOff,True,
			NULL);
		open_page = XtVaCreateManagedWidget("Open Pages",xmToggleButtonGadgetClass,menu,
			XmNset,vns->session->auto_page_open,
			XmNvisibleWhenOff,True,
			NULL);
		XtVaCreateManagedWidget("line",xmSeparatorGadgetClass,menu,
			NULL);
		save = XtVaCreateManagedWidget("Save",xmPushButtonGadgetClass,menu,
			NULL);
		XtAddCallback(outline,XmNvalueChangedCallback,sel_outlines,(XtPointer)vns);
		XtAddCallback(grid,XmNvalueChangedCallback,sel_grid,(XtPointer)vns);
		XtAddCallback(snap,XmNvalueChangedCallback,sel_snap,(XtPointer)vns);
		XtAddCallback(open_page,XmNvalueChangedCallback,sel_open_page,(XtPointer)vns);
		XtAddCallback(save,XmNactivateCallback,sel_save,(XtPointer)vns);
	}

	ch->browser = VnsBuildBrowser(vns,com,400,300,sel_browser,(XtPointer)ch);
	vns->browser = ch->browser;

	VtManageChildren(com);

	set_buttons(ch);
}
