!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
module cubetemplate_factor_types
  use cubetools_parameters
  use cubetools_structure
  use cubetemplate_messaging
  !
  public :: factor_comm_t,factor_user_t,factor_prog_t
  private
  !
  type factor_comm_t
     type(option_t), pointer :: key
   contains
     procedure, public :: register => cubetemplate_factor_comm_register
     procedure, public :: parse    => cubetemplate_factor_comm_parse
  end type factor_comm_t
  !
  type factor_user_t
     logical               :: do = .false.
     character(len=argu_l) :: val = strg_star
   contains
     procedure, public :: init   => cubetemplate_factor_user_init
     procedure, public :: toprog => cubetemplate_factor_user_toprog
     procedure, public :: list   => cubetemplate_factor_user_list
  end type factor_user_t
  !
  type factor_prog_t
     real(kind=sign_k) :: val
   contains
     procedure, public :: list   => cubetemplate_factor_prog_list
     procedure, public :: header => cubetemplate_factor_prog_header
  end type factor_prog_t
  !
contains
  !
  subroutine cubetemplate_factor_comm_register(comm,error)
    !----------------------------------------------------------------------
    !
    !----------------------------------------------------------------------
    class(factor_comm_t), intent(inout) :: comm
    logical,              intent(inout) :: error
    !
    type(standard_arg_t) :: stdarg
    character(len=*), parameter :: rname='FACTOR>REGISTER'
    !
    call cubetemplate_message(templateseve%trace,rname,'Welcome')
    !
    call cubetools_register_option(&
         'FACTOR','value',&
         'Multiply data by a factor',&
         strg_emp,&
         comm%key,error)
    if (error) return
    call stdarg%register(&
         'value',&
         'Multiplicative factor value',&
         'It defaults to 1.0 when the /FACTOR key is omitted.',&
         code_arg_mandatory,&
         error)
    if (error) return
  end subroutine cubetemplate_factor_comm_register
  !
  subroutine cubetemplate_factor_comm_parse(comm,line,user,error)
    use cubetools_structure
    !----------------------------------------------------------------------
    ! /FACTOR factor
    !----------------------------------------------------------------------
    class(factor_comm_t), intent(in)    :: comm
    character(len=*),     intent(in)    :: line
    type(factor_user_t),  intent(out)   :: user
    logical,              intent(inout) :: error
    !
    integer(kind=argu_k), parameter :: iarg=1
    character(len=*), parameter :: rname='FACTOR>COMM>PARSE'
    !
    call cubetemplate_message(templateseve%trace,rname,'Welcome')
    !
    call comm%key%present(line,user%do,error)
    if (error) return
    if (user%do) then
       call cubetools_getarg(line,comm%key,iarg,user%val,mandatory,error)
       if (error) return
    else
       user%val = strg_star
    endif
  end subroutine cubetemplate_factor_comm_parse
  !
  !------------------------------------------------------------------------
  !
  subroutine cubetemplate_factor_user_init(user,error)
    !----------------------------------------------------------------------
    ! Initialize by setting the intent of factor to out
    !----------------------------------------------------------------------
    class(factor_user_t), intent(out)   :: user 
    logical,              intent(inout) :: error
    !
    character(len=*), parameter :: rname='FACTOR>USER>INIT'
    !
    call cubetemplate_message(templateseve%trace,rname,'Welcome')
  end subroutine cubetemplate_factor_user_init
  !
  subroutine cubetemplate_factor_user_toprog(user,prog,error)
    use cubetools_unit
    use cubetools_user2prog
    !----------------------------------------------------------------------
    !
    !----------------------------------------------------------------------
    class(factor_user_t), intent(in)    :: user
    type(factor_prog_t),  intent(inout) :: prog
    logical,              intent(inout) :: error
    !
    type(unit_user_t) :: nounit
    real(kind=sign_k), parameter :: default=1.0
    character(len=*), parameter :: rname='FACTOR>USER>TOPROG'
    !
    call cubetemplate_message(templateseve%trace,rname,'Welcome')
    !
    ! *** JP This syntax seems very strange to me because we transfer a
    ! *** JP constant object named nounit!
    call nounit%get_from_code(code_unit_unk,error)
    if (error) return
    call cubetools_user2prog_resolve_star(user%val,nounit,default,prog%val,error)
    if (error) return
  end subroutine cubetemplate_factor_user_toprog
  !
  subroutine cubetemplate_factor_user_list(user,error)
    !----------------------------------------------------------------------
    ! Mostly for debugging purpose
    !----------------------------------------------------------------------
    class(factor_user_t), intent(in)    :: user 
    logical,              intent(inout) :: error
    !
    character(len=mess_l) :: mess
    character(len=*), parameter :: rname='FACTOR>USER>LIST'
    !
    call cubetemplate_message(templateseve%trace,rname,'Welcome')
    !
    write(mess,'(2a)') &
         'Factor  : (',trim(user%val)
    call cubetemplate_message(seve%r,rname,mess)
  end subroutine cubetemplate_factor_user_list
  !
  !------------------------------------------------------------------------
  !
  subroutine cubetemplate_factor_prog_header(prog,cube,error)
    use cubetuple_format_class
    use cubetools_axis_types
    use cubetools_header_methods
    !-------------------------------------------------------------------
    ! Update cube header according to the factor
    ! Nothing to be done in this specific case
    !-------------------------------------------------------------------
    class(factor_prog_t), intent(inout) :: prog
    class(format_t),      intent(inout) :: cube
    logical,              intent(inout) :: error
    !
    character(len=*), parameter :: rname='FACTOR>PROG>HEADER'
    !
    call cubetemplate_message(templateseve%trace,rname,'Welcome')
  end subroutine cubetemplate_factor_prog_header
  !
  subroutine cubetemplate_factor_prog_list(prog,error)
    use cubetools_format
    !-------------------------------------------------------------------
    ! List the factor information in a user friendly way
    !-------------------------------------------------------------------
    class(factor_prog_t), intent(in)    :: prog
    logical,              intent(inout) :: error
    !
    character(len=mess_l) :: mess
    character(len=*), parameter :: rname='FACTOR>PROG>LIST'
    !
    call cubetemplate_message(templateseve%trace,rname,'Welcome')
    !
    mess = cubetools_format_stdkey_boldval('Factor',prog%val,fsimple,nsimple)
    call cubetemplate_message(seve%r,rname,mess)
  end subroutine cubetemplate_factor_prog_list
end module cubetemplate_factor_types
! 
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
