pro write_sot,index,data,online=online,level=level,         $
   parent=parent, make_dir=make_dir, $
   prefix=prefix, outfile=outfile, outdir=outdir, millisec=millisec, $
   verbose=verbose, loud=loud, paths_only=paths_only, out_paths=out_paths, $
   add_prefix=add_prefix, flat_fits=flat_fits, quiet=quiet, version=version
;+
;   Name: write_sot
;
;   Purpose: save input sot 'index,data' -> files, default is flat fits
;
;   Input Parameters:
;      index,data - ssw standard sot index,data - 2D or 3D ok
;
;   Output Parameters:
;      ofiles=string array of output file names as written w/full path
;
;   Keyword Parameters:
;      online - if set, imply sot-like path <top>/yyyy/mm/dd/<obsdir>/Hhhhh/
;               Where top is  via $SOT_DATA_L<level> environmental 
;               or via PARENT explicit path
;      parent - if set, write to <parent>/yyyy/mm/dd/<obsdir>/Hhhhh/
;               (e.g., implies sot-like organization)
;      level -  if set, processing level  - will change environmental lookup
;               EX: /LEVEL => Level=1 -> $SOT_DATA_L1
;      outfile - optional fully qualified names/paths for output
;      outdir - fully qualified output directory (default is cudir(), unless
;                  /ONLINE is set which implies sot-like organization
;                  rooted aat <PARENT>, $SOT_DATA_L<level>, or curdir() 
;                  
;      make_dir - if set, create implied directories if they do not exist
;      millisec - if set, file name granularity->millisecs (def=decisecs)
;      loud, verbose - (switch) synonyms - print some informational messages
;      out_paths - (output) - implied/derived full file paths as run
;      paths_only - (switch) - if set, just return OUT_PATHS but don't 
;                   write any files
;      prefix - optional file prefix to inlude in filenames 
;               Default derived from index.OBS_TYPE, ;
;      add_prefix - if set, add this "partial prefix" to the implied
;                 obs_type derived prefix - for example   
;                 IDL> write_sot,index,data,add_prefix='L1' writes files like
;                      FGyyyymmdd... -> FGL1yyyymmdd... 
;                      
;   Calling Sequence:
;      IDL> write_sot,index,data [,/online], [,/level] [,outfile=filenames]
;
;   Calling Examples:
;      IDL> write_sot,index,data          ; autonamed files->current directory
;      IDL> write_sot,index,data,parent=parent,/online
;           (writes sot-like org:
;           <parent>/yyyy/mm/dd/<obsdir>/Hhhhh/<prefix>yyyymmdd_hhmmss.?.fits
; 
;      IDL> write_sot,index,parent='/parent',/online,/paths_only,out_path=ops
;           Tip: use /PATHS_ONLY to skip write and return "intended path/name"
;            via OUT_PATHS output keyword for testing various options) 
;
;   Method:
;      set up call to ssw-gen routine 'mwritefits.pro' 
;      based on index+supplied keywords
;
;   History:
;      4-Jan-2007 - S.L.Freeland
;      9-jan-2007 - S.L.Freeland - use sot_index2fileinfo.pro call - version 1.0
;     28-apr-2009 - S.L.Freeland - Fix historic OUTFILE/FILENAMES mix
;
;   Side Effects:
;      Writes files to specified or implied directory(ies); if none
;      of the auto-directory options is set and OUTDIR not explicitly
;      set, files written to current directory.
;      If /MAKE_DIR is set, implied directories which do not exist
;      are created.
;
;   Restrictions:
;      Obviously...assumes caller has appropriate permission for
;      directory and/or file creations (/online for example)
;      FITS only for today 
;
;-
version=1.0

if not required_tags(index,'obs_type,date_obs') then begin 
   box_message,'Require sot or xrt "index,data" pair(s)'
   return
endif

nindex=index
nout=n_elements(nindex) 

if not required_tags(index,'time,mjd') then $
   nindex=struct2ssw(index,/nopoint)

loud=keyword_set(loud) or keyword_set(verbose)

;   Calling Sequence:
;      IDL> write_sot,index,data [,/online] [,level=nn] [,outdir=outdir] $
;                  [,parent=parent], [,outfile=outfile] [,prefix=prefix] 


if n_elements(parent) eq 0 then parent=''
online=keyword_set(online) or keyword_set(parent) ; use sot-like organizat
 
;    determine outdirectory 

slevel='' ; level 
if keyword_set(level) then slevel=strtrim(level,2)
loglev=get_logenv('SOT_DATA_L'+slevel) ; check level dependent environmental
if n_elements(parent) eq 0 and loglev ne '' then parent=loglev ; useenv
if parent eq '' then parent=curdir()

sot_index2fileinfo,nindex,parent=parent,fprefix,obsdirs,fnames,fpaths,$
    millisec=millisec 
case 1 of 
   data_chk(outdir,/string):  ; user supplied explicitly
   online: begin 
      outdir=fpaths
   endcase
   else: outdir=curdir()
endcase

udirs=outdir(uniq(outdir,sort(outdir)))

dneed=where(1-file_exist(udirs),ncnt)

if ncnt gt 0 then begin 
   if not keyword_set(make_dir) then begin 
      box_message,['At least some implied directories do not exist',$
                  'Use /MAKE_DIR to automatically create these... returning']
      for i=0,ncnt-1 do begin 
         mk_dir,udirs(dneed(i)),verbose=loud
      endfor

   endif

endif else if loud then box_message,'All directories exist'

; contruct file names 
if n_elements(add_prefix) eq 0 then add_prefix='' ; optional prefix addendum
case 1 of
   n_elements(outfile) eq n_elements(nindex):   begin
      if loud then $
      box_message,'Using user supplied names verbatim'
      out_paths=outfile
   endcase
   else: begin 
      case n_elements(prefix) of
         1: fpre=replicate(prefix(0)+add_prefix,nout)
         nout: fpre=prefix+add_prefix 
         else: begin
            if n_elements(fprefix) eq nout then  fpre=fprefix+add_prefix else $
               fpre=strarr(nout)+add_prefix
         endcase
      endcase
      if online then out_paths=concat_dir(fpaths,fpre+fnames) else $
         out_paths=concat_dir(outdir,fpre+fnames)
   endcase
endcase

if loud then box_message,['Files to write:',out_paths]
if keyword_set(paths_only) then begin 
   if loud then box_message,['/PATHS_ONLY set, names in OUT_PATHS.., returning']
   return
endif

if n_params() lt 2 then begin 
   box_message,'No DATA array(s), so I cannot write any files...'
   return
endif

mwritefits,index,data,outfile=out_paths,_extra=_extra

return
end


