#module NEWSDIR "V4.02"
/*----------------------------------------------------------------------
        N E W S D I R . C

 Author:
     Geoff Huston
       Computer Services Centre
       Australian National University

 Functionality:
        Directory command

 Version:
    V1.0    17-Jul-1986     GIH     This version of code checkpointed
    V1.1     1-Aug-1986     GIH     Screen handling code added
    V3.0    28-Apr-1987     GIH     Version 3 Release
    V4.0    30-Oct-1987     GIH     NEWS Version 4.0 Release
    V4.02   17-Nov-1987     GIH     Bug fix with DIR/REG and DIR/NEW
                                    Added force_recalc variable in do_dir
                                    Added function do_dircall
                                    Added function dirnew_check

----------------------------------------------------------------------*/

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


/*----------------------------------------------------------------------
 *  d i r n e w _ c h e c k
 *
 * 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));
    }
}

/*----------------------------------------------------------------------
 *  i t e m _ d i r
 *
 *  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_closed)
    {
        printf("\tDir - Newsgroup is CLOSED\n");
        return;
    }

    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);
    put_line("");
    sprintf(err_oline,"Last item #%d",ga[curr_g]->grp_topnum);
    put_line(err_oline);
    put_line("");
    put_line("Number      Date         Title                                 Size");
    put_line("");
    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);
        if ((g_reg) && (iap[i].itm_unread)) sprintf(err_oline,"   %-5d  %-*.*s  %6d %s UNREAD",iap[i].itm_num,SUBJLEN,SUBJLEN,iap[i].itm_title,iap[i].itm_size,fdate);
        else sprintf(err_oline,"   %-5d  %-*.*s  %6d %s",iap[i].itm_num,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);
    }
}

/*----------------------------------------------------------------------
 *  n e w s g r o u p _ d i r
 *
 *  dir/group - directory of all groups in the system
 *----------------------------------------------------------------------
 */

static newsgroup_dir()
{
    int g,
        sg = 0;

    usr_line = 0;
    printf("\n");
    start_header();
    switch (cur_dir_type)
    {
        case DIR_OPEN:
            put_line("NEWS - Directory of Newsgroups");
            break;
        case DIR_ALL:
            put_line("NEWS - Directory of OPEN and CLOSED Newsgroups");
            break;
        case DIR_NEW:
            put_line("NEWS - Directory of Registered Newsgroups with unread items");
            break;
        case DIR_REGISTER:
            put_line("NEWS - Directory of Registered Newsgroups");
            break;
    }
    put_line("");
    sprintf(err_oline,"  Number %-*.*s     Count  Unread",SUBJLEN,SUBJLEN,"Group");
    put_line(err_oline);
    put_line("");
    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_reg) sprintf(err_oline,"   %-5d %-*.*s   %6d   %6d",ga[g]->grp_display_indx,SUBJLEN,SUBJLEN,ga[g]->grp_name,ga[g]->grp_count,ga[g]->grp_unread);
        else sprintf(err_oline,"   %-5d %-*.*s   %6d",ga[g]->grp_display_indx,SUBJLEN,SUBJLEN,ga[g]->grp_name,ga[g]->grp_count);
        if (curr_g == g)
        {
            *err_oline = '-';
            *(err_oline+1) = '>';
        }
        put_line(err_oline);
    }
    grp_display_size = sg;
}

/*-------------------COMMAND FUNCTION-----------------------------------
 *  d o _ d i r
 *
 * define verb DIRECTORY
 *    routine     do_dir
 *    qualifier   ALL,        nonnegatable
 *    qualifier   ITEMS,      nonnegatable
 *    qualifier   OPEN,       nonnegatable
 *    qualifier   NEW,        nonnegatable
 *    qualifier   NEWSGROUPS, nonnegatable
 *    qualifier   REGISTER,   nonnegatable
 *    qualifier   RESET,      nonnegatable
 *    disallow    any2 (ALL,ITEMS,OPEN,NEW,NEWSGROUPS,REGISTER)
 *
 *  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;

    if (!dt)
    {

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

        force_recalc = 1;
        if (cli$present(c$dsc("OPEN")) == CLI$_PRESENT) dir_type = DIR_OPEN;
        else if (cli$present(c$dsc("ALL")) == CLI$_PRESENT) dir_type = DIR_ALL;
        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();
        return(0);
    }

    grp_display_size = 0;
    for (gindx = 1; gindx <= ga_size; ++gindx)
    {
        switch (dir_type)
        {
            case DIR_OPEN:
                incl_grp = !(ga[gindx]->grp_closed);
                break;
            case DIR_ALL:
                incl_grp = 1;
                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();
    return(0);
}

/*----------------------------------------------------------------------
 *  d o _ d i r _ c a l l
 *
 *  CLI entry point to do_dir function
 *----------------------------------------------------------------------
 */


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