;+
; NAME:
;       XMKFITS
;
; PURPOSE:
;
;	XMKFITS is a widget based program to produce Solar-B/EIS FITS files 
;	from telemetry files. 
;
;
; CATEGORY:
;       Hansteen/Wikstøl Data analysis SW
;
; CALLING SEQUENCE:
;       xmkfits
;
; INPUTS:
;       none
;
; KEYWORD PARAMETERS:
;       none
;
;
; OUTPUTS:
;       Opens the XMKFITS GUI.
;
; CALLS:
;	eis_mkfits.pro
;
; COMMON BLOCKS:
;
;
; PROCEDURE:
;	Provides a list of telemtry files from a specified catalogue. 
;	The catalogue can be changed. By highlighting a file and pressing 
; 	the start-button, the fits generation i started. Output file directory 
;	and file name can be changed.  
;
; RESTRICTIONS:
;	In version 0.9, there are no communications with planning/as-run 
;	catalogues, and no spacecraft information. Defaults are used.
;
; MODIFICATION HISTORY:
;       2004-04-21: Øivind Wikstøl. Version 0.9
;-
;
pro xmkfits_exit, event
 widget_control, event.top, /destroy
end

; x cleanup
pro xmkfits_cleanup, tlb
  widget_control, tlb, get_uvalue = info
  ptr_free, info
end

; list files in directory
pro xmkfits_ccsdsdir, event
  widget_control, event.top, get_uvalue = info
  dirsep = (*info).dirsep

  sdir = strtrim(event.value, 2)
  if strmid(sdir, 0,1, /reverse_offset) ne dirsep then sdir = sdir+dirsep
  (*info).sdir = sdir
  dircheck = file_test(sdir, /dir)
  if dircheck eq 0 then begin
    message='Directory not found: '+strtrim(sdir, 2)
    widget_control, (*info).messages, set_value = message, /append
  endif

  filelist = file_search(sdir, '', /mark_directory, /test_regular, /nosort, count = fcount)
  if fcount ne 0 then begin
    (*info).filelist = ptr_new(strarr(fcount))
    *(*info).filelist = filelist
  endif else filelist=' '
  widget_control, (*info).ccsds_file_select, set_value = filelist

end

; read selected file and start fits creation
pro xmkfits_ccsds_file_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 first entry is subdirectory (end with a ':')
  last_char=strmid(flist((findx-1)>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
    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

    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).ccsdsfile = flist(findx)      ; selected file

end

; output fits directory:
pro xmkfits_fitsdir, event
  widget_control, event.top, get_uvalue = info
  dirsep = (*info).dirsep

  fitsdir = strtrim(event.value, 2)
  ; check if fitsdir is indeed a directory, or if it`s a user defined 
  ; fits file name:
  ext = strmid(fitsdir, 4, /reverse_offset)
  if ext eq '.fits' then begin    ; user specified fits file name
  ; extract file name
    (*info).fitsfile = $
      strmid(fitsdir,strpos(fitsdir,dirsep,/reverse_search)+1, strlen(fitsdir))
    (*info).fitsdir = $
      strmid(fitsdir, 0, strpos(fitsdir,dirsep,/reverse_search)+1)
  endif else begin
    (*info).fitsfile = ''
    (*info).fitsdir = fitsdir     
  endelse

; check if last character is dirsep or not. If not, add dirsep:
  last_char=strmid((*info).fitsdir,0,/reverse_offset)
  if last_char ne (*info).dirsep then (*info).fitsdir = (*info).fitsdir + (*info).dirsep

end

pro xmkfits_process, event
  widget_control, event.top, get_uvalue = info
; define data object and read file
  data=obj_new('eis_data', (*info).ccsdsfile, datasource='ccsds',hdr=hdr)
 
  ; no user defined fits file name, use default
  if (*info).fitsfile eq '' then begin   
    eis_mkfits, data, hdr, /doplan, /dospcd, $
                fitsdir = (*info).fitsdir, outfile = fitsfile
  endif else begin
    eis_mkfits, data, hdr, /doplan, /dospcd, $
                fitsdir = (*info).fitsdir,fitsfile = (*info).fitsfile
    fitsfile = (*info).fitsfile
  endelse
  message = 'Written FITS file '+(*info).fitsdir+strtrim(fitsfile,2)
  widget_control, (*info).messages, set_value = message, /append
end

pro xmkfits
@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)
;  endif
; top level base widget:
tlb = widget_base(/column, title='Xmkfits - EIS FITS Generation Tool')

; first row contains exit button, relist button
row1 = widget_base(tlb, /row, /frame)
exitb = widget_button(row1, value = 'Exit', event_pro = 'xmkfits_exit')
processb = widget_button(row1, value = 'Create FITS', $
                         event_pro = 'xmkfits_process') 

; CCSDS files field
row2=widget_base(tlb, /column, /frame)
ccsdsdirfield = widget_base(row2, /row, event_pro = 'xmkfits_ccsdsdir')
sls = 'Telemetry Catalogue'
ccsdsdir=cw_field(ccsdsdirfield, title=sls, value = ' ', $
                   /string, /return_events, xsize = 60)
                   
case !version.os of
  'MacOS': begin
     xsize = 80
     ysize = 5
   end
   else: begin
     xsize = 60
     ysize = 5
   end
endcase

ccsds_file_select=widget_list(row2,value='', /frame, xsize = xsize, $
                       scr_ysize = ysize, units = 2, $
                       event_pro = 'xmkfits_ccsds_file_select')

; FITS file directory:
row3=widget_base(tlb, /column, /frame)
fitsdirfield = widget_base(row2, /row, event_pro = 'xmkfits_fitsdir')
sls = 'FITS output Dir/Name'
fdir=cw_field(fitsdirfield, title=sls, value = ' ', $
                   /string, /return_events, xsize = 60)

; messages
row4=widget_base(tlb, /column, /frame)
messages=widget_text(row4, /wrap,/scroll, xsize = 80, ysize=10)

sdir = dsource_dir[0]
fitsdir = dsource_dir[1]
dirsep=path_sep()

  if strmid(sdir, 0,1, /reverse_offset) ne dirsep then sdir = sdir+dirsep

  last_char=strmid(fitsdir,0,/reverse_offset)
  if last_char ne dirsep then fitsdir = fitsdir + dirsep

filelist = file_search(sdir, '', /mark_directory, /test_regular, /nosort, count = fcount)
;filelist = file_search(sstr, count = fcount)
widget_control, ccsdsdir, set_value = sdir, sensitive = 1
widget_control, ccsds_file_select, set_value = filelist
widget_control, fdir, set_value = fitsdir, sensitive = 1
; realize the top level base widget
widget_control, tlb, /realize

; Define the info structure, used to send information around
info= { tlb:tlb, $
        dirsep:dirsep, $
        ccsdsdirfield:ccsdsdirfield, $
        ccsdsdir:ccsdsdir, $
        messages:messages, $
        sdir:sdir, $
        filelist:ptr_new(filelist), $
        ccsds_file_select:ccsds_file_select, $
        ccsdsfile:'', $
        fitsdir:fitsdir, $
        fitsfile:''}
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, messages, set_value='Messages:',/append
  
xmanager, 'xmkfits', tlb, /no_block, $
          group_leader = group, cleanup = 'xmkfits_cleanup'

end

