	Manage the tabs along the top of the view window and the title

<<*>>=
#include "config.h"
#include <Xm/Xm.h>
#include <Xfwf/XmTabs.h>
#include "w3a.h"
#include "str.h"
#include "requests.e"
#include "globals.e"

#define INSERT_AT_RIGHT 1			/* Shift tabs to the left */

#define MAXOPENDOCS 6				/* Size of tabs widget */

EXPORT int curopendoc = 0;
static int curclick = MAXOPENDOCS;
static ViewerInfo *opendocs[MAXOPENDOCS] = {
    NULL, NULL, NULL, NULL, NULL, NULL};
#if ! INSERT_AT_RIGHT
static int click[MAXOPENDOCS] = {
    0, 1, 2, 3, 4, 5};
#endif


/* set_tab_titles -- set the labels in the tabs widget */
EXPORT void set_tab_titles(void)
{
    String titles[MAXOPENDOCS];
    String url = "";
    int i;

    for (i = 0; i < MAXOPENDOCS; i++)
	if (! opendocs[i] || ! opendocs[i]->doc)
	    titles[i] = "";
	else if (opendocs[i]->doc->title)
	    titles[i] = opendocs[i]->doc->title;
	else
	    titles[i] = opendocs[i]->doc->url;
    assert(tabs);
    XtVaSetValues(tabs,
		  XtNlefttabs, curopendoc,
		  XtNrighttabs, MAXOPENDOCS - 1 - curopendoc,
		  XtNlabels, titles,
		  NULL);

    /* Set title of main window, and location field */
    if (opendocs[curopendoc] && opendocs[curopendoc]->doc
	&& opendocs[curopendoc]->doc->url)
	url = opendocs[curopendoc]->doc->url;

    XtVaSetValues(location, XtNvalue, url, NULL);
    XtVaSetValues(toplevel, XtNtitle, titles[curopendoc], NULL);
}


/* switch_to_tabbed_doc -- bring indicated doc to the front */
EXPORT void switch_to_tabbed_doc(int newopendoc)
{
    assert(0 <= newopendoc && newopendoc < MAXOPENDOCS);
    if (newopendoc != curopendoc) {
	if (opendocs[curopendoc])
	    XtUnmanageChild(opendocs[curopendoc]->w);
	if (opendocs[newopendoc]) {
	    XtManageChild(opendocs[newopendoc]->w);
#if 1
	    XmProcessTraversal(opendocs[newopendoc]->w, XmTRAVERSE_CURRENT);
#endif
	}
	curopendoc = newopendoc;
	set_tab_titles();
    }
#if ! INSERT_AT_RIGHT
    click[newopendoc] = ++curclick;		/* Becomes newest */
#endif
}


/* remove_doc -- remove the document from among the loaded docs */
EXPORT void remove_doc(int n)
{
    Widget w;
    int i;

    assert(0 <= n && n < MAXOPENDOCS);
    if (opendocs[n]) {
	(void) free_request_rec(opendocs[n]);
	XtDestroyWidget(opendocs[n]->w);
#if INSERT_AT_RIGHT
	for (i = n; i > 0; i--) opendocs[i] = opendocs[i-1];
	opendocs[0] = NULL;
	if (curopendoc < n) curopendoc++;
	else if (curopendoc == n && opendocs[curopendoc]) {
	    XtManageChild(opendocs[curopendoc]->w);
#if 1
	    XmProcessTraversal(opendocs[curopendoc]->w, XmTRAVERSE_CURRENT);
#endif
	}
#else /* INSERT_AT_RIGHT */
	opendocs[n] = NULL;
	click[n] = 0;				/* Make it the oldest */
#endif
	set_tab_titles();
    }
}

/* remove_curdoc -- remove the current document from among the loaded docs */
EXPORT void remove_cur_doc(void)
{
    remove_doc(curopendoc);
}


/* find_among_tabs -- check if the requested document is already displayed */
EXPORT int find_among_tabs(const char *url)
{
    int i;

    for (i = 0; i < MAXOPENDOCS; i++)
	if (opendocs[i] && opendocs[i]->doc && eq(opendocs[i]->doc->url, url))
	    return i;
    return -1;
}


/* create_tab -- add a new document for tab n */
EXPORT void create_tab(int n, ViewerInfo *info)
{
    int i;

    assert(0 <= n && n < MAXOPENDOCS);
    assert(info);
    if (opendocs[n]) {
	(void) free_request_rec(opendocs[n]);
	XtDestroyWidget(opendocs[n]->w);
	opendocs[n] = NULL;
    }
    if (opendocs[curopendoc]) XtUnmanageChild(opendocs[curopendoc]->w);
#if INSERT_AT_RIGHT
    for (i = n + 1; i < MAXOPENDOCS; i++) opendocs[i-1] = opendocs[i];
    curopendoc = MAXOPENDOCS - 1;
#else
    click[n] = ++curclick;			/* Becomes newest */
    curopendoc = n;
#endif
    opendocs[curopendoc] = info;
    set_tab_titles();
    XtManageChild(opendocs[curopendoc]->w);
#if 1
    XmProcessTraversal(opendocs[curopendoc]->w, XmTRAVERSE_CURRENT);
#endif
}


/* get_cur_doc -- return pointer to current document */
EXPORT ViewerInfo *get_cur_doc(void)
{
    return opendocs[curopendoc];
}


/* get_oldest_tab -- return the oldest of the 6 documents */
EXPORT int get_oldest_tab(void)
{
#if INSERT_AT_RIGHT
    return 0;					/* Always return leftmost */
#else
    int min, i;

    for (min = 0, i = 1; i < MAXOPENDOCS; i++)
	if (click[i] < click[min]) min = i;
    return min;
#endif
}


/* init_tabs -- intialize the tabs */
EXPORT void init_tabs(void)
{
    set_tab_titles();
}

