!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
module cubetools_processing_types
  use cubetools_parameters
  use cubetools_messaging
  use cubetools_nan
  use cubetools_header_types
  use cubetools_header_methods
  use cubetools_extrema_types
  !---------------------------------------------------------------------
  ! Support module for processing header and data. This in intended to
  ! provide technical components useful at processing time but discarded
  ! in the final product.
  !---------------------------------------------------------------------
  !
  type :: cubetools_processing_t
    type(cubetools_extrema_t), allocatable :: ext(:)  ! Running extremas during processing
  contains
    procedure, private :: allocate_extrema4 => processing_allocate_extrema4
    procedure, private :: allocate_extrema8 => processing_allocate_extrema8
    generic,   public  :: allocate_extrema  => allocate_extrema4,allocate_extrema8
    procedure, public  :: put_extrema       => processing_put_extrema
  end type cubetools_processing_t
  !
contains
  !
  subroutine processing_allocate_extrema4(proc,head,ntasks,error)
    !-------------------------------------------------------------------
    !-------------------------------------------------------------------
    class(cubetools_processing_t), intent(inout) :: proc
    type(cube_header_t),           intent(in)    :: head
    integer(kind=4),               intent(in)    :: ntasks
    logical,                       intent(inout) :: error
    !
    call processing_allocate_extrema8(proc,head,int(ntasks,kind=8),error)
    if (error)  return
  end subroutine processing_allocate_extrema4
  !
  subroutine processing_allocate_extrema8(proc,head,ntasks,error)
    !-------------------------------------------------------------------
    !-------------------------------------------------------------------
    class(cubetools_processing_t), intent(inout) :: proc
    type(cube_header_t),           intent(in)    :: head
    integer(kind=8),               intent(in)    :: ntasks
    logical,                       intent(inout) :: error
    !
    integer(kind=entr_k) :: itask
    !
    if (allocated(proc%ext))  deallocate(proc%ext)
    allocate(proc%ext(ntasks))
    do itask=1,ntasks
      call proc%ext(itask)%init(head,error)
      if (error)  return
    enddo
  end subroutine processing_allocate_extrema8
  !
  subroutine processing_put_extrema(proc,head,error)
    !-------------------------------------------------------------------
    !-------------------------------------------------------------------
    class(cubetools_processing_t), intent(inout) :: proc
    type(cube_header_t),           intent(inout) :: head
    logical,                       intent(inout) :: error
    !
    type(cubetools_extrema_t) :: merge
    character(len=*), parameter :: rname='PROCESSING>PUT>EXTREMA'
    !
    if (.not.allocated(proc%ext))  return
    !
    call merge%merge(head,proc%ext,error)
    if (error)  return
    deallocate(proc%ext)  ! Assume not needed anymore
    !
    ! If no valid data AND no NaN => extrema were not computed
    ! This can happend under 2 conditions:
    ! 1) the output data access does not use the extrema list
    !    (obsolescent, should not happen in the future).
    ! 2) the input data access does not use the extrema list: this
    !    is a feature as we do not recompute extrema for input cubes.
    if (ieee_is_nan(merge%min%val) .and. merge%nnan.eq.0) then
      call cubetools_message(seve%d,rname,'Extrema were not processed, skipping')
      return
    endif
    !
    ! Update header
    call cubetools_header_put_array_minmax(merge%min,merge%max,head,error)
    if (error)  return
    head%arr%n%nan = merge%nnan
  end subroutine processing_put_extrema
  !
end module cubetools_processing_types
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
