; $Id: dave_examinefiles.pro,v 1.16 2007/08/02 18:48:16 jrdcopley Exp $
;###############################################################################
;
; 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.
;
;###############################################################################
;
; Written by J.R.D. Copley.
;
;	This program is based on code written in the early part of the decade. It replaces a version
; that was basically a modification by E. Bachetti.
; attempts to use this routine to examine DAVE files will fail; a separate program exists for
;	that purpose.
;
;************************************************************************************************
function xyy,x,qty
;************************************************************************************************
;
compile_opt strictarr
;
; x is a vector of length n (n columns)
; qty is an array with dimensions [n,m] (n columns, m rows)
; The quantity returned is an array with dimensions [m+1,n]
; Its first column is x and column k contains the k'th row of qty.
return,transpose([[x],[qty]])
end

;************************************************************************************************
function mid,x
;************************************************************************************************
;
compile_opt strictarr
;
; x is a vector of length n (n columns)
; The quantity returned is the set of numbers 0.5*(x[0]+x[1]), .... 0.5*(x[n-2]+x[n-1])
n=n_elements(x)
return,0.5*(x[0:n-2]+x[1:n-1])
end

;************************************************************************************************
pro dave_displaytext,text,title,widgetid=widgetid,group_leader=group_leader,index=index
;************************************************************************************************
;
compile_opt strictarr
;
sz=size(text)
if (sz[0] eq 0) then begin
	text=string(text)
	text=strtrim(text,1)
	height=1
	width=80
endif else begin
	if (sz[0] eq 1) then begin
		text=transpose(text)
		nums=transpose(sindgen(sz[1]))
	endif
	if (sz[0] eq 2) then begin
		if (sz[1] ge sz[2]) then text=transpose(text)
		nums=transpose(sindgen(sz[1]>sz[2]))
	endif
	text=string(text)
	if (index) then text=[nums,text]
	text=strtrim(text,1)
	for i=0,n_elements(text)-1 do begin
		text[i]=((strmid(text[i],0,1) eq "-") ? " " : "  ")+text[i]
	endfor
	text=strjoin(text)
	height=n_elements(text)<24
	width=80
endelse
nuls=where(strlen(text) eq 0,count)
if (count gt 0) then text[nuls]=" "
if (!windows) then dcs_fixedfont="courier*12"
if (!unix) then dcs_fixedfont="courier-12"
if (!macos) then dcs_fixedfont="courier*12"
xdisplayfile,filename,$
	DONE_BUTTON="Proceed",$
	FONT=dcs_fixedfont,$
	GROUP=group_leader,$
	/GROW_TO_SCREEN,$
	HEIGHT=height,$
	TEXT=text,$
	TITLE=title,$
	WIDTH=width,$
	WTEXT=widgetid, $
  /modal
;
end


;************************************************************************************************
pro dave_examineafile_handler,event
;************************************************************************************************
;
; The next line is commented out as a special exception so that expressions like x(9) are
;	accepted as "derived quantities".
;compile_opt strictarr
;
maxels=6000
;
widget_control,event.top,get_uvalue=pstate
varfilename=(*pstate).varfilename
;
if (event.id eq (*pstate).cancel) then begin
	if (ptr_valid((*pstate).varsPtr)) then ptr_free,(*pstate).varsPtr
	if (file_test(varfilename)) then file_delete,varfilename
	widget_control,event.top,/destroy
	return
endif
;
if (event.id eq (*pstate).clear) then begin
	for i=0,(*pstate).ntags-1 do begin
		butnumber=(*pstate).butid[i]-(*pstate).butid[0]
		if ((*pstate).buts_pressed[butnumber] eq 1) then begin
			(*pstate).buts_pressed[butnumber]=0
			if (widget_info((*pstate).widgetid[butnumber],/valid_id)) then begin
				parentid=widget_info((*pstate).widgetid[butnumber],/parent)
				widget_control,parentid,/destroy
			endif
			widget_control,(*pstate).butid[i],set_button=0
		endif
	endfor
	n=n_elements(*(*pstate).ptrwidgetids)
	if (n gt 1) then begin
		for i=1,n-1 do begin
			if (widget_info((*(*pstate).ptrwidgetids)[i],/valid_id)) then begin; this line fixed 5/8/02
				parentid=widget_info((*(*pstate).ptrwidgetids)[i],/parent)
				widget_control,parentid,/destroy
			endif
		endfor
		*(*pstate).ptrwidgetids=-1
	endif
	widget_control,event.top,set_uvalue=pstate
	return
endif
;
if (event.id eq (*pstate).dquan) then begin
	incom=event.value
	outcom=dave_expand_expr(incom[0],longform=(*pstate).tagnames,$
		shortform=(*pstate).sns)
	davePtr=(*pstate).davePtr
	res=execute("text="+outcom)
	if (not res) then begin
		nvars=n_elements(*(*pState).varsptr)
		if (nvars gt 1) then restore,varfilename
		res=execute("text="+outcom)
		if (not res) then invalid=dialog_message("Invalid expression.")
	endif
	if (res) then begin
		if (n_elements(text) le maxels) then begin
			dave_displaytext,text,incom,widgetid=widgetid,group_leader=event.top,$
				index=(*pstate).index
			*(*pstate).ptrwidgetids=[*(*pstate).ptrwidgetids,widgetid]
		endif else begin
			invalid=dialog_message("This array is too big to display.")
		endelse
	endif
	if ((*pstate).cfiel) then widget_control,event.id,set_value=""
	widget_control,event.top,set_uvalue=pstate
	return
endif
;
if (event.id eq (*pstate).idlcom) then begin
	incom=event.value
	outcom=dave_expand_expr(incom[0],longform=(*pstate).tagnames,$
		shortform=(*pstate).sns)
	davePtr=(*pstate).davePtr
	if (strmid(outcom,0,8) eq "DISPLAY,") then begin
		rhs=strmid(outcom,8)
		res=execute("text="+rhs)
		if (not res) then begin
			nvars=n_elements(*(*pState).varsptr)
			if (nvars gt 1) then restore,varfilename
			res=execute("text="+rhs)
			if (not res) then invalid=dialog_message("Invalid expression.")
		endif
		if (res) then begin
			if (n_elements(text) le maxels) then begin
				dave_displaytext,text,rhs,widgetid=widgetid,group_leader=event.top,$
					index=(*pstate).index
				*(*pstate).ptrwidgetids=[*(*pstate).ptrwidgetids,widgetid]
				if ((*pstate).cfiel) then widget_control,event.id,set_value=""
			endif else begin
				invalid=dialog_message("This array is too big to display.")
			endelse
		endif
	endif else begin
		nvars=n_elements(*(*pState).varsptr)
		if (nvars gt 1) then restore,varfilename
		res=execute(outcom)
		if (not res) then invalid=dialog_message("Invalid command.")
		if (res and strpos(incom,"=") gt 0 and strpos(outcom,"=") gt 0 and $
			strpos(incom,"=") eq strpos(outcom,"=")) then begin
			lhs=strmid(incom,0,strpos(incom,"="))
			if (strpos(lhs," ") eq -1) then begin
				tlist=[*(*pState).varsptr,lhs]
				*(*pState).varsptr=tlist(uniq(tlist,sort(tlist)))
				nvars=n_elements(*(*pState).varsptr)
				varlist=strjoin((*(*pState).varsptr)[1:nvars-1],",")
				command="save,filename="+"'"+varfilename+"',"+varlist
				res=execute(command)
				widget_control,(*pstate).variables,$
					set_value=['ADDITIONAL','VARIABLES',(*(*pState).varsptr)[1:nvars-1]]
			endif
		endif
	endelse
	if ((*pstate).cfiel) then widget_control,event.id,set_value=""
	widget_control,event.top,set_uvalue=pstate
	return
endif
;
if (event.id eq (*pstate).indexbutt) then begin
	(*pstate).index=event.select
	widget_control,event.top,set_uvalue=pstate
	return
endif
;
if (event.id eq (*pstate).clearfiel) then begin
	(*pstate).cfiel=event.select
	widget_control,event.top,set_uvalue=pstate
	return
endif
;
if (event.id eq (*pstate).helpbutt) then begin
	helptext=[$
		"Click on the DONE button when you're done looking at this file.",$
		"Click the CLEAR button to remove all variable display windows.",$
		"Check (clear) ''Include index'' to include (exclude) the row number.",$
		"If you check (clear) ''Clear fields'', the expression entered as a",$
		"''Derived quantity'' or as an ''IDL command'' will (will not) be cleared.",$
		"''Derived quantities'', such as x-x[0] or total(qty), may be displayed.",$
		"If an ''IDL command'' defines a new variable that variable will be listed."]
	dummy=dialog_message(helptext,/information)
	return
endif
;
k=where(event.id eq (*pstate).butid)
butnumber=(*pstate).butid[k[0]]-(*pstate).butid[0]
if (event.select eq 1 and (*pstate).buts_pressed[butnumber] eq 0) then begin
	datanels=((*pstate).datanels)[k]
	if (ulong(datanels[0]) le maxels) then begin
		(*pstate).buts_pressed[butnumber]=1
		davePtr=(*pstate).davePtr
		tagname=((*pstate).tagnames)[k]
		r=execute("text="+tagname[0])
		dave_displaytext,text,tagname[0],widgetid=widgetid,group_leader=event.top,$
			index=(*pstate).index
		(*pstate).widgetid[butnumber]=widgetid
	endif else begin
		x=dialog_message("This array is too big to display.")
		widget_control,(*pstate).butid[k[0]],set_button=0
	endelse
endif
if (event.select eq 0) then begin
	(*pstate).buts_pressed[butnumber]=0
	if (widget_info((*pstate).widgetid[butnumber],/valid_id)) then begin
		parentid=widget_info((*pstate).widgetid[butnumber],/parent)
		widget_control,parentid,/destroy
	endif
endif
;
widget_control,event.top,set_uvalue=pstate
end

;************************************************************************************************
pro dave_examineafile,filetype,davePtr,done,group_leader=group_leader
;************************************************************************************************
;
compile_opt strictarr
;
done=0
;
case filetype of
	"dcs": begin
		title="Select a single dcs raw data file to be examined:"
		filter="*.*"
		inpath=!dcs_data_directory
	end
;	"DAVE": begin
;		title="Select a single DAVE data file to be examined:"
;		filter="*.dave"
;		inpath=(*!dave_defaults).workdir
;	end
	else: begin
		result=dialog_message(["Invalid file type.","Exiting ..."])
		free_all_ptrs,davePtr
		dave_makeDavePtr,davePtr=davePtr
		done=1
		return
	end
endcase
;
files=dialog_pickfile(title=title,filter=filter,/must_exist,$
	path=inpath,get_path=path)
filename=files[0]
if (filename eq "" or not file_test(filename)) then begin
	free_all_ptrs,davePtr
	dave_makeDavePtr,davePtr=davePtr
	done=1
	return
endif
;
cd,path
;
if (filetype eq "dcs") then begin
	dcs_definedavestructure,davePtr=davePtr
	nofirstline=0
	omithisto=0
	printinfo=0
	dcs_read_binaryOctavefile,filename,nofirstline,omithisto,variables_read,$
		unknowns,error,davePtr=davePtr
	if (strlen(error) gt 0) then begin
		result=dialog_message(["Error reading binary file.","Exiting ..."])
		cd,current
		return
	endif
endif
	;
if (filetype eq "DAVE") then begin
	free_all_ptrs,davePtr
	restore,filename
endif
	;
lines=""
flags=0
bptrs=ptr_new()
;
dave_beast_ops,"get_ptrs",davePtr,bpointers=dummy
;
dave_analyze_beast,davePtr,"davePtr",lines,flags,bptrs,analysis=0
;
nlines=n_elements(lines)-1
lines=lines[1:nlines]
flags=flags[1:nlines]
;
tagnames=""
;
for j=0,nlines-1 do	$
	if (flags[j] eq 0) then tagnames=[tagnames,lines[j]]
;
ntags=n_elements(tagnames)-1
tagnames=tagnames[1:ntags]
sns=strarr(ntags)
;
; Generate corresponding descriptions.
idl_type=[" Undefined",$
	" Byte",$
	" Int",$
	" Longint",$
	" Float",$
	" DP float",$
	" Complex float",$
	" String",$
	" Structure",$
	" DP complex",$
	" Pointer",$
	" Object reference",$
	" U Int",$
	" U Longint",$
	" 64-bit Integer",$
	" Unsigned 64-bit Integer"]
;
datasize=strarr(ntags)
descriptor=strarr(ntags)
datanels=strarr(ntags)
totel=0l
for j=0,ntags-1 do begin
	com="sz=size("+tagnames[j]+")"
	result=execute(com)
	sns[j]=strmid(tagnames[j],strpos(tagnames[j],'.',/reverse_search)+1)
	lsns=strlen(sns[j])
	if (lsns gt 4 and strpos(strupcase(sns[j]),"PTR)")+4 eq lsns) then $
		sns[j]=strmid(sns[j],0,lsns-4)
	lsz=n_elements(sz)
	dim=sz[0]
	typ=sz[lsz-2]
	nel=sz[lsz-1]
	if (dim gt 0) then $
		datasize[j]=strcompress(strjoin(sz[1:lsz-3],"*"),/remove_all)$
	else datasize[j]=strcompress(1,/remove_all)
	descriptor[j]=idl_type[typ]
	datanels[j]=sz[lsz-1]
endfor
defined=where(descriptor ne " Undefined" and $
	descriptor ne " Pointer" and $
	descriptor ne " Object reference",ntags)
tagnames=tagnames[defined]
sns=sns[defined]
datasize=datasize[defined]
descriptor=descriptor[defined]
datanels=datanels[defined]
ncols=5
ntags=n_elements(tagnames)
maxnrows=(ntags-1)/ncols+1
tlb=widget_base(/col,title="File "+filename,/modal,group_leader=group_leader)
	cancel=widget_button(tlb,value="DONE")
	clear=widget_button(tlb,value="CLEAR")
	middle=widget_base(tlb,/row,/frame)
		bbase=lonarr(ncols)
		butid=lonarr(ntags)
		for i=0,ncols-1 do bbase[i]=widget_base(middle,/col,/nonexclusive)
		ndisp=-1
		col=0
		for j=0,ntags-1 do begin
		  ndisp=ndisp+1
			if (ndisp ge maxnrows) then begin
				ndisp=0
				col=col+1
			endif
		  butid[j]=widget_button(bbase[col],$
		  	value=strlowcase(sns[j]+" ["+datasize[j]+" "+descriptor[j]+"]"))
		endfor
		finalcolumn=widget_base(middle,/col)
			variables=widget_list(finalcolumn,value=['ADDITIONAL','VARIABLES'],$
				xsize=10,ysize=2*maxnrows-8)
			indexbase=widget_base(finalcolumn,/nonexclusive)
			indexbutt=widget_button(indexbase,value='Include index')
			clearfiel=widget_button(indexbase,value='Clear fields')
			helpbutt=widget_button(finalcolumn,value='HELP!!!')
	geometry=widget_info(cancel,/geometry)
	width=geometry.xsize/6
	dquan=cw_field(tlb,/column,$
		title='Enter a derived quantity to be displayed, e.g. "xyy(mid(x),total(qty,2))"',$
		value="",/string,/return_events,xsize=width)
	idlcom=cw_field(tlb,/column,$
		title='Enter a legal IDL command, e.g. "xm=mid(x)" or "display,x/2" ',$
		value="",/string,/return_events,xsize=width)
;
dave_position_tlb,tlb
widget_control,tlb,/realize
widget_control,indexbutt,/set_button
;
varfilename=(*!dave_defaults).workDir+'varfile.vfn'
;
state={$
	cancel:cancel,$
	clear:clear,$
	dquan:dquan,$
	idlcom:idlcom,$
	butid:butid,$
	indexbutt:indexbutt,$
	index:1,$
	clearfiel:clearfiel,$
	cfiel:0,$
	helpbutt:helpbutt,$
	sns:sns,$
	tagnames:tagnames,$
	datasize:datasize,$
	datanels:datanels,$
	descriptor:descriptor,$
	ntags:ntags,$
	buts_pressed:intarr(ntags),$
	widgetid:lonarr(ntags),$
	ptrwidgetids:ptr_new(-1),$
	davePtr:davePtr,$
	varsPtr:ptr_new(""),$
	variables:variables,$
	varfilename:varfilename}
;
pstate=ptr_new(state,/no_copy)
;
widget_control,tlb,set_uvalue=pstate
xmanager,'dave_examineafile',tlb,$
	event_handler='dave_examineafile_handler'
;
end


;************************************************************************************************
pro dave_examinefiles,event,filetype
;************************************************************************************************
;
compile_opt strictarr
;
widget_control,event.top,get_uvalue=statePtr
davePtr=(*statePtr).davePtr
;
dcs_sysvars,davePtr=davePtr
;
cd,current=current
;
while (1) do begin
	dave_examineafile,filetype,davePtr,done,group_leader=event.top
	if (done) then begin
		(*statePtr).davePtr=davePtr
		cd,current
		return
	endif
endwhile
;
end
