; $Id: db_xspectra.pro,v 1.6 2005/02/08 17:01:16 azuah Exp $
;###############################################################################
;
; NAME:
;   DB_xSpectra
;
; PURPOSE:
;   A small utility modal widget program to obtain information about which
;   spectra to extract from a 2D (DaveDat2D object) dataset.
;
; CATEGORY:
;   Data Browser
;
; AUTHOR:
;   Richard Tumanjong Azuah
;   NIST Center for Neutron Research
;   100 Bureau Drive, Gaithersburg, MD 20899
;   United States
;   azuah@nist.gov; (301) 9755604
;   Mar, 2003
;
; 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 or if the code in this file is
;  included in another product.
;
;###############################################################################



;===============================================================================
; DB_xSpectra_Event
;
; PURPOSE:
;   Main event handler for app.
;
; PARAMETERS:
;   event [in] - the event structure to be handled
;
pro DB_xSpectra_events, event

widget_control,event.top,get_uvalue = sPtr
uname = widget_info(event.id,/uname)

case uname of
    'ACCEPT': begin
        (*sPtr).cancel=0
        widget_control,event.top,/destroy
    end

    'CANCEL': begin
        (*sPtr).cancel=1
        widget_control,event.top,/destroy
    end

    'AXIS': begin
        (*sPtr).axis = (*sPtr).axis xor 1
        widget_control,(*sPtr).nslID, set_value=(*sPtr).label[(*sPtr).axis] 
    end

    'SPECTRA': begin
        ;; Only accept numbers [0-9] and delimiters - and , in the
        ;; text field. Also, don't allow delimiters at the beginning.
        if (event.type eq 0) then begin
            res = where((*sPtr).valid_achar eq event.ch, isaValidChar)
            if (isaValidChar) then begin
                res = where((*sPtr).valid_adel eq event.ch, isaDelimiter)
                if ((strlen(strtrim((*sPtr).spectra,2)) eq 0) and isaDelimiter) then begin
                    widget_control, event.id,set_value=(*sPtr).spectra
                    break
                endif
                widget_control, event.id,get_value=value
                (*sPtr).spectra = value
            endif else widget_control, event.id,set_value=(*sPtr).spectra
        endif
    end

    else:

endcase

;print, 'Event handled...'

end
;-------------------------------------------------------------------------------



;===============================================================================
; DB_xSpectra
;
; PURPOSE:
;   Entry point and dialog builder for application.
;
; PARAMETERS
;   objRef [in;reg] - The object reference of the DaveDat2D object
;                     from which the spectra are to be extracted. 
;
; KEYWORDS:
;   group_leader [in] - the ID of the parent widget from which this
;                       dialog was launched.
;
; RETURN VALUE: 
;   A structure with information about the spectra to be extracted. 
;     CANCEL:  0 if false, 1 if true
;     AXIS:    indep. axis of extracted data: 0=>'x', 1=>'y'
;     SPECTRA: array of spectra (1-based indices) to extract
;
function DB_xSpectra, objRef, group_leader=group_leader

returnStr = {cancel:1,axis:0,spectra:-1}

; An objRef parameter must be passed
if (n_params() ne 1) then return, returnStr

; objRef must be a valid object
if (obj_valid(objRef) ne 1) then return, returnStr

; ObjRef must be a DaveDat2D object
if (obj_class(objRef) ne 'DAVEDAT2D') then return, returnStr

if (not objRef->get(xVal=xval,yVal=yval,nameTag=nameTag)) then return, returnStr

nx = n_elements(xval)
ny = n_elements(yval)

if ((nx le 0) and (ny le 0)) then return, returnStr

xlabel = (nx gt 1)? 'There are '+strtrim(string(ny),2)+' spectra present' : $
                    'There is '+strtrim(string(ny),2)+' spectrum present'
if (nx eq 0) then xlabel = 'There are no spectra present'
ylabel = (ny gt 1)? 'There are '+strtrim(string(nx),2)+' spectra present' : $
                    'There is '+strtrim(string(nx),2)+' spectrum present'
if (ny eq 0) then ylabel = 'There are no spectra present'



; Widget definition module
title = 'DATABROWSER: Extract Spectra - '+nameTag 
if (n_elements(group_leader) eq 0) then begin
    group_leader = 0L
    modal = 0
    tlb = widget_base(/col,title=title,/align_center)
endif else begin
    modal = 1
    tlb = widget_base(group_leader=group_leader,/col,title=title,modal=modal,/align_center)
endelse

cb1 = widget_base(tlb,/col,/frame,/align_center)
extAxis = ['x','y']
void = cw_bgroup(cb1,extAxis,/row,/exclusive, $
	label_left = 'Desired independent axis for extracted spectra:',/no_release, $
	set_value=0,/return_index,uname='AXIS')
nspecLabelID = widget_label(cb1,value=xlabel)

cb2 = widget_base(tlb,/col,/frame,/align_center)
label1 = 'Please, specify spectra (>= 1) to extract below.'
label2 = 'Use comma as delimiter and dash for ranges.'
label3 = 'Thus 2-4,6,8 extracts spectra 2,3,4,6 and 8.'
void = widget_label(cb2,value=label1);,yoffset=10)
void = widget_label(cb2,value=label2);,yoffset=10)
void = widget_label(cb2,value=label3);,yoffset=10)

void = widget_text(cb2,/editable,/all_events,value='',uname='SPECTRA',xsize=60)

cb3 = widget_base(tlb,/row,/align_center)
acptTip = 'Save changes and exit'
cancTip = 'Discard changes and exit'
void = widget_button(cb3,value='Accept',uname='ACCEPT',tooltip=acptTip)
void = widget_button(cb3,value='Cancel',uname='CANCEL',tooltip=cancTip)

widget_control,tlb,/realize
valid_ascii_chars = [44,45,48,49,50,51,52,53,54,55,56,57]
valid_ascii_delimiters = [44,45] 
sPtr = ptr_new({cancel:0, $
                axis:0, $
                spectra:'', $
                valid_achar:valid_ascii_chars, $
                valid_adel:valid_ascii_delimiters, $
                label:[xlabel,ylabel], $
                nslID:nspecLabelID $
               })

widget_control,tlb, set_uvalue=sPtr

registerName = 'db_xspectra'
xmanager,registerName,tlb,no_block=modal,event_handler='db_xspectra_events'

strspec = strtrim((*sPtr).spectra, 2)
if ((strlen(strspec) le 0) or (*sPtr).cancel) then begin
    cancel = (*sPtr).cancel
    axis = (*sPtr).axis
    ptr_free, sPtr
    return, {cancel:cancel,axis:axis,spectra:0}
endif

tokens = strsplit(strspec,',',/extract)
ntok = (size(tokens))[1]
intspec = -1
index = 0

for j = 0,ntok-1 do begin
    tok1 = strsplit(tokens[j],'-',/extract)
    if ((size(tok1))[1] eq 1) then begin
        i = fix(tok1[0])
        res = where(intspec eq i, isNotaNewValue)
        if (isNotaNewValue) then continue
        intspec = (index eq 0)? i : [intspec,i]
        index = index + 1
    endif else begin
        for i = fix(tok1[0]),fix(tok1[1]) do begin
            res = where(intspec eq i, isNotaNewValue)
            if (isNotaNewValue) then continue
            intspec = (index eq 0)? i : [intspec,i]
            index = index + 1
        endfor
    endelse       
endfor

returnStr = {cancel:(*sPtr).cancel,axis:(*sPtr).axis,spectra:intspec[sort(intspec)]}

ptr_free, sPtr

return, returnStr

end
