!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
module cubetools_dataformat
  use cubetools_parameters
  use cubetools_messaging
  use cubetools_structure
  use cubetools_keyword_arg
  !
  public :: dataformat_opt_t,datadescr_opt_t
  public :: code_dataformat_none,  &
            code_dataformat_cube,code_dataformat_interface, &
            code_dataformat_fits,code_dataformat_gdf,code_dataformat_vo
  private
  !
  integer(kind=code_k), parameter :: code_dataformat_none      = 0
  integer(kind=code_k), parameter :: code_dataformat_cube      = 1
  integer(kind=code_k), parameter :: code_dataformat_interface = 2
  integer(kind=code_k), parameter :: code_dataformat_fits      = 3
  integer(kind=code_k), parameter :: code_dataformat_gdf       = 4
  integer(kind=code_k), parameter :: code_dataformat_vo        = 5

  integer(kind=4),       parameter :: form_l = 9
  integer(kind=4),       parameter :: ndataformat = 5
  character(len=form_l), parameter :: dataformatkeys(ndataformat) = [&
       'CUBE     ',&
       'INTERFACE',&
       'FITS     ',&
       'GDF      ',&
       'VO       ']
  !
  type dataformat_opt_t
     type(option_t),      pointer :: opt
     type(keyword_arg_t), pointer :: arg
   contains
     procedure :: register  => cubetools_dataformat_register
     procedure :: parse     => cubetools_dataformat_parse
  end type dataformat_opt_t
  !
  type datadescr_opt_t
     type(option_t),      pointer :: opt
     type(keyword_arg_t), pointer :: arg
   contains
     procedure :: register  => cubetools_datadescr_register
     procedure :: parse     => cubetools_datadescr_parse
  end type datadescr_opt_t
  !
contains
  !
  subroutine cubetools_dataformat_register(dataformat,error)
    !---------------------------------------------------------------------
    !
    !---------------------------------------------------------------------
    class(dataformat_opt_t), intent(out)   :: dataformat
    logical,                 intent(inout) :: error
    !
    type(keyword_arg_t) :: keyarg
    character(len=*), parameter :: rname='DATAFORMAT>REGISTER'
    !
    call cubetools_message(toolseve%trace,rname,'Welcome')
    !
    call cubetools_register_option(&
         'FORMAT','format',&
         'Select the format to list the header',&
         'The are 3 possible formats: CUBE (default if option is not&
         & given), GDF (same as in VECTOR\GREG) and FITS (List the&
         & FITS file header)',&
         dataformat%opt,error)
    if (error) return
    call keyarg%register( &
         'format',  &
         'Listing format for the header', &
         strg_id,&
         code_arg_mandatory, &
         dataformatkeys, &
         .not.flexible, &
         dataformat%arg, &
         error)
    if (error) return
  end subroutine cubetools_dataformat_register
  !
  subroutine cubetools_datadescr_register(datadescr,error)
    !---------------------------------------------------------------------
    !
    !---------------------------------------------------------------------
    class(datadescr_opt_t), intent(out)   :: datadescr
    logical,                intent(inout) :: error
    !
    type(keyword_arg_t) :: keyarg
    character(len=*), parameter :: rname='DATADESCR>REGISTER'
    !
    call cubetools_message(toolseve%trace,rname,'Welcome')
    !
    call cubetools_register_option(&
         'DESCRIPTION','Description',&
         'Select the format to describe',&
         strg_id,&
         datadescr%opt,error)
    if (error) return
    call keyarg%register( &
         'description',  &
         'Listing format to be described', &
         strg_id,&
         code_arg_mandatory, &
         dataformatkeys, &
         .not.flexible, &
         datadescr%arg, &
         error)
    if (error) return
  end subroutine cubetools_datadescr_register
  !
  subroutine cubetools_dataformat_parse(dataformat,line,code,error)
    use cubetools_structure
    use cubetools_disambiguate
    !---------------------------------------------------------------------
    !
    !---------------------------------------------------------------------
    class(dataformat_opt_t), intent(in)    :: dataformat
    character(len=*),        intent(in)    :: line
    integer(kind=code_k),    intent(inout) :: code  ! Unchanged if option missing
    logical,                 intent(inout) :: error
    !
    integer(kind=4) :: ikey
    logical :: do
    character(len=argu_l) :: keyword,argument
    integer(kind=argu_k), parameter :: iarg=1
    character(len=*), parameter :: rname='DATAFORMAT>PARSE'
    !
    call cubetools_message(toolseve%trace,rname,'Welcome')
    !
    call dataformat%opt%present(line,do,error)
    if (error) return
    if (do) then
       call cubetools_getarg(line,dataformat%opt,1,argument,mandatory,error)
       if (error) return
       call cubetools_keyword_user2prog(dataformat%arg,argument,ikey,keyword,error)
       if (error) return
       code = ikey
    endif
  end subroutine cubetools_dataformat_parse
  !
  subroutine cubetools_datadescr_parse(datadescr,line,code,error)
    use cubetools_structure
    use cubetools_disambiguate
    !---------------------------------------------------------------------
    !  ZZZ Identical to cubetools_dataformat_parse except input class!
    !---------------------------------------------------------------------
    class(datadescr_opt_t), intent(in)    :: datadescr
    character(len=*),       intent(in)    :: line
    integer(kind=code_k),   intent(inout) :: code  ! Unchanged if option missing
    logical,                intent(inout) :: error
    !
    integer(kind=4) :: ikey
    logical :: do
    character(len=argu_l) :: keyword,argument
    integer(kind=argu_k), parameter :: iarg=1
    character(len=*), parameter :: rname='DATADESCR>PARSE'
    !
    call cubetools_message(toolseve%trace,rname,'Welcome')
    !
    call datadescr%opt%present(line,do,error)
    if (error) return
    if (do) then
       call cubetools_getarg(line,datadescr%opt,1,argument,mandatory,error)
       if (error) return
       call cubetools_keyword_user2prog(datadescr%arg,argument,ikey,keyword,error)
       if (error) return
       code = ikey
    endif
  end subroutine cubetools_datadescr_parse
end module cubetools_dataformat
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
