/*  ASC2ADR.CMD -- Convert ASCII file to Post Road Mailer address book.   */
/*                         Parameters: ASCII_file                         */
/*   (c) Copyright 1995, InnoVal System Solutions, Inc., Tom Springall    */
/*        (c) Copyright 1996, modifications, InnoVal, Kari Jackson        */
/*    InnoVal Systems Solutions, Inc., and the authors cannot be held     */
/*   responsible for damage that might occur while using this program.    */
/*                         Use at your own risk.                          */

 CRLF = '0D'x||'0A'x

 SAVE_FILECARDS        = X2C('0700') ; SAVE_GROUPS           = X2C('0800')
 SAVE_GNAME            = X2C('2000') ; SAVE_ADDRESSES        = X2C('2200')
 SAVE_GADDRESS         = X2C('2400') ; SAVE_BOOK_NAME        = X2C('3000')
 SAVE_FIRST            = X2C('3500') ; SAVE_CNAME            = X2C('4000')
 SAVE_COMPANY          = X2C('4500') ; SAVE_EMAIL1           = X2C('5000')
 SAVE_EMAIL2           = X2C('7500') ; SAVE_EMAIL3           = X2C('7600')
 SAVE_EMAIL4           = X2C('7700') ; SAVE_EMAIL5           = X2C('7800')
 SAVE_PHONE1           = X2C('8000') ; SAVE_PHONE2           = X2C('8500')
 SAVE_FAX              = X2C('9000') ; SAVE_ADDRESS          = X2C('9500')
 SAVE_NICKNAME1        = X2C('0001') ; SAVE_NICKNAME2        = X2C('0101')
 SAVE_NICKNAME3        = X2C('0201') ; SAVE_NICKNAME4        = X2C('0301')
 SAVE_NICKNAME5        = X2C('0401')

 Arg filespec
 If filespec = '' | Pos('?',filespec) <> 0 then Signal Help

 If Pos('.', filespec) = 0 then filespec = filespec || '.ASC'
 If Stream(filespec,'C','QUERY EXISTS') = '' then Signal Err1

 Parse var filespec file '.' ext
 If ext = 'ADR' then Signal Err2

 filename = SubStr(file, LastPos('\',file) + 1)
 outfile = filename || '.ADR'
 groupfile = filename || '.GRP'

 If '' <> Stream(outfile,'C','QUERY EXISTS') then do
   Say outfile 'already exists. Do you want to replace it? (Y/n)'
   Pull ans
   If Left(ans,1) <> 'N' then '@ERASE' outfile
   Else Exit 1
   end
 If '' = Stream(groupfile,'C','QUERY EXISTS') then GROUPFILE=''

 /* Check for address book name and write to output file. */
 lin = LineIn(filespec)
 parse var lin name ' (Post Road Mailer address book' tail
 If tail='' then Signal Err3
 Call SaveIt SAVE_BOOK_NAME, name
 do until lin=''
    lin=linein(filespec)
 end
 if groupfile<>'' then do until lin=''
    lin=linein(groupfile)
 end

 cards = 0 ; groups = 0 ; data. = ''

 Do i=1 While Lines(filespec) > 0
   lin = LineIn(filespec)
   Parse var lin data.i.LAST_NAME '09'x data.i.FIRST_NAME '09'x data.i.ORGANIZATION '09'x data.i.EMAIL1 '09'x data.i.NICKNAME1 '09'x data.i.EMAIL2 '09'x data.i.NICKNAME2 '09'x data.i.EMAIL3 '09'x data.i.NICKNAME3 '09'x data.i.EMAIL4 '09'x data.i.NICKNAME4 '09'x data.i.EMAIL5 '09'x data.i.NICKNAME5 '09'x data.i.PHONE1 '09'x data.i.PHONE2 '09'x data.i.FAX '09'x data.i.COMMENTS
   holding=''
   do while data.i.COMMENTS<>''
      parse var data.i.COMMENTS left '09'x data.i.COMMENTS
      if holding='' then holding=left
      else holding=holding||CRLF||left
   end
   data.i.COMMENTS = holding
   if data.i.LAST_NAME<>'' | data.i.ORGANIZATION<>'' then do
      cards=cards+1
      typ.i='CARD'
   end
 end
 Call LineOut filespec                      /* close input file */
 j=i
 if groupfile<>'' then Do i=j While Lines(groupfile) > 0
   lin=''
   do until right(lin,1)<>'09'x
      lin=lin||linein(groupfile)
   end
   Parse var lin data.i.GROUP_NAME '09'x gaddresses
   k=0
   do while gaddresses<>''
      parse var gaddresses left '09'x gaddresses
      k=k+1
      data.i.gaddress.k=left
   end
   data.i.addresses=k
   if data.i.GROUP_NAME<>'' then do
      groups=groups+1
      typ.i='GROUP'
   end
 end
 Call LineOut groupfile                      /* close input file */

 /* save card and group counts */
 Call SaveIt SAVE_FILECARDS, MakeNum(cards)
 Call SaveIt SAVE_GROUPS, MakeNum(groups)

 /* write out each level (each level contains an address page or group) */
 Do j = 1 to i - 1
   Select
     When typ.j = 'CARD' then do
       Call SaveIt SAVE_CNAME, data.j.LAST_NAME  /* must be 1st */
       Call SaveIt SAVE_FIRST, data.j.FIRST_NAME
       Call SaveIt SAVE_COMPANY, data.j.ORGANIZATION
       Call SaveIt SAVE_EMAIL1, data.j.EMAIL1
       Call SaveIt SAVE_EMAIL2, data.j.EMAIL2
       Call SaveIt SAVE_EMAIL3, data.j.EMAIL3
       Call SaveIt SAVE_EMAIL4, data.j.EMAIL4
       Call SaveIt SAVE_EMAIL5, data.j.EMAIL5
       Call SaveIt SAVE_PHONE1, data.j.PHONE1
       Call SaveIt SAVE_PHONE2, data.j.PHONE2
       Call SaveIt SAVE_FAX, data.j.FAX
       Call SaveIt SAVE_ADDRESS, data.j.COMMENTS
       Call SaveIt SAVE_NICKNAME1, data.j.NICKNAME1
       Call SaveIt SAVE_NICKNAME2, data.j.NICKNAME2
       Call SaveIt SAVE_NICKNAME3, data.j.NICKNAME3
       Call SaveIt SAVE_NICKNAME4, data.j.NICKNAME4
       Call SaveIt SAVE_NICKNAME5, data.j.NICKNAME5
     end /* of When */

     When typ.j = 'GROUP' then do         /* it's a group */
       /* group must begin with name of group */
       Call SaveIt SAVE_GNAME, data.j.GROUP_NAME
       /* number of addresses in group */
       Call SaveIt SAVE_ADDRESSES, MakeNum(data.j.addresses)
       /* then, each address */
       Do k = 1 to data.j.addresses
         Call SaveIt SAVE_GADDRESS, data.j.GADDRESS.k
       end
     end /* of When */
     Otherwise Nop
   end /* of Select */
 end /* of Do j... */

 Call CharOut outfile                /* close output file */

 Say ''
 Say 'The address book version of' filespec
 Say 'is now in' outfile
 Say ''
 Say 'It contains' cards 'name(s) and' groups 'group(s).'
 Say ''

 Exit

/*----------------------------------------------------------------------*/
HELP:

 Say ''
 Say 'ASC2ADR.CMD converts a text file to a Post Road Mailer address book.'
 Say ''
 Say 'Syntax is:  ASC2ADR <path>filename'
 Say ''
 Say 'The output file will have the same filename as the text file and'
 Say 'an .ADR extension, i.e., filename.ADR'
 Say ''
 Exit

/*---------------------------------------------------------------------------*/
SAVEIT: Procedure Expose outfile

   /* write field to output file */
   code = Left(Arg(1),4,D2C(0))
   valu = Arg(2)
   len = MakeNum(Length(valu))

   If 0 <> CharOut(outfile, code || len || valu) then Signal Err4

   Return

/*---------------------------------------------------------------------------*/
MAKENUM: Procedure   /* Convert integer into 4-byte Intel format */

   Return Intel(D2C(Arg(1),4))

/*---------------------------------------------------------------------------*/
INTEL:  Procedure    /* Swaps bytes in an Intel 2 or 4 byte number. */
 Parse arg x

 If Length(x) = 2 then
   Return Right(x,1) || Left(x,1)

 Else
   Return Intel(Right(x,2)) || Intel(Left(x,2))

/*---------------------------------------------------------------------------*/
ERR1:
 Say 'File' filespec 'not found.'
 Exit 1
/*---------------------------------------------------------------------------*/
ERR2:
 Say 'The input file' filespec 'should not have an address book (.ADR) extension.'
 Exit 1
/*---------------------------------------------------------------------------*/
ERR3:
 Say 'File' filespec 'does not appear to be in the PRM ASCII file format.'
 Call LineOut filespec
 Exit 1
/*---------------------------------------------------------------------------*/
ERR4:
 Say 'Error writing to file' outfile
 Call LineOut filespec
 Call CharOut outfile
 Exit 1
/*---------------------------------------------------------------------------*/
