;+
; NAME:
;       EIS_GETWINDATA
;
; PURPOSE:
;       Returns the EIS data structure for one spectral window.
;
; CALLING SEQUENCE:
;       d = eis_getwindata(file, [iwin ,keywords])
;
; INPUTS:
;       FILE: input EIS fits file. See restrictions.
;
; OPT. INPUT: 
;
;       IWIN: scalar with the index of the desired windows (iwin <
;             25). This can also be a wavelength or as a string that
;             matches one of the line ids.
;
; OUTPUTS:
;       Structure with data and header information. 
;
; KEYWORDS:
;       replace_missing : run eis_replace_missing to find and replace
;                         missing pixels, see the header of that
;                         routine for more information. This cannot be
;                         applied to level0 files and is prevented by
;                         checking the input file name for '_l0_'.
;       refill: same as replace_missing (the keyword name for this process in eis_prep is
;               called refill and it has been added here for consistency)
;
;       reinit : reread the data file. Note that data is stored on a
;                common block to speed up repeated calls.
;
;       quiet: supress messages (uses !quiet = 1)
;
; EXAMPLES:
;       IDL> d = eis_getwindata(file)         ;; interactive selection
;       IDL> d = eis_getwindata(file,0)       ;; input window number
;       IDL> d = eis_getwindata(file,195.119) ;; input wavelength
;       IDL> d = eis_getwindata(file,195.119,/refill) ;; fill-in warm pixels
;
; SPECIAL CALLS:
;       eis_getfilename, eis_get_wininfo, eis_get_iwin, 
;       obj_new('eis_data')
;
; RESTRICTIONS: 
;       The name of the input only matters when trying to retrieve 
;       the errors. The routine expects a pair of L1 and ER files
;       (standard outputs from EIS_PREP) to correctly populate the 
;       tags. Otherwise it will return zeroes in the .ERR tag. Same 
;       will happen if input is a L0 file.
;
; WRITTEN: H.P.Warren. NRL. March 2007.
;
; MODIFICATION HISTORY:
;       2007/04/09 I. Ugarte-Urra. NRL. Added documentation.
;       2007/04/24 IUU. Interpret correctly if error file given as input.
;       2007/04/27 IUU. Release to SSW.
;       2007/05/09 HPW. Modified iwin input.
;       2007/05/15 HPW. Modified iwin input.
;       2007/06/28 HPW. Fixed bug related to reading error file.
;       2007/07/05 PRY. Changed way error filename is derived.
;       2007/10/17 HPW. Added file modification time to common block.
;       2009/05/07 HPW. Added replace_missing and reinit keywords
;       2009/05/09 HPW. Minor cleanup.
;       2009/07/15 HPW. Added refill option (same as replace_missing) to mirror eis_prep.
;       2009/10/21 HPW. Fixed bug with successive reads.
;       2009/12/15 HPW. Added Quiet keyword.
;       2010/09/24 HPW. Added WAVE_CORR to structure.
;       2010/09/29 HPW. Only do WAVE_CORR for slit data
;       2010/10/18 HPW. Modified call to eis_wave_corr_hk.
;       2017/04/25 TF.  Added keyword use_local_wavecorr_file
;
;-
;; **********************************************************************

function eis_getwindata,input_file,input_iwin,$
                        replace_missing=replace_missing,$
                        refill=refill,$
                        reinit=reinit,$
                        quiet=quiet,$
                        no_wave_corr=no_wave_corr, $
                        use_local_wavecorr_file=use_local_wavecorr_file

  if keyword_set(refill) then replace_missing = 1

  if n_params() eq 2 then iwin = input_iwin

  QuietSaved = !quiet
  if keyword_set(quiet) then !quiet = 1

  ;; ----------------------------------------------------------------------
  ;; --- filename & window number

  ;; --- look for the file
  datfile = eis_getfilename(input_file)
  
  ;; --- In case input is error file, go find data
  break_file,datfile,disk,dir,name,ext
  if strpos(name,'_er_') ne -1 then begin
      datfile = str_replace(datfile,'_er_','_l1_')
      break_file,datfile,disk,dir,rename,ext
      message,name + ' is the error file.',/info 
      message,'Extracting data from: ' + rename, /info
  endif
  if not(file_exist(datfile)) then begin
    message,'no file found . . .',/info
    !quiet = QuietSaved
    return,0
  endif

  if n_elements(iwin) eq 0 then begin  
    ;; --- select iwin if it is not input, no error checking otherwise
    message,'no window number input, select one . . .',/info
    wininfo = eis_get_wininfo(datfile,/list,nwin=nwin)
    iwin = 0
    read,iwin,prompt='Select a window to read [0...'+trim(nwin-1)+']> '
  endif else begin
    wininfo = eis_get_wininfo(datfile,nwin=nwin)
    ;; --- iwin has been input, check type
    if datatype(iwin) eq 'STR' then begin
      ;; --- string, match line id
      iwin = eis_get_iwin(datfile,iwin)
    endif else begin
      ;; --- match wavelength 
      if iwin gt 25 then begin
        iwin = eis_get_iwin(datfile,iwin)
      endif
    endelse
  endelse
  
  ;; --- iwin is now the window number (0...nwin-1)
  if iwin lt 0 or iwin ge nwin then begin
    message,'window out of range ('+trim(iwin)+') . . . ',/info
    !quiet = QuietSaved
    return,0
  endif

  ;; ----------------------------------------------------------------------
  ;; --- read the object

  ;; --- record file name AND modification time
  info = file_info(datfile)
  this_file_s = datfile+','+trim(info.mtime)
  
  common eis_getwindata_com,last_file_s,data,data_er,last_iwin_s,windata
  if n_elements(last_file_s) eq 0 then last_file_s = ''
  if keyword_set(reinit) then last_file_s = ''
  
  if this_file_s ne last_file_s then begin
    message,'READING THE EIS DATA OBJECT',/info

    ;; --- destroy the old object
    if datatype(data) eq 'OBJ' then begin
      obj_destroy,data
      delvarx,data
    endif
    if datatype(data_er) eq 'OBJ' then begin
      obj_destroy,data_er
      delvarx,data_er
    endif

   ;; --- make a new object
    data = obj_new('eis_data',datfile)
    
    ;; --- look for error file
    basename=file_basename(datfile)
    dirname=file_dirname(datfile)
    errbasename=str_replace(basename,'_l1_','_er_')
    errfile=concat_dir(dirname,errbasename)

    if errfile eq datfile then errfile=''
    if file_exist(errfile) then data_er = obj_new('eis_data',errfile)

    last_file_s = this_file_s

    ;; --- new file has been read, the data window must now be read again, HPW 21-OCT-2009
    last_iwin_s = '' 
  endif 

  ;; ----------------------------------------------------------------------
  ;; --- extract the data for this window

  this_iwin_s = trim(iwin)+',replace_missing='+$
      trim(keyword_set(replace_missing))

  if n_elements(last_iwin_s) eq 0 then last_iwin_s = ''
  if keyword_set(reinit) then last_iwin_s = ''
  
  if this_iwin_s eq last_iwin_s then begin
    ;; --- do nothing, just return windata from common block
    message,'RETURNING BUFFERED DATA',/info
  endif else begin
    message,'READING THE EIS DATA STRUCTURE',/info

    windata = data->getwindata(iwin,data_er=data_er)   

    if keyword_set(replace_missing) then begin
      break_file,datfile,disk,dir,basename,ext
      if strpos(basename,'_l1_') ne -1 then begin
        eis_replace_missing,windata,/replace,quiet=quiet
      endif else begin
        message,'EIS_REPLACE_MISSING CANNOT BE APPLIED TO LEVEL0 DATA',/info
      endelse
    endif

    slit_id = strtrim(windata.hdr.slit_id,2)
    if slit_id eq '1"' or slit_id eq '2"' then begin

      ;; --- only do eis_wave_corr_hk for slit data

      if not(keyword_set(no_wave_corr)) then begin
        
        ;; --- wavelength correction is computed here
        eis_wave_corr_hk,data,wave_corr,wave_corr_tilt,wave_corr_t, use_local_wavecorr_file=use_local_wavecorr_file
        
        windata = add_tag(windata,1b            ,'WAVE_CORR_SET')
        windata = add_tag(windata,wave_corr     ,'WAVE_CORR')
        windata = add_tag(windata,wave_corr_tilt,'WAVE_CORR_TILT')
        windata = add_tag(windata,wave_corr_t   ,'WAVE_CORR_T')
        
      endif else begin
        
        ;; --- just add the memory for wave_corr
        sz = size(windata.int)
        nx = sz[2]
        ny = sz[3]
        if sz[0] eq 3 then nexp = 1 else nexp = sz[4] ;; exposures at each step
        wave_corr_tilt = fltarr(ny)
        wave_corr_t    = fltarr(nx*nexp)
        if sz[0] eq 3 then wave_corr = fltarr(nx,ny) else wave_corr = fltarr(nx,ny,nexp)
        
        windata = add_tag(windata,0b            ,'WAVE_CORR_SET')
        windata = add_tag(windata,wave_corr     ,'WAVE_CORR')
        windata = add_tag(windata,wave_corr_tilt,'WAVE_CORR_TILT')
        windata = add_tag(windata,wave_corr_t   ,'WAVE_CORR_T')
        
      endelse

    endif

    last_iwin_s = this_iwin_s
  endelse

  !quiet = QuietSaved

return,windata
end
