/*
 * 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: events.c
 * Date: 03/14/91
 *
 * Description:
 *   This file contains all of the event handlers for processing
 *   dynamic events generated by dbsrv.
 *
 * Revisions:
 ****************************************************************/
#include <stdio.h>
#include <Xm/Xm.h>
#include <Xm/Label.h>
#include <X11/StringDefs.h>
#include <X11/Intrinsic.h>
#include <X11/Shell.h>

#include "VnsP.h"

/****************************************************************
 * Function: ev_create_page 
 * Date: 03/14/91
 *
 * Description:
 *
 *
 * Linkage: void ev_create_page(srv,event,db)
 *   SrvContext *srv - srvlib connection id
 *   SrvEvent *event - pointer to the srvlib event
 *   VnsDatabase *db - pointer to database info
 *
 * Revisions:
 ****************************************************************/
static
void
ev_create_page(srv,event,db)
	SrvContext *srv;
	SrvEvent *event;
	VnsDatabase *db;
{
	VnsNotebook *nl = *(VnsFindNotebook(db,(int)event->create_page.nid));
	if (nl != NULL)
	{
		/* this function increments the total page number counter on page */
		find_last_page_of_note(nl);
	}
}

/****************************************************************
 * Function: ev_create_object 
 * Date: 03/14/91
 *
 * Description:
 *
 *
 * Linkage: void ev_create_object(srv,event,db)
 *   SrvContext *srv - srvlib connection id
 *   SrvEvent *event - pointer to the srvlib event
 *   VnsDatabase *db - pointer to database info
 *
 * Revisions:
 ****************************************************************/
static
void
ev_create_object(srv,event,db)
	SrvContext *srv;
	SrvEvent *event;
	VnsDatabase *db;
{
	VnsNotebook *nl = *(VnsFindNotebook(db,(int)event->create_object.nid));
	if (nl != NULL)
	{
		VnsPage *pl = *(VnsFindPage(nl,(int)event->create_object.pid));
		if (pl != NULL)
		{
			VnsObject *obj = add_object(pl,(int)event->create_object.oid);
			if (obj->info.type == OT_IMAGE)
			{
				set_page_colormaps(pl);
			}
			update_page_scrollbars(pl);
		}
	}
}

/****************************************************************
 * Function: ev_modify_notebook 
 * Date: 03/14/91
 *
 * Description:
 *
 *
 * Linkage: void ev_modify_notebook(srv,event,db)
 *   SrvContext *srv - srvlib connection id
 *   SrvEvent *event - pointer to the srvlib event
 *   VnsDatabase *db - pointer to database info
 *
 * Revisions:
 ****************************************************************/
static
void
ev_modify_notebook(srv,event,db)
	SrvContext *srv;
	SrvEvent *event;
	VnsDatabase *db;
{
	VnsNotebook *nl = *(VnsFindNotebook(db,(int)event->modify_notebook.nid));
	if (nl != NULL)
	{
		VnsPage *pl = nl->first_page;
		XmString xm_str;

		srv_inq_notebook(srv,event->modify_notebook.nid,&nl->info);

		VnsCallCallbacks(db->vns,CB_NOTEBOOK_MODIFY,(VnsPointer)nl);

		/* Note(BDM): this should be a callback function */
		/* modify notebook name on all displayed pages */
		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;
		}
	}
}

/****************************************************************
 * Function: ev_modify_page 
 * Date: 03/14/91
 *
 * Description:
 *
 *
 * Linkage: void ev_modify_page(srv,event,db)
 *   SrvContext *srv - srvlib connection id
 *   SrvEvent *event - pointer to the srvlib event
 *   VnsDatabase *db - pointer to database info
 *
 * Revisions:
 ****************************************************************/
static
void
ev_modify_page(srv,event,db)
	SrvContext *srv;
	SrvEvent *event;
	VnsDatabase *db;
{
	VnsNotebook *nl = *(VnsFindNotebook(db,(int)event->modify_page.nid));
	if (nl != NULL)
	{
		VnsPage *pl = *(VnsFindPage(nl,(int)event->modify_page.pid));
		if (pl != NULL)
		{
			Page_Info info;

			srv_inq_page(srv,nl->nid,pl->pid,&info);
	
			/* set the background color for the page */
			pl->col = VnsAllocNamedColor(PageToVns(pl),info.color); 
			VtSetBackColor(pl->comp,pl->col);

			if (info.width != pl->info.width ||
			    info.height != pl->info.height)
			{
				XtVaSetValues(pl->comp,
					XmNwidth,info.width,
					XmNheight,info.height,
					NULL);
			}
			pl->info = info;

			/* set the page title of the toplevel shell */
			XtVaSetValues(pl->pwd,
				XmNtitle,info.title,
				XmNiconName,info.title,
				NULL);
		}
	}
}

/****************************************************************
 * Function: ev_modify_object 
 * Date: 03/14/91
 *
 * Description:
 *
 *
 * Linkage: void ev_modify_object(srv,event,db)
 *   SrvContext *srv - srvlib connection id
 *   SrvEvent *event - pointer to the srvlib event
 *   VnsDatabase *db - pointer to database info
 *
 * Revisions:
 ****************************************************************/
static
void
ev_modify_object(srv,event,db)
	SrvContext *srv;
	SrvEvent *event;
	VnsDatabase *db;
{
	VnsNotebook *nl = *(VnsFindNotebook(db,(int)event->modify_object.nid));
	if (nl != NULL)
	{
		VnsPage *pl = *(VnsFindPage(nl,(int)event->modify_object.pid));
		if (pl != NULL)
		{
			VnsObject *obj = *(VnsFindObject(pl,(int)event->modify_object.oid));
			if (obj != NULL)
			{
				change_object(obj);
			}
		}
	}
}

/****************************************************************
 * Function: ev_object_changed 
 * Date: 03/14/91
 *
 * Description:
 *
 *
 * Linkage: ev_object_changed(srv,event,db)
 *   SrvContext *srv - srvlib connection id
 *   SrvEvent *event - pointer to the srvlib event
 *   VnsDatabase *db - pointer to database info
 *
 * Revisions:
 ****************************************************************/
static
void
ev_object_changed(srv,event,db)
	SrvContext *srv;
	SrvEvent *event;
	VnsDatabase *db;
{
	VnsNotebook *nl = *(VnsFindNotebook(db,(int)event->modify_object.nid));
	if (nl != NULL)
	{
		VnsPage *pl = *(VnsFindPage(nl,(int)event->modify_object.pid));
		if (pl != NULL)
		{
			VnsObject *obj = *(VnsFindObject(pl,(int)event->modify_object.oid));
			if (obj != NULL && obj->info.type == OT_TXT)
			{
				char *s = srv_get_object_text(srv,nl->nid,pl->pid,obj->oid);
				if (s != NULL)
				{
					XtVaSetValues(obj->auxil.txt.wd,
						XtNstring,s,
						NULL);
					free((char *)s);
				}
			}
		}
	}
}

/****************************************************************
 * Function: ev_delete_notebook 
 * Date: 03/14/91
 *
 * Description:
 *
 *
 * Linkage: void ev_delete_notebook(srv,event,db)
 *   SrvContext *srv - srvlib connection id
 *   SrvEvent *event - pointer to the srvlib event
 *   VnsDatabase *db - pointer to database info
 *
 * Revisions:
 ****************************************************************/
static
void
ev_delete_notebook(srv,event,db)
	SrvContext *srv;
	SrvEvent *event;
	VnsDatabase *db;
{
	VnsNotebook *nl = *(VnsFindNotebook(db,(int)event->delete_notebook.nid));
	if (nl != NULL)
	{
		del_notebook(nl);
	}
}

/****************************************************************
 * Function: ev_delete_page 
 * Date: 03/14/91
 *
 * Description:
 *
 *
 * Linkage: void ev_delete_page(srv,event,db)
 *   SrvContext *srv - srvlib connection id
 *   SrvEvent *event - pointer to the srvlib event
 *   VnsDatabase *db - pointer to database info
 *
 * Revisions:
 ****************************************************************/
static
void
ev_delete_page(srv,event,db)
	SrvContext *srv;
	SrvEvent *event;
	VnsDatabase *db;
{
	VnsNotebook *nl = *(VnsFindNotebook(db,(int)event->delete_page.nid));
	if (nl != NULL)
	{
		VnsPage *pl = *(VnsFindPage(nl,(int)event->delete_page.pid));
		if (event->delete_page.del_links == 1)
		{
			delete_links_to(nl,(int)event->delete_page.pid);
		}
		if (pl != NULL)
		{
			if (event->delete_page.del_links == 1)
			{
				delete_page_refs(pl);
			}
			else
			{
				update_page_refs(pl);
			}
			VnsCallCallbacks(db->vns,CB_PAGE_DELETE,(VnsPointer)pl);
			del_page(pl);
		}
		find_last_page_of_note(nl);
	}
}

/****************************************************************
 * Function: ev_delete_object 
 * Date: 03/14/91
 *
 * Description:
 *
 *
 * Linkage: void ev_delete_object(srv,event,db)
 *   SrvContext *srv - srvlib connection id
 *   SrvEvent *event - pointer to the srvlib event
 *   VnsDatabase *db - pointer to database info
 *
 * Revisions:
 ****************************************************************/
static
void
ev_delete_object(srv,event,db)
	SrvContext *srv;
	SrvEvent *event;
	VnsDatabase *db;
{
	VnsNotebook *nl = *(VnsFindNotebook(db,(int)event->delete_object.nid));
	if (nl != NULL)
	{
		VnsPage *pl = *(VnsFindPage(nl,(int)event->delete_object.pid));
		if (pl != NULL)
		{
			VnsObject *obj = *(VnsFindObject(pl,(int)event->delete_object.oid));
			if (obj != NULL)
			{
				del_object(obj);
			}
		}
	}
}

/****************************************************************
 * Function: ev_access_allowed 
 * Date: 03/14/91
 *
 * Description:
 *   This event handler handles the case where an author has
 *   allowed anothor author(s) access to a notebook. In this case,
 *   we need to add the notebook to the notebook list and add
 *   the notebook to the VNS front-end.
 *
 * Linkage: void ev_access_alllowed(srv,event,db)
 *   SrvContext *srv - srvlib connection id
 *   SrvEvent *event - pointer to the srvlib event
 *   VnsDatabase *db - pointer to database info
 *
 * Revisions:
 ****************************************************************/
static
void
ev_access_allowed(srv,event,db)
	SrvContext *srv;
	SrvEvent *event;
	VnsDatabase *db;
{
	add_notebook(db,(int)event->access_allowed.nid);
}

/****************************************************************
 * Function: ev_access_disallowed 
 * Date: 03/14/91
 *
 * Description:
 *   This event handler handles the event generated when
 *   a author has disallowed access to specific notebook.
 *   In this case, VNS must delete the notebook from the internal
 *   notebook list, remove any open pages in the notebook,
 *   and remove the notebook entry in the front-end.
 *
 * Linkage: void ev_access_disallowed(srv,event,db)
 *   SrvContext *srv - srvlib connection id
 *   SrvEvent *event - pointer to the srvlib event
 *   VnsDatabase *db - pointer to database info
 *
 * Revisions:
 ****************************************************************/
static
void
ev_access_disallowed(srv,event,db)
	SrvContext *srv;
	SrvEvent *event;
	VnsDatabase *db;
{
	VnsNotebook *nl = *(VnsFindNotebook(db,(int)event->access_disallowed.nid));
	if (nl != NULL)
	{
		del_notebook(nl);
	}
}

/****************************************************************
 * Function: ev_shutdown 
 * Date: 03/14/91
 *
 * Description:
 *   This event handler performs a shutdown on VNS by deselected
 *   all selected objects so that they are saved to the database
 *   and exits the program.
 *
 * Linkage: void ev_shutdown(srv,event,db)
 *   SrvContext *srv - srvlib connection id
 *   SrvEvent *event - pointer to the srvlib event
 *   VnsDatabase *db - pointer to database info
 *
 * Revisions:
 ****************************************************************/
static
void
ev_shutdown(srv,event,db)
	SrvContext *srv;
	SrvEvent *event;
	VnsDatabase *db;
{
	VnsContext *vns = DbToVns(db);

	/* deselect all objects thus saving them to the database */
	deselect_all(vns);

	/* display message to the user */
	printf("VNS has been shutdown. Your data has been saved.\n");

	exit(0);
}

/****************************************************************
 *                 Public Functions
 ****************************************************************/

/****************************************************************
 * Function: add_event_handlers 
 * Date: 03/14/91
 *
 * Description:
 *   This function registers all of the event handlers used by
 *   the VNS program.
 *
 * Linkage: void add_event_handlers(srv)
 *   SrvContext *srv - srvlib connection id
 *
 * Revisions:
 ****************************************************************/
void
add_event_handlers(db)
	VnsDatabase *db;
{
	srv_add_event_handler(db->srv,SRV_CREATE_PAGE,ev_create_page,(char *)db);
	srv_add_event_handler(db->srv,SRV_CREATE_OBJECT,ev_create_object,(char *)db);
	srv_add_event_handler(db->srv,SRV_MODIFY_NOTEBOOK,ev_modify_notebook,(char *)db);
	srv_add_event_handler(db->srv,SRV_MODIFY_PAGE,ev_modify_page,(char *)db);
	srv_add_event_handler(db->srv,SRV_MODIFY_OBJECT,ev_modify_object,(char *)db);
	srv_add_event_handler(db->srv,SRV_OBJECT_CONTENTS_CHANGED,ev_object_changed,(char *)db);
	srv_add_event_handler(db->srv,SRV_DELETE_NOTEBOOK,ev_delete_notebook,(char *)db);
	srv_add_event_handler(db->srv,SRV_DELETE_PAGE,ev_delete_page,(char *)db);
	srv_add_event_handler(db->srv,SRV_DELETE_OBJECT,ev_delete_object,(char *)db);
	srv_add_event_handler(db->srv,SRV_ACCESS_ALLOWED,ev_access_allowed,(char *)db);
	srv_add_event_handler(db->srv,SRV_ACCESS_DISALLOWED,ev_access_disallowed,(char *)db);
	srv_add_event_handler(db->srv,SRV_SHUTDOWN,ev_shutdown,(char *)db);
}

/****************************************************************
 * Function: get_events 
 * Date: 03/14/91
 *
 * Description:
 *   This function is provided to allow the X front-end program
 *   to add this function as a callback using XtAppAddInput. This
 *   function will process the dynamic events generated by dbsrv
 *   dispatch them to the necessary callback functions.
 *
 * Linkage: void get_events(srv)
 *   SrvContext *srv - srvlib connection id
 *
 * Revisions:
 ****************************************************************/
void
get_events(srv)
	SrvContext *srv;
{
	SrvEvent event;
	int loop = 1;

	/* process events */
	while (loop == 1)
	{
		/* get the next event */
		if (srv_next_event(srv,&event) < 0)
		{
			return;
		}

		/* dispatch event to registered event handlers */
		srv_dispatch_event(srv,event);

		/* check for any pending events AFTER processing event */
		loop = srv_pending(srv);
	}
}
