module cubeset_index
  use cubetools_parameters
  use cubetools_structure
  use cubetools_keywordlist_types
  use cubesyntax_key_types
  use cubetools_setup_types
  use cubeset_messaging
  !
  public :: index
  private
  !
  type :: index_comm_t
    type(option_t), pointer :: comm
    type(keywordlist_comm_t), pointer :: index_arg
    type(key_comm_t) :: default
   contains
    procedure, public  :: register => cubeset_index_register
    procedure, private :: parse    => cubeset_index_parse
    procedure, private :: main     => cubeset_index_main
  end type index_comm_t
  type(index_comm_t) :: index
  !
  type :: index_user_t
    logical :: list
    character(len=argu_l) :: name = strg_unk
    type(key_user_t) :: default
  contains
    procedure, private :: toprog => cubeset_index_user_toprog
  end type index_user_t
  !
  type :: index_prog_t
    logical :: list
    integer(kind=code_k) :: index = code_index_dag
    type(key_prog_t) :: default
  contains
    procedure, private :: act => cubeset_index_prog_act
  end type index_prog_t
  !
contains
  !
  subroutine cubeset_index_command(line,error)
    !---------------------------------------------------------------------
    !
    !---------------------------------------------------------------------
    character(len=*), intent(in)    :: line
    logical,          intent(inout) :: error
    !
    type(index_user_t) :: user
    character(len=*), parameter :: rname='INDEX>COMMAND'
    !
    call cubeset_message(setseve%trace,rname,'Welcome')
    !
    call index%parse(line,user,error)
    if (error) return
    call index%main(user,error)
    if (error) return
  end subroutine cubeset_index_command
  !
  !----------------------------------------------------------------------
  !
  subroutine cubeset_index_register(index,error)
    !---------------------------------------------------------------------
    ! 
    !---------------------------------------------------------------------
    class(index_comm_t), intent(inout) :: index
    logical,             intent(inout) :: error
    !
    type(keywordlist_comm_t) :: keyarg
    character(len=*), parameter :: rname='INDEX>REGISTER'
    !
    call cubeset_message(setseve%trace,rname,'Welcome')
    !
    call cubetools_register_command(&
         'INDEX','[DAG|CURRENT]',&
         'Set which index should be used when searching for cubes',&
         'No argument shows current value. Default is DAG. Use /DEFAULT&
         & to reset index settings. When /DEFAULT is combined with an&
         & argument on the same command line, reset is applied first.',&
         cubeset_index_command,&
         index%comm,&
         error)
    if (error) return
    call keyarg%register(&
         'name',&
         'Name of the index to be used',&
         strg_emp,&
         code_arg_optional,&
         indexname,&
         .not.flexible,&
         index%index_arg,&
         error)
    if (error) return
    !
    call index%default%register(&
         'DEFAULT',&
         'Reset settings',&
         'Reset index settings before applying command arguments from the&
         & same command line.',&
         error)
    if (error) return
  end subroutine cubeset_index_register
  !
  subroutine cubeset_index_parse(index,line,user,error)
    !---------------------------------------------------------------------
    !
    !---------------------------------------------------------------------
    class(index_comm_t), intent(in)    :: index
    character(len=*),    intent(in)    :: line
    type(index_user_t),  intent(out)   :: user
    logical,             intent(inout) :: error
    !
    character(len=*), parameter :: rname='INDEX>PARSE'
    !
    call cubeset_message(setseve%trace,rname,'Welcome')
    !
    user%list = cubetools_nopt().eq.0 .and. index%comm%getnarg().eq.0
    !
    if (user%list) then
      ! nothing to do
    else
      if (index%comm%getnarg().gt.0) then
        call cubetools_getarg(line,index%comm,1,user%name,mandatory,error)
        if (error) return
      endif
      call index%default%parse(line,user%default,error)
      if (error) return
    endif
  end subroutine cubeset_index_parse
  !
  subroutine cubeset_index_main(comm,user,error)
    !---------------------------------------------------------------------
    !
    !---------------------------------------------------------------------
    class(index_comm_t), intent(inout) :: comm
    type(index_user_t),  intent(in)    :: user
    logical,             intent(inout) :: error
    !
    type(index_prog_t) :: prog
    character(len=*), parameter :: rname='INDEX>MAIN'
    !
    call cubeset_message(setseve%trace,rname,'Welcome')
    !
    call user%toprog(comm,prog,error)
    if (error) return
    call prog%act(error)
    if (error) return
  end subroutine cubeset_index_main
  !
  subroutine cubeset_index_user_toprog(user,comm,prog,error)
    !---------------------------------------------------------------------
    !
    !---------------------------------------------------------------------
    class(index_user_t), intent(in)    :: user
    type(index_comm_t),  intent(in)    :: comm
    type(index_prog_t),  intent(inout) :: prog
    logical,             intent(inout) :: error
    !
    character(len=16) :: keyword
    character(len=*), parameter :: rname='INDEX>USER>TOPROG'
    !
    call cubeset_message(setseve%trace,rname,'Welcome')
    !
    prog%list = user%list
    if (user%name.ne.strg_unk) then
      call cubetools_keywordlist_user2prog(comm%index_arg,user%name,prog%index,keyword,error)
      if (error) return
    endif
    call user%default%toprog(comm%default,prog%default,error)
    if (error) return
  end subroutine cubeset_index_user_toprog
  !
  subroutine cubeset_index_prog_act(prog,error)
    use cubetools_setup_types
    !---------------------------------------------------------------------
    !
    !---------------------------------------------------------------------
    class(index_prog_t), intent(inout) :: prog
    logical,             intent(inout) :: error
    !
    type(cube_setup_api_t) :: setup
    integer(kind=code_k) :: default_index
    character(len=message_length) :: mess
    character(len=*), parameter :: rname='INDEX>PROG>ACT'
    !
    call cubeset_message(setseve%trace,rname,'Welcome')
    !
    if (prog%default%act)  call setup%index%reset()
    if (.not.prog%list) then
      call setup%index%default%set(prog%index,error)
      if (error) return
    endif
    if (prog%list) then
      call cubeset_message(seve%r,rname,'  Index')
      call setup%index%default%get(default_index)
      write(mess,'(a,a)') '    Default: ',indexname(default_index)
      call cubeset_message(seve%r,rname,mess)
    endif
  end subroutine cubeset_index_prog_act
end module cubeset_index
