!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
module cubecompute_difference
  use cubecompute_two2one_template
  use cubecompute_messaging
  !
  public :: cubecompute_difference_register
  private
  !
  type(two2one_comm_t) :: difference
  !
contains
  !
  subroutine cubecompute_difference_register(error)
    use cubedag_allflags
    !----------------------------------------------------------------------
    ! 
    !----------------------------------------------------------------------
    logical, intent(inout) :: error
    !
    character(len=*), parameter :: rname='DIFFERENCE>REGISTER'
    !
    call cubecompute_message(computeseve%trace,rname,'Welcome')
    !
    call difference%register_syntax(&
         'DIFFERENCE','subtrahend','minuend',&
         'Subtract two aligned cubes',&
         'Subtract two aligned cubes entry-by-entry over the&
         & selected region.'//strg_bl//&
         'Behavior:'//strg_cr//&
         '- The result is subtrahend-minuend in the same order as the&
         & command line.'//strg_cr//&
         '- The two inputs must have matching shapes. The output is real only&
         & when both inputs are real. Otherwise it is complex.'//strg_cr//&
         '- If units differ, a warning is emitted and the output unit keeps&
         & subtrahend naming.'//strg_bl//&
         'Examples:'//strg_cr//&
         '- CUBE> DIFFERENCE cube1 cube2.'//strg_cr//&
         '- CUBE> DIFFERENCE cube1 cube2 /RANGE -10km/s 10km/s.',&
         code_access_imaset,[flag_difference],cubecompute_difference_command,&
         error)
    if (error) return
    !
    call difference%unit%register(cubecompute_difference_prog_unit,error)
    if (error) return
    !
    call difference%act%register_imaima2ima(cubecompute_difference_prog_act_imaima,error)
    if (error) return
    call difference%act%register_imavis2vis(cubecompute_difference_prog_act_imavis,error)
    if (error) return
    call difference%act%register_visima2vis(cubecompute_difference_prog_act_visima,error)
    if (error) return
    call difference%act%register_visvis2vis(cubecompute_difference_prog_act_visvis,error)
    if (error) return
  end subroutine cubecompute_difference_register
  !
  subroutine cubecompute_difference_command(line,error)
    !----------------------------------------------------------------------
    !
    !----------------------------------------------------------------------
    character(len=*), intent(in)    :: line
    logical,          intent(inout) :: error
    !
    type(two2one_user_t) :: user
    character(len=*), parameter :: rname='DIFFERENCE>COMMAND'
    !
    call cubecompute_message(computeseve%trace,rname,'Welcome')
    !
    call difference%parse(line,user,error)
    if (error) return
    call difference%main(user,error)
    if (error) continue
  end subroutine cubecompute_difference_command
  !
  subroutine cubecompute_difference_prog_unit(unit1,unit2,ouunit,error)
    !----------------------------------------------------------------------
    ! Set the proper unit of the output cube
    !----------------------------------------------------------------------
    character(len=*), intent(inout) :: unit1
    character(len=*), intent(inout) :: unit2
    character(len=*), intent(inout) :: ouunit
    logical,          intent(inout) :: error
    !
    character(len=*), parameter :: data_unit_null='---'  ! To be factorized
    character(len=*), parameter :: rname='DIFFERENCE>UNIT'
    !
    if (unit1.ne.unit2) then
       call cubecompute_message(seve%w,rname,'Mixing units '//trim(unit1)//' and '//unit2)
    endif
    ouunit = unit1
  end subroutine cubecompute_difference_prog_unit
  !
  !----------------------------------------------------------------------
  !
  subroutine cubecompute_difference_prog_act_imaima(ie,subtrahend,minuend,difference,error)
    use cubetools_parameters
    use cubeadm_image_types
    !----------------------------------------------------------------------
    !
    !----------------------------------------------------------------------
    integer(kind=entr_k), intent(in)    :: ie
    type(image_t),        intent(inout) :: subtrahend
    type(image_t),        intent(inout) :: minuend
    type(image_t),        intent(inout) :: difference
    logical,              intent(inout) :: error
    !
    character(len=*), parameter :: rname='DIFFERENCE>PROG>ACT>IMAIMA'
    !
    include 'action-difference.inc'
  end subroutine cubecompute_difference_prog_act_imaima
  !
  subroutine cubecompute_difference_prog_act_imavis(ie,subtrahend,minuend,difference,error)
    use cubetools_parameters
    use cubeadm_image_types
    use cubeadm_visi_types
    !----------------------------------------------------------------------
    !
    !----------------------------------------------------------------------
    integer(kind=entr_k), intent(in)    :: ie
    type(image_t),        intent(inout) :: subtrahend
    type(visi_t),         intent(inout) :: minuend
    type(visi_t),         intent(inout) :: difference
    logical,              intent(inout) :: error
    !
    character(len=*), parameter :: rname='DIFFERENCE>PROG>ACT>IMAVIS'
    !
    include 'action-difference.inc'
  end subroutine cubecompute_difference_prog_act_imavis
  !
  subroutine cubecompute_difference_prog_act_visima(ie,subtrahend,minuend,difference,error)
    use cubetools_parameters
    use cubeadm_image_types
    use cubeadm_visi_types
    !----------------------------------------------------------------------
    !
    !----------------------------------------------------------------------
    integer(kind=entr_k), intent(in)    :: ie
    type(visi_t),         intent(inout) :: subtrahend
    type(image_t),        intent(inout) :: minuend
    type(visi_t),         intent(inout) :: difference
    logical,              intent(inout) :: error
    !
    character(len=*), parameter :: rname='DIFFERENCE>PROG>ACT>VISIMA'
    !
    include 'action-difference.inc'
  end subroutine cubecompute_difference_prog_act_visima
  !
  subroutine cubecompute_difference_prog_act_visvis(ie,subtrahend,minuend,difference,error)
    use cubetools_parameters
    use cubeadm_visi_types
    !----------------------------------------------------------------------
    !
    !----------------------------------------------------------------------
    integer(kind=entr_k), intent(in)    :: ie
    type(visi_t),         intent(inout) :: subtrahend
    type(visi_t),         intent(inout) :: minuend
    type(visi_t),         intent(inout) :: difference
    logical,              intent(inout) :: error
    !
    character(len=*), parameter :: rname='DIFFERENCE>PROG>ACT>VISVIS'
    !
    include 'action-difference.inc'
  end subroutine cubecompute_difference_prog_act_visvis
end module cubecompute_difference
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
