; $Id: tas_viewer.pro,v 1.9 2005/02/08 17:38:30 dimeo Exp $
;###############################################################################
;
; NAME:
;  TAS_VIEWER
;
; PURPOSE:
;  Simple TAS data viewer for previewing data prior to loading into PAN.
;
; CATEGORY:
;  DAVE, Data Analysis, PAN, curve fitting
;
; AUTHOR:
;   Robert M. Dimeo, Ph.D.
;   NIST Center for Neutron Research
;   100 Bureau Drive
;   Gaithersburg, MD 20899
;   Phone: (301) 975-8135
;   E-mail: robert.dimeo@nist.gov
;   http://www.ncnr.nist.gov/staff/dimeo
;
; LICENSE:
;  The software in this file is written by an employee of
;  National Institute of Standards and Technology
;  as part of the DAVE software project.
;
;  The DAVE software package is not subject to copyright protection
;  and is in the public domain. It should be considered as an
;  experimental neutron scattering data reduction, visualization, and
;  analysis system. As such, the authors assume no responsibility
;  whatsoever for its use, and make no guarantees, expressed or
;  implied, about its quality, reliability, or any other
;  characteristic. The use of certain trade names or commercial
;  products does not imply any endorsement of a particular product,
;  nor does it imply that the named product is necessarily the best
;  product for the stated purpose. We would appreciate acknowledgment
;  if the DAVE software is used of if the code in this file is
;  included in another product.
;
;###############################################################################
; TAS_VIEWER.PRO
;
;	Graphical user interface for TAS data browsing for use in PAN.
;	GUI written by R.M.Dimeo (4/23/03)
;
; REQUIREMENTS:
;		IDL 5.6 or higher
;		CMSET_OP.PRO by Craig Markwardt
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro tasviewer_plot,event
widget_control,event.top,get_uvalue = pstate
leaf_ids = *(*pstate).view_leaf_sel_ptr
nleaves = n_elements(leaf_ids)
xmin = 1.e32 & xmax = -1.e32 & ymin = xmin & ymax = xmax
for i = 0,nleaves-1 do begin
	widget_control,leaf_ids[i],get_uvalue = o
		ret = o->get(xvals = x,qty = y,dqty = yerr,xlabel = xlabel,ylabel = ylabel)
		if i eq 0 then xlabel_arr = xlabel else xlabel_arr = [xlabel_arr,xlabel]
		xmax = xmax > max(x)
		xmin = xmin < min(x)
		ymax = ymax > max(y+yerr)
		ymin = ymin < min(y-yerr)
		if (*pstate).tas_win_info.autoscale then begin
			(*pstate).tas_win_info.xrange = [xmin,xmax]
			(*pstate).tas_win_info.yrange = [ymin,ymax]
		endif
endfor
labels = xlabel_arr[uniq(xlabel_arr)]
nlabels = n_elements(labels)
if nlabels eq 1 then begin
	xlabel_display = labels[0]
endif else begin
	xlabel_display = labels[0]
	for i = 1,nlabels-1 do begin
		xlabel_display = xlabel_display+', '+labels[i]
	endfor
endelse

widget_control,leaf_ids[0],get_uvalue = o
ret = o->get(xvals = x,qty = y,dqty = yerr,xlabel = xlabel,ylabel = ylabel, $
	display_name = display_name)
if nleaves gt 1 then display_name = 'Multiple Files'
plot,[x],[y],psym = 8,xrange = (*pstate).tas_win_info.xrange,	$
	yrange = (*pstate).tas_win_info.yrange,/xsty,/ysty, $
	xtitle = xlabel_display,title = display_name
errplot,[x],[y-yerr],[y+yerr],width = 0.0
if nleaves gt 1 then begin
	for i = 1,nleaves-1 do begin
		widget_control,leaf_ids[i],get_uvalue = o
		ret = o->get(xvals = x,qty = y,dqty = yerr)
		oplot,[x],[y],psym = 8
		errplot,[x],[y-yerr],[y+yerr],width = 0.0
	endfor
endif
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro tasviewer_refresh,event
widget_control,event.top,get_uvalue = pstate
wset,(*pstate).tas_win_info.winpix
tasviewer_plot,event
wset,(*pstate).tas_win_info.winvis
device,copy = [0,0,!d.x_size,!d.y_size,0,0,(*pstate).tas_win_info.winpix]
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro tasviewer_context,event
widget_control,event.top,get_uvalue = pstate
tree_id = widget_info(event.top,find_by_uname = 'VIEW_TREE')
leaf_ids = widget_info(tree_id,/tree_select)
; If no leaves are selected then get out
if not widget_info(leaf_ids[0],/valid_id) then return
nleaves = n_elements(leaf_ids)
if nleaves eq 1 then begin
	context_base = widget_info(event.top,find_by_uname = 'VIEWER_SINGLE_SEL')
endif else begin
	context_base = widget_info(event.top,find_by_uname = 'VIEWER_MULTI_SEL')
endelse
widget_displaycontextmenu, event.id, event.x, event.y, context_base
*(*pstate).view_leaf_sel_ptr = leaf_ids
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro tasviewer_read_files,event
widget_control,event.top,get_uvalue = pstate
if n_elements(*(*pstate).file_ptr) eq 0 then return
limit_date = (*pstate).prefs.julian_date
filenames = *(*pstate).file_ptr
nfiles = n_elements(filenames)

for i = 0,nfiles-1 do begin
	o = obj_new('tasred_data',filename = filenames[i], $
		path = (*pstate).raw_directory,errmsg = errmsg)
	; If we've created a valid object then proceed.
	if obj_valid(o) then begin
		if n_elements(good_files) eq 0 then begin
			good_files = filenames[i]
		endif else begin
			good_files = [good_files,filenames[i]]
		endelse
		ret = o->get(julian_date = julian_date)
		if n_elements(date_array) eq 0 then date_array = julian_date else $
			date_array = [date_array,julian_date]
		obj_destroy,o
	endif else begin
		close,/all	; We may have quite a few logical units open here
					; so close them!
	endelse
endfor
date_sort = reverse(sort(date_array))
new_files = good_files[date_sort]
good_files = where(date_array ge limit_date,count)
if count eq 0 then return

*(*pstate).file_ptr = new_files[good_files]
nfiles = n_elements(*(*pstate).file_ptr)
for i = 0,nfiles-1 do begin
	o = obj_new('tasred_data',filename = new_files[i], $
		path = (*pstate).raw_directory)
	if i eq 0 then *(*pstate).dir_ptr = (*pstate).raw_directory else $
		*(*pstate).dir_ptr = [*(*pstate).dir_ptr,(*pstate).raw_directory]
	(*pstate).view_container->add,o
	; Add the objects to the "viewer" widget tree hierarchy
	ret = o->get(display_name = display_name)
	id = widget_info(event.top,find_by_uname = 'VIEW_ROOT')
	leaf_name = 'V_LEAF'
	new_leaf = widget_tree(id,value = display_name, $
		uvalue = o,uname = leaf_name)
	; Set the widget id data field in the data object equal to the
	; new leaf id created here.  This makes it easy to manipulate
	; the widget tree with only the data object reference.
	ret = o->set(wid = new_leaf)
endfor
uname = 'VIEW_SLIDER'
widget_control,widget_info(event.top,find_by_uname = uname),	$
	set_slider_max = nfiles-1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro tasviewer_show_header,event
; Which leaf was selected?
tree_id = widget_info(event.top,find_by_uname = 'VIEW_TREE')
sel_leaves = widget_info(tree_id,/tree_select)
nleaves = n_elements(sel_leaves)
valid = widget_info(sel_leaves[0],/valid_id)
if (nleaves eq 1) and valid then begin
	widget_control,sel_leaves[0],get_uvalue = o
	ret = o->get(header = header)
	void = dialog_message(dialog_parent = event.top,header,/information)
endif
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function tasviewer_get_files,dir
; Read in the names of all of the files in the current directory
bt2_filenames = file_search(dir+'*.bt*')
num_bt2_filenames = n_elements(bt2_filenames)
if bt2_filenames[0] eq '' then nbt2files = 0 else nbt2files = num_bt2_filenames
files_out = bt2_filenames

ng5_filenames = file_search(dir+'*.ng5')
num_ng5_filenames = n_elements(ng5_filenames)
if ng5_filenames[0] eq '' then nng5files = 0 else nng5files = num_ng5_filenames

if ((nbt2files+nng5files) eq 0) then return,['']
if (nbt2files eq 0) then return,ng5_filenames
if (nng5files eq 0) then return,bt2_filenames
return,[bt2_filenames,ng5_filenames]
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro tasviewer_remove_file,event
widget_control,event.top,get_uvalue = pstate
; Which leaves were selected?
tree_id = widget_info(event.top,find_by_uname = 'VIEW_TREE')
sel_leaves = widget_info(tree_id,/tree_select)
nleaves = n_elements(sel_leaves)
for i = 0,nleaves-1 do begin
	widget_control,sel_leaves[i],get_uvalue = object
	(*pstate).view_container->remove,object
	obj_destroy,object
	widget_control,sel_leaves[i],/destroy
endfor

; Update the file pointer list
nfiles = (*pstate).view_container->count()
if nfiles eq 0 then begin
	ptr_free,(*pstate).file_ptr
	(*pstate).file_ptr = ptr_new(/allocate_heap)
endif else begin
	oall = (*pstate).view_container->get(/all)
	for i = 0,nfiles-1 do begin
		ret = oall[i]->get(filename = filename)
		if i eq 0 then files_out = filename else files_out = [files_out,filename]
	endfor
	*(*pstate).file_ptr = files_out
endelse
nfiles = n_elements(*(*pstate).file_ptr)
slider_id = widget_info(event.top,find_by_uname = 'VIEW_SLIDER')
widget_control,slider_id,set_slider_max = (nfiles-1)>2
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro tasviewer_preferences,event
widget_control,event.top,get_uvalue = pstate
prefs = (*pstate).prefs
out = tas_preferences(group_leader = event.top,prefs)
if out.cancel ne 1 then begin
	(*pstate).prefs.raw_directory = out.raw_directory
	(*pstate).prefs.dave_directory = out.dave_directory
	(*pstate).raw_directory = out.raw_directory
	(*pstate).prefs.julian_date = out.julian_date
	; save these preferences to a local file
	prefs_ptr = ptr_new((*pstate).prefs)
	save,prefs_ptr,filename = (*pstate).tas_defaults
	ptr_free,prefs_ptr
	; Delete the current objects and read in the appropriate files
	nobj = (*pstate).view_container->count()
	if nobj eq 0 then begin
		*(*pstate).file_ptr = tasviewer_get_files((*pstate).raw_directory)
		if (*(*pstate).file_ptr)[0] ne '' then $
			tasviewer_read_files,event
		return
	endif
	vroot_id = widget_info(event.top,find_by_uname = 'VIEW_ROOT')
	for i = 0,nobj-1 do begin
		child = widget_info(vroot_id,/child)
		widget_control,child,get_uvalue = object
		(*pstate).view_container->remove,object
		obj_destroy,object
		widget_control,child,/destroy
	endfor
	*(*pstate).file_ptr = tasviewer_get_files((*pstate).raw_directory)
	if (*(*pstate).file_ptr)[0] ne '' then	$
		tasviewer_read_files,event
endif else begin
	return
endelse
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro tasviewer_winevents,event
widget_control,event.top,get_uvalue = pstate
case event.type of
0:	begin		; button press
	  (*pstate).tas_win_info.mouse = event.press
	  if (*pstate).tas_win_info.mouse eq 4 then begin	; right mouse button press
	    (*pstate).tas_win_info.autoscale = 1
        tasviewer_refresh,event
	  endif
	  if (*pstate).tas_win_info.mouse eq 1 then begin	; left mouse button press
	    (*pstate).tas_win_info.xbox[0] = event.x
	    (*pstate).tas_win_info.ybox[0] = event.y
	    wset,(*pstate).tas_win_info.winvis
	    device,copy = [0,0,!d.x_size,!d.y_size,0,0,(*pstate).tas_win_info.winpix]
	    empty
	    widget_control,(*pstate).tas_win_info.win,draw_motion_events = 1
	    (*pstate).tas_win_info.autoscale = 0
	  endif
	end
1:	begin	; button release
	 if (*pstate).tas_win_info.mouse eq 1 then begin
	  xll = (*pstate).tas_win_info.xbox[0] < (*pstate).tas_win_info.xbox[1]
	  yll = (*pstate).tas_win_info.ybox[0] < (*pstate).tas_win_info.ybox[1]
	  w = abs((*pstate).tas_win_info.xbox[1] - (*pstate).tas_win_info.xbox[0])
	  h = abs((*pstate).tas_win_info.ybox[1] - (*pstate).tas_win_info.ybox[0])
	  xur = xll + w
	  yur = yll + h
	  ll = convert_coord(xll,yll,/device,/to_data)
	  ur = convert_coord(xur,yur,/device,/to_data)
	  (*pstate).tas_win_info.xrange = [ll[0],ur[0]]
	  (*pstate).tas_win_info.yrange = [ll[1],ur[1]]
      tasviewer_refresh,event
	  (*pstate).tas_win_info.mouse = 0B
	  widget_control,(*pstate).tas_win_info.win,draw_motion_events = 0
	 endif
	 if (*pstate).tas_win_info.mouse eq 4 then begin
	  tasviewer_refresh,event
	  (*pstate).tas_win_info.mouse = 0B
	  widget_control,(*pstate).tas_win_info.win,draw_motion_events = 0
	 endif
	end
2:	begin	; mouse motion
	  if (*pstate).tas_win_info.mouse eq 1 then begin
	  	(*pstate).tas_win_info.xbox[1] = event.x
	  	(*pstate).tas_win_info.ybox[1] = event.y
	  	xc = [(*pstate).tas_win_info.xbox[0],event.x,event.x,$
	  	      (*pstate).tas_win_info.xbox[0],$
	  	      (*pstate).tas_win_info.xbox[0]]
	  	yc = [(*pstate).tas_win_info.ybox[0],(*pstate).tas_win_info.ybox[0],$
	  	      event.y,event.y,$
	  	      (*pstate).tas_win_info.ybox[0]]
	  	wset,(*pstate).tas_win_info.winVis
	  	device,copy = [0,0,!d.x_size,!d.y_size,0,0,(*pstate).tas_win_info.winPix]
	  	plots,xc,yc,/device
	  	empty
	  endif
	end
else:
endcase
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro tasviewer_sliderevents,event
widget_control,event.top,get_uvalue = pstate
uname = 'VIEW_SLIDER'
id = widget_info(event.top,find_by_uname = uname)
widget_control,id,get_value = val & val = fix(val[0])
; Highlight the appropriate leaf on the tree
object = (*pstate).view_container->get(position = val)
ret = object->get(wid = id)
; Deselect all of the leaves
nobj = (*pstate).view_container->count()
oall = (*pstate).view_container->get(/all)
for i = 0,nobj-1 do begin
	ret = oall[i]->get(wid = id)
	widget_control,id,set_tree_select = 0
endfor
object = (*pstate).view_container->get(position = val)
ret = object->get(wid = id)
widget_control,id,set_tree_select = 1
(*pstate).tas_win_info.autoscale = 1
*(*pstate).view_leaf_sel_ptr = id
tasviewer_refresh,event
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro tasviewer_sel_indepvar,event
widget_control,event.top,get_uvalue = pstate
this_event = tag_names(event,/structure_name)
;case this_event of
;'WIDGET_BUTTON':	$
;	begin
;		; First determine which leaf we are looking at...
;		sel_leaf = *(*pstate).view_leaf_sel_ptr
;		widget_control,sel_leaf[0],get_uvalue = object
;		if not obj_valid(object) then return
;		if strupcase(obj_class(object)) ne 'TASRED_DATA' then return
;		tas_indep_var_widget,	group_leader = event.top,			$
;								notifyids = [event.id,event.top],	$
;								object = object
;	end
;'TIVWEVENT':	$
;	begin
;
;		tasviewer_refresh,event
;	end
;else:
;endcase

sel_leaf = *(*pstate).view_leaf_sel_ptr
widget_control,sel_leaf[0],get_uvalue = object
if not obj_valid(object) then return
if strupcase(obj_class(object)) ne 'TASRED_DATA' then return
ret = tas_indep_var_widget(	group_leader = event.top,			$
							notifyids = [event.id,event.top],	$
							object = object)
tasviewer_refresh,event
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro tasviewer_make_package,event
widget_control,event.top,get_uvalue = pstate
leaf_ids = *(*pstate).view_leaf_sel_ptr
nleaves = n_elements(leaf_ids)
if nleaves eq 0 then begin
	dout = -1L
endif else begin
	widget_control,leaf_ids[0],get_uvalue = o
	ret = o->get(	xvals = x,					$
					qty = y,					$
					dqty = yerr,				$
					xlabel = xlabel,			$
					ylabel = ylabel, 			$
					header = header,			$
					display_name = display_name)

	dout =	{	x:reform(x),				$
				y:reform(y),				$
				yerr:reform(yerr),			$
				xlabel:xlabel,				$
				ylabel:ylabel,				$
				header:header,				$
				filesel:display_name		}
endelse
*(*pstate).dout_ptr = dout
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro tasviewer_event,event

widget_control,event.top,get_uvalue = pstate
; Is this is a context-sensitive menu launch event?
this_event = tag_names(event,/structure)

if (this_event eq 'WIDGET_CONTEXT') and $
	((*pstate).view_container->count() gt 0) then begin
	; What kind of leaf has been selected?
	if n_elements(*(*pstate).view_leaf_sel_ptr) eq 0 then return
	leaf = (*(*pstate).view_leaf_sel_ptr)[0]
	uname = widget_info(leaf,/uname)
	if uname ne 'V_LEAF' then return
	tasviewer_context,event
endif

uname = widget_info(event.id,/uname)
case uname of
	'QUIT':	$
		begin
			tasviewer_make_package,event
			widget_control,event.top,/destroy
		end
	'PREFERENCES': begin
	;;print,event,' before...'
			tasviewer_preferences,event
	;;print,event,' after...'
	end
	'SEND2PAN':
	'SELECT_INDEP_VAR':	tasviewer_sel_indepvar,event
	'VIEW_REMOVE_FILE':	tasviewer_remove_file,event
	'VIEW_HEADER':		tasviewer_show_header,event
	'V_LEAF':	$
		begin
			tree_id = widget_info(event.top,find_by_uname = 'VIEW_TREE')
			sel_leaves = widget_info(tree_id,/tree_select)
			*(*pstate).view_leaf_sel_ptr = sel_leaves
			if n_elements(sel_leaves) eq 1 then begin
				; move the slider to the appropriate location
				widget_control,sel_leaves[0],get_uvalue = object
				oall = (*pstate).view_container->get(/all)
				indices = where(oall eq object,count)
				if count eq 0 then return
				index = indices[0]
				uname = 'VIEW_SLIDER'
				widget_control,widget_info(event.top,find_by_uname = uname),	$
					set_value = index
			endif
			(*pstate).tas_win_info.autoscale = 1
			tasviewer_refresh,event
		end
	'VIEW_WINDOW':		tasviewer_winevents,event
	'VIEW_ROOT':	$
		begin
			ptr_free,(*pstate).view_leaf_sel_ptr
			(*pstate).view_leaf_sel_ptr = ptr_new(/allocate_heap)
		end
	'VIEW_SLIDER':	$
		begin
			if (*pstate).view_container->count() gt 0 then	$
				tasviewer_sliderevents,event
		end
else:
endcase
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function tas_viewer,group_leader = group_leader
register_name = 'TAS_VIEWER'
widget_control,group_leader,sensitive = 0
if xregistered(register_name) then return,0
; Widget definition module
device,decomposed = 0
loadct,0,/silent
; Create a tab widget with two panes:
; The first pane is the TAS data viewer
; The second pane is the TAS data reducer
if n_elements(group_leader) eq 0 then begin
	group_leader = 0L
	modal = 0
endif else begin
	modal = 1
endelse
title = "Triple-Axis Data Viewer"
tlb = widget_base(group_leader = group_leader,/row,title = title, $
	tlb_frame_attr = 1,modal=modal)
button_base = widget_base(tlb,/col)
base = widget_base(tlb,/col)
void = widget_button(button_base,value = 'Preferences',uname = 'PREFERENCES')
;void = widget_button(button_base,value = 'QUIT',uname = 'QUIT')

base = widget_base(tlb,/col)
view_base = widget_base(base,/row)

cd,current = this_directory
dave_directory = (*!dave_defaults).workDir
raw_directory = (*!dave_defaults).datDir
; Create the view pane
view_tree = widget_tree(view_base,/context_events,/multiple,uname = 'VIEW_TREE')
winxsize = 400 & winysize = 400
view_root = widget_tree(view_tree,value = 'TAS DATA',/folder,/expanded, $
	uname = 'VIEW_ROOT')
viewer_slider = widget_slider(base,value = 0,title = 'Select file', $
	uname = 'VIEW_SLIDER', min = 0,max = 2)
viewer_win = widget_draw(view_base,xsize = winxsize,ysize = winysize, $
	uname = 'VIEW_WINDOW',/button_events)

; Create the context-sensitive menus
; Single selection
viewer_single_base = widget_base(tlb,/context_menu,uname = 'VIEWER_SINGLE_SEL')
void = widget_button(viewer_single_base,value='View header',uname='VIEW_HEADER')
void = widget_button(viewer_single_base,value='Remove file',uname='VIEW_REMOVE_FILE')
void = widget_button(viewer_single_base,value='Select a different ' $
	+'independent variable', $
	uname='SELECT_INDEP_VAR')
void = widget_button(viewer_single_base,value='Send to PAN', $
	uname='QUIT')

; Multiple selection
viewer_multi_base = widget_base(tlb,/context_menu,uname = 'VIEWER_MULTI_SEL')
void = widget_button(viewer_multi_base,value='Remove files',uname='VIEW_REMOVE_FILE')

widget_control,tlb,/realize
widget_control,viewer_win,get_value = vwin_vis
window,/free,/pixmap,xsize = winxsize,ysize = winysize
view_pix = !d.window
julian_date = systime(/julian)

n = 20
xc = cos(2.*!pi*findgen(20)/(n-1.))
yc = sin(2.*!pi*findgen(20)/(n-1.))
usersym,xc,yc,/fill

; No matter what, the TAS defaults are defined in the next few lines of code.
tas_defaults = (!home_dir)+'.TAS_DEFAULTS.SAV'
print,!home_dir
if (file_test(tas_defaults)) then begin
	restore,tas_defaults
	prefs=*prefs_ptr
	ptr_free,prefs_ptr
	raw_directory = prefs.raw_directory
	dave_directory = prefs.dave_directory
endif else begin
	prefs =	{raw_directory:raw_directory,	$
			 dave_directory:dave_directory,	$
			 julian_date:julian_date}
	prefs_ptr = ptr_new(prefs)
	save,prefs_ptr,filename = tas_defaults
	ptr_free,prefs_ptr
endelse
tas_win_info =	{	win:viewer_win,						$
					winpix:view_pix,					$
					winvis:vwin_vis,					$
					autoscale:1,						$
					xrange:fltarr(2),					$
					yrange:fltarr(2),					$
					xbox:intarr(2),						$
					ybox:intarr(2),						$
					mouse:0B							}

state = {	base:base,									$
			group_leader:group_leader,					$
			tas_win_info:tas_win_info,					$
			prefs:prefs,								$
			tas_defaults:tas_defaults,					$
			view_container:obj_new('IDL_CONTAINER'),	$
			dave_directory:dave_directory,				$
			file_ptr:ptr_new(/allocate_heap),			$
			dir_ptr:ptr_new(/allocate_heap),			$
			view_leaf_sel_ptr:ptr_new(/allocate_heap),	$
			dout_ptr:ptr_new(/allocate_heap),			$
			raw_directory:raw_directory		}

pstate = ptr_new(state,/no_copy)
widget_control,tlb,set_uvalue = pstate

files = tasviewer_get_files((*pstate).raw_directory)
if files[0] ne '' then *(*pstate).file_ptr = files

if n_elements((*pstate).file_ptr) ne 0 then begin
	pseudo_event = {id:void,top:tlb,handler:0L}
	tasviewer_read_files,pseudo_event
endif


xmanager,register_name,tlb,event_handler = 'tasviewer_event',no_block=modal
if n_elements(*(*pstate).dout_ptr) ne 0 then begin
	dout = *(*pstate).dout_ptr
	; Clean everything up
endif else begin
	dout = 0L
endelse
wdelete,(*pstate).tas_win_info.winpix
obj_destroy,(*pstate).view_container
ptr_free,(*pstate).view_leaf_sel_ptr,(*pstate).dout_ptr
ptr_free,(*pstate).file_ptr,(*pstate).dir_ptr
ptr_free,pstate
widget_control,group_leader,sensitive = 1
return,dout
end
