module cubeadm_flag
  use cubetools_parameters
  use cubetools_structure
  use cubetools_keywordlist_types
  use cubetools_flag_types
  use cubeadm_messaging
  !
  public :: flag
  private
  !
  type flag_comm_t
     type(option_t), pointer :: comm
     type(option_t), pointer :: add
     type(option_t), pointer :: debug
   contains
     procedure, public  :: register => cubeadm_flag_register
     procedure, private :: parse    => cubeadm_flag_parse
     procedure, private :: main     => cubeadm_flag_main
  end type flag_comm_t
  type(flag_comm_t) :: flag
  !
  type flag_user_t
    logical               :: add_do
    character(len=argu_l) :: add_name
    logical               :: debug_do
  contains
    procedure, private :: toprog => cubeadm_flag_user_toprog
  end type flag_user_t
  !
  type flag_prog_t
    logical               :: add_do
    character(len=argu_l) :: add_name
    logical               :: debug_do
  contains
    procedure, public :: do => cubeadm_flag_do
  end type flag_prog_t
  !
contains
  !
  subroutine cubeadm_flag_command(line,error)
    !----------------------------------------------------------------------
    !
    !----------------------------------------------------------------------
    character(len=*), intent(in)    :: line
    logical,          intent(inout) :: error
    !
    type(flag_user_t) :: user
    character(len=*), parameter :: rname='FLAG>COMMAND'
    !
    call cubeadm_message(admseve%trace,rname,'Welcome')
    !
    call flag%parse(line,user,error)
    if (error) return
    call flag%main(user,error)
    if (error) return
  end subroutine cubeadm_flag_command
  !
  !----------------------------------------------------------------------
  !
  subroutine cubeadm_flag_register(flag,error)
    !----------------------------------------------------------------------
    !
    !----------------------------------------------------------------------
    class(flag_comm_t), intent(inout) :: flag
    logical,            intent(inout) :: error
    !
    type(standard_arg_t) :: stdarg
    character(len=*), parameter :: rname='FLAG>REGISTER'
    !
    call cubeadm_message(admseve%trace,rname,'Welcome')
    !
    call cubetools_register_command(&
         'FLAG','',&
         'List, add, or debug available flags',&
         'Without options, list the currently registered flags. With options,&
         & execute the requested flag-management action.',&
         cubeadm_flag_command,&
         flag%comm,error)
    if (error) return
    !
    call cubetools_register_option(&
         'ADD','Name',&
         'Add a new user-defined flag',&
         strg_emp,&
         flag%add,error)
    if (error) return
    call stdarg%register(&
         'Name', &
         'Flag name',&
         'The new flag name must be unambiguous with all other flag names.',&
         code_arg_mandatory,&
         error)
    if (error) return
    !
    call cubetools_register_option(&
         'DEBUG','',&
         'List all flags ind debug format',&
         strg_emp,&
         flag%debug,error)
    if (error) return
  end subroutine cubeadm_flag_register
  !
  subroutine cubeadm_flag_parse(flag,line,user,error)
    !-------------------------------------------------------------------
    ! Parsing facility for command FLAG
    !-------------------------------------------------------------------
    class(flag_comm_t), intent(inout) :: flag
    character(len=*),   intent(in)    :: line
    type(flag_user_t),  intent(out)   :: user
    logical,            intent(inout) :: error
    !
    character(len=*), parameter :: rname='FLAG>PARSE'
    !
    call cubeadm_message(admseve%trace,rname,'Welcome')
    !
    call flag%add%present(line,user%add_do,error)
    if (error) return
    call flag%debug%present(line,user%debug_do,error)
    if (error) return
    !
    if (user%add_do) then
      call cubetools_getarg(line,flag%add,1,user%add_name,mandatory,error)
      if (error) return
    endif
  end subroutine cubeadm_flag_parse
  !
  subroutine cubeadm_flag_main(flag,user,error)
    !-------------------------------------------------------------------
    !
    !-------------------------------------------------------------------
    class(flag_comm_t), intent(in)    :: flag
    type(flag_user_t),  intent(in)    :: user
    logical,            intent(inout) :: error
    !
    type(flag_prog_t) :: prog
    character(len=*), parameter :: rname='FLAG>MAIN'
    !
    call cubeadm_message(admseve%trace,rname,'Welcome')
    !
    call user%toprog(prog,error)
    if (error) return
    call prog%do(error)
    if (error) return
  end subroutine cubeadm_flag_main
  !
  subroutine cubeadm_flag_user_toprog(user,prog,error)
    !-------------------------------------------------------------------
    ! 
    !-------------------------------------------------------------------
    class(flag_user_t), intent(in)    :: user
    type(flag_prog_t),  intent(out)   :: prog
    logical,            intent(inout) :: error
    !
    character(len=*), parameter :: rname='FLAG>USER2PROG'
    !
    call cubeadm_message(admseve%trace,rname,'Welcome')
    !
    prog%add_do   = user%add_do
    prog%debug_do = user%debug_do
    !
    if (prog%add_do) then
      prog%add_name = user%add_name
    endif
  end subroutine cubeadm_flag_user_toprog
  !
  subroutine cubeadm_flag_do(prog,error)
    !---------------------------------------------------------------------
    ! Support for command ADM\FLAG
    !---------------------------------------------------------------------
    class(flag_prog_t), intent(in)    :: prog
    logical,            intent(inout) :: error
    !
    character(len=*), parameter :: rname='FLAG>DO'
    !
    if (prog%add_do) then
      call cubetools_flag_register_user(prog%add_name,error)
      if (error) return
    elseif (prog%debug_do) then
      call cubetools_flag_debug(error)
      if (error) return
    else
      call cubetools_flaglist_list_all(error)
      if (error) return
      call cubeadm_message(seve%r,rname,blankstr)
    endif
  end subroutine cubeadm_flag_do
  !
end module cubeadm_flag
