;+
; Project     :	SOHO - CDS
;
; Name        :	RD_RESOURCE
;
; Purpose     :	Read a resource (MDI, DSN, COM times etc) for a given date range.
;
; Explanation :	A wrapper around the LIST routines written to speed things 
;               up by not re-reading what has already been read.
;
; Use         :	RD_RESOURCE,RES, START, END, NRES=NRES
;
; Inputs      :	START, END = The range of date/time values to use in searching
;			     the database.  Can be in any standard time
;			     format.
;
; Opt. Inputs :	None.
;
; Outputs     :	RES = A structure array
;
; Opt. Outputs:	None.
;
; Keywords    :	FORCE= to force reading from DB
;               NRES = total # of resource values found
;               DAY = extra day to read on each side of START and END
;               JUMP = number of days to jump before starting a fresh read [def=10]
;
; Common      :	None.
;
; Restrictions:	None.
;
; Side effects:	None.
;
; Category    :	Planning, Database.
;
; Prev. Hist. :	None.
;
; Written     :	Dominic Zarro (ARC),  8 May 1995
;-
                               
pro rd_resource,res,cstart,cstop,force=force,nres=nres,err=err,_extra=extra,$
                day=day,jump=jump,verbose=verbose

on_error,1
nres=0
common rd_resource_com,sav_db

;-- check requested times

if (n_elements(cstop) eq 0) and (n_elements(cstart) eq 0) then begin
 err='syntax --> RD_RESOURCE,RES,START_TIME,STOP_TIME,[/DSN, /MDI]' & message,err,/cont
 return
endif
verbose=keyword_set(verbose)

;-- work out times (add +/- day to each end if user wants it)

if (n_elements(cstop) eq 0) then cstop=cstart
if (n_elements(cstart) eq 0) then cstart=cstop

secs_day=24.d*3600.d
if datatype(cstart) eq 'FLO' then cstart=double(cstart)
if datatype(cstop) eq 'FLO' then cstop=double(cstop)

err=''
tstart=anytim2tai(cstart,err=err)
if err ne '' then begin
 message,err,/cont
 return
endif

tstop=anytim2tai(cstop,err=err)
if err ne '' then begin
 message,err,/cont
 return
endif

if exist(day) then begin
 temp=tai2utc(tstart)
 temp.time=0
 temp.mjd=temp.mjd-1
 tstart=utc2tai(temp)
 temp=tai2utc(tstop)
 if temp.time eq 0 then temp.mjd=temp.mjd+1 else begin
  temp.time=0
  temp.mjd=temp.mjd+2
 endelse
 tstop=utc2tai(temp)
 dprint,'tstart: ',anytim2utc(tstart,/ecs)
 dprint,'tstop: ',anytim2utc(tstop,/ecs)
endif

if tstop le tstart then begin
 tstop=tstart+secs_day
 message,'END time lt START time; defaulting to 1 day',/con
endif

if datatype(extra) eq 'STC' then res_name=(tag_names(extra))(0)

if datatype(res) eq 'STC' then begin
 if tag_exist(res,'RES_NAME') then cur_res=res(0).res_name
endif

case 1 of

 exist(cur_res) and exist(res_name): begin
  if cur_res ne get_res_name(res_name) then begin
   message,'incompatible input resource and keyword, overriding with keyword',/cont
   rdb=1
  endif else rdb=0
 end

 exist(cur_res) and (not exist(res_name)): begin
  res_name=cur_res
  status=execute('extra={'+res_name+':1}') & rdb=0
 end

 (not exist(cur_res)) and exist(res_name) : rdb=1

 else: begin
  message,'please enter a resource type as a keyword',/cont
  return
 end
endcase

if keyword_set(force) then rdb=1
if datatype(res) eq 'STC' then rtime=get_plan_itime(res)

;-- check if jump is greater than JUMP [def = 10]
;-- in this case, read directly from DB

if n_elements(jump) eq 0 then jump=10
nsecs=jump*secs_day
if not rdb then begin
 mstart=min(res.(rtime))
 mend=max(res.(rtime+1))
 rdb= ((mstart-tstop)  gt nsecs) or ((tstart-mend) gt nsecs)
endif

;-- check if database changed

if datatype(sav_db) ne 'STR' then sav_db=getenv('ZDBASE')
cur_db=getenv('ZDBASE')
if cur_db ne sav_db then begin
 message,'ZDBASE changed!!!',/contin
 rdb=1 & sav_db=cur_db
endif

if rdb then begin
 delvarx,res
 dprint,'%RD_RESOURCE: reading '+res_name+' from DB '
 list_resource,tstart,tstop,tres,nres,_extra=extra,res_name=res_name,/quiet
 if nres gt 0 then res=add_tag(tres,res_name,'RES_NAME')
endif else begin 
 mstart=min(res.(rtime))
 mend=max(res.(rtime+1))

;-- look back in time

 if tstart lt mstart then begin         
  if verbose then message,'looking back in time for '+res_name+'...',/cont
  list_resource,tstart,mstart,tres,nres,_extra=extra,res_name=res_name,/quiet
  if (nres gt 0) then begin 
   pre_res=add_tag(tres,res_name,'RES_NAME')
   if not exist(res) then res=pre_res else $
    res=concat_struct(pre_res,temporary(res))
  endif
 endif
 
;-- look forward in time

 if tstop gt mend then begin
  if verbose then message,'looking ahead in time for '+res_name+'...',/cont
  list_resource,mend,tstop,tres,nres,_extra=extra,res_name=res_name,/quiet
  if (nres gt 0) then begin 
   post_res=add_tag(tres,res_name,'RES_NAME')
   if not exist(res) then res=post_res else $
    res=concat_struct(temporary(res),post_res)
  endif
 endif

;-- sort time entries

 nres=n_elements(res)
 if nres gt 0 then begin
  itime=get_plan_itime(res)
  res=mk_plan_sort(temporary(res),/uniq,/str,itime=itime)
  nres=n_elements(res)
 endif

endelse

nres=n_elements(res)

;-- filter out bad DB items

if nres gt 0 then begin
 rtime=get_plan_itime(res)
 day_secs=100.*3600.d*24.d
 ok=where((res.(rtime+1)-res.(rtime)) lt day_secs, cnt)
 if cnt gt 0 then begin
  res=res(ok)
  nres=n_elements(res)
 endif else begin
  delvarx,res & nres=0
 endelse
endif 

if (nres eq 0) then begin
 err='no '+res_name+' found in DB for specified times  '
 if strtrim(res_name) ne '' then dprint,'%RD_RESOURCE: '+err
 delvarx,res
 return
endif

return & end

