#module NEWSDIR "V5.6"

/*
**++
**  FACILITY:
**
**      NEWSDIR
**
**  ABSTRACT:
**
**      This module determines which newsgroups are included in the displayed
**      newsgroup directory.
**
**  AUTHOR:
**
**      Geoff Huston
**
**  COPYRIGHT:
**
**      Copyright © 1988
**
**  MODIFICATION HISTORY:
**
**      V5.5     7-Oct-1988     GIH
**          Correct error in display using line mode.
**      V5.6    11-Nov-1988     GIH
**          Additional bug fixes for NOSCREEN mode displays
**
**--
**/

#include "newsinclude.h"
#include "newsdefine.h"
#include "newsextern.h"

char dir_sincestr[132];
static int since_time;
static $DESCRIPTOR(since_dsc,dir_sincestr);

/*
 *  dirnew_check
 *
 * check if the newsdirectory requires redisplay in the case of DIR/NEW (i.e.
 * the directory currently contains newsgroups with no unread items - remove
 * them from the directory). This procedure is invoked only when cur_dir_type
 * is DIR_NEW and the screen display is active.
 */

dirnew_check()
{
    int g;


    for (g = 1; g <= ga_size; ++g) {
        if ((ga[g]->grp_display_indx) && (!ga[g]->grp_unread))
            return(do_dir(cur_dir_type + 1, 1));
        }
}

/*
 *  item_dir
 *
 *  dir - directory listing of selected group
 */

static item_dir(start)
    int start;
{
    int i,
        g_reg;
    ITM_MEM_PTR iap;
    char *fdate;

    if (!ga[curr_g]->grp_count) {
        printf("\tDir - Newsgroup is empty: %s\n",ga[curr_g]->grp_name);
        return;
        }

    if ((start + 20) > ga[curr_g]->grp_count) start = ga[curr_g]->grp_count - 20;
    if (start < 1) start = 1;

    usr_line = 0;
    printf("\n");

    start_header();
    sprintf(err_oline,"News Directory   Group %s",ga[curr_g]->grp_name);
    put_line(err_oline,0);
    put_line("",0);
    sprintf(err_oline,"Last item #%d",ga[curr_g]->grp_topnum);
    put_line(err_oline,0);
    put_line("",0);
    put_line(" Number   Title                                               Lines Date",0);
    put_line("",0);
    end_header();
    iap = ga[curr_g]->grp_ia;
    g_reg = ga[curr_g]->grp_reg;
    for (i = start; i <= ga[curr_g]->grp_count; ++i) {
        fdate = gendate(iap[i].itm_date);
        sprintf(err_oline,"  %-5d %s%s %-*.*s %5d %s",
            iap[i].itm_num,(iap[i].itm_locdate ? " " : "R"),
            (iap[i].itm_unread ? "*" : " "),SUBJLEN,SUBJLEN,iap[i].itm_title,
            iap[i].itm_size,fdate);
        if (i == ga[curr_g]->grp_c_itm) {
            *err_oline = '-';
            *(err_oline+1) = '>';
            }
        put_line(err_oline,0);
        }
}

/*
 *  newsgroup_dir
 *
 *  dir/group - directory of all groups in the system
 */

static newsgroup_dir()
{
    int g,
        sg = 0;
    char srv[10];

    usr_line = 0;
    printf("\n");
    start_header();
    switch (cur_dir_type) {
        case DIR_ALL:
            put_line("NEWS - Directory of All Newsgroups",0);
            break;
        case DIR_DATE:
            sprintf(err_oline,"NEWS - Directory of Newsgroups - New items since %s",dir_sincestr);
            put_line(err_oline,0);
            break;
        case DIR_NEW:
            put_line("NEWS - Directory of Registered Newsgroups with unread items",0);
            break;
        case DIR_REGISTER:
            put_line("NEWS - Directory of Registered Newsgroups",0);
            break;
        }
    put_line("",0);
    sprintf(err_oline,"  Number %-*.*s     Count  Unread",SUBJLEN,SUBJLEN,"Group");
    put_line(err_oline,0);
    put_line("",0);
    end_header();

    if ((!curr_g) && ga_size) curr_g = 1;
    for (g = 1; g <= ga_size; ++g) {
        if (!ga[g]->grp_display_indx) continue;

        ga[g]->grp_display_indx = ++sg;
        if (*(ga[g]->grp_server)) sprintf(srv,"[R]",ga[g]->grp_server);
        else *srv = '\0';
        if (ga[g]->grp_reg) sprintf(err_oline,"   %-5d %-*.*s %6d %6d %s",ga[g]->grp_display_indx,SUBJLEN,SUBJLEN,ga[g]->grp_name,ga[g]->grp_count,ga[g]->grp_unread,srv);
        else sprintf(err_oline,"   %-5d %-*.*s %6d        %s",ga[g]->grp_display_indx,SUBJLEN,SUBJLEN,ga[g]->grp_name,ga[g]->grp_count,srv);
        if (curr_g == g) {
            *err_oline = '-';
            *(err_oline+1) = '>';
            }
        put_line(err_oline,0);
        }
    grp_display_size = sg;
}

/*
 *  do_dir
 *
 *  Process a directory command
 */

do_dir(dt,fr)
    int dt,
        fr;
{
    int dir_type = 0,
        gindx,
        new_curr_g = 0,
        incl_grp,
        force_recalc = 0;
    short since_len;

    if (!dt) {

        if (cli$present(c$dsc("RESET")) == CLI$_PRESENT) mem_reset(cur_dir_type);

        force_recalc = 1;
        if (cli$present(c$dsc("ALL")) == CLI$_PRESENT) dir_type = DIR_ALL;
        else if (cli$get_value(c$dsc("SINCE"),&since_dsc,&since_len) & 1) {
            char *cp;
            dir_sincestr[since_len] = '\0';
            since_time = cvt_date_val(dir_sincestr);
            if (cp = strchr(dir_sincestr,' ')) *cp = '\0';
            dir_type = DIR_DATE;
            }
        else if (cli$present(c$dsc("NEW")) == CLI$_PRESENT) dir_type = DIR_NEW;
        else if (cli$present(c$dsc("REGISTER")) == CLI$_PRESENT) dir_type = DIR_REGISTER;
        else {
            force_recalc = 0;
            dir_type = cur_dir_type;
            if (cli$present(c$dsc("ITEMS")) == CLI$_PRESENT) {
                set_level(2);
                if (!screen_active) item_dir(1);
                return(0);
                }
            else if (cli$present(c$dsc("NEWSGROUPS")) == CLI$_PRESENT) set_level(1);
            else if (news_context > 1) {
                set_level(2);
                if (!screen_active) item_dir(curr_i-2);
                return(0);
                }
            }
        }
    else {
        dir_type = dt - 1;
        force_recalc = fr;
        }

    set_level(1);
    if ((!force_recalc) && (dir_type == cur_dir_type)) {
        if (!screen_active) {
            newsgroup_dir();
            set_level(1);
            set_level(2);
            }
        return(0);
        }

    grp_display_size = 0;
    for (gindx = 1; gindx <= ga_size; ++gindx) {
        switch (dir_type) {
            case DIR_ALL:
                incl_grp = 1;
                break;
            case DIR_DATE:
                incl_grp = (ga[gindx]->grp_entdate > since_time);
                break;
            case DIR_NEW:
                incl_grp = ((ga[gindx]->grp_reg) && (ga[gindx]->grp_unread));
                break;
            case DIR_REGISTER:
                incl_grp = (ga[gindx]->grp_reg);
                break;
            }
        if (incl_grp) {
            if ((!new_curr_g) || (curr_g == gindx)) new_curr_g = gindx;
            ga[gindx]->grp_display_indx = ++grp_display_size;
            }
        else ga[gindx]->grp_display_indx = 0;
        }
    cur_dir_type = dir_type;
    if (grp_display_size) curr_g = new_curr_g;
    else curr_g = 0;
    if (screen_active) screen_map_dir();
    else {
        newsgroup_dir();
        set_level(1);
        set_level(2);
        }
    return(0);
}

/*
 *  do_dir_call
 *
 *  CLI entry point to do_dir function
 */

do_dircall()
{
    return(do_dir(0,0));
}
