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

 Author:
     Geoff Huston
       Computer Services Centre
       Australian National University

 Functionality:
        Read command

 Version History:

    V1.0    17-Jul-1986     GIH

    V1.1    08-Sep-1986     GIH     Change all calls of "screen_goto_n" to
                                    "screen_goto_itm" to correct screen
                                    cursor position following the command.
    V4.0    30-Oct-1987     GIH     NEWS Version 4.0 Release\
    V4.02   23-Nov-1987     GIH
      - Change read/parent to use RIGHTMOST message-id (not the leftmost!!)
      - Change READ/NEW to pick up the newsgroup with the max priority

----------------------------------------------------------------------*/
#include "newsinclude.h"
#include "newsdefine.h"
#include "newsextern.h"

static int tpucall;

/*----------------------------------------------------------------------
 *  i t e m _ u p d a t e
 *
 *  update the uaf record for a read item
 *----------------------------------------------------------------------
 */

item_update(g,i)
    int g,
        i;
{
    if (ga[g]->grp_ia && ga[g]->grp_ia[i].itm_unread)
    {
        if (ga[g]->grp_unread > 0)
        {
            --ga[g]->grp_unread;
            screen_update_gread(g);
        }
        ga[g]->grp_ia[i].itm_unread = 0;
        screen_update_iread(g,i);
    }
}

/*----------------------------------------------------------------------
 *  d o _ r e a d f i n d
 *
 *  Read a selected item
 *----------------------------------------------------------------------
 */

do_readfind(s,rheader,rot13)
    char *s;
    int rheader,
        rot13;
{
    int g,
        i;

    if (!curr_g)
    {
        err_line("Error: Read - No Newsgroup selected");
        return;
    }

    if (news_context == 1)
    {
        set_level(2);
        if (!curr_i)
        {
            err_line("\tRead: Newsgroup is empty\n");
            return(0);
        }
    }

    if (!(i = item_find(s))) return(0);

    cur_set_itm(curr_g,i);
    item_update(curr_g,curr_i);
    do_display(rheader,tpucall,rot13);
    return(0);
}

/*----------------------------------------------------------------------
 *  d o _ r e a d n e w
 *
 *  Pick out the next unread news item - select that group and read the
 *  first unread item from the group
 *----------------------------------------------------------------------
 */

do_readnew(rheader,rot13)
    int rheader,
        rot13;
{
    int i;

    if (!no_more_news)
    {
        if ((curr_g) && (ga[curr_g]->grp_reg) && (ga[curr_g]->grp_unread) && (news_context != 1))
        {           
            set_level(2);

            i = curr_i;
            while ((i <= ga[curr_g]->grp_count) && (!(ga[curr_g]->grp_ia[i].itm_unread))) ++i;
            if (i > ga[curr_g]->grp_count) i = 1;
            while ((i <= ga[curr_g]->grp_count) && (!(ga[curr_g]->grp_ia[i].itm_unread))) ++i;
            if (i <= ga[curr_g]->grp_count)
            {
                cur_set_itm(curr_g,i);
                item_update(curr_g,curr_i);
                do_display(rheader,tpucall,rot13);
                return(0);
            }
            else
            {
                set_level(1);
                ga[curr_g]->grp_unread = 0;
                if (screen_active && ga[curr_g]->grp_display_indx)
                {
                    sprintf(err_oline,"%5d",ga[curr_g]->grp_unread);
                    smg$put_chars(&grp_vd,c$dsc(err_oline),c$rfi(ga[curr_g]->grp_display_indx),c$rfi(73),0,0,0,0);
                }
            }
        }

        set_level(1);
        if (selnew(2))
        {
            item_update(curr_g,curr_i);
            do_display(rheader,tpucall,rot13);
            return(0);
        }
    }
    else err_line("\tNo unread items in registered newsgroups\n");
    return(0);
}           

/*----------------------------------------------------------------------
 *  d o _ r e a d n e x t
 *
 *  Use the current read context to pick out the next item to display.
 *----------------------------------------------------------------------
 */

do_readnext(rheader,rot13)
    int rheader,
        rot13;
{
    if (!curr_g)
    {
        err_line("Error: Read - No Newsgroup selected");
        return;
    }
                             
    if (news_context == 1)
    {
        set_level(2);
        if (!curr_i)
        {
            err_line("\tRead: Newsgroup is empty\n");
            return(0);
        }
    }
    else if (cur_down_itm(curr_g,1,0) != 1)
    {
        if (!ga[curr_g]->grp_count)
            err_line("\tRead: Newsgroup is empty\n");
        else err_line("\tRead: No more items in Newsgroup\n");
        return(0);
    }

    item_update(curr_g,curr_i);
    do_display(rheader,tpucall,rot13);
    return(0);          
}

/*----------------------------------------------------------------------
 *  d o _ r e a d p a r e n t
 *
 *  Display the parent item of the current item - pick off the rightmost
 *  reference item
 *----------------------------------------------------------------------
 */
                                          
static do_readparent(rheader,rot13)
    int rheader,
        rot13;
{
    FILE *fp;
    char inpline[152],
         pref[IDLEN+2];
    unsigned short *gr;
    int i,
        g;
                                        
    if ((news_context > 1) && curr_g && curr_i)
    {
        if (!(fp = do_open_item(curr_g,curr_i,"r")))
        {
            err_line("\tError: Display - Cannot access item text\n");
            return;
        }
        while (fgets(inpline,512,fp))
        {
            if (*inpline == '\n')
            {
                fclose(fp);
                err_line("\tError: Read/Parent - This item has no parent reference\n");
                return;
            }
            if (!strncmp(inpline,"References: ",12))
            {
                char *ref;
          
                fclose(fp);
                if (ref = strrchr(inpline,'>'))
                {        
                    *(ref+1) = '\0';
                    if (ref = strrchr(inpline,'<'))                 
                    {
                                /* ref is the parent reference ID ! */
                        strcpy(pref,ref);
                        util_idcpy(pref,pref);
                        gr = &(pref[IDLEN]);
                        *gr = ga[curr_g]->grp_num;

                        itmrab.rab$l_kbf = pref;
                        itmrab.rab$b_ksz = IDLEN + 2;
                        itmrab.rab$b_krf = 1;
                        itmrab.rab$l_rop = RAB$M_RRL | RAB$M_NLK;
                        itmrab.rab$b_rac = RAB$C_KEY;

                        if (!(sys$get(&itmrab) & 1))
                        {
                            *gr = 0;
                            itmrab.rab$l_rop = RAB$M_KGE | RAB$M_RRL | RAB$M_NLK;
                            if ((!(sys$get(&itmrab) & 1)) || (strcmp(pref,newsitm.itm_id)))
                            {
                                err_line("\tError: Read/Parent - Parent item not found\n");
                                return;
                            }
                            if (curr_g != newsitm.itm_grp)
                            {
                                if (!(g = ga_locate(newsitm.itm_grp)))
                                {
                                    err_line("\tError: Read/Parent - Parent not located - (try DIR/RESET)\n");
                                    return;
                                }
                                do_select("%",g,2);
                            }
                        }
                        for (i = 1; i <= ga[curr_g]->grp_count; ++i)
                        {
                            if (ga[curr_g]->grp_ia[i].itm_num == newsitm.itm_num) break;
                        }
                        if (i > ga[curr_g]->grp_count)
                        {
                            err_line("\tError: Read/Parent - Parent not located - (try DIR/RESET)\n");
                            return;
                        }
                        cur_set_itm(curr_g,i);
                        item_update(curr_g,curr_i);
                        do_display(rheader,tpucall,rot13);
                        return(0);
                    }
                }
                err_line("\tError: Read/Parent - Parent reference unreadable\n");
                return;
            }
        }
        fclose(fp);
        err_line("\tError: Read/Parent - This item has no parent reference\n");
        return;
    }
    err_line("\tError: Read/Parent - No current item selected\n");
    return;
}

/*----------------------------------------------------------------------
 *  d o _ r e a d i d e n t
 *
 *  Display the item selected by the supplied identifier
 *----------------------------------------------------------------------
 */
                        
static do_readident(rheader,rot13)
    int rheader,
        rot13;
{
    FILE *fp;
    char id[152];
    unsigned short *gr,
                   id_len = 0;
    int i,
        g;
    $DESCRIPTOR(id_dsc,id);

    if (!(cli$get_value(c$dsc("IDENTIFIER"),&id_dsc,&id_len) & 1))
    {  
        get_input(&id_dsc,c$dsc("Message-ID: "),&id_len);
    }
    if (!id_len) return;
    id[id_len] = '\0';
    s_to_lower(id);
    util_idcpy(id,id);          

    gr = &(id[IDLEN]);
    itmrab.rab$l_kbf = id;
    itmrab.rab$b_ksz = IDLEN + 2;
    itmrab.rab$b_krf = 1;
    itmrab.rab$l_rop = RAB$M_RRL | RAB$M_NLK;
    itmrab.rab$b_rac = RAB$C_KEY;

    if (curr_g) *gr = ga[curr_g]->grp_num; 
    if ((!curr_g) || (!(sys$get(&itmrab) & 1)))
    {
        *gr = 0;
        itmrab.rab$l_rop = RAB$M_KGE | RAB$M_RRL | RAB$M_NLK;
        if ((!(sys$get(&itmrab) & 1)) || (strcmp(id,newsitm.itm_id)))
        {
            err_line("\tError: Read/Identifier - item not found\n");
            return;
        }
    }
    if (!(g = ga_locate(newsitm.itm_grp)))
    {
        err_line("\tError: Read/Parent - Parent not located - (try DIR/RESET)\n");
        return;
    }
    do_select("%",g,2);
    for (i = 1; i <= ga[curr_g]->grp_count; ++i)
    {
        if (ga[curr_g]->grp_ia[i].itm_num == newsitm.itm_num) break;
    }
    if (i > ga[curr_g]->grp_count)
    {
        err_line("\tError: Read/Parent - Parent not located - (try DIR/RESET)\n");
        return;
    }
    cur_set_itm(curr_g,i);
    item_update(curr_g,curr_i);
    do_display(rheader,tpucall,rot13);
    return(0);
}

/*----------------------------------------------------------------------
 *  d o _ r e a d
 *
 *  read command processing
 *----------------------------------------------------------------------
 */

do_read()
{
    char item[SUBJLEN];
    $DESCRIPTOR(item_dsc,item);
    short item_len;
    int h = 0,
        rot13 = 0;

    clear_err_line();

    tpucall = 0;
    if (cli$present(c$dsc("HEADER")) & 1) h = 1;
    if (cli$present(c$dsc("TPU")) & 1) tpucall = 1;
    else if (cli$present(c$dsc("ROT13")) & 1) rot13 = 1;
    if (cli$present(c$dsc("NEW")) & 1) return(do_readnew(h,rot13),0);
    if (cli$present(c$dsc("NEXT")) & 1) return(do_readnext(h,rot13),0);
    if (cli$present(c$dsc("PARENT")) & 1) return(do_readparent(h,rot13),0);
    if (cli$present(c$dsc("IDENTIFIER")) & 1) return(do_readident(h,rot13),0);
    if (cli$present(c$dsc("LAST")) & 1)
    {
        if ((news_context > 1) && curr_g && curr_i)
        {
            if (cur_up_itm(curr_g,1,0) == 1)
            {
                item_update(curr_g,curr_i);
                do_display(h,tpucall,rot13);
            }
        }
        return(0);
    }
    if (cli$get_value(c$dsc("NEWSITEM"),&item_dsc,&item_len) != CLI$_ABSENT)
    {
        if (curr_g)
        {
            item[item_len] = '\0';
            do_readfind(item,h,rot13);
        }
    }
    else if ((curr_g) && (curr_i))
    {
        item_update(curr_g,curr_i);
        do_display(h,tpucall,rot13);
    }
    return(0);
}
                             
