[inherit('sys$library:starlet','lib$spawn','smgdefs','smg$repaint_line',
'bb.pen')]
module message_state;

[global] procedure message_state;

{This is the new version of this procedure.  Written by Alta Paul,
Feb., 1988.  This procedure will first see if there is a file called
bb$userfile3.dat in the user's login directory.  If not, it will be
created and start records will be added for each topic board in the
selected category area.  Then using the LAST_ACCESS dates for each
topic, the procedure will produce the counts for new and total
messages that appear in the directory of topics screen in the utility.
Counts for the messages are stored by date in a sequential file in the
data area. This procedure is an improvement over the old one in that
it no longer touches every single record in the large data base before
printing the first Bulletin Board screen.

This version incorporates several of the smaller procedures and
functions of the old program.  By combining these into one module,
this routine executes must faster by avoiding very repetitious
subroutine calls and subsequent overhead even though this combining of 
routines makes this module rather lengthy and tedious.}

var
    last_access_topic : newuserrec;
    new_user_info_ok,new_user : boolean;
    last_read : string;
    topic : string;
    curr_user_file_topic : string;
    test_date : timetype;
    new, total, topic_long : integer;
    counted_topic : packed array [1..topic_length] of char;
    counted_date : timetype;
    counts : integer;

begin
  $setprv(1,prv$m_sysprv);
  topic_list := topic_root;
  if (topic_list^.next <> nil) then
    begin
      topic_list := topic_list^.next;   
      topic := topic_list^.topic;  {Needed for 1st test of user file}
    
      {This section opens user file.  If not there it is created.}
      open(newuserfile,new_user_logical+':bb$userfile3.dat',history:=unknown,
           access_method:=keyed,organization:=indexed,
           sharing:=readwrite,error:=continue);

      findk(newuserfile,0,null_date+'LAST_ACCESS_'+topic,eql,error:=continue);
      if (ufb(newuserfile)) then    {user is new to category}
        begin
          repeat   {put head records for topics into new newuserfile}
            last_access_topic.message_id := 
                                  null_date+'LAST_ACCESS_'+topic_list^.topic;
            write(newuserfile,last_access_topic);
            topic_list := topic_list^.next;
          until (topic_list = nil);
          topic_list := topic_root;    {sets topic list to beginning}

          repeat  {put tail records in file to maintain proper counts}
            {These are really "dummy" records and they are needed for first time
             access to the boards.  This was the only way I could get the 'new'
             counts to come out right if not all boards are accessed on first
             use of the utility.  They are not needed after a board is accessed
             but I have chosen not to delete them since the program works in
             the present form.}
            topic_list := topic_list^.next;
            last_access_topic.message_id := 
              chr(0)+chr(0)+chr(0)+chr(0)+chr(0)+chr(0)+chr(0)+chr(1)+
             'LAST_ACCESS_'+topic_list^.topic;
            findk(newuserfile,0,last_access_topic,eql,error:=continue);
            write(newuserfile,last_access_topic);
          until (topic_list^.next = nil);
        end;
      topic_list := topic_root;
    
      {This section sets all counters to zero.}
      repeat
        topic_list := topic_list^.next;
        with topic_list^.message_counters do
          begin
            total_message := 0;
            read_message := 0;
            new_message := 0;
            skipped_message := 0;
          end;
        topic_list^.last_date_accessed := null_date;
      until (topic_list^.next = nil);
      topic_list := topic_root;  {sets topic list to beginning}
    
      {Ready count_file for reading}
      open(count_file,file_location+count_location,history:=readonly,
                      organization:=sequential,sharing:=readonly);
      reset(count_file);
      if (not(eof(count_file))) then
        readln(count_file,counted_topic,counted_date,counts);
    
      repeat
        topic_list:=topic_list^.next;
        topic := topic_list^.topic;
        begin
    
          {No messages in the current topic?  Step forward in directory
               until current topic matches a record in count_file}
          if ((counted_topic <> topic) and (topic_list^.next <> nil)) then
            repeat
              topic_list := topic_list^.next;
              topic := topic_list^.topic;
            until ((counted_topic = topic) or (topic_list^.next = nil));
    
          if (topic_list <> nil) then
            begin
              {Find first LAST_ACCESS record in the newuserfile for this topic}
              last_access_topic.message_id := null_date+'LAST_ACCESS_'+topic;
              findk(newuserfile,0,last_access_topic,eql,error:=continue);
    
              if (ufb(newuserfile)) then
                begin  {topic new since user last accessed category}
                  write(newuserfile,last_access_topic);
                  last_access_topic.message_id := 
                    chr(0)+chr(0)+chr(0)+chr(0)+chr(0)+chr(0)+chr(0)+chr(1)+
                    'LAST_ACCESS_'+topic_list^.topic;
                  write(newuserfile,last_access_topic);
                  last_access_topic.message_id := null_date+'LAST_ACCESS_'+topic;
                  findk(newuserfile,0,last_access_topic,eql,error:=continue);
                end;
              {now we need to get to the last LAST_ACCESS record}
              topic_long := length(topic);
              repeat
                get(newuserfile);  {gets LAST_ACCESS record from user file}
                if (length(newuserfile^.message_id) >= (21 + topic_long)) then
                  curr_user_file_topic := 
                           substr(newuserfile^.message_id,9,12+topic_long);
                  until (curr_user_file_topic = 'LAST_ACCESS_'+topic) or
                          (status(newuserfile) <> 0);

              {Set date of last access in topic directory node}
              last_read := substr(newuserfile^.message_id,1,8);
              topic_list^.last_date_accessed := last_read;
    
              new := 0;
              total := 0;
              test_date := topic_list^.last_date_accessed;
              while (counted_topic = topic) and (not(eof(count_file))) do  
                begin   {current topic has messages}           
                  if (test_date < counted_date) then
                     new := new + counts;
                  total := total + counts;
                  if (not(eof(count_file))) then
                    readln(count_file,counted_topic,counted_date,counts);    
                end;
                if ((eof(count_file)) and (counted_topic = topic)) then 
                  begin     {handle last record in count_file}
                    if (test_date < counted_date) then
                      new := new + counts;
                    total := total + counts;
                  end;
              topic_list^.message_counters.total_message := total;
              topic_list^.message_counters.new_message := new;
            end;
        end;
      until (topic_list^.next = nil);
      $setprv(0,prv$m_sysprv);
      close(count_file);
    end;
end;{end of procedure}
end.
