;+
; NAME:
;       XFILES
;
; PURPOSE:
;
;       XFILES is used to select data files from data bases. It reads
;       data from many data sources. The user can also specify own
;       data sources, in which case data-read procedures must be
;       provided. XFILES defines the data objects, header objects and
;       auxiliary objects and sends them to XDISPLAY. The XDISPLAY
;       window is opened when the user selects a data file in XFILES.
;
;
; CATEGORY:
;       Hansteen/Wikstøl Data analysis SW
;
; CALLING SEQUENCE:
;       xfiles
;
; INPUTS:
;       none
;
; KEYWORD PARAMETERS:
;       none
;
;
; OUTPUTS:
;       Opens the XDISPLAY widget
;
; CALLS:
;
;
; COMMON BLOCKS:
;
;
; PROCEDURE:
;       XFILES searches through data bases (directories) for data
;       files. Which data base and directory can be selected from the
;       various data sources. The user can provide other data sources
;       under the "other" button, in which case the directory of data
;       must be specified, along with the routines to read the data.
;
; RESTRICTIONS:
;
;
; MODIFICATION HISTORY:
;       2001: Oivind Wikstol. Gradually developed through the year.
;       19-Apr-2004: Oivind Wikstol - Cleaned up.
;       06-May-2004: Oivind Wikstol. Changed call to xcontrol for
;                    ccsds type. 
;       18-Nov-2006: Viggo H. Cleaned up. Made fits default file type, 
;                    activated date filter, added filename filter.
;       29-Sep-2007: Alessandro Gardini. Added the Confirmation button. Set 
;                    the image device to Pixmap. Freed (*info).filelist 
;                    each time it is redefined, and at the end. Renamed the
;                    various Row# in the widget according to their order.
;                    The function "findfile" was replaced by "file_search"
;                    already on 19-Jun-2007.
;       18-Mar-2008: A. Gardini. Check on level 2 FITS files, and call of
;                    xmap instead of xcontrol.
;   
;$Id: xfiles.pro,v 1.11 2008/03/18 16:59:44 gardini Exp $
;-
;
; Start Xfiles:
; xfiles exit:
pro xfiles_exit, event
 widget_control, event.top, /destroy
end

; xfiles cleanup
pro xfiles_cleanup, tlb
  widget_control, tlb, get_uvalue = info
  ptr_free, (*info).filelist 
  ptr_free, info
end

; determine data source and search directory
function xfiles_source, event
  widget_control, event.top, get_uvalue = info
  sdir = (*info).dsource_dir[event.value]
  (*info).datatype=(*info).dsource[event.value]
  sensitive = 1
;  if event.value eq (*info).nsource-1 then sensitive = 1
    dirsep = path_sep()
  if strmid(sdir, 0,1, /reverse_offset) ne dirsep then sdir = sdir+dirsep
  (*info).sdir = sdir
  sstr = (*info).sdir + (*info).filter
  filelist = file_search(sstr, count = fcount)
  if fcount ne 0 then begin
    ptr_free, (*info).filelist 
    (*info).filelist = ptr_new(strarr(fcount))
    *(*info).filelist = filelist
  endif else filelist=' '
  widget_control, (*info).searchdir, set_value = sdir,  $
                  sensitive = sensitive
  widget_control, (*info).foundfiles, set_value = filelist
  return, 0
end

; set search filter
pro xfiles_filter, event
  dirsep = path_sep()
  widget_control, event.top, get_uvalue = info
  filter = strtrim(event.value, 2)
  if filter eq '' then begin
    filter='*'
    widget_control,(*info).filtercw,set_value = filter
  endif
  (*info).filter=filter
  sstr = (*info).sdir + (*info).filter
  filelist = file_search(sstr, count = fcount)
  if fcount ne 0 then begin
    ptr_free, (*info).filelist 
    (*info).filelist = ptr_new(strarr(fcount))
    *(*info).filelist = filelist
  endif else filelist=' '
  widget_control, (*info).foundfiles, set_value = filelist
end

; filters files according to date
pro xfiles_date, event
  widget_control, event.top, get_uvalue = info
  case event.id of 
  (*info).tstart: (*info).tstartval=event.value
  (*info).tstop: (*info).tstopval=event.value
  endcase
  startdate=anytim2cal((*info).tstartval,form=8,/date)
  starttime=anytim2cal((*info).tstartval,form=8,/time)
  stopdate=anytim2cal((*info).tstopval,form=8,/date)
  stoptime=anytim2cal((*info).tstopval,form=8,/time)
  sstr = (*info).sdir + (*info).filter
  filelist = file_search(sstr, count = fcount)
  filenodir = filelist
  if fcount ne 0 then begin
    filenodir = filelist
    for i=0,n_elements(filenodir)-1 do begin
      dum=(strsplit(filelist[i],path_sep(),/extract))
      filenodir[i]=dum[n_elements(dum)-1]
    endfor
    filedate=long(strmid(filenodir,7,8))
    filetime=long(strmid(filenodir,16,6))
    inrange = where(filedate ge startdate and filetime gt starttime and $
                    filedate le stopdate and filetime le stoptime)
    if inrange[0] ne -1 then begin
      filelist=filelist[inrange]
    endif else filelist=' '
  endif else filelist=' '
  ptr_free, (*info).filelist 
  (*info).filelist = ptr_new(filelist)
  widget_control, (*info).foundfiles, set_value = filelist
end

; list files in directory
pro xfiles_dir, event
  dirsep = path_sep()
  widget_control, event.top, get_uvalue = info
  sdir = strtrim(event.value, 2)
  if strmid(sdir, 0,1, /reverse_offset) ne dirsep then sdir = sdir+dirsep
  (*info).sdir = sdir
  sstr = (*info).sdir + (*info).filter
  filelist = file_search(sstr, count = fcount)
  if fcount ne 0 then begin
    ptr_free, (*info).filelist 
    (*info).filelist = ptr_new(strarr(fcount))
    *(*info).filelist = filelist
  endif else filelist=' '
  widget_control, (*info).foundfiles, set_value = filelist
end

; save the selected file
pro xfiles_select, event
  widget_control, event.top, get_uvalue = info
  findx = event.index
  flist = *(*info).filelist
  sdir=(*info).sdir

  ; add full path to filenames in subdirectories, so that these 
  ; files can be selected directly
  ; first check if the first entry is a subdirectory (it ends with a ':')

  last_char=strmid(flist(0),0,/reverse_offset)
  
  ; find the indexes of the rest of the subdirectories
  subdirindx=where(flist eq '',count)+1
  nsub = n_elements(subdirindx) ; number of subdirectories
  if count eq 0 then nsub=-1 
  ;check if first entry in flist also is subdirectory 
  ;(special case since it is then not lead by an empty entry)
  if last_char eq ':' then begin
    subdir=flist[0]
    slen=strlen(subdir)  ; length of string
    ;take out ':' at the end and add dirsep    
    subdir=strmid(subdir,0,slen-1)+(*info).dirsep
    flist[0]=subdir
    start=1
    stop=subdirindx[0]-2
    if stop gt start then flist(start:stop)=subdir+flist[start:stop]
  endif
  ; then add path to the rest of the files in subdirectories
  for i=0,nsub-1 do begin
    subdir=flist[subdirindx[i]]
    slen=strlen(subdir)  ; length of string
    ;take out ':' at the end and add dirsep    
    subdir=strmid(subdir,0,slen-1)+(*info).dirsep
    flist[subdirindx[i]]=subdir
    start = subdirindx[i]+1
    if i eq nsub-1 then stop=n_elements(flist)-1 else $
                        stop=subdirindx[i+1]-2
    if stop gt start then flist[start:stop]=subdir+flist[start:stop]
  endfor
  (*info).fileselect = flist[findx]      ; selected file
;  if the file is a directory change sdir and return
  if (file_info((*info).fileselect)).directory then begin
    dirsep = path_sep()
    sdir=(*info).fileselect
    if strmid(sdir, 0,1, /reverse_offset) ne dirsep then sdir = sdir+dirsep
    (*info).sdir = sdir
    sstr = (*info).sdir + (*info).filter
    filelist = file_search(sstr, count = fcount)
    if fcount ne 0 then begin
      ptr_free, (*info).filelist 
      (*info).filelist = ptr_new(strarr(fcount))
      *(*info).filelist = filelist
    endif else filelist=' '
    widget_control, (*info).searchdir, set_value = sdir
    widget_control, (*info).foundfiles, set_value = filelist
    return
  end
end

; read the selected file and call xcontrol
pro xfiles_read, event
; define data object and read file
; ...but first a consistency check on the file name  
  widget_control, event.top, get_uvalue = info

  case (*info).datatype of
    'CCSDS' : begin
        if stregex((*info).fileselect,/fold_case,'.fits',/bool) then begin 
          ok=dialog_message('FITS file cannot be read as CCSDS file!!', $
                            /center,title='Xfiles warning',/information)
          return
        endif
        aux_obj=obj_new('eis_aux',(*info).fileselect)
        data_obj= obj_new('eis_data',(*info).fileselect, datasource='ccsds', hdr = hdr)
        xcontrol, data_obj, hdr, aux_obj, $
                  group_leader = (*info).tlb, filename = (*info).fileselect
        end
    'FITS'  : begin
        if not stregex((*info).fileselect,/fold_case,'.fits',/bool) then begin 
          ok=dialog_message('FITS file must have ".fits" extension!!', $
                            /center,title='Xfiles warning',/information)
          return
        endif
        aux_obj = obj_new('eis_aux',(*info).fileselect)
        data_obj = obj_new('eis_data',(*info).fileselect, datasource='fits')
        if data_obj->getfitslev() eq 2 then begin 
          data_obj->setcomment,'moments'
          linelist = indgen(data_obj->getnwin())          
          xmap, data_obj, data_obj->gethdr(), aux_obj, $
                linelist=linelist, group_leader = (*info).tlb
        endif else begin
          xcontrol, data_obj, (data_obj->gethdr()), aux_obj, $
                group_leader = (*info).tlb, filename = (*info).fileselect 
        endelse
        end
    'HK'    : begin
        hk_packet, (*info).fileselect
        end
    else:
  endcase
end

pro xfiles, dsrc=dsrc, dirdsrc=dirdsrc
@environment
  ; launch the error handler:
  catch, error_status
  ; begin error handler
  if error_status ne 0 then begin
    message = dialog_message(!error_state.msg, /error,/center)
  endif
; top level base widget:
if n_elements(dsrc) ne 0 then begin
  dsource=dsrc
endif
if n_elements(dirdsrc) ne 0 then begin 
  dsourcedir=dirdsrc
endif 

tlb = widget_base(/column, title='Xfiles - EIS QL Control Window', $
                  yoffset=200)

; first row contains exit button

;row1 = widget_base(tlb, /col, /frame)
exitbase = widget_base(tlb, /row, /frame)
exitb = widget_button(exitbase, value = 'Exit', event_pro = 'xfiles_exit')

eis_icon_base=widget_base(exitbase, /col, /align_right)
eis_icon = widget_draw(eis_icon_base, retain = 2, $ 
                       XSize = 120, YSize = 60, frame = 1)  

; determine data source
row2 = widget_base(tlb, /column, /frame)
slf = widget_base(row2, /row) ; data source label field
sls = 'Select data source'    ; data source string
slabel = widget_label(slf, value=sls)
nsource = n_elements(dsource)
datasource = cw_bgroup(row2, dsource, event_func = 'xfiles_source', $
                       /exclusive, column = nsource )
                       
; date/time fields
row3=widget_base(tlb, /column, /frame)
tlabelfield = widget_base(row3,/row)
tls = 'Start/Stop for file search. Time Units: DD-MON-YR HH:MM:SS.MS'
tlabel = widget_label(tlabelfield, value=tls)
tfield=widget_base(row3, /row, event_pro='xfiles_date')
tstart=cw_field(tfield, Title='Start Time:  ', value=' ', /string ,/return_events)
tstop =cw_field(tfield, Title='Stop Time:   ', value=' ', /string ,/return_events)

; search filter
row4=widget_base(tlb, /column, /frame)
filterfield = widget_base(row4, /row, event_pro = 'xfiles_filter')
sls = 'Set search filter '
filtercw=cw_field(filterfield, title=sls, value = ' ', $
                   /string, /return_events, xsize = 50)
                   
; search file fields
row5=widget_base(tlb, /column, /frame)
searchdirfield = widget_base(row5, /row, event_pro = 'xfiles_dir')
sls = 'Search Directory  '
searchdir=cw_field(searchdirfield, title=sls, value = ' ', $
                   /string, /return_events, xsize = 50)
                   
case !version.os of
  'MacOS': begin
     xsize = 80
     ysize = 5
   end
   else: begin
     xsize = 60 ; in cm as units=2
     ysize = 5  ; in cm as units=2
   end
endcase

foundfiles=widget_list(row5, value='', /frame, xsize = xsize $
                       , scr_ysize = ysize, units = 2 $
                       , event_pro = 'xfiles_select')
confbase = widget_base(row5, /col, /align_left)
confb = widget_button(confbase, value = 'Confirm selection' $
                      , event_pro = 'xfiles_read')

; initialize
tstartval = '23-Sep-06 00:00:00'
tstopval = '31-Dec-10 23:59:59'
widget_control, tstart,set_value = tstartval
widget_control, tstop,set_value = tstopval

; set up default directory and search for files filtered with *.dat
; if n_elements(sdir) eq 0 then sdir='~/solarb/data/eis/'
def=1
sdir = dsource_dir[def]
dirsep = path_sep()

if strmid(sdir, 0,1, /reverse_offset) ne dirsep then sdir = sdir+dirsep
if n_elements(sfilter) eq 0 then sfilter = 'eis_l0_*'
sstr = sdir + sfilter
filelist = file_search(sstr, count = fcount)
widget_control, datasource, set_value = def
datatype=dsource[def]
widget_control, searchdir, set_value = sdir, sensitive = 1
widget_control, foundfiles, set_value = filelist
widget_control, filtercw, set_value = sfilter

; realize the top level base widget
widget_control, tlb, /realize

; Define the info structure, used to send information around
info= { tlb:tlb, $
        tstart:tstart, $
        tstop:tstop, $
        tstartval:tstartval, $
        tstopval:tstopval, $
        filter:sfilter, $
        dsource:dsource, $
        nsource:nsource, $
        dsource_dir:dsource_dir, $
        datatype:datatype, $
        dirsep:dirsep, $
        searchdir:searchdir, $
        filtercw:filtercw, $
        sdir:sdir, $
        filelist:ptr_new(filelist), $
        fileselect:'', $
        foundfiles:foundfiles}
info=ptr_new(info,/no_copy)

; Set the info ptr to be the user value of the tlb widget
widget_control,tlb, set_uvalue=info      

widget_control, eis_icon , get_value = drawID
wset,drawID
fileName = concat_dir(GETENV('ancillary') , 'eis_logo_sarah_small.jpg')
read_jpeg , filename , icon
icon_resized = CONGRID(icon,3,120,60)
tvscl,icon_resized,true = 1

xmanager, 'xfiles', tlb, /no_block, $
          group_leader = group, cleanup = 'xfiles_cleanup'

end

