; Copyright (c) 1998-2015 A.P. Hitchcock, Ben Watts  All rights reserved
;+
;NAME:
;	AX_NEXUS
;
;LAST CHANGED: ----------------------------------- 13-Jul-15
;
;PURPOSE:
;	This set of procedures is a widget to read in files
; in the HDF5 NeXus file format developed for STXM
; The widget uses read_nexus to perform the file input.
;
;CATEGORY:
;	AXIS: utility
;
; AX_NEXUS_EVENT ROUTINES:
; TEXT_NEXUS_FNAME		modify filename; when changed, execute BUT_NEXUS_FNAME_BROWSE to get parameters
; BUT_NEXUS_FNAME_BROWSE 	browse for new filename; if found, load new parameters
; BUT_NEXUS_STACK_IMAGE    proceed to read single image from stack
; BUT_NEXUS_OK			proceed with loading NEXUS file into AXIS
; BUT_NEXUS_CANCEL		abort read in
; BUT_NEXUS_NORMALIZE toggle flag to enable normalising data to ring current
; BUT_NEXUS_XY_CORRECT toggle flag to enable correcting per-pixel positions
; WID_DLIST_CHANNEL		drop list used to display and select the data channel
; BASE_NEXUS_UPDATE   update widgets
; WID_DLIST_REGION    drop list to display and select region
; WID_DLIST_IMAGE     drop list to display and select image
;
;COMMON BLOCKS:
;	@AXIS_COM	standard set of common blocks
;	@NEXUS_COM 	structure with header info
;
;MODIFICATION HISTORY:
; (27-Apr-15 bw)  First version written using ax_sdf.pro as a template
; (13-Jul-15 aph) integrated into 02-July-15 version of aXis2000
;-

pro TEXT_NEXUS_FNAME, Event
on_error,2
@axis_com
@nexus_com

; get the changed name
id = widget_info(Event.top, FIND_BY_UNAME = 'TEXT_NEXUS_FNAME')
WIDGET_CONTROL,id, Sensitive=1, Get_value = fname
IF fname(0) EQ nexus_lastfile then return
; generate full name with path
pfname = nexus_path + fname

; -- check if the filename exists - if not assume this is just a trap out of
; -- the user starting to type a changed name or a mistake
t = findfile(pfname(0), count=t_count) & if t_count EQ 0 then return
;print, 'New filename is ', fname(0)
nexus_lastfile = fname(0)

; update details
 BUT_NEXUS_FNAME_BROWSE, Event, file = fname(0)

end

;-----------------------------------------------------------------
pro BUT_NEXUS_FNAME_BROWSE, Event, file=file
on_error,2
@axis_com
@nexus_com
; get new filename
if NOT keyword_set(file) then begin
	fname = pickfile2(Title='Select NEXUS file', Filter = '*.hdf5')
endif else fname = file
if strlen(fname) GT 0 then begin
	t = ax_name(fname)
	nexus_path = t(0)
	nexus_lastfile = t(1)+'.'+t(2)          ; ensure the filename is saved for future use
; update nexus_path and file_name in the text box
BASE_NEXUS_UPDATE, Event.Top
endif
end

pro WID_DLIST_CHANNEL, Event
on_error,2
@axis_com
@nexus_com
; get the changed data channel
id = widget_info(Event.top, FIND_BY_UNAME = 'WID_DLIST_CHANNEL')
WIDGET_CONTROL,id, Sensitive=1, Get_value = nexus_ch
WIDGET_CONTROL,id, SET_DROPLIST_SELECT = nexus_ch
print, 'New channel selected ', nexus_ch
end

pro WID_DLIST_REGION, Event
on_error,2
@axis_com
@nexus_com
; get the changed region
id = widget_info(Event.top, FIND_BY_UNAME = 'WID_DLIST_REGION')
WIDGET_CONTROL,id, Sensitive=1, Get_value = nexus_region
WIDGET_CONTROL,id, SET_DROPLIST_SELECT = nexus_region
end

pro WID_DLIST_IMAGE, Event
on_error,2
@axis_com
@nexus_com
; get the selected image
id = widget_info(Event.top, FIND_BY_UNAME = 'WID_DLIST_IMAGE')
WIDGET_CONTROL,id, Sensitive=1, Get_value = nexus_image
;WIDGET_CONTROL,id, SET_DROPLIST_SELECT = nexus_region
end

;-------------------------Read in a single image from a stack ----------------------------------------
pro BUT_NEXUS_STACK_IMAGE, Event
@axis_com
@nexus_com
on_error,2

id = widget_info(Event.top, FIND_BY_UNAME = 'WID_DLIST_IMAGE')
nexus_image_index = WIDGET_INFO(id, /Droplist_select)

; get the selected image
id = widget_info(Event.top, FIND_BY_UNAME = 'WID_DLIST_IMAGE')
WIDGET_CONTROL,id, Sensitive=1, Get_value = nexus_image

 print, 'Extracting single image at E = ', nexus_image(nexus_image_index)
nexus_image_index = fix(nexus_image_index) +1	; kluge to avoid problem that IDL uses 0 as false !
; get the path & filename
id = widget_info(Event.top, FIND_BY_UNAME = 'TEXT_NEXUS_PATH')
WIDGET_CONTROL,id, Get_value = path
id = widget_info(Event.top, FIND_BY_UNAME = 'TEXT_NEXUS_FNAME')
WIDGET_CONTROL,id, Sensitive=1, Get_value = fname
fname = path + fname ;+ '.hdf5'
;; get the data channel
id = widget_info(Event.top, FIND_BY_UNAME = 'WID_DLIST_CHANNEL')
this_channel = 1 + WIDGET_INFO(id, /Droplist_select)
 print, 'channel is ', this_channel
; get the region
id = widget_info(Event.top, FIND_BY_UNAME = 'WID_DLIST_REGION')
this_region = 1 + widget_info(id, /DROPLIST_SELECT)
 print, 'region is ', this_region

widget_control, /hourglass
nexus = read_nexus(fname(0), channel= this_channel, region = this_region, one_image=nexus_image_index, group=NEXUS_ID)

WIDGET_CONTROL, Event.Top, /DESTROY
end


;-----------------------------------------------------------------
pro BUT_NEXUS_OK, Event
on_error,2
@axis_com
@nexus_com
; get the path & filename
id = widget_info(Event.top, FIND_BY_UNAME = 'TEXT_NEXUS_PATH')
WIDGET_CONTROL,id, Get_value = path
id = widget_info(Event.top, FIND_BY_UNAME = 'TEXT_NEXUS_FNAME')
WIDGET_CONTROL,id, Sensitive=1, Get_value = fname
fname = path + fname
print, ' Reading in NEXUS file: ', fname

; get the data channel
id = widget_info(Event.top, FIND_BY_UNAME = 'WID_DLIST_CHANNEL')
nexus_ch = WIDGET_INFO(id, /Droplist_select)
nchnls = n_elements(nexus_ch)
widget_control, /hourglass
; get the region
n_regions = nexus_head.n_regions
id = widget_info(Event.top, FIND_BY_UNAME = 'WID_DLIST_REGION')
nexus_region = WIDGET_INFO(id, /Droplist_select)
region = nexus_region(0) + 1
if  region LE n_regions then begin
; read the data file for a defined region
	nchnls=n_elements(NEXUS_Channel_List)
	print, 'Reading channel ', string(nexus_ch(0)+1,format='(i2)'), ' of ', string(nchnls,format='(i2)'), $
	' channels.  Region ', string(region,format='(i2)'), ' of ', string(n_regions,format='(i2)'), ' regions.'
	nexus = read_nexus(fname(0), channel=nexus_ch(0)+1, region=region, group=NEXUS_ID, xy_correct=xy_correct_flag)
endif else begin		; read all regions
	print, 'Reading channel ', string(nexus_ch(0)+1,format='(i2)'), ' of ', string(nchnls,format='(i2)'), $
	' channels.  All ', string(n_regions,format='(i2)'), ' regions.'
  nexus = read_nexus(fname(0), channel=nexus_ch(0)+1, region=0,xy_correct=xy_correct_flag, /all_regions, group=NEXUS_ID)
endelse

WIDGET_CONTROL, Event.Top, /DESTROY
return
end

;-----------------------------------------------------------------

pro BUT_NEXUS_NORMALIZE, Event
@axis_com
@nexus_com
on_error,2
if norm_flag EQ 1 then norm_flag = 0 else  norm_flag = 1
; print, ' normalzation status changed to ', norm_flag
 id = widget_info(Event.top, FIND_BY_UNAME = 'BUT_NEXUS_NORMALIZE')
 WIDGET_CONTROL,id, set_button=norm_flag
end

;-----------------------------------------------------------------

pro BUT_NEXUS_XY_CORRECT, Event
@axis_com
@nexus_com
on_error,2
if xy_correct_flag EQ 1 then xy_correct_flag = 0 else  xy_correct_flag = 1
; print, ' xy_correct status changed to ', xy_correct_flag
 id = widget_info(Event.top, FIND_BY_UNAME = 'BUT_NEXUS_XY_CORRECT')
 WIDGET_CONTROL,id, set_button=xy_correct_flag
end
;-----------------------------------------------------------------

pro BUT_NEXUS_CANCEL, Event
@axis_com
@nexus_com
on_error,2
nexus = 0

WIDGET_CONTROL, Event.Top, /DESTROY
end

;-----------------------------------------------------------------
; ****************************************************************
;-----------------------------------------------------------------
PRO BASE_NEXUS_UPDATE, Widget_id ; Update widgets with file info
on_error,2
@axis_com
@nexus_com
; get new filename
IF (size(nexus_path,/type) NE 0) AND (size(nexus_lastfile,/type) NE 0) THEN BEGIN ; if path and filename variables are defined
;  PRINT, 'BASE_NEXUS_UPDATE: ', nexus_path, '--',  nexus_lastfile
  t = findfile(nexus_path+nexus_lastfile, count=t_count)
  IF t_count NE 0 THEN BEGIN ; if the file can be found
    ; update nexus_path and file_name in the text box
    id = widget_info(Widget_id, FIND_BY_UNAME = 'TEXT_NEXUS_PATH')
    WIDGET_CONTROL,id, Set_value = nexus_path
    id = widget_info(Widget_id, FIND_BY_UNAME = 'TEXT_NEXUS_FNAME')
    WIDGET_CONTROL,id, Set_value = nexus_lastfile
    ; read file and update type
    widget_control, /hourglass
    nexus_head = read_nexus(nexus_path + nexus_lastfile, /header_only)
    ; update the type
    id = widget_info(Widget_id, FIND_BY_UNAME = 'TEXT_NEXUS_TYPE')
    WIDGET_CONTROL,id, Sensitive=1, Set_value = nexus_head.Type
    ;  ------------- update data channel information
    unpack_Channel_labels = nexus_head.Channel_labels(0)
    nchnl = n_elements(unpack_Channel_labels)
    NEXUS_Channel_List = strarr(nchnl)
    for i = 0, nchnl(0)-1 do NEXUS_Channel_List(i) = unpack_Channel_labels[i]
    id = widget_info(Widget_id, FIND_BY_UNAME = 'WID_DLIST_CHANNEL')
    WIDGET_CONTROL,id, Set_VALUE = NEXUS_Channel_List, sensitive = 1
    ; ------------- update region information
    ; currently there are no names associated with regions; can only set number of elements
    n_regions = nexus_head.n_regions
    if n_regions GT 1 then NEXUS_region_List = strarr(n_regions+1) else NEXUS_region_List = ' '
    for i = 0, n_regions-1 do NEXUS_Region_List(i) = 'Region '+ strtrim(string(i+1),2)
    if n_regions GT 1 then NEXUS_Region_List(n_regions) = 'all regions'
    id = widget_info(Widget_id, FIND_BY_UNAME = 'WID_DLIST_REGION')
    WIDGET_CONTROL,id, Set_VALUE = NEXUS_Region_List, Sensitive=1

    ; ---------- update image number information (for NEXAFS image sequences)
    if nexus_head.Type EQ 'sample image stack' then begin
      NEXUS_Image_List = strtrim(string(nexus_head.StackAxis.Points, format='(F7.2)'),2)
      id = widget_info(Widget_id, FIND_BY_UNAME = 'WID_DLIST_IMAGE')
      widget_control, id, Set_Value=NEXUS_Image_List, sensitive = 1
      id = widget_info(Widget_id, FIND_BY_UNAME = 'BUT_NEXUS_STACK_IMAGE')
      widget_control, id, sensitive = 1
    endif else begin
    id = widget_info(Widget_id, FIND_BY_UNAME = 'WID_DLIST_IMAGE')
      widget_control, id, sensitive = 0
      id = widget_info(Widget_id, FIND_BY_UNAME = 'BUT_NEXUS_STACK_IMAGE')
      widget_control, id, sensitive = 0
    endelse
  ENDIF ELSE PRINT, 'Last NeXus filename is not valid.'
ENDIF
END

pro BASE_NEXUS_event, Event
@axis_com
@nexus_com

  case Event.id of

    Widget_Info(Event.Top, FIND_BY_UNAME='TEXT_NEXUS_FNAME'): begin
      if( Tag_Names(Event, /STRUCTURE_NAME) eq 'WIDGET_TEXT_CH' )then $
        TEXT_NEXUS_FNAME, Event
    end
      Widget_Info(Event.Top, FIND_BY_UNAME='WID_DLIST_CHANNEL'): begin
      if( Tag_Names(Event, /STRUCTURE_NAME) eq 'WIDGET_TEXT_STR' )then $
        WID_DLIST_CHANNEL, Event
    end
      Widget_Info(Event.Top, FIND_BY_UNAME='WID_DLIST_REGION'): begin
      if( Tag_Names(Event, /STRUCTURE_NAME) eq 'WIDGET_TEXT_STR' )then $
        WID_DLIST_REGION, Event
    end
      Widget_Info(Event.Top, FIND_BY_UNAME='WID_DLIST_IMAGE'): begin
      if( Tag_Names(Event, /STRUCTURE_NAME) eq 'WIDGET_TEXT_STR' )then $
        WID_DLIST_IMAGE, Event
    end
    Widget_Info(Event.Top, FIND_BY_UNAME='BUT_NEXUS_FNAME_BROWSE'): begin
      if( Tag_Names(Event, /STRUCTURE_NAME) eq 'WIDGET_BUTTON' )then $
        BUT_NEXUS_FNAME_BROWSE, Event
    end
    Widget_Info(Event.Top, FIND_BY_UNAME='TEXT_NEXUS_TYPE_TITLE_0'): begin
      if( Tag_Names(Event, /STRUCTURE_NAME) eq 'WIDGET_TEXT_DEL' )then $
        BUT_NEXUS_FNAME_BROWSE, Event
    end
    Widget_Info(Event.Top, FIND_BY_UNAME='BUT_NEXUS_OK'): begin
      if( Tag_Names(Event, /STRUCTURE_NAME) eq 'WIDGET_BUTTON' )then $
        BUT_NEXUS_OK, Event
    end
    Widget_Info(Event.Top, FIND_BY_UNAME='BUT_NEXUS_CANCEL'): begin
      if( Tag_Names(Event, /STRUCTURE_NAME) eq 'WIDGET_BUTTON' )then $
        BUT_NEXUS_CANCEL, Event
    end
    Widget_Info(Event.Top, FIND_BY_UNAME='BUT_NEXUS_STACK_IMAGE'): begin
      if( Tag_Names(Event, /STRUCTURE_NAME) eq 'WIDGET_BUTTON' )then $
        BUT_NEXUS_Stack_IMAGE, Event
    end
    Widget_Info(Event.Top, FIND_BY_UNAME='BUT_NEXUS_NORMALIZE'): begin
      if( Tag_Names(Event, /STRUCTURE_NAME) eq 'WIDGET_BUTTON' )then $
        BUT_NEXUS_NORMALIZE, Event
    end
    Widget_Info(Event.Top, FIND_BY_UNAME='BUT_NEXUS_XY_CORRECT'): begin
      if( Tag_Names(Event, /STRUCTURE_NAME) eq 'WIDGET_BUTTON' )then $
        BUT_NEXUS_XY_CORRECT, Event
    end
    else: print, 'Undefined action'
  endcase

end

;-----------------------------------------------------------------
; ****************************************************************
;-----------------------------------------------------------------


pro BASE_NEXUS, GROUP_LEADER=wGroup,  file=file, _EXTRA=_VWBExtra_
@axis_com
@nexus_com

t = size(wGroup)
IF t(1) EQ 0 THEN modal_val=0 else modal_val=1

BASE_NEXUS = Widget_Base( GROUP_LEADER=wGroup, UNAME='BASE_NEXUS', TITLE='Read NeXus HDF5 files', modal = modal_val, /column)
row1 = widget_base(base_nexus,/row)
col1 = widget_base(row1,/column)
row = widget_base(base_nexus,/row)

tlabel = widget_label(row,value='Path ')
TEXT_NEXUS_PATH = Widget_Text(row, UNAME='TEXT_NEXUS_PATH', /FRAME,  XSIZE=50)

row = widget_base(base_nexus,/row)
tlabel = widget_label(row,value='File ')
TEXT_NEXUS_FNAME = Widget_Text(row, UNAME='TEXT_NEXUS_FNAME', /FRAME,/EDITABLE ,ALL_EVENTS = 1 , KBRD_FOCUS_EVENTS = 0, XSIZE=50)
tlabel = widget_label(row,value=' ')
BUT_NEXUS_FNAME_BROWSE = Widget_Button(row, UNAME='BUT_NEXUS_FNAME_BROWSE', /ALIGN_CENTER ,VALUE='Browse')

row = widget_base(base_nexus,/row)
tlabel = widget_label(row,value='Type ')
TEXT_NEXUS_TYPE = Widget_Text(row, UNAME='TEXT_NEXUS_TYPE', EDITABLE=0 ,/ALL_EVENTS ,VALUE='Type', /ALIGN_CENTER , XSIZE=30)
tlabel = widget_label(row,value='   ')
tlabel = widget_label(row,value='   ')
BUT_NEXUS_Stack_Image = Widget_Button(row, UNAME='BUT_NEXUS_STACK_IMAGE',  VALUE='1 image')
tlabel = widget_label(row,value='   ')
BUT_NEXUS_CANCEL = Widget_Button(row, UNAME='BUT_NEXUS_CANCEL', /ALIGN_CENTER ,VALUE='Cancel')
tlabel = widget_label(row,value='       ')
BUT_NEXUS_OK = Widget_Button(row, UNAME='BUT_NEXUS_OK',  /ALIGN_CENTER, VALUE='  OK  ')

row = widget_base(base_nexus,/row)

WID_BASE_1 = Widget_Base(row, UNAME='WID_BASE_1',COLUMN=2 ,/NONEXCLUSIVE)

BUT_NEXUS_NORMALIZE = Widget_Button(wid_base_1, UNAME='BUT_NEXUS_NORMALIZE', /ALIGN_LEFT, VALUE='I-ring norm?')

BUT_NEXUS_XY_CORRECT = Widget_Button(wid_base_1, UNAME='BUT_NEXUS_XY_CORRECT', /ALIGN_LEFT, VALUE='xy correct ?')

NEXUS_Channel_List =['PMT','OSA','Analog']
NEXUS_Ch = 0
WID_DLIST_CHANNEL = Widget_Droplist(row, /DYNAMIC_RESIZE, VALUE = NEXUS_Channel_List, UNAME='WID_DLIST_CHANNEL', TITLE='Channel')

NEXUS_Region_List =['region 1']
NEXUS_region = 0
WID_DLIST_REGION = Widget_Droplist(row, /DYNAMIC_RESIZE, VALUE = NEXUS_Region_List, UNAME='WID_DLIST_REGION', TITLE='Region')

NEXUS_Image_List =[' ']
NEXUS_Im = 0
WID_DLIST_IMAGE = Widget_Droplist(row, /DYNAMIC_RESIZE, VALUE = NEXUS_Image_List, UNAME='WID_DLIST_IMAGE', TITLE='Image #')

; ----------- start display without active displays / controls
widget_control, WID_DLIST_CHANNEL, sensitive = 0
widget_control, WID_DLIST_REGION, sensitive = 0
widget_control, WID_DLIST_IMAGE, sensitive = 0
widget_control, TEXT_NEXUS_TYPE, sensitive = 0
widget_control, BUT_NEXUS_Stack_Image, sensitive = 0
; GTK crash with RedHat6 on next line if NEXUS_Image_List is a zero length string
Widget_Control, /REALIZE, BASE_NEXUS

; ----------- set to current value of normalization flag
if norm_flag EQ 1 then widget_control, BUT_NEXUS_Normalize, set_button = 1 $
  else widget_control, BUT_NEXUS_Normalize, set_button = 0

; ----------- set to current value of xy_correct_flag
if xy_correct_flag EQ 1 then widget_control, BUT_NEXUS_xy_correct, set_button = 1 $
  else widget_control, BUT_NEXUS_xy_correct, set_button = 0

; ------ set last path and file name if they exist
; ------ use keyowrd file if provided
if keyword_set(file) then begin		; assume file contains path
	t = ax_name(file)
	nexus_path = t(0)
  nexus_lastfile = t(1)
endif

BASE_NEXUS_UPDATE, BASE_NEXUS

XManager, 'BASE_NEXUS', BASE_NEXUS
NEXUS_ID = BASE_NEXUS

end

;-----------------------------------------------------------------
; ****************************************************************
;-----------------------------------------------------------------

function ax_nexus, file = file, GROUP_LEADER=wGroup, _EXTRA=_VWBExtra_
on_error,2
@axis_com
@nexus_com

nexus = ' '
if keyword_set(file) then begin
	BASE_NEXUS, GROUP_LEADER=wGroup, file=file, _EXTRA=_VWBExtra_
endif else begin
	BASE_NEXUS, GROUP_LEADER=wGroup, _EXTRA=_VWBExtra_
endelse

return, nexus
end
