;+
;Procedure: THM_LOAD_PROC_ARG
;
;Purpose:  Generic argument validation routine for THEMIS Data File Loading
;   routines, meant to be called by
;   instrument-specific thm_load procedures.
;
;keywords:
;  post_process_proc: name of procedure to call after cdf2tplot is called
;                     will be called w/ keywords sname, dt (datatype), lvl,
;                     and _extra.
;  relpath_funct: name of routine to call in place of file_dailynames
;                 may simply be a wrapper.
;                 will be called w/ keywords sname, dt (datatype), lvl,
;                 and _extra.
;  cdf_to_tplot: user-supplied procedure to override cdf2tplot
;  sname  = site or probe name. The default is 'all',
;  type_sname = string, set to 'probe' or 'site'
;  vsnames = space-separated list of valid probes/sites
;  datatype = The type of data to be loaded, for this case, there is only
;          one option, the default value of 'fgm', so this is a
;          placeholder should there be more that one data type. 'all'
;          can be passed in also, to get all variables.
;  vdatatypes = space-separated list of valid data types
;  file_vdatatypes = space-separated list of file types corresponding to each
;          valid data type.  If there is a one-to-one correpspondence
;          between filetype and datatype, vfiletypes may be left undefined.
;          If all datatypes are in a single file, then vfiltypes may contain
;          a single name, rather than a list.
;  vL2datatypes= space-separated list of datatypes valid for L2 data
;  vL2coord= space-separated list of coordinates valid for L2 data
;  file_vL2datatypes=same as file_vdatatypes, but for L2 data.  Defaults to
;          value of file_vdatatypes.
;  TRANGE= (Optional) Time range of interest  (2 element array), if
;          this is not set, the default is to prompt the user. Note
;          that if the input time range is not a full day, a full
;          day's data is loaded
;  level = the level of the data, the default is 'l1', or level-1
;          data. A string (e.g., 'l2') or an integer can be used. 'all'
;          can be passed in also, to get all levels.
;  vlevels=A space-separated list of valid levels, e.g. 'l1 l2'
;  proc_type =  the type of data, i.e. 'raw' or 'calibrated'. This is
;          for validating the 'type' keyword to thm_load procs.
;  vtypes =A space-separated list of valid types, e.g. 'raw calibrated'
;          No validation on proc_type if not set.
;  deftype = default for type.  only applied to L1.  If not supplied, 
;            then 'calibrated' will be uses as the default value.
;  CDF_DATA: named variable in which to return cdf data structure: only works
;          for a single spacecraft and datafile name.
;  VARNAMES: names of variables to load from cdf: default is all.
;  /GET_SUPPORT_DATA: load support_data variables as well as data variables
;                      into tplot variables.
;  /valid_names, if set, then this routine will return the valid probe, datatype
;          and/or level options in named variables supplied as
;          arguments to the corresponding keywords.
;  files   named varible for output of pathnames of local files.
;  /VERBOSE  set to output some useful info
;Output Keywords:
;  oft     distinct file types that need to be loaded.  Array of strings.
;  ofdt    datatypes corresponding to each file type in ofts. Array of
;          strings, each containing a space-separate list of datatypes .
;  odt     validated datatypes
;  olvl    validated levels.
;  otyp    validated type.
;Notes:
;  This routine is a utility function used to implement thm_load_??? routines.
;
; $LastChangedBy: kenb-mac $
; $LastChangedDate: 2007-08-31 11:13:17 -0700 (Fri, 31 Aug 2007) $
; $LastChangedRevision: 1529 $
; $URL: svn+ssh://thmsvn@ambrosia.ssl.berkeley.edu/repos/thmsoc/tags/tdas_3_01/idl/themis/common/thm_load_proc_arg.pro $
;-
pro thm_load_proc_arg,sname=sname, datatype=datatype, $
                      level=level, coord=coord, proc_type=type, $
                      verbose=verbose, $
                      varformat=varformat, valid_names = valid_names, $
                      type_sname=type_sname, $
                      vsnames=vsnames, vdatatypes=vdatatypes, $
                      file_vdatatypes=file_vdatatypes, $
                      vtypes=vtypes, deftype = deftype, $
                      vlevels=vlevels, deflevel=deflevel, $
                      vL2datatypes=vL2datatypes, vL2coord=vL2coord, $
                      file_vL2datatypes= file_vL2datatypes, $
                      no_download=no_download, msglevel=msglevel, $
                      progobj = progobj, $
                      osname=snames, odt=dts, olvl=lvls, my_themis=my_themis, $
                      oft = fts, ofdt = fdts, otyp = typ, $
                      _ref_extra = _extra

  if not keyword_set(msglevel) then msglevel = -1

  thm_init
; If verbose keyword is defined, override !themis.verbose
  vb = size(verbose, /type) ne 0 ? verbose : !themis.verbose

; Valid sname names
  vsnames = strsplit(vsnames, ' ', /extract)
; Valid data names
  vdatatypes = strsplit(vdatatypes, ' ', /extract) ;for completeness
;valid data levels
  vlevels = strsplit(vlevels, ' ', /extract)
;valid types
  if keyword_set(vtypes) then vtypes = strsplit(vtypes,' ',/extract)

; parse out data level
  if keyword_set(deflevel) then lvl = deflevel else lvl = 'l1'
  if n_elements(level) gt 0 then begin
    if size(level, /type) Eq 7 then begin
      If(level[0] Ne '') Then lvl = strcompress(strlowcase(level), /remove_all)
    endif else lvl = 'l'+strcompress(string(fix(level)), /remove_all)
  endif
  lvls = thm_check_valid_name(strlowcase(lvl), vlevels)
  if not keyword_set(lvls) then return
  if n_elements(lvls) gt 1 then begin
     message, /info, level = msglevel, $
              'only one value may be specified for level'
     return
  endif
  if keyword_set(vb) then printdat, lvls, /value, varname='Level'

;valid coordinate systems for L2
  if keyword_set(vL2coord) then $
     vL2coord = strsplit(vL2coord, ' ', /extract)

  if lvls[0] eq 'l2' && keyword_set(vL2datatypes) then $
     vdatatypes = strsplit(vL2datatypes, ' ', /extract)


;If valid_names is set, return the options
  if keyword_set(valid_names) then begin
    sname = vsnames
    message, /info, level = msglevel, $
             string(strjoin(sname, ','), $
                    format = '( "Valid '+type_sname+'s:",X,A,".")')
    datatype = vdatatypes
    message, /info, level = msglevel, $
             string(strjoin(datatype, ','), $
                    format = '( "Valid '+lvls[0]+' datatypes:",X,A,".")')

    if lvls[0] eq 'l2' && keyword_set(vL2coord) then begin
       coord = vL2coord
       message, /info, level = msglevel, $
                string(strjoin(coord, ','), $
                       format = '( "Valid '+lvls[0]+' coords:",X,A,".")')
    endif

    if lvls[0] eq 'l1' and keyword_set(vtypes) then begin
       type=vtypes
       message,/info,level=msglevel, $
               string(strjoin(type,','), $
                      format='( "Valid '+lvls[0]+' types:",X,A,".")')
    endif

    level = vlevels
    message, /info, level = msglevel, $
             string(strjoin(level, ','), format = '( "Valid levels:",X,A,".")')
    return
  endif
;parse out snames
  if n_elements(sname) eq 1 then if sname eq 'f' then vsnames = ['f']
  if not keyword_set(sname) then snames = vsnames $
  else snames = thm_check_valid_name(strlowcase(sname), vsnames, /include_all)
  if not keyword_set(snames) then return
  if keyword_set(vb) then printdat, snames, /value, varname=type_sname+'s'
;datatype
  if not keyword_set(datatype) then dts = vdatatypes $
  else dts = thm_check_valid_name(strlowcase(datatype), vdatatypes, /include_all)
  if not keyword_set(dts) then return
  if keyword_set(vb) then printdat, dts, /value, varname='Datatypes'
; type
  if lvls[0] eq 'l1' then begin
     if keyword_set(vtypes) then begin
        if not keyword_set(deftype) then deftype = 'calibrated'
        if not keyword_set(type) then typ = deftype $
        else typ = thm_check_valid_name(strlowcase(type), vtypes)
        if not keyword_set(typ) then return
        if keyword_set(vb) then printdat, typ, /value, varname='Type'
     endif else begin
        if vb ge 4 then message, /cont, 'type keyword not validated'
     endelse
  endif else if keyword_set(type) then begin
     print, 'type keyword only applies to l1 data'
     return
  endif

; Level2 probe data : set varformat to get each possible combination of
; datatype and coord
  if lvls[0] eq 'l2' && strlowcase(type_sname) eq 'probe' $
     && ~keyword_set(varformat) && keyword_set(vL2coord) then begin
     if not keyword_set(coord) then crds = vL2coord $
     else crds = thm_check_valid_name(strlowcase(coord), vL2coord, /include_all)
     if not keyword_set(crds) then return
     if keyword_set(vb) then printdat, crds, /value, varname='Coord'
     cross_dt_coord = array_cross(dts, crds)
     varformat = 'th?_' + strjoin(cross_dt_coord, '_')
  endif

  if vb ge 7 then printdat,!themis

  nlvls = n_elements(lvls)
  ndts = n_elements(dts)
  nsnames = n_elements(snames)

  if lvls[0] eq 'l2' && keyword_set(file_vL2datatypes) then $
     file_vdatatypes = file_vL2datatypes

  if keyword_set(file_vdatatypes) then begin
     fts=strarr(ndts)
     file_vdatatypes = strsplit(file_vdatatypes, ' ', /extract)

     if n_elements(file_vdatatypes) eq 1 then begin
        ; fill out file_vdatatypes array to same dimension as vdatatypes
        file_vdatatypes = strarr(n_elements(vdatatypes)) + file_vdatatypes[0]
     endif

     for j = 0, ndts-1 do begin
        fts[j] = file_vdatatypes[where(vdatatypes eq dts[j])]
     endfor
     fts = fts[UNIQ(fts, SORT(fts))]
     nfts = n_elements(fts)
     ;; for each filetype, get a list of requested datatypes
     fdts=strarr(nfts)
     for j = 0, nfts-1 do begin
        file_datatypes = vdatatypes[where(file_vdatatypes eq fts[j])]
        fdts[j] = strjoin(strfilter(file_datatypes,dts), ' ')
     endfor
     if vb ge 7 then printdat, fts  ;;;;
     if vb ge 7 then printdat, fdts                 ;;;;
  endif else begin
     fts = dts
     nfts = n_elements(fts)
     fdts = dts
  endelse

  my_themis = !themis
  my_themis.no_download = !themis.no_download || keyword_set(no_download)
  if keyword_set(progobj) then my_themis.progobj = progobj
  my_themis.verbose=vb

end