!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
module cubefield_minmax
  use cubetools_parameters
  use cubetemplate_one2two_image_template
  use cubefield_messaging
  !
  public :: cubefield_minmax_register
  private
  !
  type(one2two_image_comm_t) :: minmax
  !
contains
  !
  subroutine cubefield_minmax_register(error)
    use cubedag_allflags
    !----------------------------------------------------------------------
    !
    !----------------------------------------------------------------------
    logical, intent(inout) :: error
    !
    character(len=*), parameter :: comm_abstract = &
         'Detect local minima and maxima in image slices'
    character(len=*), parameter :: comm_help = &
         'Detect strict local minima and maxima on each selected image&
         & slice of the input 3D cube by comparing every interior pixel&
         & with its 8 neighbors. The min output keeps only strict minima&
         & and the max output keeps only strict maxima. Border pixels&
         & and flat plateaus remain blank.'
    character(len=*), parameter :: incube_help = &
         'Use the input 3D cube. If omitted, use the last matching cube&
         & in the default index (DAG by default; see SET\INDEX).'
    character(len=*), parameter :: ou1help = 'Local minimum values'
    character(len=*), parameter :: ou2help = 'Local maximum values'
    character(len=*), parameter :: rname='MINMAX>REGISTER'
    !
    call cubefield_message(fieldseve%trace,rname,'Welcome')
    !
    call minmax%register_syntax(&
         'MINMAX','cubeid','3D cube',[flag_any],cubefield_minmax_command,&
         'min',[flag_local,flag_2d,flag_minimum],&
         'max',[flag_local,flag_2d,flag_maximum],&
         error,&
         comm_abstract=comm_abstract,&
         comm_help=comm_help,&
         incube_help=incube_help,&
         ou1help=ou1help,&
         ou2help=ou2help)
    if (error) return
    call minmax%register_act(cubefield_minmax_prog_act,error)
    if (error) return
  end subroutine cubefield_minmax_register
  !
  subroutine cubefield_minmax_command(line,error)
    !----------------------------------------------------------------------
    !
    !----------------------------------------------------------------------
    character(len=*), intent(in)    :: line
    logical,          intent(inout) :: error
    !
    type(one2two_image_user_t) :: user
    character(len=*), parameter :: rname='MINMAX>COMMAND'
    !
    call cubefield_message(fieldseve%trace,rname,'Welcome')
    !
    call minmax%parse(line,user,error)
    if (error) return
    call minmax%main(user,error)
    if (error) continue
  end subroutine cubefield_minmax_command
  !
  !----------------------------------------------------------------------
  !
  subroutine cubefield_minmax_prog_act(prog,ie,ima,min,max,error)
    !    use cubetools_parameters
    use cubetools_nan
    use cubeadm_image_types
    use cubefield_pixel_types
    !----------------------------------------------------------------------
    !
    !----------------------------------------------------------------------
    class(one2two_image_prog_t), intent(inout) :: prog
    integer(kind=entr_k),        intent(in)    :: ie
    type(image_t),               intent(inout) :: ima
    type(image_t),               intent(inout) :: min
    type(image_t),               intent(inout) :: max
    logical,                     intent(inout) :: error
    !
    logical :: ismin,ismax
    integer(kind=pixe_k) :: ix,iy
    integer(kind=indx_k) :: ilist
    type(pixprop_t) :: list(8)
    character(len=*), parameter :: rname='MINMAX>PROG>ACT'
    !
    !***JP: Should be parameter initialization
    list(1)%ix =  0
    list(1)%iy = +1
    list(2)%ix = +1
    list(2)%iy = +1
    list(3)%ix = +1
    list(3)%iy =  0
    list(4)%ix = +1
    list(4)%iy = -1
    list(5)%ix =  0
    list(5)%iy = -1
    list(6)%ix = -1
    list(6)%iy = -1
    list(7)%ix = -1
    list(7)%iy =  0
    list(8)%ix = -1
    list(8)%iy = +1
    !
!!$    do ilist=1,8
!!$       print *,'pixel #',ilist,'(ix,iy) = ',list(ilist)%ix,list(ilist)%iy
!!$    enddo
    !      
    call ima%get(ie,error)
    if (error) return
    call min%set(gr4nan,error)
    if (error) return
    call max%set(gr4nan,error)
    if (error) return
    do ix=2,ima%nx-1
       do iy=2,ima%ny-1
          ismin = .true.
          do ilist=1,8
             if (ima%val(ix,iy).ge.ima%val(ix+list(ilist)%ix,iy+list(ilist)%iy)) then
                ismin = .false.
                exit
             endif
          enddo
          if (ismin) then
             min%val(ix,iy) = ima%val(ix,iy)
          endif
          !
          ismax = .true.
          do ilist=1,8
             if (ima%val(ix,iy).le.ima%val(ix+list(ilist)%ix,iy+list(ilist)%iy)) then
                ismax = .false.
                exit
             endif
          enddo
          if (ismax) then
             max%val(ix,iy) = ima%val(ix,iy)
          endif
       enddo ! iy
    enddo ! ix
    call min%put(ie,error)
    if (error) return
    call max%put(ie,error)
    if (error) return
  end subroutine cubefield_minmax_prog_act
end module cubefield_minmax
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
