!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
module cubetools_terminal_tool
  use cubetools_parameters
  use cubetools_messaging
  !---------------------------------------------------------------------
  ! Tool to interact with an ASCII terminal or file
  !---------------------------------------------------------------------
  !
  public :: terminal,file
!!$  public :: terminal_width,strg_dash
!!$  public :: cubetools_terminal_terminal_width,cubetools_terminal_file_width
!!$  public :: cubetools_terminal_print
  private
  !
  ! Parameters
  integer(kind=4), parameter :: terminal_max_width=90
  integer(kind=4), parameter :: file_default_width=74  ! for e.g. COLLECT
  !
  ! Dynamic
  integer(kind=4) :: current_width=terminal_max_width
  integer(kind=code_k) :: current_format=help_format_term
  !
  ! ZZZ We should merge the 2 types into a common type "current
  ! output device":
  !
  type terminal_t
   contains
     procedure, public, nopass :: set_width  => terminal_set_width
     procedure, public, nopass :: width      => terminal_get_width
     procedure, public, nopass :: set_format => terminal_set_format
     procedure, public, nopass :: format     => file_get_format
     procedure, public, nopass :: dash_strg  => terminal_dash_strg
     procedure, public, nopass :: print_strg => terminal_print_strg
  end type terminal_t
  type(terminal_t) :: terminal
  !
  type file_t
   contains
     procedure, public, nopass :: set_width  => file_set_width
     procedure, public, nopass :: width      => terminal_get_width
     procedure, public, nopass :: set_format => file_set_format
     procedure, public, nopass :: format     => file_get_format
     procedure, public, nopass :: dash_strg  => terminal_dash_strg
     procedure, public, nopass :: print_strg => terminal_print_strg
  end type file_t
  type(file_t) :: file
  !
contains
  !
  subroutine file_set_width()
    !-------------------------------------------------------------------
    ! Set the current terminal width so that it is adapted for ouput to a
    ! file, for e.g., command COLLECT
    !-------------------------------------------------------------------
    current_width = file_default_width
  end subroutine file_set_width
  !
  subroutine file_set_format(forma)
    !-------------------------------------------------------------------
    ! Set the current output file format so that it is adapted for
    ! output to a file, for e.g., command COLLECT
    !-------------------------------------------------------------------
    integer(kind=code_k), intent(in) :: forma
    current_format = forma
  end subroutine file_set_format
  !
  function file_get_format()
    !-------------------------------------------------------------------
    ! Get the current output file format
    !-------------------------------------------------------------------
    integer(kind=code_k) :: file_get_format
    file_get_format = current_format
  end function file_get_format
  !
  !---------------------------------------------------------------------
  !
  subroutine terminal_set_width()
    use gkernel_interfaces
    !-------------------------------------------------------------------
    ! Set the current terminal width so that it is adapted to the current
    ! terminal, if any
    !-------------------------------------------------------------------
    if (sic_isatty().eq.1) then
      ! Interactive session in a terminal
      current_width = min(sic_ttyncol(),terminal_max_width)
    else
      ! Non-interactive session, e.g. batch mode redirected to file
      current_width = file_default_width
    endif
  end subroutine terminal_set_width
  !
  function terminal_get_width() result(width)
    !-------------------------------------------------------------------
    ! Return the terminal string width adapted to the terminal size.
    ! Leave 2 blank characters to the left and to the right of the
    ! terminal.
    !-------------------------------------------------------------------
    integer(kind=4) :: width
    width = current_width-4
  end function terminal_get_width
  !
  subroutine terminal_set_format()
    !-------------------------------------------------------------------
    !
    !-------------------------------------------------------------------
    current_format = help_format_term
  end subroutine terminal_set_format
  !
  !---------------------------------------------------------------------
  !
  function terminal_dash_strg() result(strg)
    !-------------------------------------------------------------------
    ! Return a string of dashes of length tt_width
    !-------------------------------------------------------------------
    character(len=:), allocatable :: strg
    strg = repeat('-',current_width)  ! Implicit allocation
  end function terminal_dash_strg
  !
  subroutine terminal_print_strg(mkind,strg)
    !-------------------------------------------------------------------
    ! Print a message to the current output device (usually terminal,
    ! but could be a file - see e.g. COLLECT). The line is split
    ! according to the device width.
    !-------------------------------------------------------------------
    integer(kind=code_k), intent(in) :: mkind
    character(len=*),     intent(in) :: strg
    !
    character(len=mess_l) :: mess,word
    integer(kind=4) :: lenword,lenline,lenstrg,ichar
    character(len=*), parameter :: spc = ' '
    character(len=*), parameter :: rname='TERMINAL>PRINT>STRG'
    !
    call cubetools_message(toolseve%trace,rname,'Welcome')
    !
    lenstrg = len_trim(strg)
    lenline = 0
    lenword = 0
    do ichar=1,lenstrg
       if (strg(ichar:ichar).eq.spc) then
          if (lenline+lenword.gt.terminal%width()) then
             ! message mess
             call cubetools_message(mkind,rname,mess)
             ! write word to begining of mess
             write(mess,'(2x,a)') word(1:lenword)
             lenline = lenword+2
          else if (lenline.eq.0) then
             write(mess,'(2x,a)') word(1:lenword)
             lenline = lenword+2
          else
             ! write word to end of mess
             write(mess(lenline+1:),'(1x,a)') word(1:lenword)
             lenline = lenline+1+lenword
          endif
          lenword=0
       elseif (ichar.eq.lenstrg) then
          lenword=lenword+1
          word(lenword:lenword) = strg(ichar:ichar)
          if (lenline+lenword.gt.terminal%width()) then
             call cubetools_message(mkind,rname,mess)
             write(mess,'(2x,a)') word(1:lenword)
             lenline = lenword+2
          else
             write(mess(lenline+1:),'(1x,a)') word(1:lenword)
             lenline = lenline+1+lenword
          endif
          call cubetools_message(mkind,rname,mess)
       else if (strg(ichar:ichar).eq.strg_cr) then
          write(mess(lenline+1:),'(1x,a)') word(1:lenword)
          lenline = lenline+1+lenword
          call cubetools_message(mkind,rname,mess(1:lenline))
          lenline = 0
          lenword = 0
       else
          lenword=lenword+1
          word(lenword:lenword) = strg(ichar:ichar)
          ! add char to word
       endif
    enddo
  end subroutine terminal_print_strg
end module cubetools_terminal_tool
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
