#line 15 "requests.c-nw"
#include "config.h"
#include <Xm/Xm.h>
#include "str.h"
#include "w3a.h"
#include "w3alib.h"


EXPORT typedef struct {
    W3ADocumentInfo *doc;
    int method;                                 /* GET, POST, etc. */
    int viewer;                                 /* Which class of viewers */
    int agent;                                  /* Which class of agents */
    int fd;                                     /* File descriptor for agent */
    int total;                                  /* # of bytes read */
    Widget w;                                   /* Widget created by browser */
    int seqnr;                                  /* Unique number */
    int cache_id;                               /* -1 if not caching */
    XtInputId write_id, read_id;                /* Input handlers */
    Bool interrupted;                           /* Flag to stop input hndlr */
    Bool need_event;                            /* Call W3Aevent when ready? */
    Bool toplevel;                              /* Document or in-line? */
    int show_progress;                          /* Which percentagebar */
    int tmpfd;                                  /* Temp. file, for "save" */
    char tmpnam[L_tmpnam];                      /* Temp file */
    Bool in_use;                                /* Used by requests.c only */
    Bool high_prio;                             /* Priority request */
    int private;                                /* Used by requests.c only */
} ViewerInfo;

static ViewerInfo **list = NULL;
static int listlen = 0;


EXPORT ViewerInfo * get_request_rec(void)
{
    int i;

    for (i = 0; i < listlen && list[i]->in_use; i++) ;
    if (i == listlen) {
        listlen++;
        renewarray(list, listlen);
        new(list[i]);
        list[i]->private = i;
    }
    list[i]->doc = NULL;
    list[i]->method = -1;
    list[i]->viewer = -1;
    list[i]->agent = -1;
    list[i]->fd = -1;
    list[i]->total = 0;
    list[i]->w = NULL;
    list[i]->seqnr = -1;
    list[i]->cache_id = -1;
    list[i]->write_id = NULL;
    list[i]->read_id = NULL;
    list[i]->interrupted = FALSE;
    list[i]->need_event = FALSE;
    list[i]->toplevel = FALSE;
    list[i]->show_progress = -1;
    list[i]->tmpfd = -1;
    list[i]->tmpnam[0] = '\0';
    list[i]->high_prio = FALSE;
    list[i]->in_use = TRUE;
    return list[i];
}


EXPORT Bool free_request_rec(ViewerInfo *v)
{
    Bool ok = TRUE;

    assert(0 <= v->private
           && v->private < listlen
           && list[v->private] == v);
    if (! v->in_use) return TRUE;
    if (v->write_id) XtRemoveInput(v->write_id);
    if (v->read_id) XtRemoveInput(v->read_id);
    if (v->agent >= 0 && v->fd >= 0) ok &= agent_close(v->agent, v->fd);
    if (v->viewer >= 0) ok &= viewer_close(v->viewer, (long) v);
#if 0
    if (v->w) XtDestroyWidget(v->w);
#endif
    if (v->doc) {dispose_doc(v->doc); v->doc = NULL;}
    if (v->tmpfd >= 0) (void) close(v->tmpfd);
    if (v->tmpnam[0]) (void) unlink(v->tmpnam);
    v->in_use = FALSE;
    return ok;
}


EXPORT void interrupt_all_request_rec(void)
{
    int i;

    for (i = 0; i < listlen; i++) list[i]->interrupted = TRUE;
}


EXPORT ViewerInfo *get_first_request_rec()
{
    int i;

    for (i = 0; i < listlen; i++)
        if (list[i]->in_use) return list[i];
    return NULL;
}


EXPORT ViewerInfo *get_next_request_rec(ViewerInfo *prev)
{
    int i;

    assert(0 <= prev->private
           && prev->private < listlen
           && list[prev->private] == prev);
    for (i = prev->private + 1; i < listlen; i++)
        if (list[i]->in_use) return list[i];
    return NULL;
}