program Draw_ALD

  ! Draw IBM ALDs

  ! Page layout:
  ! Heading
  ! One blank line
  ! Nine rows of 7 boxes, 18 lines each
  ! First and last box are edge labels, middle 5 are logic boxes 
  ! Two blank lines
  ! Twenty rows for notes and comments, notes on top, comments on bottom
  ! Total 204 lines of 132 characters

  ! Input is text, blank delimited

  ! P for page
  ! Book number
  ! Drawing number
  ! Logic number
  ! Frame/Channel number
  ! MFI
  ! Title in quotes
  ! Feature in quotes

  ! # bk drawing# logic#     FR_CH MFI  "title"                  "feature"
  ! P  7 761264   B9.40.12.1 00xc  M0   "Error stop read gating" "TAU 9"

  ! L for logic box
  ! Type
  ! Symbol
  ! Input marks, . for none
  ! Output marks, . for none
  ! EC
  ! Location
  ! Sub
  ! Col/Row, col=2..6, row=a..hj
  ! [Title in quotes]
  ! [*[*]{a-h,s-z}pin/tie]...

  ! # type     in    ec        ColRow   
  ! #    Symbol  out    loc sub     ["title"]
  ! L dhc- i    y  y  c b07 01 3b

  ! Row letters and numbers within logic box
  !              1-2 Above box
  ! Left Right     3 Title
  !   a    s       4 Top line
  !   b    t       5 Type
  !   c    u       6 MFI
  !   d    v       7 in/out marks
  !   e    w       8 FRC and EC
  !   f    x       9 HLLL
  !   g    y      10 Card/Cap
  !   h    z      11 Sub
  !               12 Coord
  !            13-18 Below box

  ! Column numbers within logic box
  !   1-4 Left trace
  !   5-6 Pin/tie
  !     7 Left edge
  !  8-11 Text
  !    12 Right edge, might include *
  ! 13-14 Pin/tie
  ! 15-17 right trace

  ! I for input edge
  ! ID Number 1..60
  ! Location as box row (a..hj) and row number in box (1..18)
  !   location is for logic number, title(s) above
  ! Logic # ab.cd.ef.g
  ! [Title 1 in quotes]
  ! [Title 2 in quotes]
  ! [* Note in quotes]

  ! #  # row Logic#     ["title 1" ["title 2"]] [*note]
  ! I 01 b06 b9.40.10.1 "-y hi clip 1" "bit"

  ! O for output edge
  ! ID Number 1..60
  ! Location as box row (a..hj) and row number in box (1..18)
  !   location is for logic number, title(s) above
  ! Logic # ab.cd.ef.g
  ! [Title 1 in quotes]
  ! [Title 2 in quotes]
  ! [* Note in quotes]

  ! #  # row Logic#     ["title 1" ["title 2"]] [*note]
  ! o 01 a15 b9.40.20.1 "+y hi chan 1" "bit"

  ! N for note
  ! Number or -
  ! Where, e.g. 00xcc01p

  ! * for comment, blanks significant

  use IO_m, only: IO_t, Draw_Edge, Parse_Edge
  use Logic_m, only: Logic_t, Draw_Logic, Parse_Logic, Rows
  use Page_m, only: Draw_Head, Page_t, Parse_Page

  implicit NONE

  type :: Note_T
    integer :: Number ! from I/O Note field
    character(8) :: Where
  end type Note_T

  type(page_t) :: Head
  type(logic_t) :: Boxes(9,2:6), Empty_Box
  type(io_t) :: Empty_Edge, In_Edge(81), Out_Edge(81)

  character(34) :: Comments(20)
  type(note_t) :: Notes(6*size(comments))
  integer, parameter :: N_Page = 2+9*18+2+size(comments) ! Lines per page
  character(132) :: Page(n_page)

  character(255) :: Line, Token
  character :: Case ! From first nonblank on Line

  integer :: I, J ! Subscripts

  integer :: N_Comments, N_Lines, N_Notes

  ! Mark logic boxes unused
  boxes = empty_box

  n_comments = 0
  n_lines = 0
  n_notes = 0

  ! Mark edge labels unused
  in_edge = empty_edge
  in_edge%io = 'I'
  out_edge = empty_edge
  out_edge%io = 'O'

  do
    read ( *, '(a)', end=9 ) line
    line = adjustl(line)
    n_lines = n_lines + 1

    case = line(1:1)
    line = adjustl(line(2:))
    select case ( case ) ! line type
    case ( '*' ) ! comment
      n_comments = n_comments + 1
      if ( n_comments > size(comments) ) then
        print *, 'Too many comments at line', n_lines
      else
        comments(n_comments) = line(2:)
      end if
    case ( 'I', 'i' ) ! Edge
      call parse_edge ( line, n_lines, in_edge )
    case ( 'L', 'l' ) ! Logic
      call parse_logic ( line, n_lines, boxes )
    case ( 'N', 'n' ) ! Note
      n_notes = n_notes + 1
      if ( n_notes > size(notes) ) then
        print *, 'Too many edge notes at line', n_lines
      else
        call parse_note ( notes(n_notes) )
      end if
    case ( 'O', 'o' )
      call parse_edge ( line, n_lines, out_edge )
    case ( 'P', 'p' )
      call parse_page ( line, n_lines, head )
    end select
  end do

! EOF on input, print the page
9 continue

  page = ''

  call draw_head ( head, page(1) )

  do i = lbound(boxes,1), ubound(boxes,1) ! rows
    do j = lbound(boxes,2), ubound(boxes,2) ! cols
      call draw_logic ( page(4:), boxes(i,j), head%MFI, head%FR_CH )
    end do
  end do

  call draw_edge ( page(4:), in_edge )
  call draw_edge ( page(4:), out_edge )

  write ( *, '(a)' ) ( trim(page(i)), i = 1, size(page) )

contains

  subroutine Parse_Note ( Note )
    type(note_t), intent(out) :: Note
  end subroutine Parse_Note

end program Draw_ALD
