!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
module cubefit_selection
  use cubefit_parameters
  use cubefit_messaging
  use cubetools_structure
  use cubetools_keywordlist_types
  !
  public :: selection_opt_t, selection_user_t, selection_prog_t
  private
  !
  type selection_opt_t
     type(option_t),      pointer :: opt
     type(keywordlist_comm_t), pointer :: meth_arg
   contains
     procedure :: register  => cubefit_selection_register
     procedure :: parse     => cubefit_selection_parse
     procedure :: user2prog => cubefit_selection_user2prog
  end type selection_opt_t
  !
  type selection_user_t
     character(len=argu_l) :: meth
     character(len=argu_l) :: ifunc
     logical               :: do
  end type selection_user_t
  !
  type selection_prog_t
     character(len=meth_l) :: meth
     integer(kind=code_k)  :: imeth
     integer(kind=func_k)  :: ifunc
  end type selection_prog_t
  !
contains
  !
  subroutine cubefit_selection_register(sel,error)
    !----------------------------------------------------------------------
    ! Register a /SELECTION option 
    ! ----------------------------------------------------------------------
    class(selection_opt_t), intent(out)   :: sel
    logical,                intent(inout) :: error
    !
    type(standard_arg_t) :: stdarg
    type(keywordlist_comm_t)  :: keyarg
    !
    character(len=*), parameter :: rname='SELECTION>REGISTER'
    !
    call cubefit_message(fitseve%trace,rname,'Welcome')
    !
    call cubetools_register_option(&
         'SELECT','method [ifunc]',&
         'Choose which fitted method/component to keep',&
         'Use /SELECT to keep either all fitted components or one chosen&
         & method/component in the output. If ifunc is omitted, 0, or "*",&
         & all components of the selected method are kept.',&
         sel%opt,error)
    if (error) return
    call keyarg%register(&
         'method',&
         'Fit family to keep',&
         'Use * to keep all fitted methods.',&
         code_arg_mandatory,&
         methnames,&
         .not.flexible,&
         sel%meth_arg,&
         error)
    if (error) return
    call stdarg%register(&
         'ifunc',&
         'Component number to keep',&
         'Use 0 or * to keep all components of the selected method. Use a&
         & positive integer to isolate one component.',&
         code_arg_optional,&
         error)
    if (error) return
  end subroutine cubefit_selection_register
  !
  subroutine cubefit_selection_parse(sel,line,user,error)
    !----------------------------------------------------------------------
    ! /SELECTION method [ifunc]
    !----------------------------------------------------------------------
    class(selection_opt_t), intent(in)    :: sel
    character(len=*),       intent(in)    :: line
    type(selection_user_t), intent(out)   :: user
    logical,                intent(inout) :: error
    !
    character(len=*), parameter     :: rname='SELECTION>PARSE'
    !
    call cubefit_message(fitseve%trace,rname,'Welcome')
    !
    call sel%opt%present(line,user%do,error)
    if (error) return
    if (user%do) then
       call cubetools_getarg(line,sel%opt,1,user%meth,mandatory,error)
       if (error) return
       user%ifunc = strg_star
       call cubetools_getarg(line,sel%opt,2,user%ifunc,.not.mandatory,error)
       if (error) return
    endif
  end subroutine cubefit_selection_parse
  !
  subroutine cubefit_selection_user2prog(sel,user,prog,error)
    use cubetools_user2prog
    !----------------------------------------------------------------------
    ! 
    !----------------------------------------------------------------------
    class(selection_opt_t), intent(in)    :: sel
    type(selection_user_t), intent(in)    :: user
    type(selection_prog_t), intent(out)   :: prog
    logical,                intent(inout) :: error
    !
    character(len=mess_l) :: mess
    integer(kind=func_k), parameter :: defifunc = 0
    character(len=*), parameter :: rname='SELECTION>USER2PROG'
    !
    call cubefit_message(fitseve%trace,rname,'Welcome')
    !
    if (user%do) then
       if (user%meth.eq.strg_star) then
          prog%imeth = code_method_all
          prog%meth  = "All"
       else
          call cubetools_keywordlist_user2prog(sel%meth_arg,user%meth,prog%imeth,prog%meth,error)
          if (error) return
       endif
       call cubetools_user2prog_resolve_star(user%ifunc,defifunc,prog%ifunc,error)
       if (error) return
       if (prog%ifunc.lt.0) then
          call cubefit_message(seve%e,rname,"Selected line must be positive")
          error = .true.
          return
       endif
    else
       prog%imeth = code_method_all
       prog%meth  = "All"
       prog%ifunc = 0
    endif
    !
    ! User feedback
    select case(prog%ifunc)
    case (0)
       write (mess,'(a)') 'Selected all lines'
    case default
       write (mess,'(a,i0,a)') 'Selected ',prog%ifunc,'-th line'
    end select
    if (prog%imeth.eq.0) then
       write (mess,'(2a)') trim(mess),' for all methods'
    else
       write (mess,'(4a)') trim(mess),' of the ',trim(prog%meth),' method'
    endif
    call cubefit_message(seve%i,rname,mess)
  end subroutine cubefit_selection_user2prog
end module cubefit_selection
