;
; NAME:
;         DISPLAY_STRUCT
;
; PURPOSE: This procedure displays, saves, or prints rows of a valid structure. User interaction and displayed information are done using IDL widgets. Maximum number of rows to be displayed is the first 2000 rows. A call to "display_struct" requires a structure plus optional 2nd and 3rd argument. If provided, the 2nd argument will be used as the title for the display widget. The 3rd argument will be used as the filename for saving the displayed data.
;
; CALLING SEQUENCE:
;
;         display_struct, structure_var [,title, filename]
;
; INPUTS:
;         structure_var:    A structure containing the data to be displayed. 
;
; OPTIONAL INPUTS:
;         title:    A string that will be used as the title for the display window.
;         filename: Filename for saving the displayed data.
;
; OUTPUTS:
;         None
;
; OPTIONAL OUTPUTS:
;         Displayed data may be saved in a file. 
;
; MODIFICATION HISTORY:
; $Log: display_struct.pro,v $
; Revision 1.1  2007/08/27 20:32:48  nathan
; *** empty log message ***
;
;   	  show_structure.pro
;         Written by:  Ed Esfandiari, LASCO/NRL, July, 1998.
;         Apr 28, 00  AEE  Added MODAL keyword to view (it was not working correctly).
;
;
;
pro disp_rows_event,event
 common disp_str, data_rows,selected_cols,save_filename,printer_name, $
        t,equals,tags,ntags,elem,new_Cols

 WIDGET_CONTROL, event.id, GET_UVALUE=uval
 WIDGET_CONTROL, event.top, GET_UVALUE=struct   ; get structure from UVALUE

 case (uval) of
  'done': begin
            WIDGET_CONTROL, /DESTROY, struct.base
          end
  'view': begin
            xdisplayfile,TITLE='View Data',GROUP=base, HEIGHT=45,WIDTH=80, $
                         TEXT= data_rows,/MODAL
;            new_cols= data_rows
          end
  'col_sel': begin
               WIDGET_CONTROL, event.id ,GET_VALUE= selected_cols
               selected_cols= strtrim(selected_cols,2)
             end
  'save': begin
           msg='Data will be saved in "'+save_filename(0)+'". Proceed?'
           res=widget_message(msg,/question,title='Confirm')
           if(res eq 'Yes') then begin
             openw,unit,save_filename(0),/get_lun
             for i=0L,n_elements(new_cols)-1 do printf,unit,new_cols(i)
             free_lun,unit
           end ;confirm
          end
  'save_name': begin
                 WIDGET_CONTROL, event.id ,GET_VALUE= save_filename
                 save_filename= strtrim(save_filename,2)
               end
  'hcopy': begin
            msg='Printer to be used is <default printer>. Proceed?'
            res=widget_message(msg,/question,title='Confirm')
            if(res eq 'Yes') then begin
             openw,unit,'print_data.db',/get_lun
             for i=0L,n_elements(new_cols)-1 do printf,unit,new_cols(i) 
             free_lun,unit
             lpr= "lp print_data.db"
             spawn,lpr
             openr,unit,'print_data.db',/get_lun,/delete
             free_lun,unit
            end; confirm
           end
  'lp_name': begin
               WIDGET_CONTROL, event.id ,GET_VALUE= printer_name
               printer_name= strtrim(printer_name,2)
             end
 endcase

end


pro display_struct, st,comm,svnm
 common disp_str

  p=n_params()
  if(p lt 1) then return
  tle= 'Data View/Save/Print Options'
  if(p ge 2) then tle= comm 
  save_filename= 'data.txt'
  if(p eq 3) then save_filename= svnm

; defaults:
  selected_cols= 'all'
;  save_filename= 'data.txt'
  printer_name= 'hp4-247'

  print,''  
  s=size(st)
  if(s(0) eq 1 and s(2) eq 8) then begin ; input is a strucutre
    tags=tag_names(st)
  
    ntags= n_elements(tags)
    maxl= max(strlen(tags))+2
    ;s= size(st) ; get # of elements (rows)
    elem= s(1)
    if(elem gt 2000) then begin
      print,'Too many rows of data. Displaying only first 2000 rows.'
      elem=2000
    end

    ; determine width and format for each column based on type and content
    fieldw=intarr(ntags)
    fieldfrmt=strarr(ntags)
    data_rows= ' ROW'
    equals='==================================================================='
    divider=   '===='
    for j=0,ntags-1 do begin
      tagtyp=datatype(st[0].(j))
      IF tagtyp EQ 'BYT' THEN fieldw[j]=4 ELSE $
      IF tagtyp EQ 'INT' THEN fieldw[j]=ndigit(max(st.(j)))+2 ELSE $
      IF tagtyp EQ 'LON' THEN fieldw[j]=ndigit(max(st.(j)))+2 ELSE $
      IF tagtyp EQ 'ULN' THEN fieldw[j]=ndigit(max(st.(j)))+2 ELSE $
      IF tagtyp EQ 'UIN' THEN fieldw[j]=ndigit(max(st.(j)))+2 ELSE $
      IF tagtyp EQ 'L64' THEN fieldw[j]=ndigit(max(st.(j)))+2 ELSE $
      IF tagtyp EQ 'U64' THEN fieldw[j]=ndigit(max(st.(j)))+2 ELSE $
      IF tagtyp EQ 'FLO' THEN fieldw[j]=ndigit(max(st.(j)))+6 ELSE $
      IF tagtyp EQ 'DOU' THEN fieldw[j]=ndigit(max(st.(j)))+6 ELSE $
      BEGIN
      	    mxstr=1
	    for k=0,elem-1 do mxstr=mxstr>(strlen(trim(st[k].(j))))
      	    fieldw[j]=mxstr+1
      ENDELSE
      fieldw[j]=(fieldw[j])<50
      fieldw[j]=(fieldw[j])>4
      fieldfrmt[j]='(I'+trim(fieldw[j])+')'
      IF tagtyp EQ 'FLO' or tagtyp EQ 'DOU' THEN fieldfrmt[j]='(F'+trim(fieldw[j])+'.3)'
      IF tagtyp EQ 'STR' THEN fieldfrmt[j]='(A'+trim(fieldw[j])+')'
      
      data_rows=    data_rows	+' '+string(tags(j),format='(A'+trim(fieldw[j]-1)+')')
      divider=	    divider 	+' '+strmid(equals,0,fieldw[j]-1)
    endfor

    data_rows= [data_rows,divider]
    for i=0L,elem-1 do begin
      this_row= string(i,format='(i4)')
      for j=0,ntags-1 do this_row= this_row+string(st[i].(j),format=fieldfrmt[j])
      data_rows= [data_rows,this_row]
    endfor

;   if only 1 row of data exists (data_rows has 3 elements), then display it 
;   vertically, one field_name + field_value per line, instead of displaying
;   all the field values for the row on long line:

    if(n_elements(data_rows) eq 3) then begin
      fields= str_sep(strcompress(strtrim(data_rows(0),2)),' ')
      nr= n_elements(fields)
      rows= strarr(nr)
      max_len= max(strlen(fields))
      fields= fields+'                                                  '
      fields= strmid(fields,0,max_len)+'= '
      for i=0,nr-1 do begin
        rows(i)= fields(i)+t(i)
      end
      data_rows= rows
    end

    new_cols= data_rows

    base= widget_base(title=tle,xsize=305,ysize=210,xoffset=10,/frame)
    b1=widget_base(base,/ROW)
    colb1= widget_base(b1,/COLUMN)
    rowb1= widget_base(colb1,/ROW)
    exit=  WIDGET_BUTTON(rowb1, VALUE='Exit',UVALUE='done',/frame)
    r1= widget_base(colb1,/ROW)
    com='                                                                    '
    lab=WIDGET_LABEL(colb1,VALUE=com)
    rr= widget_base(colb1,/ROW)
    lab=WIDGET_LABEL(rr,VALUE='                  ')
    select= WIDGET_BUTTON(rr, UVALUE='view',value='view',/frame)
;    r2= widget_base(colb1,/ROW,/frame)
    rt2= widget_base(colb1,/ROW)
    lab=WIDGET_LABEL(rt2,VALUE='')
    r2= widget_base(rt2,/ROW,/frame)
    select= WIDGET_BUTTON(r2, UVALUE='save',VALUE='save',/frame)
    lab= WIDGET_LABEL(r2,VALUE='-> filename:')
    select= WIDGET_TEXT(r2,UVALUE='save_name',VALUE=save_filename,/EDITABLE, $
                        /ALL_EVENTS)
;    r3= widget_base(colb1,/ROW,/frame)
    rt3= widget_base(colb1,/ROW)
    r3= widget_base(rt3,/ROW,/frame)
    select= WIDGET_BUTTON(r3, UVALUE='hcopy',VALUE='hardcopy',/frame)
    lab= WIDGET_LABEL(r3,VALUE='-> printer:')
    select= WIDGET_TEXT(r3,UVALUE='lp_name',VALUE='hp4-247',/EDITABLE, $
                        /ALL_EVENTS)
    rc= widget_base(colb1,/COLUMN)
    com=''
    lab= WIDGET_LABEL(rc,VALUE=com)
    lab= WIDGET_LABEL(rc,VALUE=com)

    widget_control,base,/realize
    struct={base:base}
    widget_control,base, SET_UVALUE=struct
    xmanager,'disp_rows',base,EVENT_HANDLER='disp_rows_event', $
             group_leader=group,/MODAL

  endif else begin ; input is not a structure  
    msg='Input is not a valid structure.'
    res=widget_message(msg,title='Bad Input')
  end

return
end
