function sotsp_time2scan,time0, time1, cat, files, $
   nscans=nscans, refresh=refresh, incat=incat, $
   quicklook=quicklook, debug=debug, macroid_merge=macroid_merge, $
   extend_partial=extend_partial, urls=urls, span_day=span_day 
;+
;   Name: sotsp_time2scan 
;
;   Purpose: return SP scan managment info for all scans in time range
;
;   Input Parameters:
;      time0,time1 - time range of interest
;
;   Output:
;      function returns structure vector, one element per scan
;      includes start&stop indices and some other stuff
;
;   Output Parameters:
;      cat,files - output from 'sot_cat' with OBSDIR=SP4D
;
;   Keyword Parameters:
;      incat - optional user supplied catalog or index vector (def reads cat)
;      quicklook - apply to QuickLook tree (default=level0 aka sirius)
;      refresh - if set, force redefinition of output structure
;      debug - ...
;      nscans (output) - number of scans (structures) returned; -1=problem
;      macroid_merge (switch) - if set, merge structures which have same macroid
;      extend_partial=extend_partial - if set and scan-in-progress in last element, read 'till end-of-macroid
;      span_day=span_day - if set, pad end time to complete macroid
;                          /span_day suggested for BATCH Processing
;   
;
;   Calling Sequence/Example:
;      IDL> ret=sotsp_time2scan('24-nov-2006','25-nov-2006',$
;               cat,ffn,nscans=nscans)
;      IDL> help,ret,nscans & help,ret,/str
;  RET             STRUCT    = -> <Anonymous> Array[43] ; 1 struct per scan
;  NSCANS          LONG      =           43
;** Structure <3ee5860>, 7 tags, length=36, data length=34, refs=2:
;   DATE_OBS        STRING    '2006-11-24T12:32:01.430' << 1st image in scan
;   SSSTART         LONG                 0         << indices of scan(n) start
;   SSSTOP          LONG                23         << indices of scan(n) end
;   NMISS           LONG                 0         << not yet implemented
;   PARTIAL         INT              0             << 1st/last scan in prog? 
;   NRECS           LONG                23         << #images in scan(n)
;   MACROID         LONG              7133         << macroid for scan(n)
;
;   Then, for example:
;      IDL> sp_prep,ffn(ret(N).sstart:ret(N).sstop), ; scan(N) Level0->Level1
;
;   History:
;      28-Jul-2007 - S.L.Freeland - for SP L0->L1 auto/management
;       4-oct-20007 - S.L.Freeland - add /MACROID_MERGE keyword&function
;       1-nov-2007 - S.L.Freeland - add /SPAN_DAY (implies /macroid_merge)
;       6-nov-2007 - S.L.Freeland - alter macroid_merge logic a bit; only affects "missing data" cases(?)
;
;   Restrictions:
;      Does not identify "mssing" scans within a range (yet?) - but does flag 1st or last "in progress" 
;      (hiccups in slitindx derivitive?)
;-

common sot_sp_time2scan_blk, strtemp

debug=keyword_set(debug)

span_day=keyword_set(span_day)
macroid_merge = keyword_set(macroid_merge) or span_day 

refresh=keyword_set(refresh) or n_elements(strtemp) eq 0

if refresh then strtemp={date_obs:'',ssstart:0L, ssstop:0L, nmiss:0L, $
   partial:0,nrecs:0l,macroid:0L}

level0=1-keyword_set(quicklook)

if data_chk(incat,/struct) then begin 
      cat=incat  
      files=sot_cat2files(cat,level0=level0)
endif else begin 
   sot_cat,time0,time1, sirius=level0, search='obsdir=SP4D', cat, files, urls=urls
   if span_day and anytim(time1,/time_only) eq 0 then begin 
      box_message,'Checking next UT day for scan end...'
      time_window,time1,hours=[0,12],t0,t1  ; +12/-0 window
      delvarx,cate
      sot_cat,t0,t1,cate,filese,urls=urls,sirius=level0, search='obsdir=SP4D'
      lmac=last_nelem(cat.macroid)
      if data_chk(cate,/struct) then begin
      if cate(0).macroid eq lmac then begin 
         box_message,'Scan spans next UTDAY - appending...
         ss=where(cate.macroid eq lmac)
         cat=[temporary(cat),cate(ss)]
         files=[temporary(files),filese(ss)]
      endif else box_message,'Last scan does Not span next UT-Day'
      endif else box_message,'Catalog for next day not yet available'
   endif
endelse


if not required_tags(cat,'macroid,slitindx,slitpos') then begin 
   box_message,'Need SOT SP catalog or index records...'
   return,-1
endif

slitpos=gt_tagval(cat,/slitpos,missing=-9999)
slitindx=gt_tagval(cat,/slitindx,missing=-9999)
macroid=gt_tagval(cat,/macroid,missing=-9999)
sss=where(slitindx eq 0 and shift(slitindx,1) gt slitindx,sscnt)
miss0=slitindx(0) gt 0

if miss0 then begin
   box_message,'Warning - scan in progress in first record
   sss=[0,sss]
endif

nscans=n_elements(sss)

sse=where(deriv_arr(slitindx) lt 0,ecnt)
 
missl= n_elements(sse) eq nscans-1
if missl then begin 
;   box_message,'Warning - scan in progress in last record'
   sse=[sse,n_elements(cat)-1]
endif  

ssck = where(sss ge sse,pcnt)
if pcnt gt 0 then begin 
   box_message,'Warning - scan problem??'
   if debug then stop,'sss,sse'
   nscans=-1
   return,-1
endif

if n_elements(sss) ne n_elements(sse) then begin 
   box_message,'Warning - nstarts ne nends??'
   if debug then stop,'sss,sse'
   nscans=-1
   return,-1
endif

retval=replicate(strtemp,nscans)
retval.ssstart=sss
retval.ssstop=sse
retval.nrecs=(sse-sss)+1
retval.date_obs=cat(sss).date_obs ; time of 1st image per scan
retval.macroid=cat(sss).macroid   ; assumed constant for scan?

if miss0 then retval(0).partial=1
if missl then begin
   if keyword_set(extend_partial) then begin 
       box_message,'extending in-progress scan..'
   endif else begin 
       retval(nscans-1).partial=1
   endelse
endif ; end last scan "in progress" processing

if keyword_set(macroid_merge) then begin 
   umacro=uniq(retval.macroid)
   nuniq=n_elements(umacro)
   if n_elements(umacro) ne nscans then begin 
      box_message,'Merging scans w/same macrooid
      mretval=retval(umacro)
      for m=0,nuniq-1 do begin 
         ssm=where(retval.macroid eq mretval(m).macroid,mcnt) ; inherit 1st match
         if debug then stop,'ssm,mretval
         mretval(m)=retval(ssm(0))
         if mcnt gt 1 then begin ; not uniq, so merge remaining tags
            mretval(m).ssstop=last_nelem(retval(ssm).ssstop)
            mretval(m).nmiss=total(retval(ssm).nmiss)
            mretval(m).partial=total(retval(ssm).partial) gt 0
            mretval(m).nrecs=total(retval(ssm).nrecs) 
         endif
      endfor
      retval=temporary(mretval)
      nscans=n_elements(retval)
   endif
endif

if keyword_set(macroid_merge) then begin ; new paradigm, probably soon to be only paradigm...
   umacro=uniq(cat.macroid)
   nuniq=n_elements(umacro)
   retval=replicate(strtemp,nuniq)
   for m=0,nuniq-1 do begin 
      ssm=where(cat.macroid eq cat(umacro(m)).macroid,mcnt)
      retval(m).ssstart=ssm(0)
      retval(m).ssstop=last_nelem(ssm)
      retval(m).nrecs=mcnt
      retval(m).date_obs=cat(ssm(0)).date_obs 
      retval(m).partial=cat(ssm(0)).slitindx gt 0
      retval(m).macroid=cat(ssm(0)).macroid
   endfor
endif

return,retval
end

