;BROWSE.INC Browse downloaded news groups.

;*****************************************************************************
;*                                                                           *
;* BROWSE.INC                                                                *
;* Copyright (C) 1996 Datastorm Technologies, Inc.                           *
;* All rights reserved.                                                      *
;*                                                                           *
;* This script allows the user to read and manipulate the files downloaded   *
;* with the OFFLINE.WAS script.                                              *
;*                                                                           *
;* This ASPECT SCRIPT is intended only as a sample of ASPECT programming.    *
;* DATASTORM makes no warranty of any kind, express or implied, including    *
;* without limitation, any warranties of merchantability and/or fitness      *
;* for a particular purpose.  Use of this program is at your own risk.       *
;*****************************************************************************



;*****************************************************************************
;*   GLOBAL VARIABLES                                                        *
;*****************************************************************************

string PWNEWSRC                        ;Path to PWNEWSRC.
string NewsIn                          ;Path to Input files.
string NewsOut                         ;Path to Output files.
string CurrentFolder                   ;Name of the current folder.
string ControlFile                     ;Control file for the file group.
string SubjectFile                     ;Subject file for current file group.
string Folder                          ;Full path to current folder.
string FileChoice                      ;Global for FLISTBOX in OpenFolder
string ChoiceFile                      ;Global for FLISTBOX in GetFileGroup
string CurrentGroup                    ;Name of the CurrentGroup
string ChoiceGroup                     ;User choices from Subjects dialog.
string FileGroup                       ;Current file-group.
string TopStatus                       ;Header for top group in status dialog.
string BottomStatus                    ;Bottom header for status dialog.
string StatusHeader                    ;Header for the status dialog.
string CurrentStatus                   ;Text for status window.
string InputFile                       ;Holds path and filename for folder
                                       ; data files.
integer Browsing                       ;Main dialog loop from Browse.
integer CancelFlag                     ;Lets script know what procedures to 
                                       ; follow when CANCEL is pressed in the
                                       ; status dialog box.
integer TwoLoop                        ;DLGEVENT loop from Browse.
integer ChoosingGroup                  ;Main dialog loop from GetFileGroup.
integer NineLoop                       ;DLGEVENT loop from GetFileGroup.
integer StillBrowsing                  ;Main dialog loop from Subjects.
integer TenLoop                        ;DLGEVENT loop from Subjects.
integer ContinueBrowsing               ;Indicates presence of News files.



proc Browse

;*****************************************************************************
;*                                                                           *
;* BROWSE                                                                    *
;* The Browse procedure presents the user with a list of newsgroups for      *
;* reading.  The user chooses one, then subsequent procedure present         *
;* different lists to choose items from (file group, subject).               *
;*                                                                           *
;* Called by: Main (OFFLINE.WAS)                                             *
;* Calls: CleanUp, ListFolders, GetFileGroup                                 *
;* Modifies globals: NewsIn, Browsing, TwoLoop, CurrentGroup,                *
;*                   ContinueBrowsing                                        *
;*                                                                           *
;*****************************************************************************

   long ListLength                     ;Length of the list file.
   string Message                      ;Text line for dialog box.
   string CurrentList                  ;Current list of file-groups.   
   integer Event                       ;DLGEVENT holder.
   integer Choice                      ;User choice from dialog.
   integer DlgID                       ;Window ID of dialog box.
   integer FirstBrowse                 ;Control for DLGLIST command.
   string GroupList                    ;Path to GRPLIST file.
   
   NewsIn = $PWLOCALPATH               ;Get the local PROWIN3 path.
   strcat NewsIn "`\NEWSIN"            ;Get the path to NEWSIN.
   chdir NewsIn                        ;Change to the NEWSIN directory.
   while FAILURE                       ;If CHDIR command failed, prompt
                                       ; to try again or Cancel.  Loop
                                       ; until CHDIR or user exits.
      strfmt Message "Unable to access News files!!!"
      sdlgmsgbox "Directory Error!" Message EXCLAMATION RETRYCANCEL Choice
      if Choice == 2
         CleanUp()
      endif
      chdir NewsIn
   endwhile
   strfmt GroupList "%s`\GRPLIST" NewsIn
                                       ;Get the path to GRPLIST.
   FirstBrowse = 1                     ;Indicate first pass through loop.
   Browsing = 1
   while Browsing
      TwoLoop = 1
      dialogbox 2 137 72 274 237 7 "Select Downloaded Group:"
                                       ;Simple dialog for the choosing of     
                                       ; folder to be read.
         flistbox 1 25 20 221 188 GroupList SINGLE CurrentGroup HSCROLL SORT
         pushbutton 2 62 216 40 14 "OK" DEFAULT
         pushbutton 3 160 216 40 14 "Cancel" 
      enddialog
      dlgwin 2 DlgID
      if FirstBrowse                   ;If this is the first time through this
                                       ; loop,
         dlglist 2 1 SELECT 0          ;Select the first item on the list.
         FirstBrowse = 0               ;Indicate that the first pass is done.
      endif
      while TwoLoop
         dlgevent 2 Event              ;See which dialog control was used.
         switch Event              
            case 1                     ;Ignore access to the listbox.
            endcase
            case 2                     ;If OK was pushed,
               dlgdestroy 2 CANCEL     ;Remove the dialog box.
               TwoLoop = 0             ;Exit the current loop.
               ContinueBrowsing = 1
               ListFolders()           ;Compile list of file-groups.
               
               strfmt CurrentList "%s`\LISTFILE" Folder
                                       ;Get the full path to the List file.
                                       
               fileget CurrentList SIZE ListLength
               if ((ListLength == 0) || ( ! ContinueBrowsing))
                  usermsg "There are no articles in the current folder!"
               else
                  GetFileGroup()       ;Choose file-group to read.
               endif
            endcase
            case 3                     ;If CANCEL was chosen,
               dlgdestroy 2 CANCEL     ;Remove the dialog box.
               TwoLoop = 0             ;Exit the current loop.
               Browsing = 0            ;Exit the main loop.
            endcase
            default
               winexists DlgID         ;See if the dialog box still exists.
               if FAILURE              ;If the box is gone ('X' was pressed),
                  TwoLoop = 0          ;Cancel back to the previous dialog.
                  Browsing = 0
               endif
            endcase
         endswitch
      endwhile
   endwhile
endproc
         
 
      
proc ListFolders

;*****************************************************************************
;*                                                                           *
;* LISTFOLDERS                                                               *
;* This procedure checks the PWNEWSRC for the folder relating to the group   *
;* chosen in the BROWSE procedure.                                           *
;*                                                                           *
;* Calls: CleanUp, OpenFolder                                                *
;* Called by: Browse                                                         *
;* Modifies globals: PWNEWSRC, NewsIn, CurrentGroup, CurrentFolder, Folder,  *
;*                   ContinueBrowsing                                        *
;*                                                                           *
;*****************************************************************************

   string ReadPWNEWSRC                 ;Entry from PWNEWSRC.
   string NewsStamp                    ;Creation stamp of PWNEWSRC.
   string Message                      ;Text line for message dialog.
   string StampField[4]                ;Holds fields of NewsStamp.
   string EntryField[3]                ;Holds field of PWNEWSRC entries.
   integer EntryCount                  ;Loop to check PWNEWSRC entries.
   integer EntryToken                  ;Loop for STRTOK on PWNEWSRC entries.
   integer EntryLoop                   ;Loop for reading PWNEWSRC entries.
   integer Choice                      ;User choice at message dialog.
   integer StampLoop                   ;Loop for STRTOK on NewsStamp.
   integer GroupLength                 ;Length of current group.
   integer FieldLength                 ;Length of PWNEWSRC field.
   integer NameCompare = 0             ;Result of string comparison.
   
   strfmt PWNEWSRC "%s`\PWNEWSRC" NewsIn
                                       ;Get the full path to the PWNEWSRC.
   fopen FID_PWNEWSRC PWNEWSRC READWRITE
   while FAILURE                       ;If the FOPEN command failed, prompt
                                       ; the user to exit or continue.  Loop 
                                       ; until file opens or user exits.
      strfmt Message "Unable to open file:`r`n `r`n%s" PWNEWSRC
      sdlgmsgbox "File Error!" Message EXCLAMATION RETRYCANCEL Choice
      if Choice==2                     ;Exit on Cancel.
         CleanUp()                    
         exit
      endif
      fopen FID_PWNEWSRC PWNEWSRC READWRITE
   endwhile
   fgets FID_PWNEWSRC NewsStamp        ;Pull out the NewsStamp.
   for StampLoop = 0 upto 3            ;Parse the NewsStamp into tokens.
      strtok StampField[StampLoop] NewsStamp ""
   endfor
   atoi StampField[2] EntryCount       ;Make the count of PWNEWSRC entries an 
                                       ; integer value.
   strlen CurrentGroup GroupLength     ;Get length of current group name.
   for EntryLoop = 1 upto EntryCount   ;Loop through the entries of PWNEWSRC.
      fgets FID_PWNEWSRC ReadPWNEWSRC  ;Grab the next entry.
      for EntryToken = 0 upto 2        ;Parse current entry into tokens.
         strtok EntryField[EntryToken] ReadPWNEWSRC ""
      endfor
      strlen EntryField[1] FieldLength ;Get the length of the group name taken
                                       ; from the PWNEWSRC entry.
      if (FieldLength == GroupLength)  ;If the names are of the same length,
         strcmp CurrentGroup EntryField[1] NameCompare
                                       ; see if their contents are the same.
         if NameCompare == 0           ;If the names are the same,
            exitfor
         endif
      endif
   endfor
   if NameCompare != 0                 ;If loop completed without finding the 
                                       ; correct group name in PWNEWSRC,
      errormsg "Unable to find folder for current group!!!"
      CleanUp()                        ;Error and exit.
   else
      CurrentFolder = EntryField[0]
      strfmt Folder "%s`\%s" NewsIn EntryField[0]
                                       ;Format full path to current folder.
      chdir Folder                     ;Try to move into the current folder.
      if FAILURE                       ;If unable to move into the current
                                       ; folder, assume that it does not 
                                       ; exist.
         ContinueBrowsing = 0
      else
         OpenFolder()                  ;Get the list of files in the 
                                       ; current folder.
      endif
   endif
endproc


   
proc OpenFolder

;*****************************************************************************
;*                                                                           *
;* OPENFOLDER                                                                *
;* This procedure compiles a list of available files in the current folder.  *
;*                                                                           *
;* Calls: CleanUp, GetFileGroup                                              *
;* Called by: ListFolders                                                    *
;* Modifies globals: Folder, SubjectFile                                     *
;*                                                                           *
;*****************************************************************************

   integer Choice                      ;User choice in dialog box.
   string CurrentList                  ;File containing valid folders.
   string Message                      ;Text line for dialog box.
   string DateStamp                    ;Date stamp from control file.
   string WriteChoice                  ;String to write to temp file.
   string SubjectFileSpec              ;File search parameter.
   string GroupID                      ;Current file-group ID.
   

   strfmt CurrentList "%s`\LISTFILE" Folder
   fopen FID_FILELIST CurrentList CREATE
   while FAILURE                       ;If the FOPEN command failed, prompt the
                                       ; user to try again or cancel.  Loop 
                                       ; until the file opens or user cancels.
      strfmt Message "Unable to open file %s" CurrentList
      sdlgmsgbox "File Error!" Message EXCLAMATION RETRYCANCEL Choice
      if Choice == 2                   ;Exit on Cancel.
         CleanUp()
      endif
      fopen FID_FILELIST CurrentList CREATE
   endwhile 
   strfmt SubjectFileSpec "%s`\*.SUB" Folder
   findfirst SubjectFileSpec
   while Success
      GroupID = $FNAME                 ;Get the name of the just-found file.
      strfmt SubjectFile "%s`\%s.SUB" Folder GroupID
                                       ;Get the name of the first control file.
      fopen FID_CONTROL SubjectFile READWRITE
      while FAILURE                    ;If the FOPEN command failed, prompt the
                                       ; user to try again or cancel.  Loop 
                                       ; until the file opens or user cancels.
         strfmt Message "Unable to open file:`r`n`r`n%s" SubjectFile
         sdlgmsgbox "File Error!" Message EXCLAMATION RETRYCANCEL Choice
         if Choice == 2                ;Exit on Cancel.
            CleanUp()
         endif
      endwhile
      fgets FID_CONTROL DateStamp      ;Get date stamp from Subject file.
         
      strfmt WriteChoice "%s	%s`r`n" GroupID DateStamp
                                       ;Format the entry for the temp file.
                                       
      fputs FID_FILELIST WriteChoice   ;Write the string to the temp file.
      fclose FID_CONTROL               ;Close the current Control file.
      findnext                         ;Find the next subject file.
   endwhile
   fclose FID_FILELIST
endproc


     
proc GetFileGroup

;*****************************************************************************
;*                                                                           *
;* GETFILEGROUP                                                              *
;* This procedure presents a user with a list of available files in the      *
;* current folder.                                                           *
;*                                                                           *
;* Calls: CleanUp, Subjects                                                  *
;* Called by: CleanUp, Subjects, DeleteFileGroup, ListFolders                *
;* Modifies globals: ChoiceFile, Folder, CurrentGroup, ChoosingGroup,        *
;*                   NineLoop                                                *
;*                                                                           *
;*****************************************************************************

   integer Event                       ;Holder for dialog events.
   integer Count                       ;Number of groups available.
   integer Choice                      ;User choice from message dialog.
   integer Selected                    ;Number of groups selected.
   integer DlgID                       ;Windows ID of dialog box.
   string CurrentList                  ;File with available file groups.
   string Message                      ;Text line for message dialog.
   string Title                        ;Title of main dialog box.
   
   strfmt CurrentList "%s`\LISTFILE" Folder
                                       ;Get the path to the LISTFILE file.
   strfmt ChoiceFile "%s`\CHCEFILE" Folder
                                       ;Get the path to CHCEFILE

   
   fopen FID_CHCEFILE ChoiceFile CREATE
   while FAILURE
      strfmt Message "Unable to open file:`r`n`r`n%s" ChoiceFile
      sdlgmsgbox "File Error!" Message EXCLAMATION RETRYCANCEL Choice
      if Choice == 2
         CleanUp()
      endif
      fopen FID_CHCEFILE ChoiceFile CREATE
   endwhile
   fclose FID_CHCEFILE
   
   strfmt Title "PROCOMM PLUS Off-line News Reader - %s" CurrentGroup
   ChoosingGroup = 1
   while ChoosingGroup
      dialogbox 9 137 72 274 237 7 Title
                                       ;Simple dialog that allows user to choose
                                       ; between available file groups.
         flistbox 1 25 20 221 188 CurrentList MULTIPLE ChoiceFile HSCROLL SORT
         pushbutton 2 48 218 40 14 "OK" DEFAULT
         pushbutton 3 188 218 40 14 "Delete" 
         pushbutton 4 118 218 40 14 "Cancel"
      enddialog
      dlgwin 9 DlgID
      NineLoop = 1
      while NineLoop
         dlgevent 9 Event
         switch Event
            case 1                     ;If the FLISTBOX was accessed, adjust
                                       ; the relevant controls (ie, disable the
                                       ; OK button on multiple selections).
               dlglist 9 1 ITEMCOUNT Count Selected
               if Selected > 1
                  disable DLGCTRL 9 2
                  enable DLGCTRL 9 3
               elseif Selected == 0
                  disable DLGCTRL 9 2
                  disable DLGCTRL 9 3
               else
                  enable DLGCTRL 9 2
                  enable DLGCTRL 9 3
               endif
            endcase
            case 2                     ;If OK is selected, make sure that there
                                       ; actually was an item selected, then
                                       ; save the selection to file and 
                                       ; call the next procedure.
               dlglist 9 1 ITEMCOUNT Count Selected
               if Selected > 0
                  dlgdestroy 9 OK
                  NineLoop = 0
                  Subjects()
               endif
            endcase
            case 3                     ;If DELETE was chosen, save the list
                                       ; of choices, then call procedure to
                                       ; delete the chosen file groups.
               dlgsave 9 1
               DeleteFileGroup()
               ListFolders()
               dlgupdate 9 1           ;Update the listbox after the groups
                                       ; have been deleted, and make sure
                                       ; the proper controls are active.
               dlglist 9 1 ITEMCOUNT Count Selected
               if ((Selected == 0) || (Count == 0))
                  disable DLGCTRL 9 2
                  disable DLGCTRL 9 3
               elseif Selected > 1
                  disable DLGCTRL 9 2
                  enable DLGCTRL 9 3
               else 
                  enable DLGCTRL 9 2
                  enable DLGCTRL 9 3
               endif
            endcase
            case 4
               dlgdestroy 9 CANCEL     ;Exit on CANCEL
               NineLoop = 0
               ChoosingGroup = 0
            endcase
            default
               winexists DlgID         ;Exit if X was chosen under Win95.
               if FAILURE
                  NineLoop = 0
                  ChoosingGroup = 0
               endif
            endcase
         endswitch
      endwhile
   endwhile
endproc



proc DeleteFileGroup

;*****************************************************************************
;*                                                                           *
;* DELETEFILEGROUP                                                           *
;* This procedure deletes the file-groups that were selected in the          *
;* GetFileGroup procedure when the Delete key was chosen.                    *
;*                                                                           *
;* Calls: CleanUp                                                            *
;* Called by: GetFileGroup                                                   *
;* Modifies globals: ChoiceFile, Folder, CurrentFolder, SubjectFile,         *
;*                   ControlFile                                             *
;*                                                                           *
;*****************************************************************************


   string GroupID                      ;File-group to be deleted.
   string Message                      ;Text field for message dialogs.
   string ArticleFile                  ;Article file for file-group.
   string ReadChoice                   ;String read from Choice file.
   integer DeleteDone                  ;FEOF test on ChoiceFile
   integer Choice                      ;User choice in message dialogs.

   strfmt ChoiceFile "%s`\CHCEFILE" Folder
                                       ;Get the path to CHCEFILE
   fopen FID_CHCEFILE ChoiceFile READWRITE       
                                       ;Try to open the choice file until the
                                       ; file opens or the user exits.
   while FAILURE
      Choice = 8
      strfmt Message "Unable to open file:`r`n`r`n%s" ChoiceFile
      sdlgmsgbox "File Error!" Message EXCLAMATION RETRYCANCEL Choice
      if Choice != 4
         CleanUp()
      endif
      fopen FID_CHCEFILE ChoiceFile READWRITE
   endwhile
   
   feof FID_CHCEFILE DeleteDone        ;Check for eof on the choice file.
   while ! DeleteDone                  ;Loop until eof on the choice file.
      fgets FID_CHCEFILE ReadChoice    ;Get the first choice.
      strtok GroupID ReadChoice "	"
                                       ;Pull out the current group id.
      strfmt ArticleFile "%s`\%s.%s" Folder CurrentFolder GroupID
                                       ;Get the names of the files associated
                                       ; with the current file group.
      strfmt SubjectFile "%s.SUB" GroupID
      strfmt ControlFile "%s.CTL" GroupID
      
      delfile ArticleFile              ;Delete the relevant files.
      delfile SubjectFile
      delfile ControlFile
      
      feof FID_CHCEFILE DeleteDone
   endwhile
   
   fclose FID_CHCEFILE
   fopen FID_CHCEFILE ChoiceFile CREATE          
                                       ;Wipe the choice file (no choices will
                                       ; be selected on return to caller).
   while FAILURE
      strfmt Message "Unable to open file:`r`n`r`n%s" ChoiceFile
      sdlgmsgbox "File Error!" Message EXCLAMATION RETRYCANCEL Choice
      if Choice == 2
         CleanUp()
      endif
      fopen FID_CHCEFILE ChoiceFile CREATE
   endwhile
   fclose FID_CHCEFILE
endproc



proc Subjects

;*****************************************************************************
;*                                                                           *
;* SUBJECTS                                                                  *
;* This procedure presents a user with a list of available articles,         *
;* complete with subject file, for the current folder.                       *
;*                                                                           *
;* Calls: CleanUp, Results, MultiSave                                        *
;* Called by: GetFileGroup                                                   *
;* Modifies globals: Folder, FileChoice, FileGroup, SubjectFile, ChoiceGroup,*
;*                   StillBrowsing, CurrentGroup, TenLoop, TwoLoop, NineLoop,*
;*                   Browsing, ChoosingGroup                                 *
;*                                                                           *
;*****************************************************************************

   long SubjectOffset                  ;Position of first subject line in 
                                       ; Subject file.
   string ChoiceFile                   ;File for selected file group.
   string Message                      ;Text line from message dialog.
   string DateStamp                    ;Stamp from Subject file.
   string ReadChoice                   ;String read from the ChoiceGroup file.
   integer Choice                      ;User choice from message dialog.
   integer HasArticles                 ;Result of string comparison.
   integer Event                       ;Dialog event holder.
   integer Lines                       ;Number of items in list.
   integer Selected                    ;Number of selected list items.

   integer DlgID                       ;Windows ID of dialog box.
   integer ListIndex                   ;Item-number of the selected subject.
   
   strfmt ChoiceFile "%s`\CHCEFILE" Folder
                                       ;Format full path to CHCEFILE.
   fopen FID_CHCEFILE ChoiceFile READWRITE       ;Open CHCEFILE.
   while FAILURE                       ;If the FOPEN command failed, prompt user
                                       ; to retry or cancel.  Loop until user
                                       ; exits or the file opens.
      strfmt Message "Unable to open file:`r`n`r`n%s" ChoiceFile
      sdlgmsgbox "File Error!" Message EXCLAMATION RETRYCANCEL Choice
      if Choice == 2                   ;Exit on Cancel.
         CleanUp()
      endif
      fopen FID_CHCEFILE ChoiceFile READWRITE
   endwhile
   fgets FID_CHCEFILE FileChoice       ;Grab the choice from CHCEFILE.
   fclose FID_CHCEFILE                 ;Finished with this file, close it.
   
   strtok FileGroup FileChoice "	"
                                       ;Pull the numerical group index out of 
                                       ; the string.
   strfmt SubjectFile "%s`\%s.SUB" Folder FileGroup
                                       ;Format full path to Subject file.
   
   fopen FID_SUBJECT SubjectFile READWRITE      
                                       ;Open the subject file.
   while FAILURE                       ;If the FOPEN command failed, prompt user
                                       ; to retry or cancel.  Loop until user
                                       ; exits or the file opens.
      strfmt Message "Unable to open file:`r`n`r`n%s" SubjectFile
      sdlgmsgbox "File Error!" Message EXCLAMATION RETRYCANCEL Choice
      if Choice == 2                   ;Exit on Cancel.
         CleanUp()
      endif
      fopen FID_SUBJECT SubjectFile READWRITE
   endwhile
   fgets FID_SUBJECT DateStamp         ;Pull the date stamp out of the file.
   ftell FID_SUBJECT SubjectOffset     ;Get start position of first Subject:.
   fclose FID_SUBJECT                  ;Close the file so that the dialog 
                                       ; can access it.
   
   strfmt ChoiceGroup "%s`\SUBLIST" Folder
   fopen FID_SUBLIST ChoiceGroup CREATE         
                                       ;Open the choice file.
   while FAILURE                       ;If the FOPEN command failed, prompt user
                                       ; to retry or cancel.  Loop until user
                                       ; exits or the file opens.
      strfmt Message "Unable to open file:`r`n`r`n%s" ChoiceGroup
      sdlgmsgbox "File Error!" Message EXCLAMATION RETRYCANCEL Choice
      if Choice == 2                   ;Exit on Cancel.
         CleanUp()
      endif
      fopen FID_SUBLIST ChoiceGroup CREATE
   endwhile
   fclose FID_SUBLIST                  ;Close the file once opened.  This 
                                       ; routine assures that the choice file
                                       ; exists and is empty.
                                   
   StillBrowsing = 1                   ;Initialize loop.
   while StillBrowsing                 ;Loop until user exits.
      dialogbox 10 70 36 329 255 3 "PROCOMM PLUS v3.0 for Windows Off-line News Reader "
         flistbox 1 21 36 287 185 SubjectFile offset SubjectOffset multiple ChoiceGroup hscroll
         pushbutton 2 35 232 40 14 "OK" default
         pushbutton 3 184 232 40 14 "Cancel" cancel
         pushbutton 7 105 232 40 15 "SaveAs"
         text 5 25 4 277 13 CurrentGroup left
         text 6 26 19 276 11 DateStamp left
         pushbutton 8 255 232 40 14 "Exit"
      enddialog
      
      dlgwin 10 DlgID                  ;Get the Window's ID for this dialog.
      dlglist 10 1 ITEMCOUNT Lines Selected
                                       ;See how many items are selected in the
                                       ; the list.
      if Selected == 0                 ;If none are selected,
         disable DLGCTRL 10 2          ; disable the OK button,
         disable DLGCTRL 10 7          ; disable the SaveAs button,
         disable DLGCTRL 10 4          ; disable the Decode button.
      endif      
      TenLoop = 1
      while TenLoop                    ;Loop until choice exits.
         dlgevent 10 Event             ;Get the last dialog event.
         switch Event
            case 1                     ;If the listbox was accessed, disable
                                       ; the OK button if more than one
                                       ; choice is highlighted.
               dlglist 10 1 ITEMCOUNT Lines Selected
                                       ;See how many items are now selected.
               if Selected > 1         ;If more than 1 item is selected,
                  disable DLGCTRL 10 2 ; disable the OK button and enable
                  enable DLGCTRL 10 7  ; the SaveAs and Decode buttons.
                  enable DLGCTRL 10 4
               elseif Selected == 0    ;If nothing is selected,
                  disable DLGCTRL 10 2 ; disable all but Cancel.
                  disable DLGCTRL 10 7
                  disable DLGCTRL 10 4
               else                    ;If one item is selected,
                  enable DLGCTRL 10 2  ; enable all choices.
                  enable DLGCTRL 10 7
                  enable DLGCTRL 10 4
               endif
            endcase
            case 2                     ;if the OK button is pushed,
               dlgsave 10 1
               fopen FID_SUBLIST ChoiceGroup READ TEXT
                                       ;Open the file containing the choice that
                                       ; was made.
               while FAILURE
                  strfmt Message "Unable to open file:`r`n`r`n%s" ChoiceGroup
                  sdlgmsgbox "File Error!" Message EXCLAMATION RETRYCANCEL\
                  Choice
                  if Choice == 2
                     CleanUp()
                  endif
                  fopen FID_SUBLIST ChoiceGroup READWRITE
               endwhile
               fgets FID_SUBLIST ReadChoice     
                                       ;Read the user's choice.
               fclose FID_SUBLIST      ;Close the choice file.
               strfind ReadChoice "No New Articles" HasArticles
                                       ;See if the No New Articles message
                                       ; is there.
               if HasArticles != -1    ;If there are no new articles,
                  TenLoop = 0          ; exit back to the GetFileGroup routine.
                  StillBrowsing = 0
                  dlgdestroy 10 CANCEL
               else                    ;If articles are present,
                  dlglist 10 1 ITEMFIND ReadChoice ListIndex
                                       ;Find out which subject was chosen.
                  dlgdestroy 10 CANCEL ;Get rid of this dialog box.
                  TenLoop = 0          ;Exit this dlgevent loop.
                  Results(ListIndex)   ;Read the chosen article.
               endif
            endcase
            case 3                     
               TenLoop = 0              ;Exit on Cancel.
               StillBrowsing = 0
            endcase
            case 5
            case 6
            endcase
            case 7
               MultiSave()
            endcase
            case 8
               dlgdestroy 10 CANCEL
               TwoLoop = 0
               NineLoop = 0
               TenLoop = 0
               Browsing = 0
               ChoosingGroup = 0
               StillBrowsing = 0
            endcase
            default                    ;If no main control was accessed,
               winexists DlgID         ;See if the dialog box still exists.
               if FAILURE              ;If it doesn't, then the X in the 
                                       ; corner of all Windows 95 dialogs has
                                       ; been pushed, and this loop needs to
                  TenLoop = 0          ; be exited.
                  StillBrowsing = 0
               endif
            endcase
         endswitch
      endwhile
   endwhile
endproc



proc MultiSave

;*****************************************************************************
;*                                                                           *
;* MULTISAVE                                                                 *
;* This procedure saves the files chosen in the SUBJECTS dialog box.         *
;*                                                                           *
;* Calls: CleanUp                                                            *
;* Called by: Subjects                                                       *
;* Modifies globals: Folder, CurrentFolder, FileGroup, ChoiceGroup,          *
;*                   ControlFile                                             *
;*                                                                           *
;*****************************************************************************

   long ArticleStart                   ;Start of the current article.
   long TextStart                      ;Start of the text body in the 
                                       ; current article.
   long StartIndex                     ;Control file offset.
   string ArticleFile                  ;Full path to article file.
   string ControlString                ;String read from the control file.
   string ControlField[4]              ;Array for STRTOK operation.
   string SaveArticle                  ;Path to save file.
   string Message                      ;Text field in message dialogs.
   string ReadSubject                  ;String read from choice file.
   string ReadHeader                   ;String for reading article headers.
   string ReadArticle                  ;String for reading article body.
   string DnloadPath                   ;Download path.
   string SaveStatus                   ;Text field in 'saving' dialog.
   integer SaveThem                    ;TRUE when safe to save data.
   integer FieldLoop                   ;Loop for STRTOK operation.
   integer Saving                      ;Loop for writing article body to file.
   integer FindingText                 ;Loop for finding start of article body.
   integer EndOfText                   ;Tests for end of article body.
   integer Choice                      ;User choice in message dialogs.
   integer ListIndex                   ;Current control record index.
   integer SavingLoop                  ;Loops through all user choices.
   integer SaveHeaders                 ;TRUE if headers are to be saved.
   integer EndOfSave                   ;Tests for end of choice file.
   integer NotFound                    ;Zero when search object is found.
   
   strfmt ArticleFile "%s`\%s.%s" Folder CurrentFolder FileGroup
                                       ;Format the full path to article file.
   SaveThem = 0                        ;Initialize coninuation to NO.
   dlgsave 10 1                        ;Save the current list of choices.
   fetch dnldpath DnloadPath           ;Get the current dnload path from setup.
   addfilename DnloadPath "*.TXT"      ;Format complete filespec.
   sdlgfopen "Save As" DnloadPath SINGLE SaveArticle
                                       ;Ask the user for name of save file.
   if SUCCESS                          ;If the user selects OK,
      if isfile SaveArticle            ;If the file already exists,
         strfmt Message "The file `r`n`r`n%s`r`n`r`nalready exists.  Do you \
wish to overwrite?"                    ;Ask the user to overwrite.
         sdlgmsgbox "Save As" Message QUESTION YESNO Choice
                                       ;Exit if the choice is no, otherwise
         if Choice == 6                ; continue with the procedure.
            SaveThem = 1
         else
            SaveThem = 0
         endif
      else
         SaveThem = 1
      endif
                  
      fopen FID_SUBLIST ChoiceGroup READ TEXT
                                       ;Open the file containing the choices
                                       ; that were made.
      while FAILURE
         Choice = 8
         strfmt Message "Unable to open file:`r`n`r`n%s" ChoiceGroup
         sdlgmsgbox "File Error!" Message EXCLAMATION RETRYCANCEL\
         Choice
         if Choice != 4
            CleanUp()
         endif
         fopen FID_SUBLIST ChoiceGroup READWRITE
      endwhile 
                  
      if SaveThem                      ;If the CANCEL button was not chosen.
      
         strfmt Message "Do you wish to save article headers?"
         sdlgmsgbox "Save As" Message QUESTION YESNO Choice
                                       ;Ask user if headers are desired.
         if Choice == 6
            SaveHeaders = 1
         else
            SaveHeaders = 0
         endif
         
         strfmt SaveStatus "Saving file %s" SaveArticle
         dialogbox 61 190 140 198 44 31 "Saving....."
            text 1 8 12 176 20 SaveStatus LEFT
         enddialog
      
         fopen FID_SAVEFILE SaveArticle CREATE
                                       ;Open the file for saving the article.
         while FAILURE
            Choice = 8
            strfmt Message "Unable to open file:`r`n`r`n%s"
            sdlgmsgbox "File Error!" Message EXCLAMATION RETRYCANCEL Choice
            if Choice != 4
               CleanUp()
            endif
            fopen FID_SAVEFILE SaveArticle CREATE
         endwhile
         fclose FID_SAVEFILE           ;The file exists and is empty.  Close it.
         
         fopen FID_SAVEFILE SaveArticle APPEND	
                                       ;Re-open the file in APPEND mode.
         while FAILURE
            Choice = 8
            strfmt Message "Unable to open file:`r`n`r`n%s"
            sdlgmsgbox "File Error!" Message EXCLAMATION RETRYCANCEL Choice
            if Choice != 4
               CleanUp()
            endif
            fopen FID_SAVEFILE SaveArticle APPEND
         endwhile
         
         SavingLoop = 1                ;Initialize the copy loop.
         strfmt ControlFile "%s`\%s.CTL" Folder FileGroup
                                       ;Format full path to Control file.
         while SavingLoop
                                     
            fgets FID_SUBLIST ReadSubject       
                                       ;Pull out the current article string.
            dlglist 10 1 ITEMFIND ReadSubject ListIndex
                                       ;Find out which subject was chosen.
            fopen FID_CONTROL ControlFile READWRITE    
                                       ;Open the ControlFile.
            while FAILURE              ;If the FOPEN command fails, prompt user
                                       ; to try again or cancel.  Loop until
                                       ; file opens or user exits.
               Choice = 8
               strfmt Message "Unable to open file:`r`n`r`n%s" ControlFile
               sdlgmsgbox "File Error!" Message EXCLAMATION RETRYCANCEL Choice
               if Choice != 4          ;Exit on Cancel
                  CleanUp()
               endif
               fopen FID_CONTROL ControlFile READWRITE
            endwhile
   
            StartIndex = ListIndex     ;Get the control reference.
            StartIndex *= 30           ;Times 30 = beginning of control entry.
            fseek FID_CONTROL StartIndex 0
                                       ;Seek to the beginning of control entry.
            fgets FID_CONTROL ControlString
                                       ;Get the control entry.
            fclose FID_CONTROL         ;Close the control file.
   
            for FieldLoop = 0 upto 3   ;Parse the entry into tokens.
               strtok ControlField[FieldLoop] ControlString ""
            endfor
                         
            fopen FID_ARTICLE ArticleFile READWRITE  
                                       ;Open the article file.
            while FAILURE              ;If the FOPEN command fails, prompt user
                                       ; to try again or cancel.  Loop until
                                       ; file opens or user exits.
               Choice = 8
               strfmt Message "Unable to open file:`r`n`r`n%s" ArticleFile
               sdlgmsgbox "File Error!" Message EXCLAMATION RETRYCANCEL Choice
               if Choice != 4
                  CleanUp()
               endif
               fopen FID_ARTICLE ArticleFile READWRITE
            endwhile
   
            atol ControlField[1] ArticleStart 
                                       ;Start of article = long variable.
            fseek FID_ARTICLE ArticleStart 0              
                                       ;Move pointer to start of article.
            FindingText = 1            ;Search for first line of text in the
                                       ; article.
            while FindingText          ;Loop until the text if found.
               fgets FID_ARTICLE ReadHeader      ;Grab the next line of header info.
               strnicmp ReadHeader "`r`n" 2 NotFound
                                       ;See if it's the Start of Text header.
               if NotFound == 0        ;If the body of the message is found,
                  ftell FID_ARTICLE TextStart    
                                       ;Get the position of the file pointer.
                  FindingText = 0      ;Search is over, exit this loop.
               endif
            endwhile
            Saving = 1                 ;Initialize loop.
            if SaveHeaders == 1        ;If headers are wanted,
               fseek FID_ARTICLE ArticleStart 0
                                       ;Start copying at start of article.
            else                       ;If headers are not wanted,
               fseek FID_ARTICLE TextStart 0
                                       ;Start copying at start of text.
            endif
            while Saving               ;Loop until end of article.
               fgets FID_ARTICLE ReadArticle
                                       ;Grab a string from the article file.
               strnicmp ReadArticle ".`r`n" 3 EndOfText
                                       ;See if it's the last line of article.
               if EndOfText == 0       ;If it is the last line,
                  if SaveHeaders == 1  ;If headers are wanted,
                     fputs FID_SAVEFILE ReadArticle
                                       ;Put the period into the file.
                  endif
                  Saving = 0           ;Exit this loop.
               else                    ;If not last line or article,
                  fputs FID_SAVEFILE ReadArticle
                                       ;Write the line to save file.
               endif
            endwhile
            feof FID_SUBLIST EndOfSave ;See if end of list is reached.
            if EndOfSave
               SavingLoop = 0
            endif
         endwhile
         fclose FID_SAVEFILE
         dlgdestroy 61 CANCEL
      endif
      fclose FID_SUBLIST
   endif
endproc



proc Results

;*****************************************************************************
;*                                                                           *
;* RESULTS                                                                   *
;* This procedure merely opens an flist dialog box for easy browsing of the  *
;* results of this script.                                                   *
;*                                                                           *
;* Calls: CleanUp, NewArticle, RSetup, GroupReply, AuthorReply, SaveArticle  *
;* Called by: Subjects                                                       *
;* Modifies globals: Offline_INI, Folder, CurrentFolder, ControlFile,        *
;*                   ChoiceGroup, SubjectFile, CurrentGroup, TwoLoop,        *
;*                   NineLoop, TenLoop, Browsing, ChoosingGroup,             *
;*                   StillBrowsing                                           *
;*                                                                           *
;*****************************************************************************

param integer ListIndex                ;Index of control file entry.

   long EndControl                     ;Last entry in the control list.
   long CountControl                   ;Current Control entry number.
   long StartIndex
   long ArticleStart                   ;Start of the current article.
   long ArticleLength                  ;Length of text + headers.
   long TextStart                      ;Start of text of article.
   long TextEnd                        ;End of this article.
   long LongBlockCount                 ;Number of 128-byte blocks in article.
   long DisplayLength                  ;Length of file to display in dialog.
   long LengthControl                  ;Length of the control file.
   string ControlString                ;String read from the Control file.
   string ReadSubject                  ;Subject line from the choice-file.
   string PassSubject                  ;String to pass to the FINDCTRL function.
   string OnlySubject                  ;Subject pulled from ReadSubject.
   string ArticleFile                  ;Full path to the current article file.
   string ArticleDate                  ;Date stamp for the article file.
   string Article                      ;Current article number.
   string ReadHeader                   ;Header read from the current article.
   string ChoiceFile                   ;Full path to the file-group choice-file.
   string From                         ;From: line from article file.
   string Message                      ;Text line for message dialogs.
   string FileChoice                   ;String read from ChoiceFile.
   string Extension                    ;Index pulled from FileChoice.
   string ControlField[4]              ;Fields of control entries.
   string SaveFile                     ;Path and name of save file.
   string DnloadPath                   ;Path to the dnload directory.
   integer FindingFrom                 ;Loop to look for From: line.
   integer FindingText                 ;Integer to search for start of text.
   integer FindingDate                 ;Loop to find the Date header.
   integer DateLength                  ;Length of the actual date field.
   integer FieldLoop                   ;Control loop for STRTOK operations.
   integer FromLength                  ;Length of the From: line.
   integer Choice                      ;User choice from message dialogs.
   integer NotFound                    ;String comparisons.
   integer ReadMode                    ;TRUE when still reading article.
   integer Event                       ;User choice at main dialog box.
   integer True                        ;Dialog event loop.
   integer DlgID                       ;Windows ID of dialog box.
   
   strfmt Offline_INI "%s`\OFFLINE.INI" $PWLOCALPATH
   strfmt ChoiceFile "%s`\CHCEFILE" Folder
                                       ;Get the full path to CHCEFILE.
   fopen FID_CHCEFILE ChoiceFile READWRITE       
                                       ;Open ChoiceFile.
   while FAILURE                       ;If the FOPEN command fails, prompt user
                                       ; to try again or cancel.  Loop until
                                       ; file opens or user exits.
      strfmt Message "Unable to open file:`r`n`r`n%s" ChoiceFile
      sdlgmsgbox "File Error!" Message EXCLAMATION RETRYCANCEL Choice
      if Choice == 2                   ;Exit on Cancel.
         CleanUp()
      endif
      fopen FID_CHCEFILE ChoiceFile READWRITE
   endwhile
   fgets FID_CHCEFILE FileChoice       ;Get file group identifier.
   fclose FID_CHCEFILE                 ;Nothing else needed from this file.
   strtok Extension FileChoice "	"
                                       ;Pull the folder index from the string.
   strfmt ArticleFile "%s`\%s.%s" Folder CurrentFolder Extension
                                       ;Format full path to Article file.
   strfmt ControlFile "%s`\%s.CTL" Folder Extension
                                       ;Format full path to Control file.

   fopen FID_SUBLIST ChoiceGroup READ TEXT      
                                       ;Open the subject choice-file.
   while FAILURE                       ;If the FOPEN command fails, prompt user
                                       ; to try again or cancel.  Loop until
                                       ; file opens or user exits.
      strfmt Message "Unable to open file:`r`n`r`n%s" SubjectFile
      sdlgmsgbox "File Error!" Message EXCLAMATION RETRYCANCEL Choice
      if Choice == 2
         CleanUp()
      endif
      fopen FID_SUBLIST ChoiceGroup READ TEXT
   endwhile
   
   fgets FID_SUBLIST ReadSubject       ;Pull out the current article string.
   PassSubject = ReadSubject           ;Hold on to the whole subject string.
   fclose FID_SUBLIST                  ;No longer need this file open.
   strtok Article ReadSubject "	"      ;Parse string into number and text.
   strtok OnlySubject ReadSubject "	"
                                       ;Knock off the left-over "tab".
   fileget ControlFile SIZE LengthControl
                                       ;Get the length of the control file.
   EndControl = LengthControl / 30     ;See how many entries total in Control.
   EndControl -= 1                     ;Make EndControl zero-referenced.
   fopen FID_CONTROL ControlFile READWRITE      
                                       ;Open the ControlFile.
   while FAILURE                       ;If the FOPEN command fails, prompt user
                                       ; to try again or cancel.  Loop until
                                       ; file opens or user exits.
      strfmt Message "Unable to open file:`r`n`r`n%s" ControlFile
      sdlgmsgbox "File Error!" Message EXCLAMATION RETRYCANCEL Choice
      if Choice == 2
         CleanUp()
      endif
      fopen FID_CONTROL ControlFile READWRITE
   endwhile
   
   StartIndex = ListIndex              ;Convert ListIndex to Long format.
   CountControl = StartIndex           ;Keep the long reference.
   StartIndex *= 30                    ;Calculate start of control entry.
   fseek FID_CONTROL StartIndex 0      ;Find the control entry.
   fgets FID_CONTROL ControlString     ;Read the control entry.
   
   for FieldLoop = 0 upto 3            ;Parse the entry into tokens.
      strtok ControlField[FieldLoop] ControlString ""
   endfor
                         
   atol ControlField[2] LongBlockCount 
                                       ;Number of 128-byte blocks = longvar.
   ArticleLength = LongBlockCount * 128    
                                       ;Length of article = number of 128-byte
                                       ; blocks * 128.
   
   fopen FID_ARTICLE ArticleFile READ TEXT       
                                       ;Open the article file.
   while FAILURE                       ;If the FOPEN command fails, prompt user
                                       ; to try again or cancel.  Loop until
                                       ; file opens or user exits.
      strfmt Message "Unable to open file:`r`n`r`n%s" ArticleFile
      sdlgmsgbox "File Error!" Message EXCLAMATION RETRYCANCEL Choice
      if Choice == 2
         CleanUp()
      endif
      fopen FID_ARTICLE ArticleFile READ TEXT
   endwhile
   
   atol ControlField[1] ArticleStart   ;Start of article = long variable.
   fseek FID_ARTICLE ArticleStart 0    ;Move pointer to start of article.
   FindingFrom = 1                     ;Initialize search loop.
   while FindingFrom                   ;Loop while searching.
      fgets FID_ARTICLE ReadHeader     ;Grab the first header from the article.
      strnicmp ReadHeader "From:" 5 NotFound
                                       ;See if this is the FROM: header.
      if NotFound == 0                 ;If the header has been found,
         strlen ReadHeader FromLength  ;Get the length of the header string.
         FromLength -= 5               ;Reduce the length by "From:".
         substr From ReadHeader 5 FromLength
                                       ;Knock "From: " off of the string.
         FindingFrom = 0               ;Search is over, exit this loop.
      endif
   endwhile
   
   strreplace From "`r" ""
   strreplace From "`n" ""
   
   fseek FID_ARTICLE ArticleStart 0    ;Move pointer to start of article.
   FindingDate = 1                     ;Initialize search loop.
   while FindingDate                   ;Loop while searching.
      fgets FID_ARTICLE ReadHeader     ;Grab the first header from the article.
      strnicmp ReadHeader "Date:" 5 NotFound
                                       ;See if this is the FROM: header.
      if NotFound == 0                 ;If the header has been found,
         strlen ReadHeader DateLength  ;Get the length of the header string.
         FromLength -= 6               ;Reduce the length by "From: ".
         substr ArticleDate ReadHeader 5 DateLength
                                       ;Knock "From: " off of the string.
         FindingDate = 0               ;Search is over, exit this loop.
      endif
   endwhile
   
   FindingText = 1                     ;Search for first line of text in the
                                       ; article.
   while FindingText                   ;Loop until the text if found.
      fgets FID_ARTICLE ReadHeader     ;Grab the next line of header info.
      strnicmp ReadHeader "" 2 NotFound
                                       ;See if it's the Start of Text header.
      if NotFound == 0                 ;If the body of the message is found,
         ftell FID_ARTICLE TextStart   ;Get the position of the file pointer.
         TextEnd = ArticleStart + ArticleLength
                                       ;Get the position of the end of the text.
         DisplayLength = TextEnd - TextStart
                                       ;Total length to display to the user is
                                       ; the difference in the two.
         if DisplayLength > 17000
            usermsg "Body is too long!`r`n`Unable to display whole article!"
            DisplayLength = 17000
         endif
         FindingText = 0               ;Search is over, exit this loop.
      endif
   endwhile 
   fclose FID_ARTICLE
   ReadMode = 1                        ;Loop until user exits the reading box.
   while ReadMode   
      dialogbox 50 55 17 350 263 3 "PROCOMMM PLUS v3.0 Off-line News Reader"
         text 6 40 23 278 8 From LEFT
         text 5 9 23 30 8 "From:" LEFT
         text 3 9 12 32 8 "Subject:" LEFT
         text 4 41 12 278 8 OnlySubject LEFT
         text 1 9 1 28 8 "Article:" LEFT
         text 2 41 1 279 8 Article LEFT
         text 7 9 45 28 8 "Group:" LEFT
         text 8 41 45 279 8 CurrentGroup LEFT
         text 9 9 34 20 8 "Date:" LEFT
         text 10 40 34 183 8 ArticleDate LEFT
         ftext 11 5 61 340 170 ArticleFile offset TextStart length DisplayLength
         pushbutton 12 144 232 40 29 "Previous"
         pushbutton 13 185 232 40 29 "Next" DEFAULT
         pushbutton 14 253 233 91 14 "Reply to Group"
         pushbutton 15 253 247 91 14 "Reply to Author"
         pushbutton 16 50 240 40 14 "Save As"
         pushbutton 18 96 240 40 14 "Cancel" CANCEL
         pushbutton 19 5 240 40 14 "Exit"
      enddialog
      dlgwin 50 DlgID
      if EndControl == 0
         disable DLGCTRL 50 12         ;Disable the PREVIOUS and NEXT choices if
                                       ; the choice does not exist.
         disable DLGCTRL 50 13
      elseif CountControl == EndControl
         disable DLGCTRL 50 13
      elseif CountControl == 0
         disable DLGCTRL 50 12
      endif
      True = 1                         ;Initialize the dlgevent loop.
      while True                       ;Loop until user exits.
         dlgevent 50 Event             ;See which control was accessed.
         switch Event
            case 1
            case 2
            case 3
            case 4
            case 5
            case 6
            case 7
            case 8
            case 9
            case 10
            case 11
            endcase
            case 12
               CountControl -= 1       ;Go to the previous Control entry.
               if CountControl >= 0
                  NewArticle(&Extension, &CountControl, &From, &OnlySubject, \
&Article, &TextStart, &DisplayLength, &ArticleDate, ArticleFile)
                  dlgupdate 50 1 11
                  if CountControl == 0 
                     disable DLGCTRL 50 12
                     enable DLGCTRL 50 13
                  else
                     enable DLGCTRL 50 13
                     enable DLGCTRL 50 12
                  endif
               endif
            endcase
            case 13
               CountControl += 1       ;Go to the next Control entry.
               if CountControl <= EndControl
                  NewArticle(&Extension, &CountControl, &From, &OnlySubject, \
&Article, &TextStart, &DisplayLength, &ArticleDate, ArticleFile)
                  dlgupdate 50 1 11
                  if CountControl == EndControl
                     disable DLGCTRL 50 13
                     enable DLGCTRL 50 12
                  else
                     enable DLGCTRL 50 12
                     enable DLGCTRL 50 13
                  endif
               endif
            endcase
            case 14
               dlgdestroy 50 CANCEL
               True = 0
               isfile Offline_INI
               while FAILURE
                  RSetup()
                  isfile Offline_INI
               endwhile
               
               GroupReply(Extension, From, OnlySubject, TextStart, ArticleFile,\
               ArticleStart)
            endcase
            case 15
               dlgdestroy 50 CANCEL
               True = 0
               isfile Offline_INI
               while FAILURE
                  RSetup()
                  isfile Offline_INI
               endwhile
               
               AuthorReply(Extension, From, OnlySubject, TextStart, ArticleFile,\
               ArticleStart)
            endcase
            case 16
               fetch dnldpath DnloadPath
               addfilename DnloadPath "*.TXT"
               sdlgfopen "Save As" DnloadPath SINGLE SaveFile
               if SUCCESS
                  SaveArticle(ArticleFile, ArticleStart, TextStart, SaveFile)
               endif
            endcase
            case 17
               usermsg "Decoding features not yet added!"
            endcase
            case 18                    ;Exit on Cancel.
               True = 0
               ReadMode = 0
            endcase
            case 19
               dlgdestroy 50 CANCEL
               TwoLoop = 0
               NineLoop = 0
               TenLoop = 0
               Browsing = 0
               ChoosingGroup = 0
               StillBrowsing = 0
               True = 0
               ReadMode = 0
            endcase
            default
               winexists DlgID
               if FAILURE
                  True = 0
                  ReadMode = 0
               endif
            endcase
         endswitch
      endwhile
   endwhile
endproc



proc NewArticle

;*****************************************************************************
;*                                                                           *
;* NEWARTICLE                                                                *
;* This procedure refreshes the dialog box in RESULTS whenever the Next or   *
;* Previous buttons are pushed, as well as initializing the dialog for the   *
;* article chosen by subject in SUBJECTS.                                    *
;*                                                                           *
;* Calls: CleanUp                                                            *
;* Called by: Results                                                        *
;* Modifies globals: ControlFile, Folder, SubjectFile, FileGroup, ChoiceGroup*
;*                                                                           *
;*****************************************************************************

param string Extension                 ;ID of the current file group.
param long CountControl                ;Id of the current control entry.
param string From                      ;Source of the article.
param string ReadSubject               ;Current subject header.
param string Article                   ;Current article number.
param long TextStart                   ;Start of text for current article.
param long DisplayLength               ;Length of current article for display.
param string ArticleDate               ;Date of the article.
param string ArticleFile               ;Filespec of the article file.
   
   long ControlOffset                  ;Offset jump in Control file.
   long ArticlePointer                 ;Article file pointer position.
   long ArticleStart                   ;Position of new article.
   long LongBlockCount                 ;Number of 128-byte blocks in article.
   long ArticleLength                  ;Total length of new article.
   long TextEnd                        ;End of the text of the article.
   long SubjectStart                   ;Start of the current subject line.
   long ArticleOffset                  ;Jump offset for article file.
   string ControlField[4]              ;Array to hold Control entry tokens.
   string ControlString                ;Entry read from the control file.
   string ReadHeader                   ;Header read from the article.
   string Message                      ;Text field of message dialogs.
   integer FieldLoop                   ;Loop controller for STRTOK operation.
   integer FromLength                  ;Length of the From: header.
   integer FindingDate                 ;Loop to find Date: header.
   integer DateLength                  ;Length of the Date: field.
   integer Choice                      ;User choice at message dialogs.
   integer FindingFrom                 ;Loop controller for reading headers.
   integer FindingText                 ;Loop controller for reading headers.
   integer LengthSubject               ;Length of the Subject: line.
   integer NotFound                    ;True while still looking for entry.
 
   strfmt ControlFile "%s`\%s.CTL" Folder Extension
                                       ;Format full path to Control file.
   fopen FID_CONTROL ControlFile READWRITE      
                                       ;Open the ControlFile.
   while FAILURE                       ;If the FOPEN command fails, prompt user
                                       ; to try again or cancel.  Loop until
                                       ; file opens or user exits.
      strfmt Message "Unable to open file:`r`n`r`n%s" ControlFile
      sdlgmsgbox "File Error!" Message EXCLAMATION RETRYCANCEL Choice
      if Choice == 2
         CleanUp()
      endif
      fopen FID_SUBLIST ControlFile READWRITE
   endwhile
   
   fopen FID_ARTICLE ArticleFile READWRITE       
                                       ;Open the article file.
   while FAILURE                       ;If the FOPEN command fails, prompt user
                                       ; to try again or cancel.  Loop until
                                       ; file opens or user exits.
      strfmt Message "Unable to open file:`r`n`r`n%s" ArticleFile
      sdlgmsgbox "File Error!" Message EXCLAMATION RETRYCANCEL Choice
      if Choice == 2
         CleanUp()
      endif
      fopen FID_ARTICLE ArticleFile READWRITE
   endwhile
   
   ControlOffset = CountControl * 30   ;Find position of control entry.
   fseek FID_CONTROL ControlOffset 0   ;Set file pointer to control entry.
   fgets FID_CONTROL ControlString     ;Get the current control entry.
   for FieldLoop = 0 upto 3            ;Parse the entry into tokens.
      strtok ControlField[FieldLoop] ControlString ""
   endfor
   fclose FID_CONTROL                  ;Close the control file.
   atol ControlField[2] LongBlockCount 
                                       ;Number of 128-byte blocks = longvar.
   ArticleLength = LongBlockCount * 128    
                                       ;Length of article = number of 128-byte
                                       ; blocks * 128.
   
   strfmt SubjectFile "%s`\%s.SUB" Folder FileGroup
                                       ;Format full path to Subject file.
   
   fopen FID_SUBJECT SubjectFile READWRITE      
                                       ;Open the subject file.
   while FAILURE                       ;If the FOPEN command failed, prompt user
                                       ; to retry or cancel.  Loop until user
                                       ; exits or the file opens.
      strfmt Message "Unable to open file:`r`n`r`n%s" SubjectFile
      sdlgmsgbox "File Error!" Message EXCLAMATION RETRYCANCEL Choice
      if Choice == 2                   ;Exit on Cancel.
         CleanUp()
      endif
      fopen FID_SUBJECT SubjectFile READWRITE
   endwhile
   
   fopen FID_SUBLIST ChoiceGroup CREATE         
                                       ;Open the subject choice-file.
   while FAILURE                       ;If the FOPEN command fails, prompt user
                                       ; to try again or cancel.  Loop until
                                       ; file opens or user exits.
      strfmt Message "Unable to open file:`r`n`r`n%s" SubjectFile
      sdlgmsgbox "File Error!" Message EXCLAMATION RETRYCANCEL Choice
      if Choice == 2
         CleanUp()
      endif
      fopen FID_SUBLIST ChoiceGroup CREATE
   endwhile
   
   SubjectStart = CountControl * 100   ;Get position of subject line.
   SubjectStart += 20                  ;Offset by length of date header.
   fseek FID_SUBJECT SubjectStart 0    ;Put file pointer to subject start.
   fgets FID_SUBJECT ReadSubject       ;Get the current subject line.
   fputs FID_SUBLIST ReadSubject       ;Put the line into the subject file.
   fclose FID_SUBLIST                  ;Close the subject file.
   strtok Article ReadSubject "	"      ;Reduce subject line to subject only.
   strlen ReadSubject LengthSubject    ;Get the length of the subject line.
   LengthSubject -= 1
   substr ReadSubject ReadSubject 1 LengthSubject
   fclose FID_SUBJECT
   
   atol ControlField[1] ArticleStart   ;Start of article = long variable.
   ftell FID_ARTICLE ArticlePointer    ;Get the current pointer position.
   ArticleOffset = ArticleStart - ArticlePointer
                                       ;See where the next article is 
                                       ; relative to the current position.
   fseek FID_ARTICLE ArticleOffset 1   ;Move pointer to start of article.
   FindingFrom = 1                     ;Initialize search loop.
   while FindingFrom                   ;Loop while searching.
      fgets FID_ARTICLE ReadHeader     ;Grab the first header from the article.
      strnicmp ReadHeader "From:" 5 NotFound
                                       ;See if this is the FROM: header.
      if NotFound == 0                 ;If the header has been found,
         strlen ReadHeader FromLength  ;Get the length of the header string.
         FromLength -= 5               ;Reduce the length by "From: ".
         substr From ReadHeader 5 FromLength
                                       ;Knock "From: " off of the string.
         FindingFrom = 0               ;Search is over, exit this loop.
      endif
   endwhile
   
   fseek FID_ARTICLE ArticleStart 0    ;Move pointer to start of article.
   FindingDate = 1                     ;Initialize search loop.
   while FindingDate                   ;Loop while searching.
      fgets FID_ARTICLE ReadHeader     ;Grab the first header from the article.
      strnicmp ReadHeader "Date:" 5 NotFound
                                       ;See if this is the FROM: header.
      if NotFound == 0                 ;If the header has been found,
         strlen ReadHeader DateLength  ;Get the length of the header string.
         FromLength -= 6               ;Reduce the length by "From: ".
         substr ArticleDate ReadHeader 5 DateLength
                                       ;Knock "From: " off of the string.
         FindingDate = 0               ;Search is over, exit this loop.
      endif
   endwhile
   
   FindingText = 1                     ;Search for first line of text in the
                                       ; article.
   while FindingText                   ;Loop until the text if found.
      fgets FID_ARTICLE ReadHeader     ;Grab the next line of header info.
      strnicmp ReadHeader "`r`n" 2 NotFound
                                       ;See if it's the Start of Text header.
      if NotFound == 0                 ;If the body of the message is found,
         ftell FID_ARTICLE TextStart   ;Get the position of the file pointer.
         TextEnd = ArticleStart + ArticleLength
                                       ;Get the position of the end of the text.
         DisplayLength = TextEnd - TextStart
                                       ;Total length to display to the user is
                                       ; the difference in the two.
         if DisplayLength > 17000
            usermsg "Body is too long!`r`nUnable to display entire article!"
            DisplayLength = 17000
         endif
         FindingText = 0               ;Search is over, exit this loop.
      endif
   endwhile
   fclose FID_ARTICLE 
endproc



proc SaveArticle

;*****************************************************************************
;*                                                                           *
;* SAVEARTICLE                                                               *
;* This procedure saves the article that was currently being displayed in    *
;* the Results dialog box.  Article can be saved with or without headers.    *
;*                                                                           *
;* Calls: CleanUp                                                            *
;* Called by: Results                                                        *
;* Modifies globals: <none>                                                  *
;*                                                                           *
;*****************************************************************************


param string ArticleFile               ;Filespec of article file.
param long ArticleStart                ;Start of article in article file.
param long TextStart                   ;Start of text in article file.
param string SaveArticle               ;Filespec of save file.
           
   string Message                      ;Text field in message dialogs.
   string ReadArticle                  ;String for file reads.
   string SaveStatus                   ;Status of 'saving' procedure.
   integer Choice                      ;User choice in message dialogs.
   integer SaveIt                      ;Save-status flag.
   integer Saving                      ;Main loop.
   integer EndOfText                   ;Flag for ending loop.
   
   SaveIt = 0                          ;Initialize save to NO.
   
   fopen FID_ARTICLE ArticleFile READ
                                       ;Open the article file.
   while FAILURE
      Choice = 8
      strfmt Message "Unable to open file:`r`n`r`n%s" ArticleFile
      sdlgmsgbox "File Error!" Message EXCLAMATION RETRYCANCEL Choice
      if Choice != 4
         CleanUp()
      endif
      fopen FID_ARTICLE ArticleFile READ
   endwhile
   
   Choice = 8
   strfmt Message "Do you wish to save the article with headers?"
   sdlgmsgbox "Save As" Message QUESTION YESNO Choice
                                       ;Ask user if headers need to be saved.
   if Choice == 6                      ;If yes, start saving at start of
                                       ; article index.
      fseek FID_ARTICLE ArticleStart 0
   else
      fseek FID_ARTICLE TextStart 0    ;If No, start saving at start of text
                                       ; index.
   endif
    
   if isfile SaveArticle               ;If the savefile already exists, ask
                                       ; user to overwrite.
      Choice = 8
      strfmt Message "The file `r`n`r`n%s`r`n`r`nalready exists, to you wish\
 to overwrite?" SaveArticle
      sdlgmsgbox "Save As" Message QUESTION YESNO Choice
      if Choice == 6
         SaveIt = 1
      endif
   else
      SaveIt = 1
   endif
   
   if SaveIt                           ;If nothing has interrupted this
                                       ; operation,
      
      strfmt SaveStatus "Saving file %s" SaveArticle
                                       ;Display a dialog box for the duration
                                       ; of the save operation, which can take
                                       ; some time.
      dialogbox 61 190 140 198 44 31 "Saving....."
         text 1 8 12 176 20 SaveStatus LEFT
      enddialog
      
      Saving = 1
      
      fopen FID_SAVEFILE SaveArticle CREATE
      while FAILURE
         Choice = 8
         strfmt Message "Unable to open file:`r`n`r`n%s" SaveArticle
         sdlgmsgbox "File Error!" Message EXCLAMATION RETRYCANCEL Choice
         if Choice != 4
            CleanUp()
         endif
         fopen FID_SAVEFILE SaveArticle CREATE
      endwhile
      
      while Saving
         fgets FID_ARTICLE ReadArticle ;The save routine merely copies lines of 
                                       ; text from one file to another.
         strnicmp ReadArticle ".`r`n" 3 EndOfText
         if EndOfText == 0
            fputs FID_SAVEFILE ReadArticle
            Saving = 0
         else
            fputs FID_SAVEFILE ReadArticle
         endif
      endwhile
      
      fclose FID_SAVEFILE
      dlgdestroy 61 CANCEL
   endif
   fclose FID_ARTICLE
endproc
         
      
 
proc AuthorReply

;*****************************************************************************
;*                                                                           *
;* AUTHORREPLY                                                               *
;* This procedure composes a reply to the author of the selected article.    *
;*                                                                           *
;* Calls:  CleanUp                                                           *
;* Called by:  Results                                                       *
;* Modifies globals: Offline_INI, NewsOut, CurrentGroup                      *
;*                                                                           *
;*****************************************************************************
     
   
param string FileGroup                 ;Three-digit file-group index.
param string From                      ;Contents of article's From: header.
param string OnlySubject               ;Contents of article's Subject: header.
param long TextStart                   ;Position in article file of text body.
param string ArticleFile               ;Name and path to article file.
param long ArticleStart                ;Beginning of article in file.

   string Message                      ;Text field for all message dialogs.
   string UserEMail                    ;E-Mail address from the INI file.
   string SaveReply                    ;Name of file to save reply in.
   string SigFile                      ;Signature file.
   string ReadSig                      ;Reads characters from signature file.
   string ReplyHeader                  ;First line of reply file.
   string FromHeader                   ;From: header for reply file.
   string DateHeader                   ;Date: header for reply file.
   string ToHeader                     ;To: header for reply file.
   string ReplyName                    ;User name.
   string SubjectHeader                ;Subject: header for reply file.
   string ReplyPrefix                  ;Prefix for quoted lines.
   string ReplySuffix                  ;Line that follows quoted lines.
   string ReadArticle                  ;String for reading from article file.
   string BodyTemp                     ;Temp file for reply body.
   string ReadTemp                     ;String for reading from temp file.
   string TimeZone                     ;Current time zone.
   string ReadHeader                   ;Reads headers from the article file.
   string Chronology                   ;Result of LTIMESTRING on $LTIME.
   string WeekDay                      ;Day of the week.
   integer Extension                   ;File extension for reply file.
   integer NotFound                    ;Search tracker.
   integer RTLength                    ;Length of the reply-to header.
   integer FindingReplyTo              ;Loop for finding Reply-To: header.
   integer Choice                      ;User choice in all message dialogs.
   integer EndOfText                   ;End-of-article test in article file.
   integer Searching                   ;Loop controller for file-name search.
   integer Saving                      ;Loop for copying article text to reply.
   integer QuoteLines                  ;Max number of article lines to quote.
   integer WritingReply                ;String to write to reply file.
   integer DoneCopy                    ;EOF test on data files.
   integer Event                       ;Event holder for DLGEVENT statement.
   integer DlgID                       ;Windows ID of this dialog box.
   integer StillThere                  ;TRUE if the dialog has not been closed
                                       ; with the Win95 X.
   integer LengthSubject               ;Length of the OnlySubject string.
   integer NewThread                   ;TRUE if OnlySubject does not start with 
                                       ; RE: .

   strreplace From "`r" ""
   strreplace From "`n" ""
   
   strfmt Offline_INI "%s`\OFFLINE.INI" $PWLOCALPATH
   
   profilerd Offline_INI "PostReply" "UserName" ReplyName
   profilerd Offline_INI "PostReply" "EMailAddress" UserEMail
                                       ;Get user's e-mail address from INI.
   profilerd Offline_INI "PostReply" "ReplyPrefix" ReplyHeader
   profilerd Offline_INI "PostReply" "ReplySuffix" ReplySuffix
   profilerd Offline_INI "PostReply" "QuoteLines" QuoteLines
   profilerd Offline_INI "PostReply" "QuotePrefix" ReplyPrefix
   profilerd Offline_INI "PostReply" "TimeZone" ZoneSelect
   profilerd Offline_INI "PostReply" "SigFile" SigFile
   
   strfmt FromHeader "%s <%s>`r`n" ReplyName UserEMail
   
   ltimestring $LTIME Chronology       ;Get the current date and time.
   strtok WeekDay Chronology ","
   substr WeekDay WeekDay 0 3

   switch ZoneSelect
      case 2
         TimeZone = "EST"
      endcase
      case 3
         TimeZone = "EDT"
      endcase
      case 4
         TimeZone = "CST"
      endcase
      case 5
         TimeZone = "CDT"
      endcase
      case 6
         TimeZone = "MST"
      endcase
      case 7
         TimeZone = "MDT"
      endcase
      case 8
         TimeZone = "PST"
      endcase
      case 9
         TimeZone = "PDT"
      endcase
   endswitch
         
   
   strfmt DateHeader "%s%s %s`r`n" WeekDay Chronology TimeZone
   
   strfmt ToHeader "%s`r`n" From       ;Put the address of the article writer
                                       ; in the To: header.
   fopen FID_ARTICLE ArticleFile READ  ;Try opening the article file until
                                       ; the file opens or the user exits.
   while FAILURE
      strfmt Message "Unable to open file:`r`n`r`n%s" ArticleFile
      sdlgmsgbox "File Error!" Message EXCLAMATION RETRYCANCEL Choice
      if Choice == 2
         CleanUp()
      endif
      fopen FID_ARTICLE ArticleFile READ
   endwhile
   
   fseek FID_ARTICLE ArticleStart 0    ;Move pointer to start of article.
   for FindingReplyTo = 1 upto 30      ;Initialize search loop.
      fgets FID_ARTICLE ReadHeader     ;Grab the first header from the article.
      strnicmp ReadHeader "Reply-To:" 9 NotFound
                                       ;See if this is the Reply-To: header.
      if NotFound == 0                 ;If the header has been found,
         strlen ReadHeader RTLength    ;Get the length of the header string.
         RTLength -= 9                 ;Reduce the length by "Reply-To:".
         substr ToHeader ReadHeader 9 RTLength
                                       ;Knock "Reply-To: " off of the string.
         FindingReplyTo = 31           ;Search is over, exit this loop.
      endif
   endfor
   
   strlen OnlySubject LengthSubject    ;Get the length of the Subject: field.
   if LengthSubject > 3                ;If there are more than three characters,
      strnicmp OnlySubject "Re:" 3 NewThread
                                       ;See if the line starts with Re:.
      if NewThread != 0                ;If it doesn't,
         strfmt SubjectHeader "Re: %s`r`n" OnlySubject
                                       ;Add Re: to the front of the line.
      else                             ;If it does,
         strcpy SubjectHeader OnlySubject
                                       ;Copy the line straight and
         strcat SubjectHeader "`r`n"   ; add a CR/LF pair to the end.
      endif
   else                                ;If there were less than three 
                                       ; characters, Re: was not there.
      strfmt SubjectHeader "Re: %s`r`n" OnlySubject
                                       ;Add Re: and CR/LF to the line.
   endif
   
   
   Extension = 0                       ;Set the file extension to 000.
   Searching = 1                       ;Initialize the search loop.
   while Searching
      strfmt SaveReply "%s`\MAIL%s.%03i" NewsOut FileGroup Extension
                                       ;Format a file name for a Mail reply.
      if isfile SaveReply              ;If the file already exists,
         Extension += 1                ;Add one to the file extension
      else                             ; and try again, otherwise exit
         Searching = 0                 ; this loop.
      endif
   endwhile
     
  
   fseek FID_ARTICLE TextStart 0       ;Go to the start of the article body.
    
   strfmt BodyTemp "%s`\TEMP2.TMP" NewsOut
                                       ;Format the name of the file that will
                                       ; hold the text to be edited.
   fopen FID_REPLYFILE BodyTemp CREATE         
                                       ;Open the edit file.
   while FAILURE
      strfmt Message "Unable to open file:`r`n`r`n%s" SaveReply
      sdlgmsgbox "File Error!" Message EXCLAMATION RETRYCANCEL Choice
      if Choice == 2
         CleanUp()
      endif
      fopen FID_REPLYFILE BodyTemp CREATE
   endwhile
   
   strreplace ReplyHeader "%s" From    ;Replace %s with the originator name.
   strreplace ReplyHeader "%u" ReplyName
                                       ;Replace %u with the user name.
   strcat ReplyHeader "`r`n"           ;Add a CR/LF pair.
   fputs FID_REPLYFILE ReplyHeader     ;Write the reply header to the edit file.
      
   strcat ReplySuffix "`r`n"           ;Add a CR/LF pair.
   strreplace ReplySuffix "%s" From    ;Replace %s with the originator name.
   strreplace ReplySuffix "%u" ReplyName
                                       ;Replace %u with the user name.
      
   for Saving = 1 upto QuoteLines      ;Copy up to n lines of text from the
                                       ; article file to the edit file.
      fgets FID_ARTICLE ReadArticle    ;Grab a line from the article file.
      strnicmp ReadArticle ".`r`n" 3 EndOfText
                                       ;See if the line is end of article.
      if EndOfText == 0                ;If it IS the end of the article,
         Saving = 500                  ;Exit the quoting loop.
         fputs FID_REPLYFILE ReplySuffix
                                       ;Insert the quote suffix.
      else                             ;If not end of article,
         fputs FID_REPLYFILE ReplyPrefix
                                       ;Insert quote prefix into reply file.
         fputs FID_REPLYFILE ReadArticle
                                       ;Insert quoted line into reply file.
      endif
   endfor
      
   fclose FID_REPLYFILE                ;Close the edit file.
   fclose FID_ARTICLE                  ;Close the article file.
      
   dialogbox 60 110 92 350 268 7 "PROCOMMM PLUS v3.0 Off-line News Reader - Reply to Author"
                                       ;Draw the dialog box for editing the reply.
      text 1 6 4 20 8 "Date:" LEFT
      text 2 6 16 30 8 "From:" LEFT
      text 3 6 27 16 8 "To:" LEFT
      text 4 6 38 32 8 "Subject:" LEFT
      text 5 37 4 289 8 DateHeader LEFT
      text 6 37 16 289 8 FromHeader LEFT
      text 7 37 27 294 8 ToHeader LEFT
      text 8 37 38 292 8 SubjectHeader LEFT
      feditbox 9 4 51 341 185 BodyTemp 
      pushbutton 10 232 246 40 14 "Cancel" CANCEL
      pushbutton 11 79 246 40 14 "Done" 
   enddialog
   dlgwin 60 DlgID                  ;Get the Windows ID of the dialog box.
   WritingReply = 1                 ;Initialize the DLGEVENT loop.
   mspause 200
   sendkey CTRL 0x23
   while WritingReply
      dlgevent 60 Event             ;Get the last dialog event.
      switch Event
         case 1                     ;Ignore all non-pushbutton controls.
         case 2
         case 3
         case 4
         case 5
         case 6
         case 7
         case 8
         case 9
         endcase
         case 10 
            dlgdestroy 60 CANCEL    ;Exit on Cancel.
            WritingReply = 0
         endcase
         case 11
            dlgdestroy 60 OK
            
            fopen FID_BODYTEMP SaveReply CREATE
                                       ;On DONE, open the reply file, write all
                                       ; write all necessary headers into the
                                       ; file, then copy the edit file into it.
            while FAILURE
               Choice = 8
               strfmt Message "Unable to open file:`r`n`r`n%s" SaveReply
               sdlgmsgbox "File Error!" Message EXCLAMATION RETRYCANCEL \
               Choice
               if Choice != 4
                  CleanUp()
               endif
               fopen FID_BODYTEMP SaveReply CREATE
            endwhile
               
            fopen FID_REPLYFILE BodyTemp READ
            while FAILURE
               Choice = 8
               strfmt Message "Unable to open file:`r`n`r`n%s" SaveReply
               sdlgmsgbox "File Error!" Message EXCLAMATION RETRYCANCEL Choice
               if Choice != 4
                  CleanUp()
               endif
               fopen FID_REPLYFILE BodyTemp READ
            endwhile
               
            fputs FID_BODYTEMP "Date: "
                                       ;Write the date header to file.
            fputs FID_BODYTEMP DateHeader 
            fputs FID_BODYTEMP "From: "
                                       ;Write the From header to file.
            fputs FID_BODYTEMP FromHeader
            fputs FID_BODYTEMP "To: "
                                       ;Write the To header to file.
            fputs FID_BODYTEMP ToHeader
            fputs FID_BODYTEMP "Subject: "
                                       ;Write the Subject header to file.
            fputs FID_BODYTEMP SubjectHeader
            fputs FID_BODYTEMP "`r`n"  ;Add a blank line for Start of Text.
            DoneCopy = 0
            while ! DoneCopy
               fgets FID_REPLYFILE ReadTemp
                                       ;Get a line from the reply file.
               fputs FID_BODYTEMP ReadTemp
                                       ;Copy the line into the temp file.
               feof FID_REPLYFILE DoneCopy
                                       ;End the loop when eof.
            endwhile
            if isfile SigFile          ;If a signature file is present.
               fopen FID_SIGFILE SigFile READ
                                       ;Open the sigfile.
               while FAILURE
                  Choice = 8
                  strfmt Message "Unable to open file:`r`n`r`n%s" SigFile
                  sdlgmsgbox "File Error!" Message EXCLAMATION RETRYCANCEL\
                  Choice
                  if Choice != 4
                     CleanUp()
                  endif
                  fopen FID_SIGFILE SigFile READ
               endwhile
               
               DoneCopy = 0            ;Initialize copy loop.
               while ! DoneCopy        ;Copy the sig file into the temp file.
                  fgets FID_SIGFILE ReadSig
                  fputs FID_BODYTEMP ReadSig
                  feof FID_SIGFILE DoneCopy
               endwhile
            endif
            fputs FID_BODYTEMP "`r`n.`r`n"
                                       ;Add a period on a line by itself.
            WritingReply = 0
            fclose FID_REPLYFILE
            fclose FID_BODYTEMP
         endcase
         default                       ;If no controls were accessed, but an
                                       ; event still registers,
            winexists DlgID StillThere
                                       ;See if this dialog box still exists.
            if ! StillThere            ;If the dialog is gone, the X from 
                                       ; Windows 95 has been selected, and this
                                       ; loop needs to be exited.
               dlgdestroy 60 CANCEL
               WritingReply = 0
            endif
         endcase
      endswitch
   endwhile
   delfile BodyTemp
endproc



proc GroupReply

;*****************************************************************************
;*                                                                           *
;* GROUPREPLY                                                                *
;* This procedure composes a reply to the selected article.                  *
;*                                                                           *
;* Calls:  CleanUp                                                           *
;* Called by: Results                                                        *
;* Modifies globals: Offline_INI, NewsOut, CurrentGroup                      *
;*                                                                           *
;*****************************************************************************
 
 
param string FileGroup                 ;Three-digit file-group index.
param string From                      ;Contents of article's From: header.
param string OnlySubject               ;Contents of article's Subject: header.
param long TextStart                   ;Position in article file of text body.
param string ArticleFile               ;Name and path to article file.
param long ArticleStart                ;Position in article file of article.

   string Message                      ;Text field for all message dialogs.
   string UserEMail                    ;E-Mail address from the INI file.
   string SaveReply                    ;Name of file to save reply in.
   string SigFile                      ;Signature file.
   string ReadSig                      ;Reads characters from signature file.
   string ReplyHeader                  ;First line of reply file.
   string FromHeader                   ;From: header for reply file.
   string ToHeader                     ;To: header for reply file.
   string ReplyName                    ;User name.
   string SubjectHeader                ;Subject: header for reply file.
   string ReplyPrefix                  ;Prefix for quoted lines.
   string ReplySuffix                  ;Line that follows quoted lines.
   string ReadArticle                  ;String for reading from article file.
   string BodyTemp                     ;Temp file for reply body.
   string ReadTemp                     ;String for reading from temp file.
   string RefHeader                    ;Reference header for news post.
   string ReplyToHeader                ;Reply-To header for news post.
   string ReadHeader                   ;Reads headers from article file.
   string ArticleID                    ;Message-ID of this article.
   integer Extension                   ;File extension for reply file.
   integer Choice                      ;User choice in all message dialogs.
   integer EndOfText                   ;End-of-article test in article file.
   integer Searching                   ;Loop controller for file-name search.
   integer Saving                      ;Loop for copying article text to reply.
   integer QuoteLines                  ;Max number of article lines to quote.
   integer WritingReply                ;String to write to reply file.
   integer DoneCopy                    ;EOF test on data files.
   integer Event                       ;Event holder for DLGEVENT statement.
   integer DlgID                       ;Windows ID of this dialog box.
   integer FindingID                   ;Loop for finding ID header.
   integer IDLength                    ;Length of the ID header.
   integer NotFound                    ;ZERO when header is found.
   integer StillThere                  ;TRUE if the dialog has not been closed
                                       ; with the Win95 X.
   integer LengthSubject               ;Length of the OnlySubject string.
   integer NewThread                   ;TRUE if OnlySubject does not start with 
                                       ; RE: .

   strfmt Offline_INI "%s`\OFFLINE.INI" $PWLOCALPATH
   
   profilerd Offline_INI "PostReply" "UserName" ReplyName
   profilerd Offline_INI "PostReply" "EMailAddress" UserEMail
                                       ;Get user's e-mail address from INI.
   profilerd Offline_INI "PostReply" "ReplyPrefix" ReplyHeader
   profilerd Offline_INI "PostReply" "ReplySuffix" ReplySuffix
   profilerd Offline_INI "PostReply" "QuoteLines" QuoteLines
   profilerd Offline_INI "PostReply" "QuotePrefix" ReplyPrefix
   profilerd Offline_INI "PostReply" "SigFile" SigFile
   
   strfmt FromHeader "%s <%s>`r`n" ReplyName UserEMail
   
   strfmt ToHeader "%s`r`n" From       ;Put the address of the article writer
                                       ; in the To: header.
   
   strlen OnlySubject LengthSubject    ;Get the length of the Subject: field.
   if LengthSubject > 3                ;If there are more than three characters,
      strnicmp OnlySubject "Re:" 3 NewThread
                                       ;See if the line starts with Re:.
      if NewThread != 0                ;If it doesn't,
         strfmt SubjectHeader "Re: %s`r`n" OnlySubject
                                       ;Add Re: to the front of the line.
      else                             ;If it does,
         strfmt SubjectHeader "%s`r`n" OnlySubject
                                       ;Copy the line straight.
      endif
   else                                ;If there were less than three 
                                       ; characters, Re: was not there.
      strfmt SubjectHeader "Re: %s`r`n" OnlySubject
                                       ;Add Re: and CR/LF to the line.
   endif
   
   
   Extension = 0                       ;Set the file extension to 000.
   Searching = 1                       ;Initialize the search loop.
   while Searching
      strfmt SaveReply "%s`\RPLY%s.%03i" NewsOut FileGroup Extension
                                       ;Format a file name for a NEWS reply.
      if isfile SaveReply              ;If the file already exists,
         Extension += 1                ;Add one to the file extension
      else                             ; and try again, otherwise exit
         Searching = 0                 ; this loop.
      endif
   endwhile
     
   fopen FID_ARTICLE ArticleFile READ  ;Try opening the article file until
                                       ; the file opens or the user exits.
   while FAILURE
      strfmt Message "Unable to open file:`r`n`r`n%s" ArticleFile
      sdlgmsgbox "File Error!" Message EXCLAMATION RETRYCANCEL Choice
      if Choice == 2
         CleanUp()
      endif
      fopen FID_ARTICLE ArticleFile READ
   endwhile
   
   fseek FID_ARTICLE ArticleStart 0    ;Move pointer to start of article.
   FindingID = 1                       ;Initialize search loop.
   while FindingID                     ;Loop while searching.
      fgets FID_ARTICLE ReadHeader     ;Grab the first header from the article.
      strnicmp ReadHeader "Message-ID:" 11 NotFound
                                       ;See if this is the ID header.
      if NotFound == 0                 ;If the header has been found,
         strlen ReadHeader IDLength    ;Get the length of the header string.
         IDLength -= 12                ;Reduce the length by "From:".
         substr ArticleID ReadHeader 12 IDLength
                                       ;Knock "From: " off of the string.
         FindingID = 0                 ;Search is over, exit this loop.
      endif
   endwhile
   
   fseek FID_ARTICLE TextStart 0       ;Go to the start of the article body.
    
   strfmt BodyTemp "%s`\TEMP2.TMP" NewsOut
                                       ;Format the name of the file that will
                                       ; hold the text to be edited.
   fopen FID_REPLYFILE BodyTemp CREATE ;Open the edit file.
   while FAILURE
      strfmt Message "Unable to open file:`r`n`r`n%s" SaveReply
      sdlgmsgbox "File Error!" Message EXCLAMATION RETRYCANCEL Choice
      if Choice == 2
         CleanUp()
      endif
      fopen FID_REPLYFILE BodyTemp CREATE
   endwhile
   
   strreplace ReplyHeader "%s" From    ;Replace %s with originator's name.
   strreplace ReplyHeader "%u" ReplyName
                                       ;Replace %s with user's name.
   strcat ReplyHeader "`r`n"           ;Add a CR/LF pair.
   fputs FID_REPLYFILE ReplyHeader     ;Write the reply header to the edit file.
      
   strcat ReplySuffix "`r`n"           ;Add a CR/LF pair.
   strreplace ReplySuffix "%s" From    ;Replace %s with originator's name.
   strreplace ReplySuffix "%u" ReplyName
                                       ;Replace %u with user's name.
      
   for Saving = 1 upto QuoteLines      ;Copy up to n lines of text from the
                                       ; article file to the edit file.
      fgets FID_ARTICLE ReadArticle
      strnicmp ReadArticle ".`r`n" 3 EndOfText
      if EndOfText == 0
         Saving = 500
         fputs FID_REPLYFILE ReplySuffix
      else
         fputs FID_REPLYFILE ReplyPrefix
         fputs FID_REPLYFILE ReadArticle
      endif
   endfor
      
   fclose FID_REPLYFILE                        ;Close the edit file.
   fclose FID_ARTICLE                         ;Close the article file.
      
   dialogbox 60 110 92 350 268 7 "PROCOMMM PLUS v3.0 Off-line News Reader - Reply to Group"
      text 1 3 36 20 8 "Date:" LEFT
      text 2 3 3 30 8 "From:" LEFT
      text 3 3 14 40 8 "NewsGroup:" LEFT
      text 4 3 25 32 8 "Subject:" LEFT
      text 6 46 3 270 8 FromHeader LEFT
      text 7 46 14 270 8 CurrentGroup LEFT
      text 8 46 25 290 8 SubjectHeader LEFT
      feditbox 9 4 51 341 185 BodyTemp
      pushbutton 10 232 246 40 14 "Cancel" CANCEL
      pushbutton 11 79 246 40 14 "Done"
   enddialog
   dlgwin 60 DlgID                  ;Get the Windows ID of the dialog box.
   WritingReply = 1                 ;Initialize the DLGEVENT loop.
   mspause 200
   sendkey CTRL 0x23
   while WritingReply
      dlgevent 60 Event             ;Get the last dialog event.
      switch Event
         case 1                     ;Ignore all non-pushbutton controls.
         case 2
         case 3
         case 4
         case 5
         case 6
         case 7
         case 8
         case 9
         endcase
         case 10 
            dlgdestroy 60 CANCEL       ;Exit on Cancel.
            WritingReply = 0
         endcase
         case 11
            dlgdestroy 60 OK
            
            fopen FID_BODYTEMP SaveReply CREATE
                                       ;On DONE, open the reply file, write all
                                       ; necessary headers into the
                                       ; file, then copy the edit file into it.
            while FAILURE
               Choice = 8
               strfmt Message "Unable to open file:`r`n`r`n%s" SaveReply
               sdlgmsgbox "File Error!" Message EXCLAMATION RETRYCANCEL \
               Choice
               if Choice != 4
                  CleanUp()
               endif
               fopen FID_BODYTEMP SaveReply CREATE
            endwhile
               
            fopen FID_REPLYFILE BodyTemp READ
            while FAILURE
               Choice = 8
               strfmt Message "Unable to open file:`r`n`r`n%s" SaveReply
               sdlgmsgbox "File Error!" Message EXCLAMATION RETRYCANCEL Choice
               if Choice != 4
                  CleanUp()
               endif
               fopen FID_REPLYFILE BodyTemp READ
            endwhile
            
            strfmt RefHeader "References: %s" ArticleID
            strfmt ReplyToHeader "Reply-To: %s`r`n" UserEMail
                                       ;Put the news headers into reply file.
            fputs FID_BODYTEMP "From: "
            fputs FID_BODYTEMP FromHeader
            fputs FID_BODYTEMP "Newsgroups: "
            fputs FID_BODYTEMP CurrentGroup
            fputs FID_BODYTEMP "`r`n"
            fputs FID_BODYTEMP "Subject: "
            fputs FID_BODYTEMP SubjectHeader
            fputs FID_BODYTEMP "Distribution: world`r`n"
            fputs FID_BODYTEMP RefHeader
            fputs FID_BODYTEMP ReplyToHeader
            fputs FID_BODYTEMP "`r`n"
            DoneCopy = 0               ;Copy Reply file into temp file.
            while ! DoneCopy
               fgets FID_REPLYFILE ReadTemp
               fputs FID_BODYTEMP ReadTemp
               feof FID_REPLYFILE DoneCopy
            endwhile
            if isfile SigFile          ;Copy sigfile, if it exists.
               fopen FID_SIGFILE SigFile READ
               while FAILURE
                  strfmt Message "Unable to open file:`r`n`r`n%s" SigFile
                  sdlgmsgbox "File Error!" Message EXCLAMATION RETRYCANCEL Choice
                  if Choice == 2
                     CleanUp()
                  endif
                  fopen FID_SIGFILE SigFile READ
               endwhile
               feof FID_SIGFILE DoneCopy
               while ! DoneCopy
                  fgets FID_SIGFILE ReadSig
                  fputs FID_BODYTEMP ReadSig
                  feof FID_SIGFILE DoneCopy
               endwhile
            endif
            fputs FID_BODYTEMP "`r`n.`r`n"
            WritingReply = 0
            fclose FID_REPLYFILE
            fclose FID_BODYTEMP
         endcase
         default                       ;If no controls were accessed, but an
                                       ; event still registers,
            winexists DlgID StillThere
                                       ;See if this dialog box still exists.
            if ! StillThere            ;If the dialog is gone, the X from 
                                       ; Windows 95 has been selected, and this
                                       ; loop needs to be exited.
               dlgdestroy 60 CANCEL
               WritingReply = 0
            endif
         endcase
      endswitch
   endwhile
   delfile BodyTemp
endproc 


 
