;+
; PROJECT:
;	SDAC
; NAME:
; 	FS_OPEN
; PURPOSE:
;       This procedure opens 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:
;       BATSE, I/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
;	VERSION 10, richard.schwartz@gsfc.nasa.gov, 4-sep-1997,
;	used loc_file with path_dir('batse') to locate help files.
;	Test for pad bytes and set environmental if true. add msfc hkg files, 14.
;	VERSION 11, richard.schwartz@gsfc.nasa.gov, 7-oct-1997,
;	made input filename first default, use dd_type for bdb, too.
;	VERSION 12, richard.schwartz@gsfc.nasa.gov, 20-nov-1997,
;	made dd_type more robust, fixed bug in using numbers for msfc types.
;	VERSION 13, richard.schwartz@gsfc.nasa.gov, 3-dec-1997,
;	fixed type_passed default.
; 	Version 14, richard.schwartz@gsfc.nasa.gov, 24-jun-1998, forced old VAX float format on write.
;	Version 15, amy@aloha.nascom.nasa.gov, 16-jun-1999, changed reference
;	     to def_dir after dominic changed the output of chklog
;-
; =====================================================================================


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','HKG']

; 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 mod 10 )+10
    endif
if n_elements(type_passed) eq 1 then msfc = type_passed ge 10
; 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)
    
    if n_elements(dd_type) eq 0 then begin
        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
            strpos(filename_up, 'HKG') ne -1: type = 4
            else: begin
                print,'FS_OPEN:  Invalid file type.'
                goto, error_exit
                end
            endcase
        endif
    if type mod 10 gt (n_elements(filetypes)-1 ) then begin
	message,/continue,'Invalid file type.'
	goto, error_exit
	endif
    file_dir = 'BATSE_' + filetypes(type mod 10)
    def_dir = chklog(file_dir)
    fileexist = loc_file( infile, count=count)
    if count eq 0 then fileexist = loc_file( path=[curdir(),file_dir], infile, count=count)

    if count eq 0  and def_dir[0] eq '' then begin
        print,'Logical name for this file type is not defined: ', file_dir
        goto, error_exit
        endif
    if count gt 0 then begin
        newfile = fileexist(0)
        if msfc then type = (type mod 10) + 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
;print,type
; 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
    10: dd_open = mdiscla_open
    11: dd_open = mdiscla_open
    12: dd_open = mcont_open
    13: dd_open = mdiscsp_open
    14: dd_open = mhkg_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(fileexist) then filename = fileexist(0) $
 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.)
if keyword_set(fileexist) then count=1 else begin

	file_dir = 'BATSE_' + filetypes(type mod 10)
	
def_dir = chklog(file_dir)
	fileexist = loc_file (filename,path=[curdir(),file_dir], count=count)
	if count eq 0 and os_family() ne 'vms' $
	then fileexist = loc_file (strlowcase(filename),path=[curdir(),file_dir], count=count)
	if count eq 0 and os_family() ne 'vms' $
	then fileexist = loc_file (strupcase(filename),path=[curdir(),file_dir], count=count)
	if count eq 0 and def_dir[0] eq '' then begin
	    print,'Logical name for this file type is not defined: ', file_dir
	    goto, error_exit
	    endif
	endelse    

    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
    head = dd_open.header
    readu, lun, head
    head = conv_vax_unix(use_vax_float(/old2new, 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
    ;
    ; Test for pad bytes.  These exist on fixed record length files exported from
    ; VMS to Unix.
    ; 
    if os_family() ne 'vms' then begin
        ntestrec  = dd_open.numrec < 50
        last_col = size_struct(dd_open.data)
        testbuff1 = bytarr( last_col + 1 , ntestrec)
        point_lun, -dd_open.lun, location
        point_lun, dd_open.lun, 0
        readu, dd_open.lun, testbuff1
        point_lun, dd_open.lun, location
        testit = where(testbuff1(last_col,*) eq 10b, ntest)
        ;If all testit are 10b, then there is a pad byte.
        

        set_logenv,'pad_byte_'+dd_open.filename, strtrim(fix(ntest eq ntestrec),2),/quiet
        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:
end
