!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
module cubeset_scaling
  use cubetools_parameters
  use cubetools_structure
  use cubetools_keyword_arg
  use cubeset_messaging
  !
  public :: scaling,cubeset_scaling_register
  public :: usersca
  private
  !
  type :: scaling_comm_t
     type(option_t),      pointer :: comm
     type(option_t),      pointer :: range
     type(option_t),      pointer :: transfer
     type(keyword_arg_t), pointer :: func_arg
     type(option_t),      pointer :: defaults
   contains
     procedure, public  :: register => cubeset_scaling_register
     procedure, private :: parse    => cubeset_scaling_parse
  end type scaling_comm_t
  type(scaling_comm_t) :: scaling
  !
  type scaling_user_t
     logical               :: dolist     = .false.
     logical               :: dodefaults = .false.
     character(len=argu_l) :: zmin       = strg_star
     character(len=argu_l) :: zmax       = strg_star
     character(len=argu_l) :: function   = strg_star
     real(kind=8)          :: parameter  = 1.0
   contains
     procedure, private :: init    => cubeset_scaling_user_init
     procedure, public  :: toprog  => cubeset_scaling_user_toprog
     procedure, private :: list    => cubeset_scaling_user_list
  end type scaling_user_t
  type(scaling_user_t) :: usersca
  !
contains
    !
  subroutine cubeset_scaling_command(line,error)
    !-------------------------------------------------------------------
    ! Support routine for command SCALING
    !-------------------------------------------------------------------
    character(len=*), intent(in)    :: line
    logical,          intent(inout) :: error
    !
    character(len=*), parameter :: rname='SCALING>COMMAND'
    !
    call cubeset_message(setseve%trace,rname,'Welcome')
    !
    call scaling%parse(line,error)
    if (error) return
    if (usersca%dodefaults) then
       call usersca%init(error)
       if (error) return
    else
       ! Do nothing
    endif
    if (usersca%dolist) then
       call usersca%list(error)
       if (error) return
    else
       ! Do nothing
    endif
  end subroutine cubeset_scaling_command
  !
  !----------------------------------------------------------------------
  !
  subroutine cubeset_scaling_register(scaling,error)
    !-------------------------------------------------------------------
    ! Support routine for register SCALING
    !-------------------------------------------------------------------
    class(scaling_comm_t), intent(inout) :: scaling
    logical,               intent(inout) :: error
    !
    type(standard_arg_t) :: stdarg
    type(keyword_arg_t) :: keyarg
    character(len=*), parameter :: func_list(3) = &
         ['LINEAR     ','LOGARITHMIC','ASINH      ']
    character(len=*), parameter :: comm_abstract = &
         'Set the scaling region of interest'
    character(len=*), parameter :: comm_help = &
         strg_id
    character(len=*), parameter :: rname='SCALING>REGISTER'
    !
    call cubeset_message(setseve%trace,rname,'Welcome')
    !
    call cubetools_register_command(&
         'SCALING','',&
         comm_abstract,&
         comm_help,&
         cubeset_scaling_command,&
         scaling%comm,error)
    if (error) return
    !
    call cubetools_register_option(&
         'RANGE','zmin zmax',&
         'Set minimum and maximum on cubes',&
         strg_id,&
         scaling%range,error)
    if (error) return
    call stdarg%register( &
         'zmin',  &
         'Minimum', &
         strg_id,&
         code_arg_mandatory, &
         error)
    if (error) return
    call stdarg%register( &
         'zmax',  &
         'Maximum', &
         strg_id,&
         code_arg_mandatory, &
         error)
    if (error) return
    !
    call cubetools_register_option(&
         'TRANSFER','function [parameter]',&
         'Set transfer function for plots',&
         'Default transfer function is linear',&
         scaling%transfer,error)
    if (error) return
    call keyarg%register( &
         'function',  &
         'Transfer function to be used', &
         strg_id,&
         code_arg_mandatory, &
         func_list,  &
         .not.flexible,  &
         scaling%func_arg,  &
         error)
    if (error) return
    call stdarg%register( &
         'parameter',  &
         'Parameter for ASINH transfer function, default = 1.0', &
         strg_id,&
         code_arg_optional, &
         error)
    if (error) return
    !
    call cubetools_register_option(&
         'DEFAULTS','',&
         'Reset SCALING defaults',&
         strg_id,&
         scaling%defaults,error)
    if (error) return
  end subroutine cubeset_scaling_register
  !
  subroutine cubeset_scaling_parse(scaling,line,error)
    !-------------------------------------------------------------------
    ! SCALING
    ! /RANGE zmin zmax
    ! /TRANSFER function [parameter]
    ! /DEFAULTS
    !-------------------------------------------------------------------
    class(scaling_comm_t), intent(in)    :: scaling
    character(len=*),      intent(in)    :: line
    logical,               intent(inout) :: error
    !
    character(len=*), parameter :: rname='SCALING>PARSE'
    !
    call cubeset_message(setseve%trace,rname,'Welcome')
    !
    if (cubetools_nopt().eq.0) then
       usersca%dolist = .true.
    else
       usersca%dolist = .false.
       call scaling%defaults%present(line,usersca%dodefaults,error)
       if (error) return
       call cubeset_scaling_parse_range(line,error)
       if (error) return
       call cubeset_scaling_parse_transfer(line,error)
       if (error) return
    endif
  end subroutine cubeset_scaling_parse
  !
  subroutine cubeset_scaling_parse_range(line,error)
    !-------------------------------------------------------------------
    ! /RANGE zmin zmax
    !-------------------------------------------------------------------
    character(len=*), intent(in)    :: line
    logical,          intent(inout) :: error
    !
    logical :: dorange
    character(len=*), parameter :: rname='SCALING>PARSE>RANGE'
    !
    call cubeset_message(setseve%trace,rname,'Welcome')
    !
    call scaling%range%present(line,dorange,error)
    if (error) return
    if (dorange) then
       call cubetools_getarg(line,scaling%range,1,usersca%zmin,mandatory,error)
       if (error) return
       call cubetools_getarg(line,scaling%range,2,usersca%zmax,mandatory,error)
       if (error) return
    endif
  end subroutine cubeset_scaling_parse_range
   !
  subroutine cubeset_scaling_parse_transfer(line,error)
    !-------------------------------------------------------------------
    ! /TRANSFER function [parameter]
    !-------------------------------------------------------------------
    character(len=*), intent(in)    :: line
    logical,          intent(inout) :: error
    !
    logical :: dotransfer
    character(len=*), parameter :: rname='SCALING>PARSE>TRANSFER'
    !
    call cubeset_message(setseve%trace,rname,'Welcome')
    !
    call scaling%transfer%present(line,dotransfer,error)
    if (error) return
    if (dotransfer) then
       call cubetools_getarg(line,scaling%transfer,1,usersca%function,mandatory,error)
       if (error) return
       call cubetools_getarg(line,scaling%transfer,2,usersca%parameter,.not.mandatory,error)
       if (error) return
    endif
  end subroutine cubeset_scaling_parse_transfer
  !
  !----------------------------------------------------------------------
  !
  subroutine cubeset_scaling_user_init(user,error)
    !----------------------------------------------------------------------
    !
    !----------------------------------------------------------------------
    class(scaling_user_t), intent(out)   :: user
    logical,               intent(inout) :: error
    !
    character(len=*), parameter :: rname='SCALING>USER>INIT'
    !
    call cubeset_message(setseve%trace,rname,'Welcome')
    !
  end subroutine cubeset_scaling_user_init
  !
  subroutine cubeset_scaling_user_toprog(user,cube,error)
    use cube_types
    use cubetopology_sparange_types
    !-------------------------------------------------------------------
    ! 
    !-------------------------------------------------------------------
    class(scaling_user_t), intent(inout) :: user
    type(cube_t), pointer, intent(in)    :: cube
    logical,               intent(inout) :: error
    !
    character(len=*), parameter :: rname='SCALING>USER>TOPROG'
    !
    call cubeset_message(setseve%trace,rname,'Welcome')
    !
    ! VVV TO be determined
  end subroutine cubeset_scaling_user_toprog
  !
  subroutine cubeset_scaling_user_list(user,error)
    !-------------------------------------------------------------------
    ! List
    !-------------------------------------------------------------------
    class(scaling_user_t), intent(in)    :: user
    logical,               intent(inout) :: error
    !
    character(len=mess_l) :: mess
    character(len=*), parameter :: rname='SCALING>USER>LIST'
    !
    call cubeset_message(setseve%trace,rname,'Welcome')
    !
    call cubeset_message(seve%r,rname,blankstr)
    write(mess,'(4a)') 'Scale     : ',trim(user%zmin),' to ',trim(user%zmax)
    call cubeset_message(seve%r,rname,mess)
    write(mess,'(3a,1pg14.7,a)') 'Transfer  : ',trim(user%function),', [',user%parameter,']'
    call cubeset_message(seve%r,rname,mess)
    call cubeset_message(seve%r,rname,blankstr)
  end subroutine cubeset_scaling_user_list
end module cubeset_scaling
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
