!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
module cubedag_allflags
  use cubetools_parameters
  use cubedag_messaging
  use cubedag_flag
  !
  public
  !
  ! Alphabetically ordered list of flags
  type(flag_t), target :: flag_absorption
  type(flag_t), target :: flag_amplitude
  type(flag_t), target :: flag_aperture
  type(flag_t), target :: flag_area
  type(flag_t), target :: flag_average
  type(flag_t), target :: flag_base
  type(flag_t), target :: flag_baseline
  type(flag_t), target :: flag_beam
  type(flag_t), target :: flag_brightness
  type(flag_t), target :: flag_cc
  type(flag_t), target :: flag_centroid
  type(flag_t), target :: flag_circle
  type(flag_t), target :: flag_clean
  type(flag_t), target :: flag_column
  type(flag_t), target :: flag_compare
  type(flag_t), target :: flag_continuum
  type(flag_t), target :: flag_convert
  type(flag_t), target :: flag_cube
  type(flag_t), target :: flag_density
  type(flag_t), target :: flag_detected
  type(flag_t), target :: flag_dirty
  type(flag_t), target :: flag_divergence
  type(flag_t), target :: flag_dx
  type(flag_t), target :: flag_dy
  type(flag_t), target :: flag_edit
  type(flag_t), target :: flag_eight
  type(flag_t), target :: flag_energy
  type(flag_t), target :: flag_equivalent
  type(flag_t), target :: flag_extract
  type(flag_t), target :: flag_extrema
  type(flag_t), target :: flag_feather
  type(flag_t), target :: flag_fft
  type(flag_t), target :: flag_fidelity
  type(flag_t), target :: flag_fields
  type(flag_t), target :: flag_fit
  type(flag_t), target :: flag_five
  type(flag_t), target :: flag_flag
  type(flag_t), target :: flag_four
  type(flag_t), target :: flag_frequency
  type(flag_t), target :: flag_fwhm
  type(flag_t), target :: flag_fwzl
  type(flag_t), target :: flag_gaussian
  type(flag_t), target :: flag_gradient
  type(flag_t), target :: flag_hfs
  type(flag_t), target :: flag_histo1d
  type(flag_t), target :: flag_histo2d
  type(flag_t), target :: flag_horn
  type(flag_t), target :: flag_image
  type(flag_t), target :: flag_inclined
  type(flag_t), target :: flag_line
  type(flag_t), target :: flag_luminosity
  type(flag_t), target :: flag_mask
  type(flag_t), target :: flag_maximum
  type(flag_t), target :: flag_merge
  type(flag_t), target :: flag_method
  type(flag_t), target :: flag_minimize
  type(flag_t), target :: flag_minimum
  type(flag_t), target :: flag_modify
  type(flag_t), target :: flag_moment
  type(flag_t), target :: flag_nh31
  type(flag_t), target :: flag_nh32
  type(flag_t), target :: flag_nh33
  type(flag_t), target :: flag_nine
  type(flag_t), target :: flag_nlines
  type(flag_t), target :: flag_noise
  type(flag_t), target :: flag_npix
  type(flag_t), target :: flag_observed
  type(flag_t), target :: flag_one
  type(flag_t), target :: flag_parameters
  type(flag_t), target :: flag_peak
  type(flag_t), target :: flag_polar
  type(flag_t), target :: flag_primary
  type(flag_t), target :: flag_replace
  type(flag_t), target :: flag_reproject
  type(flag_t), target :: flag_resample
  type(flag_t), target :: flag_residuals
  type(flag_t), target :: flag_result
  type(flag_t), target :: flag_rotate
  type(flag_t), target :: flag_segments
  type(flag_t), target :: flag_seven
  type(flag_t), target :: flag_shell
  type(flag_t), target :: flag_shuffle
  type(flag_t), target :: flag_signal
  type(flag_t), target :: flag_six
  type(flag_t), target :: flag_sky
  type(flag_t), target :: flag_slice
  type(flag_t), target :: flag_smooth
  type(flag_t), target :: flag_snr
  type(flag_t), target :: flag_sort
  type(flag_t), target :: flag_spectrum
  type(flag_t), target :: flag_stack
  type(flag_t), target :: flag_stitch
  type(flag_t), target :: flag_sum
  type(flag_t), target :: flag_table
  type(flag_t), target :: flag_tau
  type(flag_t), target :: flag_template
  type(flag_t), target :: flag_ten
  type(flag_t), target :: flag_three
  type(flag_t), target :: flag_tmp
  type(flag_t), target :: flag_two
  type(flag_t), target :: flag_uv
  type(flag_t), target :: flag_uvfit
  type(flag_t), target :: flag_velocity
  type(flag_t), target :: flag_volume
  type(flag_t), target :: flag_weight
  type(flag_t), target :: flag_width
  type(flag_t), target :: flag_window
  type(flag_t), target :: flag_xy
  !
contains
  !
  subroutine cubedag_allflags_init(error)
    !-------------------------------------------------------------------
    ! Register all flags
    !-------------------------------------------------------------------
    logical, intent(inout) :: error
    !
    ! Action flags
    call flag_aperture%register ('aperture',   code_kind_action,error)
    call flag_average%register  ('averaged',   code_kind_action,error)
    call flag_baseline%register ('baselined',  code_kind_action,error)
    call flag_compare%register  ('compared',   code_kind_action,error)
    call flag_convert%register  ('converted',  code_kind_action,error)
    call flag_detected%register ('detected',   code_kind_action,error)
    call flag_edit%register     ('edited',     code_kind_action,error)
    call flag_extract%register  ('extracted',  code_kind_action,error)
    call flag_extrema%register  ('extrema',    code_kind_action,error)
    call flag_feather%register  ('feathered',  code_kind_action,error)
    call flag_merge%register    ('merged',     code_kind_action,error)
    call flag_minimize%register ('minimized',  code_kind_action,error)
    call flag_modify%register   ('modified',   code_kind_action,error)
    call flag_replace%register  ('replaced',   code_kind_action,error)
    call flag_reproject%register('reprojected',code_kind_action,error)
    call flag_resample%register ('resampled',  code_kind_action,error)
    call flag_rotate%register   ('rotated',    code_kind_action,error)
    call flag_shuffle%register  ('shuffled',   code_kind_action,error)
    call flag_slice%register    ('slice',      code_kind_action,error) ! *** JP ???
    call flag_smooth%register   ('smoothed',   code_kind_action,error)
    call flag_sort%register     ('sorted',     code_kind_action,error)
    call flag_stack%register    ('stacked',    code_kind_action,error)
    call flag_stitch%register   ('stitched',   code_kind_action,error)
    call flag_template%register ('template',   code_kind_action,error)
    if (error) return
    !
    ! Product flags
    ! Basics
    call flag_flag%register      ('flag',      code_kind_product,error) ! *** JP ???
    call flag_tmp%register       ('tmp',       code_kind_product,error)
    call flag_cube%register      ('cube',      code_kind_product,error)
    call flag_spectrum%register  ('spectrum',  code_kind_product,error)
    call flag_image%register     ('image',     code_kind_product,error)
    call flag_window%register    ('window',    code_kind_product,error)
    ! Signal, noise, weight, SNR, ...
    call flag_mask%register      ('mask',      code_kind_product,error)
    call flag_signal%register    ('signal',    code_kind_product,error)
    call flag_noise%register     ('noise',     code_kind_product,error)
    call flag_snr%register       ('snr',       code_kind_product,error)
    call flag_weight%register    ('weight',    code_kind_product,error)
    ! BASELINE related flags
    call flag_base%register      ('base',      code_kind_product,error)
    call flag_line%register      ('line',      code_kind_product,error)
    ! CIRCLE related flags
    call flag_circle%register    ('circle',    code_kind_product,error)
    call flag_npix%register      ('npix',      code_kind_product,error)
    call flag_sum%register       ('sum',       code_kind_product,error)
    call flag_minimum%register   ('minimum',   code_kind_product,error)
    call flag_maximum%register   ('maximum',   code_kind_product,error)
    ! COMPARE related flags
    call flag_residuals%register ('residuals', code_kind_product,error)
    call flag_fidelity%register  ('fidelity',  code_kind_product,error)
    ! HISTO related flags
    call flag_histo1d%register   ('histo1d',   code_kind_product,error)
    call flag_histo2d%register   ('histo2d',   code_kind_product,error)
    ! MOMENTS related flags
    call flag_moment%register    ('moment',    code_kind_product,error)
    call flag_peak%register      ('peak',      code_kind_product,error)
    call flag_area%register      ('area',      code_kind_product,error)
    call flag_velocity%register  ('velocity',  code_kind_product,error)
    call flag_centroid%register  ('centroid',  code_kind_product,error)
    call flag_fwhm%register      ('fwhm',      code_kind_product,error)
    call flag_equivalent%register('equivalent',code_kind_product,error)
    call flag_width%register     ('width',     code_kind_product,error)
    call flag_brightness%register('brightness',code_kind_product,error)
    ! POLAR related flags
    call flag_polar%register     ('polar',     code_kind_product,error)
    ! SEGMENT related flags
    call flag_segments%register  ('segments',  code_kind_product,error)
    call flag_energy%register    ('energy',    code_kind_product,error)
    call flag_luminosity%register('luminosity',code_kind_product,error)
    if (error) return
    !
    ! COMPUTE related flags
    call flag_amplitude%register ('amplitude', code_kind_product,error)
    call flag_fft%register       ('fft',       code_kind_product,error)
    if (error) return
    !
    ! CLASS and MAPPING flags
    call flag_uvfit%register  ('uvfit',  code_kind_product,error)
    call flag_uv%register     ('uv',     code_kind_product,error)
    call flag_xy%register     ('xy',     code_kind_product,error)
    !
    call flag_cc%register     ('cc',     code_kind_product,error)
    call flag_table%register  ('table',  code_kind_product,error)
    !
    call flag_beam%register   ('beam',   code_kind_product,error)
    call flag_clean%register  ('clean',  code_kind_product,error)
    call flag_dirty%register  ('dirty',  code_kind_product,error)
    call flag_fields%register ('fields', code_kind_product,error)
    call flag_primary%register('primary',code_kind_product,error)
    call flag_sky%register    ('sky',    code_kind_product,error)
    if (error) return
    !
    ! FIT related flags
    call flag_fit%register       ('fit',       code_kind_product,error)
    call flag_method%register    ('method',    code_kind_product,error)
    call flag_nlines%register    ('nlines',    code_kind_product,error)
    call flag_parameters%register('parameters',code_kind_product,error)
    call flag_result%register    ('result',    code_kind_product,error)
    call flag_gaussian%register  ('gaussian',  code_kind_product,error)
    call flag_hfs%register       ('hfs',       code_kind_product,error)
    call flag_nh31%register      ('nh31',      code_kind_product,error)
    call flag_nh32%register      ('nh32',      code_kind_product,error)
    call flag_nh33%register      ('nh33',      code_kind_product,error)
    call flag_absorption%register('absorption',code_kind_product,error)
    call flag_shell%register     ('shell',     code_kind_product,error)
    call flag_fwzl%register      ('fwzl',      code_kind_product,error)
    call flag_horn%register      ('horn',      code_kind_product,error)
    call flag_one%register       ('1',         code_kind_product,error)
    call flag_two%register       ('2',         code_kind_product,error)
    call flag_three%register     ('3',         code_kind_product,error)
    call flag_four%register      ('4',         code_kind_product,error)
    call flag_five%register      ('5',         code_kind_product,error)
    call flag_six%register       ('6',         code_kind_product,error)
    call flag_seven%register     ('7',         code_kind_product,error)
    call flag_eight%register     ('8',         code_kind_product,error)
    call flag_nine%register      ('9',         code_kind_product,error)
    call flag_ten%register       ('10',        code_kind_product,error)
    call flag_tau%register       ('tau',       code_kind_product,error)
    call flag_continuum%register ('continuum', code_kind_product,error)
    call flag_frequency%register ('frequency', code_kind_product,error)
    if (error) return
    !
    ! FIELD related flags
    call flag_inclined%register('inclined',code_kind_action,error)
    call flag_observed%register('observed',code_kind_action,error)
    if (error) return
    call flag_column%register    ('column',    code_kind_product,error)
    call flag_volume%register    ('volume',    code_kind_product,error)
    call flag_density%register   ('density',   code_kind_product,error)
    call flag_divergence%register('divergence',code_kind_product,error)
    call flag_gradient%register  ('gradient',  code_kind_product,error)
    call flag_dx%register        ('dx',        code_kind_product,error)
    call flag_dy%register        ('dy',        code_kind_product,error)
    if (error) return
    !
    ! Compute the sorting array
    call cubedag_flaglist_sort(error)
    if (error)  return
  end subroutine cubedag_allflags_init
  !
  subroutine cubedag_mapping_ext2flag(ext,flag,error)
    use gkernel_interfaces
    use cubetools_disambiguate
    use cubedag_messaging
    !-------------------------------------------------------------------
    ! Return MAPPING90 related flag(s) from a file extension. Leave
    ! unallocated if no match (no warning nor error).
    !-------------------------------------------------------------------
    character(len=*),          intent(in)    :: ext
    type(flag_t), allocatable, intent(out)   :: flag(:)
    logical,                   intent(inout) :: error
    !
    character(len=argu_l) :: key
    integer(kind=4) :: ier
    character(len=*), parameter :: rname='MAPPING>EXT2FLAG'
    !
    call cubedag_message(seve%t,rname,'Welcome')
    !
    call cubetools_disambiguate_toupper(ext,key,error)
    if (error) return
    select case(key)
    case('BEAM')
       allocate(flag(2),stat=ier)
       if (failed_allocate(rname,'flags',ier,error)) return
       flag(:) = [flag_dirty,flag_beam]
    case('LMV')
       allocate(flag(2),stat=ier)
       if (failed_allocate(rname,'flags',ier,error)) return
       flag(:) = [flag_dirty,flag_cube]
    case('LMV-CLEAN')
       allocate(flag(2),stat=ier)
       if (failed_allocate(rname,'flags',ier,error)) return
       flag(:) = [flag_clean,flag_cube]
    case('LOBE')
       allocate(flag(1),stat=ier)
       if (failed_allocate(rname,'flags',ier,error)) return
       flag(:) = [flag_primary]
    case('LMV-RES')
       allocate(flag(2),stat=ier)
       if (failed_allocate(rname,'flags',ier,error)) return
       flag(:) = [flag_clean,flag_residuals]
    case('MSK')
       allocate(flag(2),stat=ier)
       if (failed_allocate(rname,'flags',ier,error)) return
       flag(:) = [flag_clean,flag_mask]
    case('LMV-SKY')
       allocate(flag(3),stat=ier)
       if (failed_allocate(rname,'flags',ier,error)) return
       flag(:) = [flag_clean,flag_sky,flag_cube]
    case('FIELDS')
       allocate(flag(1),stat=ier)
       if (failed_allocate(rname,'flags',ier,error)) return
       flag(:) = [flag_fields]
    case('UVT')
       allocate(flag(2),stat=ier)
       if (failed_allocate(rname,'flags',ier,error)) return
       flag(:) = [flag_uv,flag_table]
    case('TAB')
       allocate(flag(2),stat=ier)
       if (failed_allocate(rname,'flags',ier,error)) return
       flag(:) = [flag_xy,flag_table]
    case('UVFIT')
       allocate(flag(2),stat=ier)
       if (failed_allocate(rname,'flags',ier,error)) return
       flag(:) = [flag_uvfit,flag_table]
    case('CCT')
       allocate(flag(2),stat=ier)
       if (failed_allocate(rname,'flags',ier,error)) return
       flag(:) = [flag_cc,flag_table]
    end select
  end subroutine cubedag_mapping_ext2flag
  !
  subroutine cubedag_class_ext2flag(ext,flag,error)
    use gkernel_interfaces
    use cubetools_disambiguate
    use cubedag_messaging
    !-------------------------------------------------------------------
    ! Return CLASS90 related flag(s) from a file extension. Leave
    ! unallocated if no match (no warning nor error).
    !-------------------------------------------------------------------
    character(len=*),          intent(in)    :: ext
    type(flag_t), allocatable, intent(out)   :: flag(:)
    logical,                   intent(inout) :: error
    !
    character(len=argu_l) :: key
    integer(kind=4) :: ier
    character(len=*), parameter :: rname='CLASS>EXT2FLAG'
    !
    call cubedag_message(seve%t,rname,'Welcome')
    !
    call cubetools_disambiguate_toupper(ext,key,error)
    if (error) return
    select case(key)
    case('LMV')
       allocate(flag(1),stat=ier)
       if (failed_allocate(rname,'flags',ier,error)) return
       flag(:) = [flag_cube]
    case('WEI')
       allocate(flag(1),stat=ier)
       if (failed_allocate(rname,'flags',ier,error)) return
       flag(:) = [flag_weight]
    case('TAB')
       allocate(flag(1),stat=ier)
       if (failed_allocate(rname,'flags',ier,error)) return
       flag(:) = [flag_table]
    end select
  end subroutine cubedag_class_ext2flag
end module cubedag_allflags
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
