Viewing contents of file '../idllib/astron/contrib/varosi/code/allpro/approx_xsecs.pro'
; NAME:
;	Approx_Xsecs_Ev
;
; PURPOSE:
;	Approximate a cross-section by interactively
;	selecting points for piece-wise Linear interpolation.
;	This is the event handler routine that the XManager calls when
;	a widget event occurs for the Approx_Xsecs widget.
;	Process button events which are user requests for I/O, display, select,
;	or unmap/destroy the widget if the user has pressed the DONE button.
;
; CALLING:
;	Approx_Xsecs_Ev, event
;
; INPUT:
;	event = structure variable defining the widget event.
;
; EXTERNAL CALLS:
;	pros:	Approx_Xsec_Cur, force_events,
;	funcs:	PickFile, get_text_input
; PROCEDURE:
;	Big CASE breakdown.
; HISTORY:
;	written: Frank Varosi HSTX @ NASA/GSFC 1995.

pro Approx_Xsecs_Ev, event

     Widget_Control, event.handler, GET_UVAL=state,/NO_COPY

     if (event.id EQ state.draw_wid) then begin
						;process cursor events:
		Approx_Xsec_Cur, event, state
		Widget_Control, event.handler, SET_UVAL=state,/NO_COPY
		return
      endif

     Widget_Control, event.id, GET_UVAL=uval

     CASE uval(0) OF

	"SELECT": BEGIN

		state.Lsel = event.index
		Handle_value, state.ELevs, ELevs,/NO_COPY
		ELevel = ELevs(state.Lsel)
		Handle_value, state.ELevs, ELevs,/NO_COPY,/SET

; must make copy of freq & xsec by creating new handles and keeping old ones:

		if Handle_info( ELevel.freq_approx ) then begin
			Handle_value, ELevel.freq_approx, freq
			Handle_value, ELevel.xsec_approx, xsec
			ELevel.npx = N_elements( freq ) < N_elements( xsec )
		 endif else ELevel.npx = 0

		if (ELevel.npx GT 0) then begin
			ELevel.freq_approx = Handle_create( VAL=freq,/NO_COPY )
			ELevel.xsec_approx = Handle_create( VAL=xsec,/NO_COPY )
		 endif else begin
			ELevel.freq_approx = 0
			ELevel.xsec_approx = 0
		  endelse

		wset, state.window
		Levid = Level_info( ELevel )
		Plot_Xsec, ELevel, TITLE=Levid
		state.Lplot = state.Lsel
		state.ELevel = Handle_create( VAL=ELevel,/NO_COPY )

		Widget_Control, state.info_wid, SET_VAL=Levid
		Widget_Control, state.instr_wid, $
				SET_VAL="Left button = Insert a point,  " + $
					"Middle = Delete point nearest cursor"
		Widget_Control, state.axes_wid,/SENSITIVE
		Widget_Control, state.draw_wid,/DRAW_BUTTON_EV,/DRAW_MOTION_EV

		for i=0,1 do begin
     			Widget_Control, state.x_wids(i),/SENSITIVE
     			Widget_Control, state.y_wids(i),/SENSITIVE
		  endfor
		END

	"HARDCOPY": BEGIN

   		if (state.Lsel GE 0) AND Handle_info( state.ELevel ) then begin

			Handle_value, state.ELevel, ELevel,/NO_COPY
			ApXsec_hardcopy, ELevel, get_words( event.value )
			Handle_value, state.ELevel, ELevel,/NO_COPY,/SET

		 endif else if (state.Lplot GE 0) then begin

			Handle_value, state.ELevs, ELevs,/NO_COPY
			ELevel = ELevs(state.Lplot)
			Handle_value, state.ELevs, ELevs,/NO_COPY,/SET
			ApXsec_hardcopy, ELevel, get_words( event.value )
		  endif
		END

	"CANCEL":	Cancel_Xsec, state

	"KEEP":		Commit_Xsec, state

	"DONE": BEGIN

   		if state.modified AND $
		   (state.Lsel GE 0) AND Handle_info( state.ELevel ) then begin

			if yes_no_menu( "Keep new approx. X-sec",/BIN ) $
				then Commit_Xsec,state  else Cancel_Xsec,state

		 endif else Cancel_Xsec, state

		!X.range = 0
		!Y.range = 0
		!X.style = 0
		!Y.style = 0

		if (state.modal) then begin
			Widget_Control, event.top,/DESTROY
			return
		 endif else Widget_Control, event.top, MAP=0
		END

	"AXES":	BEGIN

		state.xyfix = event.value
		replot = 1

		CASE state.xyfix OF

		  0: BEGIN
			!X.range = 0
			!Y.range = 0
			!X.style = 0
			!Y.style = 0
			END

		  1: BEGIN
			!X.range = state.xrange
			!Y.range = state.yrange
			!X.style = 1
			!Y.style = 1
			END

		  2: BEGIN
			Widget_Control, state.instr_wid, GET_VAL=instr
			Widget_Control, state.instr_wid, SET_VAL = $
			  "define Zoom Box: Left -> Middle buttons, Right=abort"
			wset, state.window
			tvcrs,0.5,0.5,/NORM
			zoomxy
			state.xrange = !X.range
			state.yrange = !Y.range
			!X.style = 1
			!Y.style = 1
			for i=0,1 do begin
				Widget_Control, state.x_wids(i),SET_VAL = $
					string( state.xrange(i), F="(F6.2)" )
				Widget_Control, state.y_wids(i),SET_VAL = $
					string( state.yrange(i), F="(F6.2)" )
			  endfor
			Widget_Control, state.instr_wid, SET_VAL=instr
			END
		  else:
		 ENDCASE

		state.xyfix = (state.xyfix > 0) < 1
		Widget_Control, event.id, SET_VAL=state.xyfix
	    END

	"XRANGE": BEGIN
			Widget_Control, event.id, GET_VAL=value
			ix = fix( uval(1) )
			state.xrange(ix) = float( value )
			Widget_Control, event.id, $
				SET_VAL=string( state.xrange(ix), F="(F6.2)" )

			if (state.xyfix) then begin
				replot = 1
				!X.range = state.xrange
			   endif
		    END

	"YRANGE": BEGIN
			Widget_Control, event.id, GET_VAL=value
			ix = fix( uval(1) )
			state.yrange(ix) = float( value )
     			Widget_Control, event.id, $
				SET_VAL=string( state.yrange(ix), F="(F6.2)" )

			if (state.xyfix) then begin
				replot = 1
				!Y.range = state.yrange
			   endif
		    END

	  else:	BEGIN
			help,/st,event
			message,uval(0)+" not yet implemented",/INFO
		END
     ENDCASE

     if keyword_set( replot ) then begin
	if Handle_info( state.ELevel ) then begin
		Handle_value, state.ELevel, ELevel,/NO_COPY
		wset, state.window
		Plot_Xsec, ELevel, TITLE=Level_info( ELevel )
		Handle_value, state.ELevel, ELevel,/NO_COPY,/SET
	   endif
       endif

     Widget_Control, event.handler, SET_UVAL=state,/NO_COPY
END

;+
; NAME:
;	Approx_Xsecs
;
; PURPOSE:
;	Create a widget to approximate a cross-section by interactively
;	selecting points for piece-wise Linear interpolation.
;	Events are handled by pro Approx_Xsecs_Ev.
;	State of widget is stored in user value so multiple instances
;	can be running simultaneously.
;	Called by Build_BFree_Tr which is called by Modion_Event (pro modion).
; CALLING:
;	Approx_Xsecs
;
; INPUT:
;	ELevs = array of structures with tags for energy of level,
;		quantum numbers, and handles pointing to
;		full and approximate photo-ionization cross-sections.	
;		This array is stored via handle of the widget base state.
; OUTPUT:
;	ELevs = returned with updated x-secs if /MODAL when widget is DONE,
;		otherwise, if not /MODAL then widget is never destroyed
;		and the user must retrieve it from the state structure
;		in the user-value of the base widget.
; KEYWORDS:
;	/MODAL : causes Xmanager to wait until this widget is destroyed,
;		so that events from all other widgets are suspended.
;
;	GROUP = optional, the ID of the widget that calls this procedure,
;		if specified, death of caller results in death of this widget.
;
;	XPOS, YPOS = optional, desired position on screen of the widget.
;
;	PLOT_SIZE = [xsize,ysize] of draw widget for plotting of X-secs.,
;		default = [640,640].
;
; EXTERNAL CALLS:
;	pros:	Xmanager, widget_Location
;	funcs:	CW_Bgroup, CW_pdmenu, widget_Tree_Map
; PROCEDURE:
;	Create the state structure variable.
;	Create and register the widgets with the Xmanager.
;	Events are then processed by pro Approx_Xsecs_Ev (above in same file).
; HISTORY:
;	written: Frank Varosi HSTX @ NASA/GSFC 1995.
;-

function Approx_Xsecs, ELevs, ion_info, GROUP=group, MODAL=modal, $
				PLOT_SIZE=xysize, XPOS=xpos, YPOS=ypos

	state = {	base:0L		,$
			group:0L	,$
			draw_wid:0L	,$
			window:0	,$
			xyfix:0		,$
			xrange:fltarr(2),$
			yrange:fltarr(2),$
			x_wids:Lonarr(2),$
			y_wids:Lonarr(2),$
			info_wid:0L	,$
			cursor_wid:0L	,$
			instr_wid:0L	,$
			List_wid:0L	,$
			axes_wid:0L	,$
			modal:0		,$
			ELevs:0L	,$	;handle to Energy Levels.
			Lsel:-1		,$
			Lplot:-1	,$
			ELevel:0L	,$	;handle to selected Energy Level
			modified:0	,$
			release:"version 1.5"	,$
			wmap:replicate( widget_Tree_Map(), 70 ) }

	if N_struct( ELevs ) LE 0 then begin
		message,"Energy Level structure is missing",/INFO
		return,0
	   endif

	base = Widget_Base( TIT="Cross-Section Approximator : " + $
				state.release,/ROW )
	state.base = base
	message, state.release,/INFO
	if N_elements( group ) EQ 1 then state.group = group $
				    else state.group = 0

	baseL = Widget_Base( base, /COLUMN )
	baseR = Widget_Base( base, /COLUMN, SPACE=10 )

;first the Left side of widget:

	state.instr_wid = Widget_Lab_Info( baseL,VALUE="Select from List",/DYN )
	state.info_wid = Widget_Lab_Info( baseL, TIT="Selection:",/DYN )
	state.cursor_wid = Widget_Lab_Info( baseL, TIT="Cursor:",/DYN )

	if N_elements( xysize ) NE 2 then xysize = [640,640]
	state.draw_wid = Widget_Draw( baseL, XSIZE=xysize(0), YSIZE=xysize(1) )

;Now the Right side of widget:

	b = Widget_Button( baseR, VALUE="DONE", UVALUE="DONE" )

	pdmenu =  replicate( { CW_PDMENU_S, flags:0, name:"" }, 5 )
	pdmenu.flags = [ 1, 0, 0, 0, 2 ]
	pdmenu.name = ["HARDCOPY of Graph",	$
			"Black on white",	$
			"Black on white encapsulated PS",$
			"Color on White Background",	$
			"Color on Black Background"	]

	b = CW_pdmenu( baseR, pdmenu, /RETURN_NAME, UVAL="HARDCOPY" )

	name = "( Z=" + strtrim( ELevs(0).nz,2 ) + $
		" , ne=" + strtrim( ELevs(0).nel,2 ) + " )"
	if N_struct( ion_info ) EQ 1 then name = ion_info.name + " " + name
	b = Widget_Label( baseR, VAL=name )

	Levids = Level_info( ELevs, title )
	b = Widget_Label( baseR, VAL=title )

	state.List_wid = Widget_List( baseR, UVAL="SELECT", VAL=Levids, $
					YSIZE = N_elements( Levids ) < 13 )

	b = Widget_Label( baseR, VAL="Status of Selected X-sec:" )
	b = Widget_Button( baseR, VAL="KEEP new approx X-sec", UVAL="KEEP" )
	b = Widget_Button( baseR, VALUE="CANCEL (keep old)", UVALUE="CANCEL" )

	state.axes_wid = CW_Bgroup( UVAL="AXES", baseR, $
				["Floating X-Y Axes","Fixed X-Y Axes","ZOOM"], $
				/FRAME,/COLUMN,/EXCLUSIVE, SET_VAL=state.xyfix )

	state.y_wids = Widget_Lab_Text( baseR, L="Y:", F=["min="," max="], $
				VAL=string( state.yrange, F="(F6.2)" ), $
				UVAL=[ ["YRANGE",'0'], ["YRANGE",'1'] ] )

	state.x_wids = Widget_Lab_Text( baseR, L="X:", F=["min="," max="], $
				VAL=string( state.xrange, F="(F6.2)" ), $
				UVAL=[ ["XRANGE",'0'], ["XRANGE",'1'] ] )

	Widget_Control, base, /REALIZE
	Widget_Control, state.axes_wid,SENS=0

	for i=0,1 do begin
     		Widget_Control, state.x_wids(i),SENS=0
     		Widget_Control, state.y_wids(i),SENS=0
	  endfor

	state.wmap = widget_Tree_Map( base )
	widget_Location, base, XPOS=xpos, YPOS=ypos

	Widget_Control, state.draw_wid, GET_VAL=window
	state.window = window
	state.ELevs = Handle_create( VALUE=ELevs,/NO_COPY )

	if keyword_set( modal ) then begin
		state.modal = 1
		ELevs_Handle = state.ELevs
	   endif

	Widget_Control, base, SET_UVAL=state,/NO_COPY

	Xmanager, "Approx_Xsecs", base, EVENT="Approx_Xsecs_Ev", $
				GROUP=group, MODAL=modal

	if keyword_set( modal ) then begin
		Handle_value, ELevs_Handle, ELevs,/NO_COPY
		Handle_free, ELevs_Handle
	   endif

return, base
END