;+
; NAME:
; 	FS_OPEN
; PURPOSE:
;       Open a BATSE data file.
;	User passes in a file name, flare number, or time, and a data
;	type, and fs_open finds the correct file, opens it, reads the
;	header, and fills in the dd_open structure containing info
;	about this file.  The dd_open structure looks like:
;		discla_open = {discla_open, $ 
;		type:1, $             ; data type: 0/1/2/3=bdb/fdb/cont/discsp
;               filename:' ',  $      ; string file name
;               numrec: 0L, $         ; number of data records (total-1)
;               num_audit_rec: 0L, $  ; number of audit records after header
;               startsec: 0.d0, $     ; start time in seconds since 79/1/1
;               endsec: 0.d0, $       ; end time in seconds since 79/1/1
;               header:fdr_sdac, $    ; structure containing header record
;               data: discla_str, $   ; structure showing form of data record
;               lun:-1}               ; logical unit
;	A generic structure for each allowed data type is saved in ddfiles_com.
;	If dd_init hasn't already been called to set up the generic
;	structures, fs_open calls it.  
;
;	Current data types allowed are:DISCLA (BDB or FDB), CONT (MSFC or
;	SDAC), and DISCSP (MSFC or SDAC).
;
; CATEGORY:
;       BATSEI/O
; CALLING SEQUENCE:
;	fs_open, [file=infile, flare=flare, time=time, dd_type=dd_type, $
;	   dd_open=dd_open, verbose=verbose, error=error, msfc=msfc]
; RESTRICTIONS:
;	User must pass one of the file, flare, or time keywords.
;
; OPTIONAL KEYWORD INPUTS:
;	FILE -	string name of file. If no disk or directory is specified, 
;		the file is looked for in the current directory and if
;		still not found then BATSE_DATA is the default.
;	FLARE -	BATSE flare number.  FS_OPEN will find file containing FLARE.
;	TIME -	Time as ASCII string ('yy/mm/dd,hhmm:ss.xxx') or seconds
;		since 79/1/1.  FS_OPEN will find file containing this time.
;	DD_TYPE - Type of data as string or number:
;		'BDB', 'FDB', CONT', or 'DISCSP'  or 
;		0/1/2/3 = discla bdb, discla fdb, cont, discsp
;		Unless the FILE keyword is passed, FS_OPEN will find this 
;		type of file for the flare or time requested.  Default is FDB.
;	DD_OPEN - Returned structure containing info about open file.  An
;		example of this structure is:
;		discla_open = {discla_open, $ 
;		type:1, $             ; data type: 0/1/2/3=bdb/fdb/cont/discsp
;               filename:' ',  $      ; string file name
;               numrec: 0L, $         ; number of data records (total-1)
;               num_audit_rec: 0L, $  ; number of audit records after header
;               startsec: 0.d0, $     ; start time in seconds since 79/1/1
;               endsec: 0.d0, $       ; end time in seconds since 79/1/1
;               header:fdr_sdac, $    ; structure containing header record
;               data: discla_str, $   ; structure showing form of data record
;               lun:-1}               ; logical unit
;	VERBOSE - If set, FS_OPEN prints a message when opening a file.
;	MSFC    - If set the data structure is MSFC, "native" format
;	ERROR -	0/1 means no error/error.
;
; SAMPLE CALL:
;	fs_open,flare=300,dd_type='CONT',error=error
;	fs_open,file='930902.bdb'
;
; MODIFICATION HISTORY:
;	Kim Tolbert   9/93
;       ras, 23-mar-94, fixed uppercase test bug
;	Mod KT 1-APR-1994 to use the individual directories (BATSE_CONT,
;		BATSE_FDB, etc) rather than BATSE_DATA (which points
;		to all those directories.  A multi-defined logical won't
;		work in unix.  Did it now because moving bdb files to
;		BATSE_BDB rather than having them on BATSE_DATA.
;	Mod Kt 13-apr-1994. Restrict access to cont or discsp files less than 
;		one year old if user is logged in via the BATSE account.
;	Mod ras 18-apr-1994 - added MSFC keyword to force MSFC structure
;       Mod AES 7-sep-1994.  enabled MSFC keyword by adding ten to type
;               if MSFC is set.
;       Mod AES 2-oct-1995 - changed addresses to nascom domain
;	mod ras 11-oct-1995 - changed default to current directory, then batse_bdb
;	Version 9, ras, 31-dec-1996, maintain version numbers in filename
;	Mod RCJ 29-jul-1997, open file as stream
;-
;=====================================================================================


pro fs_open, file=infile, flare=flare, time=time, dd_type=dd_type, $
   dd_open=dd_open, msfc=msfc, verbose=verbose, error=error


; ddfiles_com common contains generic structures for info about open files 
; of each data type.
@ddfiles_com

error = 0

checkvar, verbose, 1   ; default for verbose is true
checkvar, version, ''  ; in case this isn't defined

msfc = keyword_set(msfc)
filetypes = ['BDB', 'FDB', 'CONT', 'DISCSP']

; if type was specified as a string, convert to a number 0/1/2/3
if n_elements(dd_type) ne 0 then begin
   if (size(dd_type))(1) eq 7 then begin
      type = strupcase(dd_type)
      if type eq 'DISCLA' then type = 'FDB'
      q = where (type eq filetypes, count) 
      type = q(0)
   endif else type = dd_type
   type_passed = type
   if msfc then type_passed=type_passed+10
endif

; If specified a file name, get type from file. 

if keyword_set(infile) then begin
   break_file, infile, disk, dir, name, ext, version
   filename = name + ext + version
   filename_up = strupcase(filename)                    ;ras, 23-mar-94
   ext = strupcase(ext)
   case 1 of
   strpos(ext, 'BDB') ne -1: type = 0
   strpos(ext, 'FDB') ne -1: type = 1
   strpos(filename_up, 'CONT') ne -1: type = 2
   strpos(filename_up, 'DISCSP') ne -1: type = 3
   else: begin
      print,'FS_OPEN:  Invalid file type.'
      goto, error_exit
      end
   endcase
   ; Open file to make sure it exists.  If MSFC, add 10 to type.
   ;
   ; If file is in the current directory, put that into disk
   ;
   if disk eq '' then begin
	filefound = findfile(infile, count=countfile)
   endif

   if disk eq '' and dir eq '' and fcheck( countfile,0) eq 0 then begin
      file_dir = 'BATSE_' + filetypes(type)
      def_dir = chklog(file_dir)
      if def_dir eq '' then begin
         print,'Logical name for this file type is not defined: ', file_dir
         goto, error_exit
      endif
      filename = concat_dir(def_dir,filename) 
   endif else filename = disk + dir + filename 
   fileexist = findfile (filename, count=count)
   if count gt 0 then begin
      newfile = fileexist(0)
      if msfc then type = type + 10
   endif else begin
      print,'File ', filename, ' does not exist.'
      goto,error_exit
   endelse
   if n_elements(dd_type) ne 0 then if type_passed ne type then $
      print, 'Type of data in file does not match dd_type passed in args.' 
endif else begin
   if n_elements(dd_type) eq 0 then begin
      print, 'Assuming FDB data type.'
      type = 1
   endif
endelse

; if this dd_open exists and is a structure, then if it's the right type,
; don't reinit it.  If it's not the right type, but was connected with
; an open file, just close the file.
if (size(dd_open))(2) eq 8 then begin
   if dd_open.type eq type then goto,get_filename
   if dd_open.lun ne -1 then dd_close, dd_open
endif

; if the data open structures haven't been defined, call dd_init to init them.
if (size(discla_open))(0) eq 0 then dd_init

; Set dd_open to the type of structure requested in this call to fs_open.
case type of
0: dd_open = discla_open
1: dd_open = discla_open
2: dd_open = cont_open
3: dd_open = discsp_open
12: dd_open = mcont_open
13: dd_open = mdiscsp_open
else:  begin
   print,'FS_OPEN: Invalid data type.'
   goto, error_exit
   end
endcase
dd_open.type = type   ; this is normally already set, except for bdb case



get_filename:
; Get file name from file keyword, flare specified in keyword input, or
; time specified in keyword input
filename = ' '

if keyword_set(infile) then begin
   filename = infile

endif else begin
   if keyword_set(flare) then begin
      if keyword_set(time) then $
         print,'Specify only one of FILE, FLARE, or TIME.  Using FLARE keyword.'
      flare_f_name, flare, dd_open, filename, error=error
      if error then goto,error_exit
   endif else begin
      if keyword_set(time) then begin
         asctime = anytim(time, /hxrbs) 
         time_f_name, asctime, dd_open, filename, error=error
         if error then goto,error_exit
      endif else begin
         filename = dd_open.filename
      endelse
   endelse
endelse
if filename eq ' ' then begin
   print, 'You must specify FILE, FLARE, or TIME keyword.'
   goto, error_exit
endif


; Now we have filename.  Check that file exists.  (If no disk and directory
; specified, use BATSE_DATA.)
break_file, filename, disk, dir, name, ext, version
filename = name + ext + version
if disk eq '' and dir eq '' and fcheck(countfile,0) eq 0 then begin
   file_dir = 'BATSE_' + filetypes(type)
   def_dir = chklog(file_dir)
   if def_dir eq '' then begin
      print,'Logical name for this file type is not defined: ', file_dir
      goto, error_exit
   endif
   filename = concat_dir(def_dir,filename) 
endif else filename = disk + dir + filename
fileexist = findfile (filename, count=count)

if count eq 0 then begin
  print,'File ', filename, ' does not exist.'
  goto,error_exit

endif else begin
   ; check if this is the currently opened file.  If so, we're done.
   if dd_open.lun ne -1 then begin
      fstat = fstat(dd_open.lun)
      if fstat.open then begin
         if filename eq dd_open.filename then goto,getout else $
            free_lun, dd_open.lun
      endif
   endif

   on_ioerror, got_error
   ; open file, read header, and fill in variables in dd_open structure.
   newfile = fileexist(0)
   openr, lun, newfile, /get_lun,/stream
   head = dd_open.header
   readu, lun, head
   head = conv_vax_unix(head)
   dd_open.lun = lun
   dd_open.filename = filename 
   ; # of data records is stored in different variable in SDAC and MSFC files
   if msfc then dd_open.numrec = head.data_recs_num $
      else  dd_open.numrec = head.numrec_w
   dd_open.header = head
   if type lt 10 then begin
      dd_open.num_audit_rec = 0
      dd_open.startsec = head.st_time
      dd_open.endsec = head.en_time
   endif else begin
      dd_open.num_audit_rec = head.num_audit_rec
      dd_open.startsec = tjd2ymd(head.sc_start_day) + head.sc_start_sec
      dd_open.endsec = tjd2ymd(head.sc_stop_day) + head.sc_stop_sec
   endelse

   ; For cont and discsp data, if user is logged on through BATSE account,
   ; and time if file is within the last year, print message and deny access.
   if type gt 1 then begin
      if !version.os eq 'vms' then login='SYS$LOGIN' else login='LOGNAME'
      trans = chklog(login)
      if strpos(strupcase(trans), 'BATSE') ne -1 then begin
         currsec = anytim(systime(1)+utime('70/1/1,0'), /sec)
         if dd_open.startsec gt (currsec - 365*86400.d0) then begin
            msg = [' ', $
       'CONT and DISCSP data less than one year old are not available to',$
       'the public.  For access to these data please contact: ',$
       'R. Schwartz  (301-286-4714, richard@sdac.nascom.nasa.gov)  or ', $
       'A. Skowronek (301-286-4713, amy@sdac.nascom.nasa.gov)', ' ']
            for i=0,5 do print,msg(i)
            dd_close, dd_open
            goto, error_exit
         endif
      endif
   endif
 

   if verbose then begin
      print, format='(a," opened:")', filename
      print, format='(7x,"File Start Time = ",a22)', $
         atime(dd_open.startsec,/hxr)
      print, format='(7x,"File End Time   = ",a22)', atime(dd_open.endsec,/hxr)
   endif

   goto, getout                                             
endelse

got_error:
print,'Error opening file ', newfile
goto, error_exit

error_exit:
error = 1

getout:
return&end
