#include <X11/Xatom.h>
#include <X11/Intrinsic.h>
#include <Xm/Xm.h>
#include <stdio.h>
#ifndef __hpux
#include <rpc/rpc.h>
#endif
static Display *d;       /*  Display             */
static char *propName = "_Frame_RPC";
#include "client.c"

typedef struct _XDHelpDoc_s {
	char *doc;
	char **path;
	int handle;
	Bool new_window;
} _XDHelpDoc_t, *_XDHelpDoc_p;

typedef struct _XDHelpPair_s {
	_XDHelpDoc_p doc;
	char **tag;
	Bool open_doc;
} _XDHelpPair_t, *_XDHelpPair_p;


static int last_doc = 0;

static Bool
open_doc ( doc )
    _XDHelpDoc_p doc;
{
    if ( ! doc->doc )
	return False;
    if ( doc->doc[0] == '/' || ! *(doc->path) )
	doc->handle = OpenDoc ( doc->doc );
    else
    {
	char *doc_name = NULL;
	doc_name = (char *) XtMalloc ( strlen ( doc->doc ) + strlen ( *(doc->path) ) + 2 );
	strcpy ( doc_name, *(doc->path) );
	strcat ( doc_name, "/" );
	strcat ( doc_name, doc->doc );
	printf ( "%s\n", doc_name );
	doc->handle = OpenDoc ( doc_name );
	XtFree ( doc_name );
    }
    if ( doc->handle < 0 )
	return False;
/*
    if ( ! doc->new_window )
	last_doc = doc->handle;
    else
	if ( last_doc == doc->handle )
	    last_doc = 0;
*/
    return True;
}

static int
go_to_link ( doc, tag )
    _XDHelpDoc_p doc;
    char *tag;
{
    if ( ! doc->doc )
	return False;
    if ( doc->doc[0] == '/' || ! *(doc->path) )
	return GoToLink ( doc->handle, doc->doc, tag, FALSE );
    else
    {
	char *doc_name = NULL;
	int return_value;
	doc_name = (char *) XtMalloc ( strlen ( doc->doc ) + strlen ( *(doc->path) ) + 2 );
	strcpy ( doc_name, *(doc->path) );
	strcat ( doc_name, "/" );
	strcat ( doc_name, doc->doc );
	return_value = GoToLink ( doc->handle, doc_name, tag, FALSE );
	XtFree ( doc_name );
	return return_value;
    }
}

void XDhelp_link (w, client_data, call_data)
Widget w;		/*  widget id           */
caddr_t client_data;	/*  data from application   */
caddr_t call_data;      /*  data from widget class  */
{
    _XDHelpPair_p help_pair = (_XDHelpPair_p) client_data;
    _XDHelpDoc_p doc = help_pair->doc;
    char *tag;
    /*
    ** d is required by the client module provided by Frame
    */
    if ( XmIsGadget ( w ) ) {
	d = XtDisplay ( XtParent ( w ) );
    }
    else {
	d = XtDisplay ( w );
    }

    if ( ! localCall ( NULLPROC, xdr_void, NULL, xdr_void, NULL, fiveSeconds ) )
    {
	int pid = fork ();
	int retval;
	switch (pid) {
	    case 0:
		retval = execlp ( "viewer", "viewer", "+viewerIsServer", (char *)0 );
		fprintf ( stderr, "Failed to start viewer, errno = %d\n", retval );
		exit ( -1 );
	    case -1:
		fprintf ( stderr, "Failed to fork to start viewer\n" );
		return;
	    default:
		sleep (10);
	}
    }
    if ( help_pair->open_doc )
    {
	if ( ! open_doc ( doc ) )
	    return;
	if ( !doc->new_window )
	{
	    if ( last_doc != 0 && last_doc != doc->handle )
		CloseDoc ( last_doc );
	    last_doc = doc->handle;
	}
	return;
    }
    if ( help_pair->tag )
	tag = *(help_pair->tag);
    else
	tag = XtName ( w );
    if ( ! doc->new_window )
	doc->handle = last_doc;
    if ( doc->handle )
	if ( go_to_link ( doc, tag ) == 0 )
	    return;
    if ( ! open_doc ( doc ) )
	return;
    if ( !doc->new_window )
	last_doc = doc->handle;
    else
	if ( last_doc == doc->handle )
	    last_doc = 0;
    (void) go_to_link ( doc, tag );
}
