/*
 * 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: link_props.c
 * Date: 05/06/91
 *
 * Description:
 *   This file contains the functions for managing link properties
 *   in the property manager.
 *
 * Revisions:
 ****************************************************************/
#include <Xm/Xm.h>
#include <Xm/PushB.h>
#include <Xm/ScrolledW.h>
#include <Xm/Label.h>
#include <Xm/TextF.h>
#include <X11/IntrinsicP.h>
#include <X11/StringDefs.h>
#include <X11/CoreP.h>

#include <VList.h>

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

static Widget dest_note;
static Widget dest_page;

/* external pixmaps */
extern Pixmap link_bitmap;
extern Pixmap dlink_bitmap;
extern Pixmap badlink_bitmap;

/*
 * Callback when the "link here" button is selected on a destination page
 */
static
linkit_callback(obj,nid,pid)
	VnsObject *obj;
	int nid;
	int pid;
{
	Notebook_Info ninfo;
	Page_Info pinfo;
	char buf[256];
	int valid;

	srv_inq_notebook(ObjectToSrv(obj),nid,&ninfo);
	srv_inq_page(ObjectToSrv(obj),nid,pid,&pinfo);

	XtVaSetValues(dest_note,
		XmNvalue,ninfo.title,
		NULL);
	sprintf(buf,"%d",pid);
	XtVaSetValues(dest_page,
		XmNvalue,buf,
		NULL);

	/* modify the displayed link icon */
	valid = srv_validate_page(ObjectToSrv(obj),nid,pid);

	if (valid == 1)
	{
		XtVaSetValues(obj->auxil.link.button,
			XmNlabelPixmap,link_bitmap,
			NULL);
	}
	else if (valid == 2)
	{
		XtVaSetValues(obj->auxil.link.button,
			XmNlabelPixmap,dlink_bitmap,
			NULL);
	}
	else if (valid == 3)
	{
		XtVaSetValues(obj->auxil.link.button,
			XmNlabelPixmap,badlink_bitmap,
			NULL);
	}

	/* update the notebook and page ids */
	obj->info.data.l_info.dest_note = nid;
	obj->info.data.l_info.dest_page = pid;

	/* modify the database */
	srv_modify_object(ObjectToSrv(obj),obj->parent->parent->nid,obj->parent->pid,obj->oid,&obj->info);
}

static
void
sel_specific(w,prop)
	Widget w;
	VnsProp prop;
{
	Widget vp = XtNameToWidget(prop->vp,"*LinkViewport");

	VnsPropDisplay(vp);
}

static 
void
add_link_button(prop)
	VnsProp prop;
{
	Widget buttons = prop->buttons;

	Widget link = XtVaCreateManagedWidget("Specific",xmPushButtonWidgetClass,buttons,
		NULL);
	XtAddCallback(link,XmNactivateCallback,sel_specific,(XtPointer)prop);
}

static
void
add_link_vp(prop)
	VnsProp prop;
{
	Pixmap link_here_pixmap;
	XmString xm_str;
	Widget vp = prop->vp;
	Widget sw = XtVaCreateWidget("LinkViewport",xmScrolledWindowWidgetClass,vp,
		XmNscrollingPolicy,XmAUTOMATIC,
		XmNvisualPolicy,XmVARIABLE,
		XtNstretchVert,True,
		XtNstretchHoriz,True,
		NULL);
	Widget lp = XtVaCreateManagedWidget("LinkProps",vListWidgetClass,sw,
		XtNnumColumns,1,
		XtNvSpacing,2,
		XtNhSpacing,2,
		XtNborderWidth,0,
		XtNrowPivot,2,
		XtNstretchVert,True,
		XtNstretchHoriz,True,
		NULL);
	{
		Widget label;
		Widget info = XtVaCreateManagedWidget("HelpInfo",vListWidgetClass,lp,
			XtNnumColumns,3,
			XtNstretchHoriz,True,
			NULL);

		xm_str = XmStringCreateLtoR("To set destination, select ",
			XmSTRING_DEFAULT_CHARSET);
		label = XtVaCreateManagedWidget("HelpInfoLabel",xmLabelWidgetClass,info,
			XmNlabelString,xm_str,
			NULL);
		XmStringFree(xm_str);

		link_here_pixmap = XmGetPixmap(XtScreen(label),"link_here",
			label->core.border_pixel,label->core.background_pixel);
		XtVaCreateManagedWidget("LinkHereLabel",xmLabelWidgetClass,info,
			XmNlabelPixmap,link_here_pixmap,
			NULL);

		xm_str = XmStringCreateLtoR("on desired page.",
			XmSTRING_DEFAULT_CHARSET);
		XtVaCreateManagedWidget("HelpInfoLabel",xmLabelWidgetClass,info,
			XmNlabelString,xm_str,
			XtNstretchHoriz,True,
			NULL);
		XmStringFree(xm_str);
	}
	{
		Widget table = XtVaCreateManagedWidget("LinkData",vListWidgetClass,lp,
			XtNnumColumns,2,
			XtNstretchHoriz,True,
			NULL);

		xm_str = XmStringCreateLtoR("Destination Notebook Name:",
			XmSTRING_DEFAULT_CHARSET);
		XtVaCreateManagedWidget("DestNoteNameLabel",xmLabelWidgetClass,table,
			XmNlabelString,xm_str,
			NULL);
		XmStringFree(xm_str);

		dest_note = XtVaCreateManagedWidget("DestNoteName",xmTextFieldWidgetClass,table,
			XtNstretchHoriz,True,
			NULL);

		xm_str = XmStringCreateLtoR("Destination Page Name:",
			XmSTRING_DEFAULT_CHARSET);
		XtVaCreateManagedWidget("DestPageNumberLabel",xmLabelWidgetClass,table,
			XmNlabelString,xm_str,
			NULL);
		XmStringFree(xm_str);

		dest_page = XtVaCreateManagedWidget("DestPageNumber",xmTextFieldWidgetClass,table,
			XtNstretchHoriz,True,
			NULL);
	}
}

vns_link_here_on(vns)
	VnsContext *vns;
{
	VnsPage *pl = vns->first_page;

	while(pl != NULL)
	{
		XtVaSetValues(pl->link_here,
			XmNsensitive,True,
			NULL);
		pl = pl->npage;
	}
}

vns_link_here_off(vns)
	VnsContext *vns;
{
	VnsPage *pl = vns->first_page;

	while(pl != NULL)
	{
		XtVaSetValues(pl->link_here,
			XmNsensitive,False,
			NULL);
		pl = pl->npage;
	}
}

vns_activate_link(obj)
	VnsObject *obj;
{
	VnsContext *vns = ObjectToVns(obj);

	vns->link_callback = linkit_callback;
	vns->link_data = (XtPointer)obj;

	vns_link_here_on(vns);
}

vns_deactivate_link(obj)
	VnsObject *obj;
{
	VnsContext *vns = ObjectToVns(obj);

	vns->link_callback = NULL;
	vns->link_data = (XtPointer)NULL;

	vns_link_here_off(vns);
}

static
void
update_link(prop,obj)
	VnsProp prop;
	VnsObject *obj;
{
	char buf[256];
	int valid;

	if (obj == NULL) return;

	/* get the information about the destination notebook */
	valid = srv_validate_page(ObjectToSrv(obj),(int)obj->info.data.l_info.dest_note,
			(int)obj->info.data.l_info.dest_page);

	if (valid == 1)
	{
		Notebook_Info info;
		srv_inq_notebook(ObjectToSrv(obj),(int)obj->info.data.l_info.dest_note,&info);
		XtVaSetValues(dest_note,
			XmNvalue,info.title,
			NULL);
	}
	else
	{
		XtVaSetValues(dest_note,
			XmNvalue,"NULL Destination",
			NULL);
	}
	sprintf(buf,"%d",obj->info.data.l_info.dest_page);
	XtVaSetValues(dest_page,
		XmNvalue,buf,
		NULL);

	/* reset the text field to the first position */
	XmTextFieldShowPosition(dest_note,0);
	XmTextFieldShowPosition(dest_page,0);

	/* set the current color for the link */
	VnsPropSetColor(obj->info.data.l_info.color);
	VnsPropSetFont(obj->info.data.l_info.font);
}

static
void
modify_link(prop,obj)
	VnsProp prop;
	VnsObject *obj;
{
	XFontStruct *font;
	char *dnote;
	char *dpage;
	char *color_name;
	char *font_name;
	int valid;
	long col;
	int nid;
	int pid;

	/* obtain information to be updated */
	color_name = VnsPropGetColor();
	font_name = VnsPropGetFont();
	XtVaGetValues(dest_note,
		XmNvalue,&dnote,
		NULL);
	XtVaGetValues(dest_page,
		XmNvalue,&dpage,
		NULL);

	/* find the page id using the notebook name specified */
	/* WARNING: This function is currently ambiguous in the current
	 * srvlib implementation since notebooks can have the same name
	 */
	nid = srv_find_note_by_name(ObjectToSrv(obj),dnote);
	pid = atoi(dpage);
	valid = srv_validate_page(ObjectToSrv(obj),nid,pid);

	if (valid == 1)
	{
		XtVaSetValues(obj->auxil.link.button,
			XmNlabelPixmap,link_bitmap,
			NULL);
	}
	else if(valid == 2)
	{
		XtVaSetValues(obj->auxil.link.button,
			XmNlabelPixmap,dlink_bitmap,
			NULL);
	}
	else if(valid == 3)
	{
		XtVaSetValues(obj->auxil.link.button,
			XmNlabelPixmap,badlink_bitmap,
			NULL);
	}

	/* update specific object info */
	strcpy(obj->info.data.l_info.color,color_name);
	strcpy(obj->info.data.l_info.font,font_name);
	obj->info.data.l_info.dest_note = nid;
	obj->info.data.l_info.dest_page = pid;

	/* modify the database */
	srv_modify_object(ObjectToSrv(obj),obj->parent->parent->nid,obj->parent->pid,obj->oid,&obj->info);

	/* modifiy the foreground color for the displayed object */
	col = VnsAllocNamedColor(ObjectToVns(obj),color_name);
	VtSetForeColor(obj->owd,col);
	font = alloc_named_font(ObjectToVns(obj),font_name);
	XtVaSetValues(obj->auxil.link.wd,
		XtNfont,font,
		NULL);
}

init_link_props(vns)
	VnsContext *vns;
{
	VnsProp prop;
	Widget vp;

	prop = VnsPropCreate(vns,"Link Object",VNS_OBJECT,OT_LINK);
	add_link_button(prop);
	add_link_vp(prop);
	VnsPropAddColor(prop);
	VnsPropAddFonts(prop);
	VnsPropAddModify(prop,modify_link);
	VnsPropAddUpdate(prop,update_link);
}
