; Written by  Craig Brown
;************************************************************************************************
;###############################################################################
;
; 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.
;
;  Additional functions adapted from xobjview supplied by RSI inc.
;  Makes use of open source idl (David Fannings color codes, Rick Towler vectors)
;###############################################################################
;with just a gaussian object and the best quality model runs on about 20MB memory
;
; this is a schematic of the graphics hierarchy

;                     model
;        |             |
;      light        group
;                      |      \
;                   crystal    \
;                  /   |         \
;        model_x+y    bonds  vectors
;            |         |             |
;        atom+x+y     bond_i       eigenvectors
;                       |
;                   [poly components]
;
;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
FUNCTION Normalize, range, Position=position

    ; This is a utility routine to calculate the scaling vector
    ; required to position a vector of specified range at a
    ; specific position given in normalized coordinates. The
    ; scaling vector is given as a two-element array like this:
    ;
    ;   scalingVector = [translationFactor, scalingFactor]
    ;
    ; The scaling vector should be used with the [XYZ]COORD_CONV
    ; keywords of a graphics object or model. For example, if you
    ; wanted to scale an X axis into the data range of -0.5 to 0.5,
    ; you might type something like this:
    ;
    ;   xAxis->GetProperty, Range=xRange
    ;   xScale = Normalize(xRange, Position=[-0.5, 0.5])
    ;   xAxis, XCoord_Conv=xScale

IF (N_Elements(position) EQ 0) THEN position = [0.0, 1.0] ELSE $
    position=Float(position)
range = Float(range)

scale = [((position[0]*range[1])-(position[1]*range[0])) / $
    (range[1]-range[0]), (position[1]-position[0])/(range[1]-range[0])]

RETURN, scale
END

;--------------------------------------------------------------------
function GetViewportDims, $
    inobj=inobj,$             ; what we want to query
    oDestDevice=oDestDevice, $      ; IN
    inches=inches, $    ; IN: (opt) boolean. Return result in inches.
    location=location, $; OUT: (opt)
    defaulted=defaulted ; OUT: (opt) boolean.
compile_opt hidden

defaulted = 0b
inobj->GetProperty, dimensions=dimensions, location=location, units=units
if max(dimensions) eq 0 then begin
    oDestDevice->GetProperty, units=orig_dest_units
    oDestDevice->SetProperty, units=units
    oDestDevice->GetProperty, dimensions=dimensions
    oDestDevice->SetProperty, units=orig_dest_units

    location = [0., 0.]
    defaulted = 1b
    end

if keyword_set(inches) then begin
    case units of
        0 : begin ; Pixels.
            oDestDevice->GetProperty, $
                resolution=cpd ; Centimeters per dot.
            dpi = 2.54 / float(cpd) ; Dots per inch.
            dimensions = dimensions / dpi
            location = location / (dpi - 1.)
            end
        1 :       ; Inches.
        2 : begin ; Centimeters.
            dimensions = dimensions / 2.54
            location = location / 2.54
            end
        3 : begin ; Normalized.
            oDestDevice->GetProperty, units=orig_dest_units
            oDestDevice->SetProperty, units=1 ; Inches.
            oDestDevice->GetProperty, dimensions=dest_dimensions
            oDestDevice->SetProperty, units=orig_dest_units

            dimensions = dimensions * dest_dimensions
            location = location * dest_dimensions
            end
        endcase
    end

return, dimensions
end


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function g3dviewmakeTube, v0, v1, tubedia, tubecolor, p1, _extra=e
    ;  MESH_OBJ params
    p2 = v0
    p3 = v1 - v0

    ;  Calculate the x-product
    ;  You'll have to handle special case where p3==[0,0,1]
    if p3[0] eq 0 and p3[1] eq 0 then begin
    cp = CROSSP(p3,[0.,1.,0.])
    endif else begin
    cp = CROSSP(p3,[0.,0.,1.])
    endelse
    ;  Normalize x-product
    s = SQRT(TOTAL(cp^2))
    cp = cp / s
    ;  Create the line to rotate
    array1 = [[v0],[v1]] - REBIN(tubedia * cp, 3, 2)
    ;  Create the mesh
    MESH_OBJ, 6, verts, polys, array1, P1=p1, P2=p2, P3=p3

    ;  Create a polygon and a line representing the original vector
    oTube = OBJ_NEW('IDLgrPolygon', verts, POLYGONS=polys, $
        COLOR=tubecolor, STYLE=2, _extra=e)
    oVec = OBJ_NEW('IDLgrPolyline', [[v0],[v1]], COLOR=tubecolor)

    RETURN, [oTube, oVec]
end

Pro g3dview_Kill_Notify, wID
Compile_Opt Hidden

Widget_Control, wID, Get_UValue = oThing
If (N_elements(oThing) ne 0) then Begin
    If (Obj_Valid(oThing)) then Begin
       oThing->Destruct
    EndIf
EndIf
End
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Pro g3dview::Cleanup
self->Destruct
End
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro g3dview::free, var
compile_opt idl2, hidden

on_error, 2

case size(var, /tname) of
    'OBJREF': obj_destroy, var
    'POINTER': ptr_free, var
    'LONG': widget_control, var, /destroy
    else:
    endcase

end

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Pro g3dview::SaveFile,type
self->Update_LabelStatus, 'Saving'
if not obj_valid(self.gauss) then return

wid_mono=widget_info(self.tlb,find_by_uname='mono')
mono=widget_info(wid_mono, /DROPLIST_SELECT)
wid_coll=widget_info(self.tlb,find_by_uname='collim')
coll=widget_info(wid_coll, /DROPLIST_SELECT)
pow=WIDGET_INFO(self.tlb,find_by_uname='OverCheck')
plotover=WIDGET_INFO(pow,/button_set)

data=self.gauss->reduce(mono=mono,coll=coll,scalefactor=self.scalefactor,$
              oversf=self.oversf,Freqfactor=self.Freqfactor,$
              flatbg=self.flatbg,linearbg=self.linearbg,DWF=self.DWF,$
              plotover=plotover )

if plotover eq 0 then begin
x=data[*,0]
y=data[*,1]
endif else begin
x=data[*,0]
y=(data[*,1]+data[*,3])
fundx=data[*,0]
fundy=data[*,1]
overx=data[*,2]
overy=data[*,3]
endelse


;need x y, units
xunits='cm-1'

case type of
 'Dave' : begin
   fileout = DIALOG_PICKFILE(/WRITE, FILTER = '*.dave',path=(*!dave_defaults).workDir)
   if (fileout ne '') then begin
      f2=StrSplit(fileout,'/',/Extract)
      file2=f2[N_elements(f2)-1]
      wheredave2=where(strmatch(file2,'*.dave',/fold_case) eq 1,dave2)
      if dave2 ge 1 then begin
         file=fileout
      endif else begin
         file=fileout+'_gauss.dave'
      endelse

      ret=create_dave_pointer(daveptr,$
          INSTRUMENT = 'GAUSSIAN',$
          QTY = y,$
          QTUNITS = 'Total Calculated Intensity:arb_units',$
          QTLABEL = 'I(Calc) (arb units)',$
          XVALS = x,$
          XTYPE = 'POINTS',$
          XUNITS = xunits,$
          XLABEL = 'Energy Transfer',$
          ;SPECIFICSTR = specificstr,$
         ; TREATMENT = treatment,$
          ERMSG = errmsg)
      if ret eq 0 then begin
        msg = 'Problem creating the DAVE pointer'
        if ptr_valid(daveptr) then heap_free,daveptr
          return
      endif
      if ptr_valid(daveptr) then begin
         save,daveptr,filename = file
         heap_free,daveptr
      endif
   endif

        end
 'Ascii' : begin
            file = DIALOG_PICKFILE(/WRITE, FILTER = '*.out',path=(*!dave_defaults).workDir)
            if n_elements(file) ne 0 then begin
               OPENW, datout, file, /GET_LUN
               FOR i=0,n_elements(x)-1 DO BEGIN
                  printf,datout,x[i],y[i],format='(f10.4,x,f10.4)'
               ENDFOR
            FREE_LUN, datout
            endif
        end
  else:
  endcase
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Pro g3dview::Plot_params,event,element
self->Update_LabelStatus, 'Updating'
case element of
 'scaleint' : begin
            self.scalefactor=event.value
     end
 'scalefreq' : begin
            self.freqfactor=event.value
     end
 'linear' : begin
            self.flatbg=event.value
     end
 'grad' : begin
           self.linearbg=event.value
     end
 'dwf' : begin
          self.dwf=event.value
     end
 'overscale' : begin
           self.oversf=event.value
    end
 else:
 endcase
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Pro g3dview::LoadGaussFile,event

filename=DIALOG_PICKFILE(/READ,/MUST_EXIST,FILTER=['*.log','*.out'],path=(*!dave_defaults).workDir)
if n_elements(filename) le 0 then return
;filename='c:\idlstuff\objects\pyz.log'
gauss = Obj_New('g98log',filename=filename)
if gauss->dataloaded() then begin
   if obj_valid(self.gauss) then obj_destroy,self.gauss
   self->Update_LabelStatus, filename+': File Loaded'
   self.gauss=gauss
   self.xran=[0,0]
   self.yran=[0,0]
   self.vibmode=0
   self->spectrum
   self->do_scene
endif else begin
   obj_destroy,gauss
endelse

end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Pro g3dview::Set_Atom,code,type
;which type of atom, and do we only want to change this one?
self->Update_LabelStatus, 'Setting Atom '+code
case code of
'Color' :  begin
  new_color=pickcolorname('White',group_leader=self.tlb,cancel=cancel)
  if cancel eq 1 then return
  in=strsplit(new_color," ",/extract)
  if (n_elements(in) eq 1) then new_color=in[0]
  if (n_elements(in) ge 2) then new_color=in[0]+"_"+in[1]
  COM="test=(*self.color_ptr)."+new_color
  ret=execute(com)
  new_col=reform(test)
  oGroup =   self.oModel->getbyname('oGroup')
  ocrystal = oGroup->getbyname('oCrystal')
  case type of
    'All': begin
          oatom =  ocrystal->getbyname('Atoms')
          oChildren = oatom->Get(/All, Count = Count)
          For I = 0L, Count - 1 Do Begin
            self->Set_Prop_On_Children,  oChildren[I], color = new_col,diffuse=[255,255,255]
          EndFor
        end
     'Element': begin
            bigname=self.lastselected
            ret=strsplit(bigname,": ",/extract)
            aname=ret[2] ;this is the atom name of the form atom_Ca_11
            res=strsplit(aname,'_',/extract)
            element=res[1]
            oModel =  ocrystal->getbyname('Atoms')
            oChildren = oModel->Get(/All, count=count)
            For I = 0L, Count - 1 Do Begin
               oChildren[I]->GetProperty, Name = Name
               res=strsplit(Name,'_',/extract)
               if res[1] eq element then self->Set_Prop_On_Children, oChildren[I], color = new_col
            EndFor
         end
     'This': begin
            ;get the name
            bigname=self.lastselected
            ret=strsplit(bigname,": ",/extract)
            aname=ret[2] ;this is the atom name of the form atom_Ca_11
                        ; need to make it more like model_Ca_11
            res=strsplit(aname,'_',/extract)
            mname='model_'+res[1]+'_'+res[2]
            oModel =  ocrystal->getbyname('Atoms')
            oChild = oModel->Getbyname(mname)
            oAtom = oChild->Getbyname(aname)
            oAtom->setproperty,color=new_col
         end
    else:
    endcase
  end
'Alpha' :  begin
  if !version.release le 6.0 then return
  alpha=getvalue(type='float',Group_leader=self.tlb,title='Opacity 0 to 1.0')
  if alpha le 0.0 then return
  if alpha gt 1.0 then return
  oGroup =   self.oModel->getbyname('oGroup')
  ocrystal = oGroup->getbyname('oCrystal')
  case type of
    'All': begin
          oatom =  ocrystal->getbyname('Atoms')
          oChildren = oatom->Get(/All, Count = Count)
          For I = 0L, Count - 1 Do Begin
            self->Set_Prop_On_Children,  oChildren[I], alpha_channel = alpha
          EndFor
        end
     'Element': begin
            bigname=self.lastselected
            ret=strsplit(bigname,": ",/extract)
            aname=ret[2] ;this is the atom name of the form atom_Ca_11
            res=strsplit(aname,'_',/extract)
            element=res[1]
            oModel =  ocrystal->getbyname('Atoms')
            oChildren = oModel->Get(/All, count=count)
            For I = 0L, Count - 1 Do Begin
               oChildren[I]->GetProperty, Name = Name
               res=strsplit(Name,'_',/extract)
               if res[1] eq element then self->Set_Prop_On_Children, oChildren[I], alpha_channel = alpha
            EndFor
         end
     'This': begin
            ;get the name
            bigname=self.lastselected
            ret=strsplit(bigname,": ",/extract)
            aname=ret[2] ;this is the atom name of the form atom_Ca_11
                        ; need to make it more like model_Ca_11
            res=strsplit(aname,'_',/extract)
            mname='model_'+res[1]+'_'+res[2]
            oModel =  ocrystal->getbyname('Atoms')
            oChild = oModel->Getbyname(mname)
            oAtom = oChild->Getbyname(aname)
            oAtom->setproperty,alpha_channel = alpha
         end
  else:
  endcase
  end
'Dia' :  begin
  value=getvalue(type='float',Group_leader=self.tlb,title='VdW scaling 0 to 1.0')
  if value le 0.0 then return
  if value gt 1.0 then return
  self.vdwfactor=value
  self.gauss->getproperty,vdw=vdw,atomlist=atomlist
  oGroup =   self.oModel->getbyname('oGroup')
  ocrystal = oGroup->getbyname('oCrystal')
  case type of
    'All': begin
          oatom =  ocrystal->getbyname('Atoms')
          oChildren = oatom->Get(/All, Count = Count)
          For I = 0L, Count - 1 Do Begin
            self->Set_Prop_On_Children,  oChildren[I],RADIUS=vdw[i]*value
          EndFor
        end
     'Element': begin
            bigname=self.lastselected
            ret=strsplit(bigname,": ",/extract)
            aname=ret[2] ;this is the atom name of the form atom_Ca_11
            res=strsplit(aname,'_',/extract)
            element=res[1]
            test=where(atomlist eq element)
            oModel =  ocrystal->getbyname('Atoms')
            oChildren = oModel->Get(/All, count=count)
            For I = 0L, Count - 1 Do Begin
               oChildren[I]->GetProperty, Name = Name
               res=strsplit(Name,'_',/extract)
               if res[1] eq element then self->Set_Prop_On_Children, oChildren[I],RADIUS=vdw(test[0])*value
            EndFor
         end
     'This': begin
            ;get the name
            bigname=self.lastselected
            ret=strsplit(bigname,": ",/extract)
            aname=ret[2] ;this is the atom name of the form atom_Ca_11
                        ; need to make it more like model_Ca_11
            res=strsplit(aname,'_',/extract)
            ;need to find out what the atom is
            mname='model_'+res[1]+'_'+res[2]
            atomtype=res[1]
            test=where(atomlist eq atomtype)
            oModel =  ocrystal->getbyname('Atoms')
            oChild = oModel->Getbyname(mname)
            oAtom = oChild->Getbyname(aname)
            ;need to find out what the atom is
            oAtom->setproperty,RADIUS=vdw(test[0])*value
         end
  else:
  endcase
  end
'QualityLow' :  begin

  oGroup =   self.oModel->getbyname('oGroup')
  ocrystal = oGroup->getbyname('oCrystal')
  case type of
    'All': begin
          oatom =  ocrystal->getbyname('Atoms')
          oChildren = oatom->Get(/All, Count = Count)
          For I = 0L, Count - 1 Do Begin
            self->Set_Prop_On_Children,  oChildren[I],density=1.
          EndFor
        end
  else:
  endcase
  end
  'QualityMed' :  begin

  oGroup =   self.oModel->getbyname('oGroup')
  ocrystal = oGroup->getbyname('oCrystal')
  case type of
    'All': begin
          oatom =  ocrystal->getbyname('Atoms')
          oChildren = oatom->Get(/All, Count = Count)
          For I = 0L, Count - 1 Do Begin
            self->Set_Prop_On_Children,  oChildren[I],density=2.
          EndFor
        end
  else:
  endcase
  end
  'QualityHigh' :  begin

  oGroup =   self.oModel->getbyname('oGroup')
  ocrystal = oGroup->getbyname('oCrystal')
  case type of
    'All': begin
          oatom =  ocrystal->getbyname('Atoms')
          oChildren = oatom->Get(/All, Count = Count)
          For I = 0L, Count - 1 Do Begin
            self->Set_Prop_On_Children,  oChildren[I],density=5.
          EndFor
        end
  else:
  endcase


end
else:
endcase
   self->render_scene
end

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Pro g3dview::Set_Bond,code,quality=quality
self->Update_LabelStatus, 'Setting bond '+code
case code of
'Color' :  begin
 ;  get old color
 ;could reverse look up vvalue in table?
 ;get new color
  new_color=pickcolorname('White',group_leader=self.tlb,cancel=cancel)
  if cancel eq 1 then return
  in=strsplit(new_color," ",/extract)
  if (n_elements(in) eq 1) then new_color=in[0]
  if (n_elements(in) ge 2) then new_color=in[0]+"_"+in[1]
  COM="test=(*self.color_ptr)."+new_color
  ret=execute(com)
  new_col=reform(test)
  self.bondcolor=new_col

  oGroup =   self.oModel->getbyname('oGroup')
  ocrystal = oGroup->getbyname('oCrystal')

  obond =  ocrystal->getbyname('Bonds')
  oChildren = obond->Get(/All, Count = Count)
  For I = 0L, Count - 1 Do Begin
            self->Set_Prop_On_Children,  oChildren[I], color = new_col
   EndFor
   self->render_scene
   end
'Alpha' :  begin
 ; get new alpha
   if !version.release le 6.0 then return
  alpha=getvalue(type='float',Group_leader=self.tlb,title='Opacity 0 to 1.0')
  if alpha le 0.0 then return
  if alpha gt 1.0 then return
  self.bondalpha=alpha
  oGroup =   self.oModel->getbyname('oGroup')
  ocrystal = oGroup->getbyname('oCrystal')
  obond =  ocrystal->getbyname('Bonds')
  oChildren = obond->Get(/All, Count = Count)
  For I = 0L, Count - 1 Do Begin
            self->Set_Prop_On_Children,  oChildren[I], alpha_channel=alpha
   EndFor
   self->render_scene
   end
'QualityLow' :  begin
                   SELF.BONDFACETS=10
                   self->Set_Bond,'Dia',quality=1
             end
'QualityMed' :  begin
                   SELF.BONDFACETS=20
                   self->Set_Bond,'Dia',quality=1
             end
'QualityHigh' :  begin
                   SELF.BONDFACETS=100
                   self->Set_Bond,'Dia',quality=1
              end
'Dia' :  begin
  if not keyword_set(quality) then begin
    value=getvalue(type='float',Group_leader=self.tlb,title='Bond diameter 0 to 1.0')
    if value le 0.0 then return
    if value gt 1.0 then return
  endif else begin
       value=self.bondradius
  endelse
  self.bondradius=value
  oGroup =   self.oModel->getbyname('oGroup')
  ocrystal = oGroup->getbyname('oCrystal')
  obond =  ocrystal->getbyname('Bonds')
  oChildren = obond->Get(/All, Count = Count)
  if count ge 1 then  oc=oChildren[0]->Get(/All, Count = Count)
  if count le 0 then return
  ;get the number of facets & colors
    if !version.release le 6.0 then begin
      oc[0]->getproperty,color=bcolor
    endif else begin
      oc[0]->getproperty,color=bcolor,ALPHA_CHANNEL=ALPHA_CHANNEL,shininess=shininess,diffuse=diffuse
    endelse
  ;get some ogauss parameter
   self.gauss->getproperty,numberatoms=numberatoms,initcoords=initcoords,$
                atomlist=atomlist,covalent=covalent
  ;killall the bonds and make them again.
   obj_destroy,obond
  ;where are the bonds
   bonds=self->do_bonding(numberatoms=numberatoms,initcoords=initcoords,covalent=covalent,bondfactor=self.bondfactor)
   tubedia=value
   tubecolor=bcolor
   p1=SELF.BONDFACETS ;P1 specifies the number of "facets" in the revolution
   omodela=OBJ_NEW('IDLgrModel',name='Bonds')
   oCrystal->Add,omodela
   for i=0,(size(bonds))[2]-1 do begin
     v0 = [bonds[0,i],bonds[2,i],bonds[4,i]]
     v1 = [bonds[1,i],bonds[3,i],bonds[5,i]]
     name= "bond_"+strtrim(string(i),2)
     omodelb=OBJ_NEW('IDLgrModel',name=name)
     omodela->Add,omodelb
     namebond="bond_"+strtrim(string(i),2)
     if !version.release le 6.0 then begin
        omodelb->Add,g3dviewmakeTube(v0, v1, tubedia, tubecolor, p1,$
                                name=namebond)
     endif else begin
                omodelb->Add,g3dviewmakeTube(v0, v1, tubedia, tubecolor, p1,shininess=shininess,$
                                SPECULAR=SPECULAR,$
                                DIFFUSE=DIFFUSE,$
                                ALPHA_CHANNEL=ALPHA_CHANNEL,$
                                name=namebond)
     endelse
   endfor
   self->render_scene
end


else:
endcase
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Pro g3dview::Set_Defaults,code
            self->Update_LabelStatus, 'All objects are now at default settings'
            self.bondfactor=0.4
            self.BONDFACETS=200
            self.bondradius=0.1
            self.vdwfactor=0.2
            self.shininess=128
            self.bondcolor=[255,215,0]
            self.bondalpha=1.0
            self.vectorcolor=[255,0,0]
            self.vectorscale=4.
            Menu = Widget_Info(self.tlb,Find_by_UName =  'GM_showvector')
            sens = Widget_Info(Menu,/sensitive)
            if sens then widget_control,Menu,sensitive=0
            self->clean_scene
            self->build_scene,bg=[255,255,255]

end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Pro g3dview::Set_Vector,code
self->Update_LabelStatus, 'Setting eigenvector '+code
case code of
'Color' :  begin
 ;  get old color
 ;could reverse look up vvalue in table?
 ;get new color
  new_color=pickcolorname('White',group_leader=self.tlb,cancel=cancel)
  if cancel eq 1 then return
  in=strsplit(new_color," ",/extract)
  if (n_elements(in) eq 1) then new_color=in[0]
  if (n_elements(in) ge 2) then new_color=in[0]+"_"+in[1]
  COM="test=(*self.color_ptr)."+new_color
  ret=execute(com)
  new_col=reform(test)
  self.vectorcolor=new_col

  ;get all things in the view
  ; First, select the view.
  oGroup =   self.oModel->getbyname('oGroup')
;  ocrystal = oGroup->getbyname('oCrystal')
  oVector =  oGroup->getbyname('Vector')
  self->Set_Prop_On_Children, oVector, color = new_col
   end
'Hide' : begin
         oGroup =   self.oModel->getbyname('oGroup')
         oVector =  oGroup->getbyname('Vector')
         self->Set_Prop_On_Children, oVector, hide=1
         self->render_scene
         Menu = Widget_Info(self.tlb, $
                     Find_by_UName =  'GM_showvector')
         widget_control,menu,sensitive=1
         end
'Show'  : begin
         oGroup =   self.oModel->getbyname('oGroup')
         oVector =  oGroup->getbyname('Vector')
         self->Set_Prop_On_Children, oVector, hide=0
         Menu = Widget_Info(self.tlb, $
                     Find_by_UName =  'GM_showvector')
         widget_control,menu,sensitive=0
         self->render_scene
         end
 'SizeSmall'  : begin
         vector_scale=2.
         self.vectorscale=2.
         mode=self.vibmode
         self.gauss->getproperty,evector=evector ,numberatoms=numberatoms
         vecs=fltarr((size(evector))[2],(size(evector))[3])
         vecs=evector[mode,*,*]
         oGroup =   self.oModel->getbyname('oGroup')
         oVector =  oGroup->getbyname('Vector')
         oChildren = oVector->Get(/All, Count = Count)
         For I = 0L, Count - 1 Do Begin
            magnitude=reform(vecs[0,i,*]*vector_scale)
            oChildren[I]->SetProperty, magnitude = magnitude
         EndFor
         self->render_scene
         end
 'SizeMed'  : begin
         vector_scale=4.
         self.vectorscale=4.
         mode=self.vibmode
         self.gauss->getproperty,evector=evector ,numberatoms=numberatoms
         vecs=fltarr((size(evector))[2],(size(evector))[3])
         vecs=evector[mode,*,*]
         oGroup =   self.oModel->getbyname('oGroup')
         oVector =  oGroup->getbyname('Vector')
         oChildren = oVector->Get(/All, Count = Count)
         For I = 0L, Count - 1 Do Begin
            magnitude=reform(vecs[0,i,*]*vector_scale)
            oChildren[I]->SetProperty, magnitude = magnitude
         EndFor
         self->render_scene
         end
 'SizeLong'  : begin
         vector_scale=8.
         self.vectorscale=8.
         mode=self.vibmode
         self.gauss->getproperty,evector=evector ,numberatoms=numberatoms
         vecs=fltarr((size(evector))[2],(size(evector))[3])
         vecs=evector[mode,*,*]
         oGroup =   self.oModel->getbyname('oGroup')
         oVector =  oGroup->getbyname('Vector')
         oChildren = oVector->Get(/All, Count = Count)
         For I = 0L, Count - 1 Do Begin
            magnitude=reform(vecs[0,i,*]*vector_scale)
            oChildren[I]->SetProperty, magnitude = magnitude
         EndFor
         self->render_scene
         end

else:
endcase
end

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Pro g3dview::set_coll
  self->spectrum
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Pro g3dview::set_mono
   self->spectrum
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Pro g3dview::Print
self->Update_LabelStatus, 'Attempting to print'
Compile_Opt Hidden
oPrinter = Obj_New('IDLgrPrinter')
self.oTopLevelContainer->Add, oPrinter
If (not Dialog_PrinterSetup(oPrinter, Dialog_Parent = self.TLB)) then Begin
    Obj_Destroy, oPrinter
    Return
EndIf
If (not Dialog_PrintJob(oPrinter, Dialog_Parent = self.TLB)) then Begin
    Obj_Destroy, oPrinter
    Return
EndIf
Widget_Control, /Hourglass
;findout which view to print,
 ftab=widget_info(self.tlb,find_by_uname='DATA_TAB')
 thistab=widget_info(ftab,/tab_current)  ; if 0 then the plot, 1 the 3D
;
; Convert views to inches.
;
case thistab of
   '0' : begin
  oViews = self.drawPlotView
  If not(obj_valid(self.drawPlotView)) then Begin
    Obj_Destroy, oPrinter
    Return
  EndIf

    oViews->GetProperty, Units = Units, Dimensions = Dim, $
       Location = Loc
    Unit_Arr = Units
    Dim_Arr = Dim
    Loc_Arr = Loc
    Dim = GetViewportDims(inobj=oViews, oDestDevice=self.o2dwindow, Location = Loc, /Inches, Defaulted = Defaulted)
    print,dim
    Default_Arr = Defaulted
    oViews->SetProperty, Location = Loc, Dimensions = Dim, Units = 1
  self->Draw, oPrinter, self.drawPlotView, Vector = self.Vector
  oPrinter->NewDocument
;
; Restore views to their original units.
;

    oViews->SetProperty, Location = Loc_Arr, $
       Dim = Dim_Arr, Units = Unit_Arr

  Obj_Destroy, oPrinter
end
1: begin
  oViews = self.oScene->Get(/All, Count = Count)
  If (Count eq 0) then Begin
    Obj_Destroy, oPrinter
    Return
  EndIf
  Default_Arr = BytArr(Count)
  Unit_Arr = BytArr(Count)
  Dim_Arr = FltArr(2, Count)
  Loc_Arr = FltArr(2, Count)

  For I = 0L, Count - 1 Do Begin
    oViews[i]->GetProperty, Units = Units, Dimensions = Dim, $
       Location = Loc
    Unit_Arr[I] = Units
    Dim_Arr[0, I] = Dim
    Loc_Arr[0, I] = Loc

    Dim = GetViewportDims(inobj=oViews[I], oDestDevice=self.o3DWindow, Location = Loc, /Inches, Defaulted = Defaulted)

;    Dim = oViews[I]->ViewportDimensions(self.o3DWindow, $
;       Location = Loc, /Inches, Defaulted = Defaulted)
    Default_Arr[I] = Defaulted
    oViews[I]->SetProperty, Location = Loc, Dimensions = Dim, Units = 1
  EndFor
  self->Draw, oPrinter, self.oScene, Vector = self.Vector
  oPrinter->NewDocument
;
; Restore views to their original units.
;
  For I = 0L, Count - 1 Do Begin
    oViews[I]->SetProperty, Location = Default_Arr[I] ? [0, 0] : Loc_Arr[*, I], $
       Dim = Default_Arr[I] ? [0, 0] : Dim_Arr[*, I], Units = Unit_Arr[I]
  EndFor
  Obj_Destroy, oPrinter
  end
else:
endcase


End

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Pro g3dview::Copy_To_Clipboard
Compile_Opt Hidden
 ftab=widget_info(self.tlb,find_by_uname='DATA_TAB')
 thistab=widget_info(ftab,/tab_current)  ; if 0 then the plot, 1 the 3D
 case thistab of
   0: begin
      self.o2DWindow->GetProperty, Dimension = WDims, Resolution = Res, $
      Color_Model = CM, Units = Units, N_Colors = IColors
     oClipboard = Obj_New('IDLgrClipboard', Dimensions = WDims, $
      Resolution = Res, Color_Model = CM, Units = Units, $
      N_Colors = IColors)
     self.oTopLevelContainer->Add, oClipboard
     self->draw, oClipboard, self.drawPlotView
     Obj_Destroy, oClipboard
      end
   1: begin
     self.o3DWindow->GetProperty, Dimension = WDims, Resolution = Res, $
      Color_Model = CM, Units = Units, N_Colors = IColors
     oClipboard = Obj_New('IDLgrClipboard', Dimensions = WDims, $
      Resolution = Res, Color_Model = CM, Units = Units, $
      N_Colors = IColors)
     self.oTopLevelContainer->Add, oClipboard
     self->draw, oClipboard, self.oScene
     Obj_Destroy, oClipboard
    End
    else:
  endcase
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Pro g3dview::Export_Image
self->Update_LabelStatus, 'Exporting screen image'
Compile_Opt Hidden
;findout which view to print,
 ftab=widget_info(self.tlb,find_by_uname='DATA_TAB')
 thistab=widget_info(ftab,/tab_current)  ; if 0 then the plot, 1 the 3D
 case thistab of
   0: begin
     Geo = Widget_Info(self.pDraw, /Geometry)
     oBuff = Obj_New('IDLgrBuffer', Dimensions = [Geo.Scr_XSize, Geo.Scr_YSize])
     self.oTopLevelContainer->Add, oBuff
     oBuff->Draw, self.drawPlotView
     oBuff->GetProperty, Image_Data = Image_Data
     void = Dialog_Write_Image(Image_Data, Dialog_Parent = self.TLB)
     Obj_Destroy, oBuff
  end
   1: begin
     Geo = Widget_Info(self.wDraw, /Geometry)
     oBuff = Obj_New('IDLgrBuffer', Dimensions = [Geo.Scr_XSize, Geo.Scr_YSize])
     self.oTopLevelContainer->Add, oBuff
     oBuff->Draw, self.oScene
     oBuff->GetProperty, Image_Data = Image_Data
     void = Dialog_Write_Image(Image_Data, Dialog_Parent = self.TLB)
     Obj_Destroy, oBuff
    end
else:
endcase
End
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Pro g3dview::FRAMES_Output
Compile_Opt Hidden
If (not Obj_Valid(self.oCurrentView)) then Begin
    Return
EndIf
File = Dialog_Pickfile(/Write, File='', $
    Group = self.TLB, Filter = ['*.gif','*.jpeg','*.tiff','*.png'],path=(*!dave_defaults).workDir)
If (File eq '') then Begin
    Return
EndIf
self->do_vibs,Frames=File


return
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Pro g3dview::VRML_Output
self->Update_LabelStatus, 'Writing 3D VRML scene'
Compile_Opt Hidden
If (not Obj_Valid(self.oCurrentView)) then Begin
    Return
EndIf
File = Dialog_Pickfile(/Write, File='untitled.wrl', $
    Group = self.TLB, Filter = '*.wrl',path=(*!dave_defaults).workDir)
If (File eq '') then Begin
    Return
EndIf
self.o3DWindow->GetProperty, Dimensions = Dimensions, $
    Resolution = Resolution, Units = Units, $
    Color_Model = Color_Model, N_Colors = N_Colors
oVRML = Obj_New('IDLgrVRML', $
    Dimensions = Dimensions, Resolution = Resolution, $
    Units = Units, Color_Model = Color_Model, $
    N_Colors = N_Colors)
self.oTopLevelContainer->Add, oVRML
oVRML->SetProperty, FileName = File
self->draw, oVRML, self.oCurrentView
Obj_Destroy, oVRML
End
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Pro g3dview::Set_Backg_Color, Color
self->Update_LabelStatus, 'Setting background color'
Compile_Opt Hidden
case Color of
'Color' :  begin
 ;  get old color
 ;could reverse look up vvalue in table?
 ;get new color
  new_color=pickcolorname('White',group_leader=self.tlb,cancel=cancel)
  if cancel eq 1 then return
  in=strsplit(new_color," ",/extract)
  if (n_elements(in) eq 1) then new_color=in[0]
  if (n_elements(in) ge 2) then new_color=in[0]+"_"+in[1]
  COM="test=(*self.color_ptr)."+new_color
  ret=execute(com)
  new_col=reform(test)
  self.oScene->SetProperty, Color = new_col
  self->Set_Prop_On_Children, self.oScene, Color = new_col
  self->Render_Scene
end
else:
endcase

End

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Pro g3dview::Set_Plot_Linestyle,object,line
self->Update_LabelStatus, 'Setting Linestyle'
Compile_Opt Hidden

if line le 0 then line = 0
if line ge 6 then line =5

case object of
'Total' :  begin
         self.myplot->SetProperty, linestyle = line
         self.o2DWindow ->Draw, self.drawPlotView
        end
'Fund' :  begin
         self.fundplot->SetProperty, linestyle = line
         self.o2DWindow ->Draw, self.drawPlotView
        end
'Over' :  begin
         self.overplot->SetProperty, linestyle = line
         self.o2DWindow ->Draw, self.drawPlotView
        end
 else:
endcase
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Pro g3dview::Set_Plot_Thick,object
self->Update_LabelStatus, 'Setting Line thickness'
Compile_Opt Hidden
  thick=getvalue(type='float',Group_leader=self.tlb,title='Line Thickness 1.0 to 10.0')
  if thick le 1.0 then value = 1.0
  if thick gt 10. then return =10.


case object of
'Total' :  begin
         self.myplot->SetProperty, thick = thick
         self.o2DWindow ->Draw, self.drawPlotView
         self.totalthick=thick
        end
'Fund' :  begin
         self.fundplot->SetProperty, thick = thick
         self.o2DWindow ->Draw, self.drawPlotView
         self.fundthick=thick
         end
'Over' :  begin
         self.overplot->SetProperty, thick = thick
         self.o2DWindow ->Draw, self.drawPlotView
         self.overthick=thick
        end
 else:
endcase
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Pro g3dview::Set_PlotBackg_Color, object
self->Update_LabelStatus, 'Setting Color'
Compile_Opt Hidden
 ;  get old color
 ;could reverse look up vvalue in table?
 ;get new color
  new_color=pickcolorname('White',group_leader=self.tlb,cancel=cancel)
  if cancel eq 1 then return
  in=strsplit(new_color," ",/extract)
  if (n_elements(in) eq 1) then new_color=in[0]
  if (n_elements(in) ge 2) then new_color=in[0]+"_"+in[1]
  COM="test=(*self.color_ptr)."+new_color
  ret=execute(com)
  new_col=byte(reform(test))

case object of
'Plot' :  begin
         self.drawPlotView->SetProperty, Color = new_col
         self->Set_Prop_On_Children, self.drawPlotView, Color = new_col
         self.o2DWindow ->Draw, self.drawPlotView
        end
'Total' :  begin
         ;self.myPlot->GetProperty, Symbol=symbolObject
         ;symbolObject->SetProperty, Color = new_col
         self.myplot->SetProperty, Color = new_col
         self.o2DWindow ->Draw, self.drawPlotView
        end
'Fund' :  begin
         ;self.myPlot->GetProperty, Symbol=symbolObject
         ;symbolObject->SetProperty, Color = new_col
         self.fundplot->SetProperty, Color = new_col
         self.o2DWindow ->Draw, self.drawPlotView
        end
'Over' :  begin
         ;self.myPlot->GetProperty, Symbol=symbolObject
         ;symbolObject->SetProperty, Color = new_col
         self.overplot->SetProperty, Color = new_col
         self.o2DWindow ->Draw, self.drawPlotView
        end
'Labels' :  begin
        end
'Title' :  begin
         self.Title->SetProperty, Color = new_col
         self.o2DWindow ->Draw, self.drawPlotView
        end
'Axes' :  begin
         self.myxaxis->SetProperty, Color = new_col
         self.myyaxis->SetProperty, Color = new_col

         self.o2DWindow ->Draw, self.drawPlotView
        end
else:
endcase

End
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Pro g3dview::choosemode,event
Compile_Opt Hidden
 ;just get the mode and make the scene
 List = Widget_Info(self.TLB, Find_by_UName = 'MODE_LIST')
 index = Widget_Info(List,/list_select)
 self.vibmode=index
; self->do_scene
 ;the scene keeps estting to the default view.
; can we just change the vectors?
 oGroup =   self.oModel->getbyname('oGroup')
 oVector =  oGroup->getbyname('Vector')

self.gauss->getproperty,numberatoms=numberatoms,initcoords=initcoords,$
               evector=evector,sym=sym


vector_color=self.vectorcolor
vector_THICK=2.0
vector_scale=self.vectorscale  ;how long are they?



if (size(evector))[0] eq 3 then begin
   vecs=fltarr((size(evector))[2],(size(evector))[3])
   magnitude=fltarr((size(evector))[2])
   location=fltarr((size(evector))[3])
   vecs=evector[index,*,*]
   vecObj=objarr(numberatoms)
endif else begin
  return
endelse
;safe to destroy now
 obj_destroy,oVector

for i=0,numberatoms-1 do begin
  location=reform(initcoords[i,*])
  magnitude=reform(vecs[0,i,*]*vector_scale)
  vecObj[i] = OBJ_NEW('vector', LOCATION=LOCATION, MAGNITUDE=MAGNITUDE, $
           COLOR=vector_color, THICK=vector_thick,name='eigenvector'+strtrim(string(i),2))
endfor
oVector = OBJ_NEW('IDLgrModel',name='Vector')
oGroup->Add, oVector
oVector -> Add, vecobj

Menu = Widget_Info(self.tlb,Find_by_UName =  'GM_showvector')
sens = Widget_Info(Menu,/sensitive)
if sens then self->Set_Prop_On_Children, oVector, hide=1
self->render_scene
text='Mode Symmetry: '+sym[index]
self->Update_LabelStatus, text
END
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Pro g3dview::Reset_Scene
Compile_Opt Hidden
oViews = self.oScene->Get(/All, Count = Count)
For I = 0L, Count - 1 Do Begin
    If (!version.release gt '5.4') then Begin
       oViews[I]->Reset, self.o3DWindow
       oViews[I]->PadViewplaneRect, self.o3DWindow
       oViews[I]->Reset, self.o3DWindow, /Full
    EndIf Else Begin
       oViews[I]->ResetTransforms
       oViews[I]->SetViewVolume, self.o3DWindow, $
         /Quiet, /Isotropic, Scale = self.Scale
    EndElse
    self->Draw, self.o3DWindow, self.oScene
EndFor
End

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro g3dview::Destruct
Compile_Opt Hidden

If (Widget_Info(self.TLB, /Valid_ID)) then Begin
    Widget_Control, self.TLB, Kill_Notify = ''
    Widget_Control, self.TLB, /Destroy
EndIf

If (Obj_Valid(self.oScene)) then Begin
    If (self.oScene->Count() gt 0) then Begin
       self.oScene->Remove, /All
    EndIf
EndIf

If (Obj_Valid(self.oTopLevelContainer)) then Begin
    self.oTopLevelContainer->Remove, self.oCurrentView
    Obj_Destroy, self.oTopLevelContainer
EndIf

;reomve all the 1D plot stuff and the new symbols
If (Obj_Valid(self.font[0])) then Begin
         obj_destroy,(self.font)
EndIf
If (Obj_Valid(self.title)) then Begin
         obj_destroy,(self.title)
EndIf
If (Obj_Valid(self.myxAxis)) then Begin
         obj_destroy,(self.myxAxis)
EndIf
If (Obj_Valid(self.myyAxis)) then Begin
         obj_destroy,(self.myyAxis)
EndIf
If (Obj_Valid(self.xtext)) then Begin
         obj_destroy,(self.xtext)
EndIf
If (Obj_Valid(self.ytext)) then Begin
         obj_destroy,(self.ytext)
EndIf
If (Obj_Valid(self.myplot)) then Begin
    Obj_Destroy, self.myplot
EndIf
If (Obj_Valid(self.dataplot)) then Begin
   self.dataplot->getproperty,symbol=tmp1
         if obj_valid(tmp1) then begin
          tmp1[0]->getproperty,data=tmp2
          if obj_valid(tmp2) then obj_destroy,tmp2
          obj_destroy,tmp1
         endif
    Obj_Destroy, self.dataplot
EndIf

If (Obj_Valid(self.oTopLevelPlotCont)) then Begin
    Obj_Destroy, self.oTopLevelPlotCont
EndIf
If (Obj_Valid(self.o2DWindow)) then Begin
    Obj_Destroy, self.o2DWindow
EndIf
;;;;;;;;;
If (Obj_Valid(self.gauss)) then Begin
    Obj_Destroy, self.gauss
EndIf
If (Obj_Valid(self.omodel)) then Begin
    Obj_Destroy, self.omodel
EndIf
If (self.Do_Destroy_View) then Begin
    Obj_Destroy, self.oCurrentView
EndIf
If (Ptr_Valid(self.pGroup_Leader)) then Begin
    Ptr_Free, self.pGroup_Leader
EndIf
If (Ptr_Valid(self.notifyIdPtr)) then Begin
   ptr_free,self.notifyIdPtr
endif
If (Ptr_Valid(self.daveptr)) then Begin
   heap_free,self.daveptr
endif
If (Ptr_Valid(self.bondsptr)) then Begin
   heap_free,self.bondsptr
endif
If (Ptr_Valid(self.color_ptr)) then Begin
   heap_free,self.color_ptr
endif
If (Ptr_Valid(self.default_atom_color_ptr)) then Begin
   heap_free,self.default_atom_color_ptr
endif
If (Ptr_Valid(self.actual_atom_color_ptr)) then Begin
   heap_free,self.actual_atom_color_ptr
endif
If (Ptr_Valid(self.freqlist_ptr)) then Begin
   heap_free,self.freqlist_ptr
endif

Help, Calls = Calls
InInit = Where(StrPos(Calls, '::INIT') ne -1, NInInit)
If (NInInit eq 0) then Begin
    Obj_Destroy, self
EndIf
help,/heap,/brief
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro g3dview::do_vibs,frames=frames
if not obj_valid(self.gauss) then return
self->Update_LabelStatus, "Performing Animation. Speeds may vary..."
;need the atom list, need to loop, need to stop if I press button AND reset view

mode=self.vibmode
period=.01
self.gauss->getproperty,evector=evector,numberatoms=numberatoms,initcoords=initcoords,$
                        atomlist=atomlist,covalent=covalent
oGroup =   self.oModel->getbyname('oGroup')
ocrystal = oGroup->getbyname('oCrystal')
oatom =  ocrystal->getbyname('Atoms')
oChildren = oatom->Get(/All, Count = Count)

totaltimes=6
totalsteps=20
coords=initcoords
;shrink vector
shrink=.75
evector=evector*shrink

doframes=0
if Keyword_Set(frames) then begin
  framefiles=frames
  framedir=FILE_DIRNAME(framefiles, /MARK_DIRECTORY)
  framebasename=FILE_BASENAME(framefiles)
  test=strsplit(framebasename,'.',/extract,count=cnt)
  if cnt ge 2 then begin
     framextn=test[cnt-1]
     if framextn eq 'jpg' then framextn='jpeg'
  endif else return

  doFRAMES=1
  totaltimes=1
endif


recreate=1 ; i.e. we will not recreat the bonds
times=0
while times ne totaltimes do begin ;self.stopvib ne 1 do begin
for ii=0,totalsteps-1 do begin
  if ii le totalsteps/4-1 then stepvector=reform(evector(mode,*,*)/5.)
  if (ii ge totalsteps/4) and  (ii le 3*totalsteps/4-1) then begin
     stepvector=-reform(evector(mode,*,*)/5.)
  endif else begin
     stepvector=reform(evector(mode,*,*)/5.)
  endelse
  coords=coords+stepvector
  ;move the atoms
  For I = 0L, Count - 1 Do Begin
      oChildren[I]->translate,stepvector[i,0],stepvector[i,1],stepvector[i,2]
  EndFor

if recreate eq 1 then begin
  ;adjust the bonds
  obond =  ocrystal->getbyname('Bonds')
  oBChildren = obond->Get(/All, Count = BCount)
  if Bcount ge 1 then  oc=oBChildren[0]->Get(/All, Count = BCount)
  if Bcount le 0 then return
  ;get the number of facets & colors
  if !version.release le 6.0 then begin
      oc[0]->getproperty,color=bcolor
  endif else begin
        oc[0]->getproperty,color=bcolor,ALPHA_CHANNEL=ALPHA_CHANNEL,shininess=shininess,diffuse=diffuse
  endelse
  ;killall the bonds and make them again.
   obj_destroy,obond
  ;where are the bonds?  one method is to recreate them..
;   bonds=self->do_bonding(numberatoms=numberatoms,initcoords=coords,covalent=covalent,bondfactor=self.bondfactor)


   tubedia=self.bondradius
   tubecolor=bcolor
   p1=SELF.BONDFACETS ;P1 specifies the number of "facets" in the revolution
;make it go faster
   if p1 ge 20. then begin
     p1old = p1
     p1=20.
   endif
   omodela=OBJ_NEW('IDLgrModel',name='Bonds')
   oCrystal->Add,omodela
   for i=0,(size(*self.bondsptr))[2]-1 do begin
   ; we get the bonded atom list and compare it to the atom  children to make the new bonds
     oChildren[(*self.bondsptr)[0,i]] -> GetProperty,transform=transform1
     oChildren[(*self.bondsptr)[1,i]] -> GetProperty,transform=transform2
     v0=[transform1[3,0],transform1[3,1],transform1[3,2]]
     v1=[transform2[3,0],transform2[3,1],transform2[3,2]]
     name= "bond_"+strtrim(string(i),2)
     omodelb=OBJ_NEW('IDLgrModel',name=name)
     omodela->Add,omodelb
     namebond="bond_"+strtrim(string(i),2)
     if !version.release le 6.0 then begin
        omodelb->Add,g3dviewmakeTube(v0, v1, tubedia, tubecolor, p1,$
                                name=namebond)
      endif else begin
        omodelb->Add,g3dviewmakeTube(v0, v1, tubedia, tubecolor, p1,shininess=shininess,$
                                SPECULAR=SPECULAR,$
                                DIFFUSE=DIFFUSE,$
                                ALPHA_CHANNEL=ALPHA_CHANNEL,$
                                name=namebond)
      endelse
   endfor


  wait,period/1000.

  self->render_scene
  ;get the window snapshot

  if doframes then  begin
     Geo = Widget_Info(self.wDraw, /Geometry)
     oBuff = Obj_New('IDLgrBuffer', Dimensions = [Geo.Scr_XSize, Geo.Scr_YSize])
     self.oTopLevelContainer->Add, oBuff
     oBuff->Draw, self.oScene
     oBuff->GetProperty, Image_Data = Image_Data
     stringfile=framedir+framebasename+'_'+strtrim(string(ii),2)+'.'+framextn
     WRITE_IMAGE, stringfile, framextn, Image_Data
     Obj_Destroy, oBuff
   endif

endif

endfor
times =times +1
endwhile

self->Update_LabelStatus, 'End of Animation'
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro g3dview::do_scene,event

self->clean_scene,bg=bg
if n_elements(bg) eq 3 then begin
   self->build_scene,bg=bg
endif else begin
   self->build_scene
endelse
end

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro g3dview::Change_atoms,event
   self->Update_LabelStatus, 'Editing Atoms'
   if not obj_valid(self.gauss) then return
   ret = self.gauss->edit_atoms(group_leader=self.tlb)
   if ret eq 1 then  begin
   self->Update_LabelStatus, reset=1
   self->spectrum ; i.e. things changed
   endif else begin
   self->Update_LabelStatus, reset=1
   endelse
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro g3dview::spectrum,event
self->Update_LabelStatus, ''
if not obj_valid(self.gauss) then return
self.gauss->getproperty,freq=freq
*self.freqlist_ptr=strtrim(string(freq),2)
list = Widget_Info(self.tlb, Find_by_UName =  'MODE_LIST')
widget_control,list,set_value=*self.freqlist_ptr

wid_mono=widget_info(self.tlb,find_by_uname='mono')
mono=widget_info(wid_mono, /DROPLIST_SELECT)
wid_coll=widget_info(self.tlb,find_by_uname='collim')
coll=widget_info(wid_coll, /DROPLIST_SELECT)
pow=WIDGET_INFO(self.tlb,find_by_uname='OverCheck')
plotover=WIDGET_INFO(pow,/button_set)

data=self.gauss->reduce(mono=mono,coll=coll,scalefactor=self.scalefactor,$
              oversf=self.oversf,Freqfactor=self.Freqfactor,$
              flatbg=self.flatbg,linearbg=self.linearbg,DWF=self.DWF,$
              plotover=plotover )

if plotover eq 0 then begin
if min(data[*,0]) lt self.xdatarange[0] then self.xdatarange[0] =  min(data[*,0])
if max(data[*,0]) lt self.xdatarange[1] then self.xdatarange[1] =  max(data[*,0])
if min(data[*,1]) lt self.ydatarange[0] then self.ydatarange[0] =  min(data[*,1])
if max(data[*,1]) lt self.ydatarange[1] then self.ydatarange[1] =  max(data[*,1])
  self->Change_Plot,x=data[*,0],y=data[*,1]
endif else begin
if min(data[*,0]) lt self.xdatarange[0] then self.xdatarange[0] =  min(data[*,0])
if max(data[*,0]) lt self.xdatarange[1] then self.xdatarange[1] =  max(data[*,0])
if min(data[*,1]+data[*,3]) lt self.ydatarange[0] then self.ydatarange[0] =  min(data[*,1]+data[*,3])
if max(data[*,1]+data[*,3]) lt self.ydatarange[1] then self.ydatarange[1] =  max(data[*,1]+data[*,3])
  self->Change_Plot,x=data[*,0],y=(data[*,1]+data[*,3]),$
        fundx=data[*,0],fundy=data[*,1],overx=data[*,2],overy=data[*,3]
endelse
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function g3dview::do_nothing,event
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro g3dview::draw, o3DWindow, oPicture, vector=vector
compile_opt hidden
;
;Purpose: On some platforms, when IDLgrWindow::Draw is invoked, math
;errors (e.g. "% Program caused arithmetic error: Floating illegal
;operand") are printed.  xobjview::draw suppresses the
;printing of these errors.
;
;Flush and print any accumulated math errors
;
void = check_math(/print)
;
;Silently accumulate any subsequent math errors.
;
orig_except = !except
!except = 0
;
;Draw.
;
if (obj_Valid(o3DWindow)) then begin
    if (n_elements(vector) eq 1) then begin
        o3DWindow->Draw, oPicture, vector = vector
    endif else begin
        o3DWindow->Draw, oPicture
    endelse
endif else begin
    self.o3DWindow->Draw
endelse
;
;Silently flush any accumulated math errors.
;
void = check_math()
;
;Restore original math error behavior.
;
!except = orig_except
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Pro g3dview::Render_Scene
self->Draw, self.o3DWindow, self.oScene
End
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Pro g3dview::Render_Plot
self->Draw, self.o2DWindow, self.drawPlotView
End

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Pro g3dview::Main_Plot_Widget_Event, Event
Compile_Opt Hidden
Case Event.Type of
    4 : Begin
;
;    Expose.
;
       self->Render_Plot
       End
    0 : Begin
;
; Button press
;
       Case Event.Press of
            4 : Begin
;
; Right mouse-button.
;
          oArr = self.o2DWindow->Select(self.drawPlotView, $
                    [Event.x, Event.y], DIMENSIONS=[3,3] )
          ; If we have a selection...
          IF ((SIZE(oArr))[0] NE 0) THEN BEGIN
               oObj = oArr[0]
                  oObj->GetProperty, NAME=name
                  CASE name of
                       'Plot_View' : begin
                                         label = 'Current Selection: ' + name
                                         ;WIDGET_DISPLAYCONTEXTMENU, event.id, event.x, event.y, $
                                         ;    WIDGET_INFO(event.id, FIND_BY_UNAME = 'Atom_Menu')
                                 end
                       'Plot' : begin
                                         label = 'Current Selection: ' + name
                                         WIDGET_DISPLAYCONTEXTMENU, event.id, event.x, event.y, $
                                             WIDGET_INFO(event.id, FIND_BY_UNAME = 'Plot_Menu')
                                       end
                       'FundPlot' : begin
                                         label = 'Current Selection: ' + name
                                         WIDGET_DISPLAYCONTEXTMENU, event.id, event.x, event.y, $
                                             WIDGET_INFO(event.id, FIND_BY_UNAME = 'Fund_Menu')
                                       end
                       'OverPlot' : begin
                                         label = 'Current Selection: ' + name
                                         WIDGET_DISPLAYCONTEXTMENU, event.id, event.x, event.y, $
                                             WIDGET_INFO(event.id, FIND_BY_UNAME = 'Over_Menu')
                                       end
                       'Xaxis' : begin
                                         label = 'Current Selection: ' + name
                                         WIDGET_DISPLAYCONTEXTMENU, event.id, event.x, event.y, $
                                             WIDGET_INFO(event.id, FIND_BY_UNAME = 'Axis_Menu')
                                 end
                       'Yaxis' : begin
                                         label = 'Current Selection: ' + name
                                         WIDGET_DISPLAYCONTEXTMENU, event.id, event.x, event.y, $
                                             WIDGET_INFO(event.id, FIND_BY_UNAME = 'Axis_Menu')
                                end
                       'Title' : begin
                                         label = 'Current Selection: ' + name
                                         WIDGET_DISPLAYCONTEXTMENU, event.id, event.x, event.y, $
                                             WIDGET_INFO(event.id, FIND_BY_UNAME = 'Title_Menu')
                                end
                  else: label = ''
                  ENDCASE
;                  ENDIF ELSE BEGIN
;
;                               label=''
;                 ENDELSE
           ENDIF ELSE BEGIN
                 label = ''
                 self.xran=self.xdatarange
                 self.yran=self.ydatarange
                 self->spectrum
           ENDELSE
                  self->Update_LabelStatus, label
                  self.LastSelected = label
;if we have not selected anything, put up the general menu:

          IF ((SIZE(oArr))[0] EQ 0) THEN BEGIN
             autoscale = 0
             geometry=widget_info(self.pDraw,/geo)
             if event.x le geometry.scr_xsize *.15*.66666 then autoscale=1
             if event.x gt geometry.scr_xsize *.925 then autoscale=1
             if event.y le geometry.scr_ysize *.15*.66666 then autoscale=1
             if event.y gt geometry.scr_ysize *.925 then autoscale=1
             if not autoscale then begin
                WIDGET_DISPLAYCONTEXTMENU, event.id, event.x, event.y, $
                  WIDGET_INFO(event.id, FIND_BY_UNAME = 'General_PMenu')
             endif
          ENDIF
          END

         2 : Begin
;
; Middle mouse-button.
;
          End
         1 : Begin
;
; Left mouse button.
;


          If (Obj_Valid(self.drawPlotView)) then Begin
             self.myxAxis->getproperty,color=color
             widget_control,self.pDraw,draw_motion_events=1
             self.xs = event.x
             self.ys = event.y
             geo=widget_info(self.pDraw,/geometry)
             self.theBox = Obj_New('IDLgrPolyline', Replicate(self.xs, 5) / geo.scr_xsize, $
                           Replicate(self.ys, 5) / geo.scr_ysize, Color=color)
             self.DrawPlotmodel->Add, self.theBox
          EndIf
          End
         Else:
       EndCase
       End
    2 : Begin
;
; Mouse motion.
;
       If (Obj_Valid(self.thebox)) then Begin
          geo=widget_info(self.pDraw,/geometry)
          self.xd = 0 > event.x < (geo.scr_xsize-1)
          self.yd = 0 > event.y < (geo.scr_ysize-1)

         ; Re-set the box coordinates

          theBoxData = FltArr(2,5)
          theBoxData[0,*] = [self.xs, self.xd, self.xd, self.xs, self.xs] / Float(geo.scr_xsize)
          theBoxData[1,*] = [self.ys, self.ys, self.yd, self.yd, self.ys] / Float(geo.scr_ysize)

          self.theBox->SetProperty, Data=theBoxData
          self.o2Dwindow->draw,self.drawPlotView
       EndIf
       End
    1 : Begin
;
; Button release.
;
       Case Event.Release of
         4 : Begin
;
; Right mouse-button.
;
          End
         2 : Begin
;
; Middle mouse-button.
;
          End
         1 : Begin
;
; Left mouse button.
;
          If (Obj_Valid(self.drawPlotView)) then Begin
             ;now we know the size of the box
              self.theBox->getproperty,data=data
              xran = [min(data[0,[0,1]]),max(data[0,[0,1]])]
              yran = [min(data[1,[1,2]]),max(data[1,[1,2]])]
              if xran[0] eq xran[1] then begin
                Obj_Destroy, self.theBox
                Widget_Control, event.id, Draw_Motion_Events=0
                self.o2Dwindow->draw,self.drawPlotView
                return
              endif
             ;actual data limits:
             self.myxAxis->GetProperty, xcoord_conv=xcc
             x_in_data=(xran-xcc[0])/xcc[1]
             self.myyAxis->GetProperty, ycoord_conv=ycc
             y_in_data=(yran-ycc[0])/ycc[1]
             self.xran=x_in_data
             self.yran=y_in_data
       ; this shows only the relevent data
         self.myplot->setproperty,xrange=x_in_data,yrange=y_in_data
         self.fundplot->setproperty,xrange=x_in_data,yrange=y_in_data
         self.overplot->setproperty,xrange=x_in_data,yrange=y_in_data

         self.myxaxis->setproperty,range=x_in_data
         self.myyaxis->setproperty,range=y_in_data
         self.myxaxis->GetProperty, CRange=xrange
         self.myyaxis->GetProperty, CRange=yrange
         position = [0.15, 0.15, 0.925, 0.925]
         xs = Normalize(xrange, Position=[position[0], position[2]])
         ys = Normalize(yrange, Position=[position[1], position[3]])
         self.myplot->SetProperty, XCoord_Conv=xs, YCoord_Conv=ys
         self.fundplot->SetProperty, XCoord_Conv=xs, YCoord_Conv=ys
         self.overplot->SetProperty, XCoord_Conv=xs, YCoord_Conv=ys
         self.myxaxis->SetProperty, XCoord_Conv=xs
         self.myyaxis->SetProperty, YCoord_Conv=ys
         self.myyaxis->getproperty,ticktext=xtick,title=xtitle
           xtick->setproperty,recompute_dimensions=2
           xtitle->setproperty,recompute_dimensions=2
         self.myxaxis->getproperty,ticktext=ytick,title=ytitle
           ytick->setproperty,recompute_dimensions=2
           ytitle->setproperty,recompute_dimensions=2
             Obj_Destroy, self.theBox
             Widget_Control, event.id, Draw_Motion_Events=0
             self.o2Dwindow->draw,self.drawPlotView

          EndIf
          End
         Else:
       EndCase
       End
    Else:
EndCase
End

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Pro g3dview::Main_Draw_Widget_Event, Event
Compile_Opt Hidden
Case Event.Type of
    4 : Begin
;
;    Expose.
;
       self->Render_Scene
       End
    0 : Begin
;
; Button press
;
       Case Event.Press of
            4 : Begin
;
; Right mouse-button.
;

          self.LastSelected = ''
         ; First, select the view.
          oViewArr = self.o3DWindow->Select(self.oScene, $
                    [Event.x, Event.y], DIMENSIONS=[1,1] )
          nSel = N_ELEMENTS(oViewArr)
          ; If we have a view selection...
          IF ((SIZE(oViewArr))[0] NE 0) THEN BEGIN
               oView = oViewArr[0]
              ; Now select an object within the view.
               oObjArr = self.o3DWindow->Select(oView, $
                             [Event.x, Event.y], DIMENSIONS=[1,1] )
               nSel = N_ELEMENTS(oObjArr)
             ; If we have an object selection...
               IF ((SIZE(oObjArr))[0] NE 0) THEN BEGIN
                  oObjArr[0]->GetProperty, NAME=name
                  basename=strsplit(name,'_',/extract)
                  res=strmatch(basename[0],'eigenvector*')
                  if res then basename = 'eigenvector'

                  CASE basename[0] of
                       'atom' : begin
                                         label = 'Current Selections: ' + name
                                         WIDGET_DISPLAYCONTEXTMENU, event.id, event.x, event.y, $
                                             WIDGET_INFO(event.id, FIND_BY_UNAME = 'Atom_Menu')
                                 end
                       'eigenvector' : begin
                                         label = 'Current Selections: ' + name
                                         WIDGET_DISPLAYCONTEXTMENU, event.id, event.x, event.y, $
                                             WIDGET_INFO(event.id, FIND_BY_UNAME = 'Vector_Menu')
                                       end
                       'bond' : begin
                                         label = 'Current Selections: ' + name
                                         WIDGET_DISPLAYCONTEXTMENU, event.id, event.x, event.y, $
                                             WIDGET_INFO(event.id, FIND_BY_UNAME = 'Bond_Menu')
                                end
                  else: label = ''
                  ENDCASE
                ENDIF ELSE BEGIN
                               label=''
                 ENDELSE
           ENDIF ELSE BEGIN
                 label = 'No View to Select'
           ENDELSE
                  self->Update_LabelStatus, label
                  self.LastSelected = label
;if we have not selected anything, put up the general menu:

          IF ((SIZE(oObjArr))[0] EQ 0) THEN BEGIN
             WIDGET_DISPLAYCONTEXTMENU, event.id, event.x, event.y, $
                  WIDGET_INFO(event.id, FIND_BY_UNAME = 'General_Menu')
          ENDIF

          End
         2 : Begin
;
; Middle mouse-button.
;
          End
         1 : Begin
;
; Left mouse button.
;
          self.LastSelected = ''
          self->Set_Current_View, Event
          If (Obj_Valid(self.oCurrentView)) then Begin
              Void = self.oCurrentView->Update(Event)
              If (self.Mode eq 'select') then Begin
                 self.oCurrentView->GetProperty, Selected = oSelected
                 If (Obj_Valid(oSelected[0])) then Begin
                   oSelected[0]->GetProperty, Name = Name
                   If (Name eq '') then Begin
                    Name = Obj_Class(oSelected[0])
                   EndIf
                 EndIf Else Begin
                   Name = ' '
                 EndElse
                 self->Update_LabelStatus, Name
                 self.LastSelected = Name
              EndIf Else Begin
                 self.o3DWindow->SetProperty, Quality = self.DragQ
                 self->Render_Scene
              EndElse
          EndIf
          End
         Else:
       EndCase
       End
    2 : Begin
;
; Mouse motion.
;
       If (Obj_Valid(self.oCurrentView)) then Begin
         If (self.oCurrentView->Update(Event)) then Begin
          self->Render_Scene
         EndIf
       EndIf
       End
    1 : Begin
;
; Button release.
;
       Case Event.Release of
         4 : Begin
;
; Right mouse-button.
;
          End
         2 : Begin
;
; Middle mouse-button.
;
          End
         1 : Begin
;
; Left mouse button.
;
          self.o3DWindow->SetProperty, Quality = 2
          If (Obj_Valid(self.oCurrentView)) then Begin
              If (self.oCurrentView->Update(Event)) then Begin
                 self->Render_Scene
              EndIf
          EndIf
          End
         Else:
       EndCase
       End
    Else:
EndCase
End
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Pro g3dview::Update_DragQual_Menu, NewQuality
Compile_Opt Hidden
self.DragQ = NewQuality
self->Update_LabelStatus, "Changing 'drag' quality"
DragQualMenu = Widget_Info(self.tlb, $
    Find_by_UName =  'DragQualMenu')
If (Widget_Info(DragQualMenu, /Valid_ID)) then Begin
    Sibling = Widget_Info(DragQualMenu, /Child)
    For I = 0L, 2 Do Begin
       Widget_Control, Sibling, Sensitive = self.DragQ ne I
       Sibling = Widget_Info(Sibling, /Sibling)
    EndFor
EndIf
End
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Pro g3dview::Set_Cursor_Mode, Mode
self->Update_LabelStatus, /Reset
Case StrUpCase(Mode) of
    'TRANSLATE' : Begin
       self.Mode = 'translate'
       End
    'ROTATE' : Begin
       self.Mode = 'rotate'
       End
    'ZOOM' : Begin
       If (!version.release gt '5.4') then Begin
         self.Mode = 'zoom'
       EndIf Else Begin
         self.Mode = 'scale'
       EndElse
       End
    'SELECT' : Begin
       self.Mode = 'select'
       End
    Else :
EndCase
self->Update_Button_BMPs
self->Set_Prop_On_Children, self.oScene, Mode = self.Mode
End
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Pro g3dview::Set_Prop_On_Children, oContainer, _Extra = Extra
Compile_Opt Hidden
;
;Purpose: set properties on all immediate children contained
;in a given container.  The properties to be set are given by
;keyword.
;
oChildren = oContainer->Get(/All, Count = Count)
For I = 0L, Count - 1 Do Begin
    oChildren[I]->SetProperty, _Extra = Extra
EndFor
End
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Pro g3dview::Update_Button_BMPs
Compile_Opt Hidden

FName_prefixes = ['pan',       'rotate', 'zoom',  'select']
Modes =          ['translate', 'rotate', 'zoom', 'select']
If (!version.release le '5.4') then Begin
    FName_prefixes[2] = 'zoom'
    Modes[2] = 'scale'
EndIf

Indx = (Where(Modes eq StrLowcase(self.Mode)))[0]

ToolbarBase = Widget_Info(self.TLB, Find_by_UName ='ToolbarBase')
Sibling  = Widget_Info(ToolbarBase, /Child)
Repeat Begin
    UName = Widget_Info(Sibling, /UName)
    AKnownMode = (Where(FName_Prefixes eq Uname, NAKnownMode))[0]
    If (NAKnownMode ne 0) then Begin
       Filename = FilePath( $
         FName_Prefixes[AKnownMode] + $
         (Modes[AKnownMode] eq self.Mode ? '_active.bmp':'.bmp'), $
         Subdirectory = self.Bitmap_Subdir)
       Widget_Control, Sibling, /Bitmap, Set_Value = Filename
    EndIf
    Sibling = Widget_Info(Sibling, /Sibling)
EndRep Until (not Widget_Info(Sibling, /Valid_ID))
End
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Pro g3dview::Set_Current_View, Event
Compile_Opt Hidden

oSelectedView = self.o3DWindow->Select(self.oScene, [Event.X, Event.Y])
If Obj_Valid(oSelectedView[0]) then Begin
    self.oCurrentView = oSelectedView[0]
EndIf Else Begin
    self.oCurrentView = Obj_New()
EndElse
End
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function g3dview::about,event
strout = strarr(4)
strout[0] = 'Gaussian for FANS'
strout[1] = 'Written by Craig Brown'
strout[2] = 'August 17, 2005'
strout[3] = 'NIST Center for Neutron Research'
void = dialog_message(dialog_parent = event.top,strout,  $
   title = 'About G3dview',/information)
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function g3dview::init_colors
color_names = fsc_color(/names)
ncolors = n_elements(color_names)
s = create_struct(color_names[0],FSC_COLOR(color_names[0], !D.Table_Size-1,/Triple))
for i = 1,ncolors-1 do begin
   s = create_struct(s,color_names[i],FSC_COLOR(color_names[i], !D.Table_Size-1-i,/Triple))
endfor
c=strarr(96,2)
c[0,*]=['H','WHITE']
c[1,*]=['He','LIGHT_GRAY']
c[2,*]=['Li','Lawn_Green']
c[3,*]=['Be','Chartreuse']
c[4,*]=['B','Green']
c[5,*]=['C','Slate_Gray']
c[6,*]=['N','Royal_Blue']
c[7,*]=['O','Tomato']
c[8,*]=['F','Powder_Blue']
c[9,*]=['Ne','Hot_Pink']
c[10,*]=['Na','Yellow']
c[11,*]=['Mg','Orange']
c[12,*]=['Al','Light_Cyan']
c[13,*]=['Si','Steel_Blue']
c[14,*]=['P','Dark_Gray']
c[15,*]=['S','Gold']
c[16,*]=['Cl','Lime_Green']
c[17,*]=['Ar','Pale_Green']
c[18,*]=['K','Violet']
c[19,*]=['Ca','Cyan']
c[20,*]=['Sc','Plum']
c[21,*]=['Ti','Turquoise']
c[22,*]=['V','Red']
c[23,*]=['Cr','Charcoal']
c[24,*]=['Mn','Thistle']
c[25,*]=['Fe','Brown']
c[26,*]=['Co','Navy']
c[27,*]=['Ni','Medium_Gray']
c[28,*]=['Cu','Blue']
c[29,*]=['Zn','Gray']
c[30,*]=['Ga','Spring_Green']
c[31,*]=['Ge','Charcoal']
c[32,*]=['As','Forest_Green']
c[33,*]=['Se','Green_Yellow']
c[34,*]=['Br','Sienna']
c[35,*]=['Kr','Rose']
c[36,*]=['Rb','Pink']
c[37,*]=['Sr','Sea_Green']
c[38,*]=['Y','Olive']
c[39,*]=['Zr','Lawn_Green']
c[40,*]=['Nb','Olive_Drab']
c[41,*]=['Mo','Sandy_Brown']
c[42,*]=['Tc','Rosy_Brown']
c[43,*]=['Ru','Beige']
c[44,*]=['Rh','Coral']
c[45,*]=['Pd','Burlywood']
c[46,*]=['Ag','Moccasin']
c[47,*]=['Cd','Deep_Pink']
c[48,*]=['In','Salmon']
c[49,*]=['Sn','Orchid']
c[50,*]=['Sb','Chocolate']
c[51,*]=['Te','Pale_Goldenrod']
c[52,*]=['I','Light_Coral']
c[53,*]=['Xe','Sky_Blue']
c[54,*]=['Cs','Aquamarine']
c[55,*]=['Ba','Dark_Green']
c[56,*]=['La','Forest_Green']
c[57,*]=['Ce','Goldenrod']
c[58,*]=['Pr','Dark_Goldenrod']
c[59,*]=['Nd','Orange_Red']
c[60,*]=['Pm','Magenta']
c[61,*]=['Sm','VioletRed']
c[62,*]=['Eu','Maroon']
c[63,*]=['Gd','Medium_Orchid']
c[64,*]=['Tb','Dodger_Blue']
c[65,*]=['Dy','Blue']
c[66,*]=['Ho','Steel_Blue']
c[67,*]=['Er','Khaki']
c[68,*]=['Tm','Light_Salmon']
c[69,*]=['Yb','Light_Cyan']
c[70,*]=['Lu','Snow']
c[71,*]=['Hf','Ivory']
c[72,*]=['Ta','Linen']
c[73,*]=['W','Antique_White']
c[74,*]=['Re','Cornsilk']
c[75,*]=['Os','Seashell']
c[76,*]=['Ir','Almond']
c[77,*]=['Pt','Light_Yellow']
c[78,*]=['Au','Gold']
c[79,*]=['Hg','Lavender']
c[80,*]=['Tl','Dark_Khaki']
c[81,*]=['Pb','Black']
c[82,*]=['Bi','Indian_Red']
c[83,*]=['Po','Peru']
c[84,*]=['At','Dark_Salmon']
c[85,*]=['Rn','Tan']
c[86,*]=['Fr','Firebrick']
c[87,*]=['Ra','Honeydew']
c[88,*]=['Ac','Saddle_Brown']
c[89,*]=['Th','Papaya']
c[90,*]=['Pa','Bisque']
c[91,*]=['U','Wheat']
c[92,*]=['Np','GRAY']
c[93,*]=['Pu','GRAY']
c[94,*]=['Am','GRAY']
c[95,*]=['Cm','GRAY']

*self.default_atom_color_ptr=c
*self.actual_atom_color_ptr=c
*self.color_ptr = s
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro g3dview::Update_LabelStatus, Value, Reset = Reset
Label = Widget_Info(self.TLB, Find_by_UName = 'label')
If (Keyword_Set(Reset)) then Begin
    Widget_Control, Label, Set_Value = ''
EndIf Else Begin
    Widget_Control, Label, Set_Value = Value
EndElse
End
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function g3dview::get_obj,event

if not obj_valid(self.gauss) then return,0
;balls
vdwfactor=self.vdwfactor ;space filling size
bondfactor=self.bondfactor;are the atoms bonded at covalent + this factor
density=1     ;polygon density
shininess=self.shininess ; max 128

SPECULAR=[255,255,255]
ALPHA_CHANNEL=1.
diffuse=[255,255,255]

;if lines
thick=2.
bondcolor=self.bondcolor

;vectors
vector_color=self.vectorcolor
vector_THICK=2.0
vector_scale=self.vectorscale  ;how long are they?
mode=self.vibmode ; the vibration we want to see

self.gauss->getproperty,numberatoms=numberatoms,initcoords=initcoords,$
                atomlist=atomlist,covalent=covalent,vdw=vdw,evector=evector
oTop = OBJ_NEW('IDLgrModel',name='oModel')
; Create some light
oLight1 = OBJ_NEW('IDLgrLight', LOCATION=[17,22,29], TYPE=2, INTENSITY=0.15,name='oLight')
oTop->Add, oLight1
oGroup = OBJ_NEW('IDLgrModel',name='oGroup')
oTop->Add, oGroup
oCrystal = OBJ_NEW('IDLgrModel',name='oCrystal')
oGroup->Add, oCrystal

;get atom colors, the gray is default
color_str=intarr(numberatoms,3)
for i=0,numberatoms-1 do begin
  test=where(*self.actual_atom_color_ptr eq atomlist[i])
  name=(*self.actual_atom_color_ptr)[test,1]
  ret="col=(*self.color_ptr)."+name[0]
  ret=execute(ret)
  color_str[i,*]=reform(col)
endfor


oat=OBJ_NEW('IDLgrModel',name='Atoms')
ocrystal->add,oat

;make the orbs
for i=0,numberatoms-1 do begin
   name= "model_"+strtrim(string(atomlist[i]),2)+"_"+strtrim(string(i),2)
   omodela=OBJ_NEW('IDLgrModel',name=name)
   omodela->Translate,(initcoords[i,0]),(initcoords[i,1]),(initcoords[i,2])
   ;omodela->Translate,reform(initcoords[i,0]),reform(initcoords[i,1]),reform(initcoords[i,2])
   oat->Add, omodela
   atname='atom_'+strtrim(string(atomlist[i]),2)+"_"+strtrim(string(i),2)

   if !version.release le 6.0 then begin
   oatom=OBJ_NEW('Orb', COLOR=reform(color_str[i,*]),$
                                RADIUS=vdw[i]*vdwfactor,$
                                 DENSITY=density,$
                                name=atname,$
                                /TEX_COORDS)
   endif else begin
   oatom=OBJ_NEW('Orb', COLOR=reform(color_str[i,*]),$
                                RADIUS=vdw[i]*vdwfactor,$
                                 DENSITY=density,$
                                shininess=shininess,$
                                SPECULAR=SPECULAR ,$
                                DIFFUSE=DIFFUSE ,$
                                ALPHA_CHANNEL=ALPHA_CHANNEL,$
                                name=atname,$
                                /TEX_COORDS)
   endelse
   omodela->Add,oatom
endfor


;where are the bonds
bonds=self->do_bonding(numberatoms=numberatoms,initcoords=initcoords,covalent=covalent,bondfactor=bondfactor)
;bonds
tubedia=self.bondradius
tubecolor=bondcolor
p1=SELF.BONDFACETS ;P1 specifies the number of "facets" in the revolution
omodela=OBJ_NEW('IDLgrModel',name='Bonds')
oCrystal->Add,omodela
for i=0,(size(bonds))[2]-1 do begin
    v0 = [bonds[0,i],bonds[2,i],bonds[4,i]]
    v1 = [bonds[1,i],bonds[3,i],bonds[5,i]]
   name= "bond_"+strtrim(string(i),2)
   omodelb=OBJ_NEW('IDLgrModel',name=name)
   omodela->Add,omodelb
   namebond="bond_"+strtrim(string(i),2)
   if !version.release le 6.0 then begin
   omodelb->Add,g3dviewmakeTube(v0, v1, tubedia, tubecolor, p1,$
                                name=namebond)
   endif else begin
      omodelb->Add,g3dviewmakeTube(v0, v1, tubedia, tubecolor, p1,shininess=shininess,$
                                SPECULAR=SPECULAR,$
                                DIFFUSE=DIFFUSE,$
                                ALPHA_CHANNEL=self.BONDALPHA,$
                                name=namebond)
   endelse
endfor


;make the bonds
;for stick do this
;for i=0,k-1 do begin
;   name='oBonding'+strtrim(string(i),2)
;   com1=name+"=OBJ_NEW('IDLgrModel')"
;   ;com2=name+"->Translate,"+string(initcoords[i,0])+','+string(initcoords[i,1])+','+string(initcoords[i,2])
;   com3="oCrystal->Add, "+name
;   atname='oBond'+strtrim(string(i),2)
;   com4=atname+"=OBJ_NEW('IDLgrPolyline',(x[*,i]),(y[*,i]),(z[*,i]), COLOR="+ bondcolor +", thick="+ strtrim(string(thick),2)+")"
;   com5=name+"->Add,"+atname
;   res=execute(com1)
;   ;res=execute(com2)
;   res=execute(com3)
;   res=execute(com4)
;   res=execute(com5)
;endfor

;for the vectors
;       vecObj = OBJ_NEW('vector', LOCATION=[0,0,0], MAGNITUDE=[3,2,1], $
;           COLOR=[255,0,0], THICK=2.0)

if (size(evector))[0] eq 3 then begin
   vecs=fltarr((size(evector))[2],(size(evector))[3])
   magnitude=fltarr((size(evector))[2])
   location=fltarr((size(evector))[3])
   vecs=evector[mode,*,*]
   vecObj=objarr(numberatoms)
endif else begin
  return,0
endelse

for i=0,numberatoms-1 do begin
  location=reform(initcoords[i,*])
  magnitude=reform(vecs[0,i,*]*vector_scale)
  vecObj[i] = OBJ_NEW('vector', LOCATION=LOCATION, MAGNITUDE=MAGNITUDE, $
           COLOR=vector_color, THICK=vector_thick,name='eigenvector'+strtrim(string(i),2))
endfor
oVector = OBJ_NEW('IDLgrModel',name='Vector')
oGroup->Add, oVector
oVector -> Add, vecobj

Menu = Widget_Info(self.tlb,Find_by_UName =  'GM_showvector')
sens = Widget_Info(Menu,/sensitive)
if sens then self->Set_Prop_On_Children, oVector, hide=1
if obj_valid(self.omodel) then obj_destroy,self.omodel
self.omodel=otop
return,self.omodel
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function g3dview::do_bonding,numberatoms=numberatoms,initcoords=initcoords,covalent=covalent,bondfactor=bondfactor

k=0
bonds=intarr(2,500)
x=fltarr(2,500)
y=fltarr(2,500)
z=fltarr(2,500)

for i=0,numberatoms-1 do begin
   for j=i+1,numberatoms-1 do begin
      part=(initcoords[i,*]-initcoords[j,*])
      dist=sqrt(part[0]^2+part[1]^2+part[2]^2)     ; make a fn to calculate vector distance
      if dist le (bondfactor+covalent[i]+covalent[j]) then begin
         bonds[*,k]=[i,j]; BONDED
         x[*,k]=[initcoords[i,0],initcoords[j,0]]
         y[*,k]=[initcoords[i,1],initcoords[j,1]]
         z[*,k]=[initcoords[i,2],initcoords[j,2]]
         k=k+1
      endif
   endfor
endfor
*self.bondsptr=bonds[*,0:k-1]

x=x[*,0:k-1]
y=y[*,0:k-1]
z=z[*,0:k-1]
return,[x,y,z]
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Pro g3dview::Build_Scene, Stationary = Stationary,bgcolor=bgcolor
Compile_Opt Hidden

;get initial bg color for new scenes:
;
;Build the scene.
;
self.oScene = Obj_New('IDLgrScene',name='SCENE')
self.oTopLevelContainer->Add, self.oScene
;
;Obtain one or more views.
;
oobj=self->get_obj()
if not obj_valid(oobj) then return

If (Obj_IsA(oObj[0], 'IDLgrView')) then Begin
    For I = 0L, N_elements(oObj) - 1 Do Begin
       If (not Obj_IsA(oObj[I], 'IDLexObjView')) then Begin
         Message, 'Array argument containing a' + $
          'reference to an IDLexObjView must ' + $
          'contain only references to IDLexObjViews.', /NoName
       EndIf
       oObj[I]->SetViewVolume, o3DWindow, /Quiet, /Isotropic, Scale = Scl
    EndFor

    self.oScene->Add, oObj
    self.oCurrentView = oObj[0]
    self.oScene->SetProperty, Color = bgcolor
    self->Set_Prop_On_Children, self.oScene, Color = bgcolor
EndIf Else Begin
    self.oCurrentView = Obj_New('IDLexObjView', oObj, Stationary = Stationary)
    self.oTopLevelContainer->Add, self.oCurrentView
    self.oCurrentView->SetViewVolume, self.o3DWindow, /Quiet, /Isotropic, Scale = Scl
    self.oScene->Add, self.oCurrentView
    self.oScene->SetProperty, Color = bgcolor
    self->Set_Prop_On_Children, self.oScene, Color = bgcolor
    self.Do_Destroy_View = 1b
EndElse
End
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro g3dview::clean_scene,bg=bg
 If (Obj_Valid(self.oScene)) then Begin
    self.oScene->getproperty,color=bg
    If (self.oScene->Count() gt 0) then Begin
       self.oScene->Remove, /All
    EndIf
EndIf
If (Obj_Valid(self.oTopLevelContainer)) then Begin
    self.oTopLevelContainer->Remove, self.oCurrentView
EndIf
If (Obj_Valid(self.omodel)) then Begin
;    ctm=self.oCurrentView->GetCTM()
    Obj_Destroy, self.omodel

EndIf
If (self.Do_Destroy_View) then Begin
    Obj_Destroy, self.oCurrentView
EndIf
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro g3dview::change_plot,x=x,y=y,fundx=fundx,fundy=fundy,$
            overx=overx,overy=overy,datax=datax,datay=datay,datady=datady

if not keyword_set(x) then x=[0.0,0.2,0.4,0.6,0.8,1.0]
if not keyword_set(y) then y =[2,8,5,3,6,8]
if self.xran[0] eq self.xran[1] then begin
     self.xran[0] = min(x)
     self.xran[1] = max(x)
endif

if self.yran[0] eq self.yran[1] then begin
     self.yran[0] = min(y)
     self.yran[1] = max(y)
endif

position = [0.15, 0.15, 0.925, 0.925]

if obj_valid(self.myplot) then begin
;  if obj_isa(self.myplot,'IDLgrPlot') then self.myplot->getproperty,symbol=tmp1
;         if obj_valid(tmp1) then begin
;          tmp1[0]->getproperty,data=tmp2
;          if obj_valid(tmp2) then obj_destroy,tmp2
;          obj_destroy,tmp1
;         endif
    self.myplot->getproperty,color=plotcolor,linestyle=linestyle
    obj_destroy,self.myplot

endif

;self.fundplot = Obj_New("IDLgrPLOT", x, y, _Extra=extra, $
;   Color=plum,linestyle=2,Thick=self.default[2],name="FundPlot")
;self.overplot = Obj_New("IDLgrPLOT", x, y, _Extra=extra, $
;   Color=plum,linestyle=1,Thick=self.default[2],name="OverPlot")
;self.dataplot = Obj_New("IDLgrPLOT", x, y, _Extra=extra, $
;   Color=black, Symbol=self.Symbol, Thick=self.default[2],name="DataPlot")


if obj_valid(self.xtext) then obj_destroy,self.xtext
if obj_valid(self.ytext) then obj_destroy,self.ytext
if obj_valid(self.myxaxis) then begin
   self.myxaxis->getproperty,color=axiscolor
   obj_destroy,self.myxaxis
endif
if obj_valid(self.myyaxis) then obj_destroy,self.myyaxis
white= reform((*self.color_ptr).white)
black= reform((*self.color_ptr).black)
plum= reform((*self.color_ptr).plum)
if n_elements(axiscolor) eq 0 then axiscolor=black
if n_elements(plotcolor) eq 0 then plotcolor=plum

self.myplot = Obj_New("IDLgrPLOT", x, y, XRange=self.xran, YRange=self.yran, $
   Color=plotcolor, linestyle=linestyle,Thick=self.totalthick,name='Plot')
;self.myplot->GetProperty, XRange=xrange, YRange=yrange

;xSymSize = (xrange[1] - xrange[0])* self.default[1]*0.1
;ySymSize = (yrange[1] - yrange[0]) * self.default[1]*0.1
;IF Obj_Valid(self.Symbol) THEN self.Symbol->SetProperty, Size=[xSymSize, ySymSize]

xtitle = 'Energy Transfer (cm-1)'
ytitle = 'Intensity (arb)'
self.xtext = Obj_New('IDLgrText', xtitle, Color=axiscolor,name='Xlabel')
self.ytext = Obj_New('IDLgrText', ytitle, Color=axiscolor,name='Ylabel')

self.myxaxis = Obj_New("IDLgrAxis", 0, Color=axiscolor, Ticklen=self.default[0], $
    Minor=4, Range=self.xran, Title=self.xtext,name='Xaxis', $
    Location=[1000, position[1] ,0], Exact=1)
;self.myxaxis->GetProperty, Ticktext=xAxisText
;xAxisText->SetProperty, Font=self.font[0]

self.myyaxis = Obj_New("IDLgrAxis", 1, Color=axiscolor, Ticklen=self.default[0], $
    Minor=4, Title=self.ytext, Range=self.yran, $
    Location=[position[0], 1000, 0], Exact=1,name='Yaxis')
;self.myyaxis->GetProperty, Ticktext=yAxisText
;yAxisText->SetProperty, Font=self.font[0]

self.myxaxis->GetProperty, CRange=xrange
self.myyaxis->GetProperty, CRange=yrange
xs = Normalize(xrange, Position=[position[0], position[2]])
ys = Normalize(yrange, Position=[position[1], position[3]])
self.myplot->SetProperty, XCoord_Conv=xs, YCoord_Conv=ys
self.myxaxis->SetProperty, XCoord_Conv=xs
self.myxaxis->SetProperty, XCoord_Conv=xs
self.myyaxis->SetProperty, YCoord_Conv=ys
self.myyaxis->SetProperty, YCoord_Conv=ys
self.drawPlotModel->Add, self.myxaxis
self.drawPlotModel->Add, self.myyaxis


if keyword_set(fundx) then begin
   if obj_valid(self.fundplot) then begin
      self.fundplot->getproperty,color=fundcolor,linestyle=fundline
      obj_destroy,self.fundplot
  endif
  self.fundplot = Obj_New("IDLgrPLOT", fundx, fundy, _Extra=extra, XRange=self.xran, YRange=self.yran,$
  Color=fundcolor,linestyle=fundline,Thick=self.fundthick,name="FundPlot")
;  self.fundplot->GetProperty, XRange=xrange, YRange=yrange
  self.fundplot->SetProperty, XCoord_Conv=xs, YCoord_Conv=ys
  self.drawPlotModel->Add, self.fundplot
endif else begin
   if obj_valid(self.fundplot) then begin
      self.fundplot->getproperty,color=fundcolor,linestyle=fundline
      obj_destroy,self.fundplot
   endif
  self.fundplot = Obj_New("IDLgrPLOT", [0], [0], _Extra=extra,XRange=self.xran, YRange=self.yran, $
  Color=fundcolor,linestyle=fundline,Thick=self.fundthick,name="FundPlot")
  self.fundplot->SetProperty, XCoord_Conv=xs, YCoord_Conv=ys
  self.drawPlotModel->Add, self.fundplot
endelse

if keyword_set(overx) then begin
   if obj_valid(self.overplot) then begin
      self.overplot->getproperty,color=overcolor,linestyle=overline
      obj_destroy,self.overplot
   endif
  self.overplot = Obj_New("IDLgrPLOT", overx, overy, _Extra=extra, XRange=self.xran, YRange=self.yran,$
   Color=overcolor,linestyle=overline,Thick=self.overthick,name="OverPlot")
   self.overplot->SetProperty, XCoord_Conv=xs, YCoord_Conv=ys
   self.drawPlotModel->Add, self.overplot
endif else begin
   if obj_valid(self.overplot) then begin
      self.overplot->getproperty,color=overcolor,linestyle=overline
      obj_destroy,self.overplot
   endif
  self.overplot = Obj_New("IDLgrPLOT", [0], [0], _Extra=extra, XRange=self.xran, YRange=self.yran,$
  Color=overplot,linestyle=overline,Thick=self.overthick,name="OverPlot")
  self.overplot->SetProperty, XCoord_Conv=xs, YCoord_Conv=ys
  self.drawPlotModel->Add, self.overplot
endelse


self.drawPlotModel->Add, self.myplot

self.o2DWindow ->Draw, self.drawPlotView

end

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro g3dview::build_plot,event
self.oTopLevelPlotCont = Obj_New('IDL_Container')
; Create a view
self.drawPlotView = Obj_New('IDLgrView', Viewplane_Rect=[0.0, 0.0, 1.0, 1.0], $
   Location=[0,0], Color=reform((*self.color_ptr).white),name="Plot_View")

xtitle = 'Energy Transfer (cm-1)'
ytitle = 'Intensity (arb)'
title = "FANS from Gaussian Calculation"
symsize=self.default[1]
linestyle=0
psym=0
position = [0.15, 0.15, 0.925, 0.925]
white= reform((*self.color_ptr).white)
black= reform((*self.color_ptr).black)
plum= reform((*self.color_ptr).plum)

IF N_Elements(psym) EQ 0 THEN psym = 0
IF N_Elements(position) EQ 0 THEN position = [0.15, 0.15, 0.925, 0.925]
IF N_Elements(title) EQ 0 THEN title = ''
IF N_Elements(symsize) EQ 0 THEN symsize = self.default[1]
IF N_Elements(xtitle) EQ 0 THEN xtitle = ''
IF N_Elements(ytitle) EQ 0 THEN ytitle = ''
 self.totalthick = 1.0
 self.fundthick = 1.0
 self.overthick = 1.0
colorprint = 1
vector = 1


x=[0]
y=[0]

; Create titles for the axes.
self.xtext = Obj_New('IDLgrText', xtitle, Color=black,name='Xlabel')
self.ytext = Obj_New('IDLgrText', ytitle, Color=black,name='Ylabel')

psym=4
; Make a symbol object.
self.Symbol = Obj_New('IDLgrSymbol', psym, Color=plum)
;self.symbol = self->getpsym(psym,symsize,thick,plum)

    ; Make a font object.
helvetica10pt = Obj_New('IDLgrFont', 'Helvetica', Size=10)
;self.font = OBJ_NEW('IDLgrFont', 'times')


self.myplot = Obj_New("IDLgrPLOT", x, y, _Extra=extra, $
   Color=plum, Thick=self.totalthick,name="Plot")
self.fundplot = Obj_New("IDLgrPLOT", x, y, _Extra=extra, $
   Color=plum,linestyle=2,Thick=self.fundthick,name="FundPlot")
self.overplot = Obj_New("IDLgrPLOT", x, y, _Extra=extra, $
   Color=plum,linestyle=1,Thick=self.overthick,name="OverPlot")
self.dataplot = Obj_New("IDLgrPLOT", x, y, _Extra=extra, $
   Color=black, Symbol=self.Symbol, Thick=self.default[2],name="DataPlot")

    ; Get the data ranges from the Plot Object.

self.myplot->GetProperty, XRange=xrange, YRange=yrange
if xrange[0] le xrange [1] then xrange[1]=xrange[1]+1.
if yrange[0] le yrange [1] then yrange[1]=yrange[1]+1.
self.myxaxis = Obj_New("IDLgrAxis", 0, Color=black, Ticklen=self.default[0], $
    Minor=4, Range=xrange, Title=self.xtext, $
    Location=[1000, position[1] ,0], Exact=1,name='Xaxis')
self.myxaxis->GetProperty, Ticktext=xAxisText
xAxisText->SetProperty, Font=helvetica10pt

;xAxis2 = Obj_New("IDLgrAxis", 0, Color=black, Ticklen=0.025, $
;    Minor=4, /NoText, Range=xrange, TickDir=1, $
;    Location=[1000, position[3], 0], Exact=exact[0])

self.myyaxis = Obj_New("IDLgrAxis", 1, Color=black, Ticklen=0.025, $
    Minor=4, Title=self.ytext, Range=yrange, $
    Location=[position[0], 1000, 0], Exact=1,name='Yaxis')
self.myyaxis->GetProperty, Ticktext=yAxisText
yAxisText->SetProperty, Font=helvetica10pt

;yAxis2 = Obj_New("IDLgrAxis", 1, Color=black, Ticklen=0.025, $
;    Minor=4, /NoText, Range=yrange, TickDir=1, $
;    Location=[position[2], 1000, 0], Exact=exact[1])

    ; Because we may not be using exact axis ranging, the axes
    ; may extend further than the xrange and yrange. Get the
    ; actual axis range so that the plot, etc. can be scaled
    ; appropriately.

self.myxaxis->GetProperty, CRange=xrange
self.myyaxis->GetProperty, CRange=yrange

    ; Set up the scaling so that the axes for the plot and the
    ; plot data extends from 0->1 in the X and Y directions.

xs = Normalize(xrange, Position=[position[0], position[2]])
ys = Normalize(yrange, Position=[position[1], position[3]])

    ; Scale the plot data and axes into 0->1.

self.myplot->SetProperty, XCoord_Conv=xs, YCoord_Conv=ys
self.overplot->SetProperty, XCoord_Conv=xs, YCoord_Conv=ys
self.fundplot->SetProperty, XCoord_Conv=xs, YCoord_Conv=ys
self.dataplot->SetProperty, XCoord_Conv=xs, YCoord_Conv=ys
self.myxaxis->SetProperty, XCoord_Conv=xs
self.myxaxis->SetProperty, XCoord_Conv=xs
self.myyaxis->SetProperty, YCoord_Conv=ys
self.myyaxis->SetProperty, YCoord_Conv=ys


    ; Size the symbols appropriately for the plot.

xSymSize = (xrange[1] - xrange[0])* self.default[1]*0.05
ySymSize = (yrange[1] - yrange[0]) * self.default[1]*0.05
IF Obj_Valid(self.Symbol) THEN self.Symbol->SetProperty, Size=[xSymSize, ySymSize]

; Create a plot title. Center it at a location above the plot.
helvetica14pt = Obj_New('IDLgrFont', 'Helvetica', Size=14)
self.Title = Obj_New('IDLgrText', title, Color=black, name='Title',$
   Location=[0.5, .95, 0.0], Alignment=0.5, Font=helvetica14pt)

; Create a plot model and add axes, plot, and plot title.
self.drawPlotModel = Obj_New('IDLgrModel')
self.drawPlotModel->Add, self.myplot
self.drawPlotModel->Add, self.myxaxis
;self.drawPlotModel->Add, xAxis2
self.drawPlotModel->Add, self.myyaxis
;self.drawPlotModel->Add, yAxis2
self.drawPlotModel->Add, self.Title
self.drawPlotView->Add, self.drawPlotModel


;xmax = max(xdat)
;xmin = min(xdat)
;self.xran = [temporary(xmin),temporary(xmax)]
;if self.xran[0] eq self.xran[1] then begin
;     tmp = (self.xran[0] eq 0)? 0.5:abs(self.xran[0]/2.)
;     self.xran[0] = self.xran[0]-tmp
;     self.xran[1] = self.xran[1]+tmp
;endif
;
;ymax = max(ydat)
;ymin = min(ydat)
;self.yran = [temporary(ymin),temporary(ymax)]
;if self.yran[0] eq self.yran[1] then begin
;     tmp = (self.yran[0] eq 0)? 0.5:abs(self.yran[0]/2.)
;     self.yran[0] = self.yran[0]-tmp
;     self.yran[1] = self.yran[1]+tmp
;endif

self.oTopLevelPlotCont->Add, self.drawPlotView
self.oTopLevelPlotCont->Add, self.dataplot
self.oTopLevelPlotCont->Add, self.overplot
self.oTopLevelPlotCont->Add, self.fundplot
self.o2DWindow ->Draw, self.drawPlotView
; so we can destroy them later
self.font[0]=helvetica10pt
self.font[1]=helvetica14pt

end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro g3dview::event,event,BranchCode = BranchCode
EventType = Tag_Names(Event, /Structure)

if EventType eq 'WIDGET_BASE' then begin
   widget_control,event.top,get_uvalue = the_object
     the_object->resize,event
   return
endif
if EventType eq 'WIDGET_TAB' then begin
   ftab=widget_info(self.tlb,find_by_uname='DATA_TAB')
   thistab=widget_info(ftab,/tab_current)  ; if 0 then the plot, 1 the 3D
   ;if 0 make all icons untouchables:
   case thistab of
   '0' : begin
      ToolbarBase = Widget_Info(self.TLB, Find_by_UName ='ToolbarBase')
      Sibling  = Widget_Info(ToolbarBase, /Child)
      Repeat Begin
         UName = Widget_Info(Sibling, /UName)
         if UName ne 'label' then widget_control,sibling,sensitive=0
         Sibling = Widget_Info(Sibling, /Sibling)
       EndRep Until (not Widget_Info(Sibling, /Valid_ID))
       ;menus
       menu1=Widget_Info(self.TLB, Find_by_UName ='Export VRML')
       widget_control,menu1,sensitive=0
       menu2=Widget_Info(self.TLB, Find_by_UName ='Export FRAMES')
       widget_control,menu2,sensitive=0
       menu3=Widget_Info(self.TLB, Find_by_UName ='ViewMenu')
       widget_control,menu3,sensitive=0
       menu4=Widget_Info(self.TLB, Find_by_UName ='DO_VIBS')
       widget_control,menu4,sensitive=0
       menu5=Widget_Info(self.TLB, Find_by_UName ='Save Dave')
       widget_control,menu5,sensitive=1
       menu6=Widget_Info(self.TLB, Find_by_UName ='Save Ascii')
       widget_control,menu6,sensitive=1
     end
    '1': begin
      ToolbarBase = Widget_Info(self.TLB, Find_by_UName ='ToolbarBase')
      Sibling  = Widget_Info(ToolbarBase, /Child)
      Repeat Begin
         widget_control,sibling,sensitive=1
         Sibling = Widget_Info(Sibling, /Sibling)
       EndRep Until (not Widget_Info(Sibling, /Valid_ID))

       menu1=Widget_Info(self.TLB, Find_by_UName ='Export VRML')
       widget_control,menu1,sensitive=1
       menu2=Widget_Info(self.TLB, Find_by_UName ='Export FRAMES')
       widget_control,menu2,sensitive=1
       menu3=Widget_Info(self.TLB, Find_by_UName ='ViewMenu')
       widget_control,menu3,sensitive=1
       menu4=Widget_Info(self.TLB, Find_by_UName ='DO_VIBS')
       widget_control,menu4,sensitive=1
       menu5=Widget_Info(self.TLB, Find_by_UName ='Save Dave')
       widget_control,menu5,sensitive=0
       menu6=Widget_Info(self.TLB, Find_by_UName ='Save Ascii')
       widget_control,menu6,sensitive=0

    end
    else:
    endcase
    return
endif

If (N_elements(BranchCode) eq 0) then Begin
    Widget_Control, Event.ID, Get_UValue = BranchCode
    If (N_elements(BranchCode) eq 0) then Begin
       Return
    EndIf
EndIf
IsTracking = EventType eq 'WIDGET_TRACKING'
If (IsTracking) then Begin
    If (Event.Enter eq 0) then Begin
       self->Update_LabelStatus, /Reset

    EndIf
EndIf

Case BranchCode of
    'ResetScene' : Begin
       If (IsTracking) then Begin
         self->Update_LabelStatus, 'Reset scene'
       EndIf Else Begin
         self->Reset_Scene
       EndElse
       End
    'Choose_Mode' : Begin
       self->choosemode,event
       END
    'DO_VIBS' : Begin
        button = Widget_Info(self.TLB, Find_by_UName = 'DO_VIBS')
        widget_control,button,get_value=value
        if value eq 'A N I M A T E' then begin
            self.stopvib=0
            ;widget_control,button,set_value='S T O P'
            self->Do_vibs
        endif else begin
            ;widget_control,button,set_value= 'A N I M A T E'
            ;self.stopvib=1
        endelse
        END
    'Quit' : Begin
       If (Obj_Valid(self)) then Begin
         self->Destruct
       EndIf
       Return
       End
    'ExportFRAMES' : Begin
       Widget_Control, /Hourglass
       self->FRAMES_Output
       End
    'ExportVRML' : Begin
       Widget_Control, /Hourglass
       self->VRML_Output
       End
    'ExportImage' : Begin
       self->Export_Image
       End
    'Save_Dave' : Begin
       self->Savefile,'Dave'
       End
    'Save_Ascii' : Begin
       self->Savefile,'Ascii'
       End
    'CopyToClipboard' : Begin
       self->Copy_to_Clipboard
       End
    'Print' : Begin
       self->Print
       End
    'RefreshScene': Begin
       self->Render_Scene
       End
    'DrawWindow': Begin
       self->Main_Draw_Widget_Event, Event
       End
    'PlotWindow': Begin
       self->Main_Plot_Widget_Event, Event
       End
    'edatoms': Begin
       self->Change_atoms
       END
    'ChooseGaussFile': Begin
       self->LoadGaussFile,event
       END
    'overtone': Begin
       self->spectrum
       END
    'data': Begin
       ;self->LoadGaussFile,event
       END

    Else: Begin
       Components = StrTok(BranchCode, '_', /Extract)
       Case Components[0] of
         'Drag' : Begin
          self->Update_DragQual_Menu, Long(Components[1])
          End
         'Color' : Begin
          self->Set_Backg_Color, Components[1]
          End
         'PlotColor' : Begin
          self->Set_PlotBackg_Color, Components[1]
          End
         'PlotLine' : Begin
          self->Set_Plot_Linestyle, Components[1], Components[2]
          End
         'PlotThick' : Begin
          self->Set_Plot_Thick, Components[1]
          End
         'Atom' : Begin
          self->Set_Atom,Components[1],Components[2]
          End
         'Bond' : Begin
          self->Set_Bond,Components[1]
          End
         'Vector' : Begin
          self->Set_Vector,Components[1]
          End
         'Defaults' : begin
          self->set_defaults
          self->render_scene
          end
          'Plotparams' : begin
          self->plot_params,event,Components[1]
          self->spectrum
          end
          'gaussmono' : begin
          self->set_mono
          end
          'gausscoll' : begin
          self->set_coll
          end
         'Mode' : Begin
          If (IsTracking) then Begin
              Case Components[1] of
                 Else : Tip = ''
              EndCase
              self->Update_LabelStatus, Components[1]
          EndIf Else Begin
              self->Set_Cursor_Mode, Components[1]
          EndElse
          End
         Else :
       EndCase
       End
EndCase

;uname = widget_info(event.id,/uname)
;widget_control,event.id,get_uvalue = cmd
;ret = call_method(cmd.method,cmd.object,event)
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Pro g3dview::Resize, Event
;If (N_elements(Event) ne 0) then Begin
;    Dimensions = ([Event.X, Event.Y] - self.NonDrawDimensions) > 1
;EndIf
Widget_Control, self.tlb, XSize = self.TLBDimensions[0], YSize = self.TLBDimensions[1]
End
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Pro g3dview_Events, Event
Widget_Control, Event.Handler, Get_UValue = oThing
If (N_elements(oThing) ne 0) then Begin
    If (Obj_Valid(oThing)) then Begin
       oThing->Event, Event
    EndIf
EndIf
End
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function g3dview::build_gui,No_Rotate = No_Rotate, Renderer = Renderer


if n_elements(*self.pgroup_leader) eq 0 then begin
  tlb = widget_base(title = 'G3dview',  $
                        /col,mbar = mbar,/tlb_size_events,uname='TLB')
endif else begin
   tlb = widget_base(title = 'G3dview',  $
                        /col,mbar = mbar,/tlb_size_events,   $
                           group_leader = *self.pgroup_leader,uname='TLB')
endelse

self.tlb = tlb

FileMenu = Widget_Button(MBar, Value = 'File', /Menu, $
    UName = 'FileMenu')
wchoosefile=widget_button(FileMenu,value='Choose Gaussian .log file',$
    uname='bChooseGaussFile',uvalue='ChooseGaussFile')

wExportImageButton = Widget_Button(FileMenu, $
    UName = 'Export Image', Value = 'Export Image...', $
    UValue = 'ExportImage')
wExportMpgButton = Widget_Button(FileMenu, $
    UName = 'Export FRAMES', Value = 'Export 3D FRAMES...', $
    UValue = 'ExportFRAMES')
wVRMLButton = Widget_Button(FileMenu, $
    UName =  'Export VRML', Value = 'Export 3D VRML...', $
    UValue = 'ExportVRML')
wPrintButton = Widget_Button(FileMenu, $
    UName =  'Print', Value = 'Print...', $
    UValue = 'Print')
wSDButton = Widget_Button(FileMenu, $
    UName =  'Save Dave', Value = 'Save as DAVE', $
    UValue = 'Save_Dave')
wSAButton = Widget_Button(FileMenu, $
    UName =  'Save Ascii', Value = 'Save as Ascii', $
    UValue = 'Save_Ascii')

wQuitButton = Widget_Button(FileMenu, $
    /Separator, UName = 'Quit', Value = 'Quit', $
    UValue = 'Quit')

EditMenu = Widget_Button(MBar, /Menu, Value = 'Edit', $
    UName =  'EditMenu')
wClipboardButton = Widget_Button(EditMenu, $
    UName =  'Copy to Clipboard', $
    Value='Copy Scene to Clipboard', $
    UValue = 'CopyToClipboard')

ViewMenu = Widget_Button(MBar, Value = 'View', /Menu, $
    UName =  'ViewMenu')
DragQualMenu = Widget_Button(ViewMenu, $
    Value = 'Drag Quality', /Menu, $
    UName =  'DragQualMenu')
wDragQualLow = Widget_Button(DragQualMenu, $
    UName = 'Low', Value = 'Low', $
    UValue = 'Drag_0')
wDragQualMedium = Widget_Button(DragQualMenu, $
    UName =  'Medium', Value='Medium', $
    UValue = 'Drag_1')
wDragQualHigh = Widget_Button(DragQualMenu, $
    UName =  'High', Value = 'High', $
    UValue = 'Drag_2')
BackgroundMenu = Widget_Button(ViewMenu, $
    Value = 'Background', $
    UName =  'BackgroundMenu', $
    UValue='Color_Color')
DefaultsButton = Widget_Button(ViewMenu, $
    Value = 'Reset to Defaults', $
    UName='ResetDefaults', $
    uvalue='Defaults_Do')
RefreshButton = Widget_Button(ViewMenu, $
    UName = 'Refresh', Value='Refresh', $
    UValue = 'RefreshScene')

self.Bitmap_Subdir = ['resource', 'bitmaps']
wToolbarBase = Widget_Base(self.TLB, /Row, /Frame, $
    UName =  'ToolbarBase')
wReset = Widget_Button(wToolbarBase, $
    UName =  'reset', $
    Value = FilePath('reset.bmp', Subdirectory = self.Bitmap_Subdir), $
    /Bitmap, UValue = 'ResetScene', $
    /Tracking_Events)
EmptyBase = Widget_Base(wToolbarBase, /Row, Scr_XSize = 8)
wRotate = Widget_Button(wToolbarBase, $
    UName =  'rotate', $
    Value = FilePath('rotate_active.bmp', Subdirectory = self.Bitmap_Subdir), $
    /Bitmap, UValue = 'Mode_Rotate', $
    /Tracking_Events)
If (Keyword_Set(No_Rotate)) then Begin
    Widget_Control, wRotate, Sensitive = 0
EndIf
wZoom = Widget_Button(wToolbarBase, $
    UName =  'zoom', $
    Value = FilePath('zoom.bmp', Subdirectory = self.Bitmap_Subdir), $
    /Bitmap, UValue = 'Mode_Zoom', $
    /Tracking_Events)
wPan = Widget_Button(wToolbarBase, $
    UName = 'pan', $
    Value = FilePath('pan.bmp', Subdirectory = self.Bitmap_Subdir), $
    /Bitmap, UValue = 'Mode_Translate', $
    /Tracking_Events)
wSelect = Widget_Button(wToolbarBase, $
    UName =  'select', $
    Value = FilePath('select.bmp', Subdirectory = self.Bitmap_Subdir), $
    /Bitmap, UValue = 'Mode_Select', $
    /Tracking_Events)
wLabel = Widget_Label(wToolbarBase, Value=' ', /Dynamic_Resize, $
    UName = 'label')

;Make a set of tabs;
fTab = WIDGET_TAB(self.tlb,uname='DATA_TAB')
;fill in the file tab

toprow_base=widget_base(fTab,/col,title='DATA',uname = 'DATA_BASE')
row_base = widget_base(toprow_base,/row,title='DATA',uname = 'DATA_BASE')

choosefile=widget_button(row_base,value='Choose Gaussian .log file',$
    uname='ChooseGaussFile',uvalue='ChooseGaussFile',xsize=160,tooltip='Load a LOG file')

choosedata=widget_button(row_base,value='                   ',$;'Choose expt. data',$
    uvalue='gaussChooseData',xsize=130,tooltip='load any FANS file')
editatom=widget_button(row_base,value='Edit atoms',$
    uname='edatoms',uval='edatoms',xsize=90,tooltip='change mass and ix of atoms')
;monochromator=['Cu','Pg','delta']
monochromator=['Cu','Pg']
collimation=['10-10','10-20','20-10','20-20','20-40','40-20',$
                   '40-40','40-60','60-40','60-60']

mono=widget_droplist(row_base,title="Monochromator",value=monochromator, $
       uname='mono',uvalue='gaussmono_Events',xsize=160)
collim=widget_droplist(row_base,title="Collim",value=collimation, $
       uname='collim',uvalue='gausscoll_Events',xsize=120)

butbase3=widget_base(toprow_base,/row,/base_align_left)

winxsize=500
winysize=370
xsize=600
ysize=400

butbase5=widget_base(butbase3,/row,/base_align_center,frame=1,/CONTEXT_EVENTS)
;plotwin1=widget_draw(butbase5,xsize=winxsize,ysize=YSize,$
;       /button_events,event_pro = 'gaussfunGenWinDraw')

self.pDraw = Widget_Draw(butbase5, $
    XSize = winxsize, YSize = winYSize, $
    /Button_Events, /Motion_Events, /Expose_Events, $
    Retain = 0, Renderer = 0, Graphics_Level = 2, $
    UName = 'plot', UValue = 'PlotWindow')



butbase4=widget_base(butbase3,/col,/base_align_right,/frame)
scaleint = cw_field(butbase4,title = 'Int. Scale factor: ',/float,value = self.scalefactor,$
                UValue = 'Plotparams_scaleint',/return_events,xsize = 10)
scalefreq = cw_field(butbase4,title = 'Freq. Scale factor:',/float,value = self.freqfactor,$
                UValue = 'Plotparams_scalefreq',/return_events,xsize = 10)
bglinear = cw_field(butbase4,title = 'Bg (linear): ',value = self.flatbg,/float,$
                UValue = 'Plotparams_linear',/return_events,xsize = 10)
bgparam = cw_field(butbase4,title = 'Bg (E*B1)  ',value = self.linearbg,/float,$
               UValue = 'Plotparams_grad', /return_events,xsize = 10)
dwfl = cw_field(butbase4,title = 'Debye-Waller:',value = self.dwf,/float,$
               UValue = 'Plotparams_dwf', /return_events,xsize = 10)
cwoversf = cw_field(butbase4,title = 'Comb. Scale fact:',value = self.oversf,/float,$
               UValue = 'Plotparams_overscale', /return_events,xsize = 10)

row1ne = widget_base(butbase4,/col, /NONEXCLUSIVE)
;fundcheck = widget_button(row1ne, VALUE = 'Fundamentals', $
;    uname='FundCheck',UVALUE = 'fund',tooltip='plot the calculated fundamental')
overcheck = widget_button(row1ne, VALUE = 'Overtones', $
    uname='OverCheck',UVALUE = 'overtone',tooltip='Plot the calculated & comb/overtones')
;datacheck = widget_button(row1ne, VALUE = 'Data', $
;    uname='DataCheck',UVALUE = 'data',tooltip='Plot the loaded experimental data')

butbase7=widget_base(butbase4,/col,/base_align_center)
;mevbutton=widget_button(butbase7,value='Plot Frequency in meV',uvalue='tomev',tooltip='Change energy scale')

General_PMenu  = widget_base(self.pDraw,/CONTEXT_MENU,UNAME='General_PMenu')  ;CONTEXT MENU
  pbg   = widget_button(General_PMenu,value='Background',uname='GM_pbg',UValue = 'PlotColor_Plot')
GPlot_PMenu  = widget_base(self.pDraw,/CONTEXT_MENU,UNAME='Plot_Menu')  ;CONTEXT MENU
  psymcol   = widget_button(GPlot_PMenu,value='Total Plot Color',uname='GM_ps',UValue = 'PlotColor_Total')
  psymthk   = widget_button(GPlot_PMenu,value='Line Thickness',uname='GM_pl',UValue = 'PlotThick_Total')
  psymlin   = widget_button(GPlot_PMenu,value='Total Linestyle',uname='GM_ls',UValue = 'PlotLine_Total',/menu)
  plin   = widget_button(psymlin,value='solid ',uname='GM_ls0',UValue = 'PlotLine_Total_0')
  plin   = widget_button(psymlin,value='.....',uname='GM_ls1',UValue = 'PlotLine_Total_1')
  plin   = widget_button(psymlin,value='- - -',uname='GM_ls2',UValue = 'PlotLine_Total_2')
  plin   = widget_button(psymlin,value='-.-.-',uname='GM_ls3',UValue = 'PlotLine_Total_3')
  plin   = widget_button(psymlin,value='-...-',uname='GM_ls4',UValue = 'PlotLine_Total_4')
  plin   = widget_button(psymlin,value='long dash',uname='GM_ls5',UValue = 'PlotLine_Total_5')

GFund_PMenu  = widget_base(self.pDraw,/CONTEXT_MENU,UNAME='Fund_Menu')  ;CONTEXT MENU
  pfundcol   = widget_button(GFund_PMenu,value='Fundamantal Color',uname='GM_pf',UValue = 'PlotColor_Fund')
  pfundthk   = widget_button(GFund_PMenu,value='Line Thickness',uname='GM_fl',UValue = 'PlotThick_Fund')
  pfundlin   = widget_button(GFund_PMenu,value='Fundamental Linestyle',uname='GM_lf',UValue = 'PlotLine_Fund',/menu)
  pfin   = widget_button(pfundlin,value='solid ',uname='GM_lf0',UValue = 'PlotLine_Fund_0')
  pfin   = widget_button(pfundlin,value='.....',uname='GM_lf1',UValue = 'PlotLine_Fund_1')
  pfin   = widget_button(pfundlin,value='- - -',uname='GM_lf2',UValue = 'PlotLine_Fund_2')
  pfin   = widget_button(pfundlin,value='-.-.-',uname='GM_lf3',UValue = 'PlotLine_Fund_3')
  pfin   = widget_button(pfundlin,value='-...-',uname='GM_lf4',UValue = 'PlotLine_Fund_4')
  pfin   = widget_button(pfundlin,value='long dash',uname='GM_lf5',UValue = 'PlotLine_Fund_5')

GOver_PMenu  = widget_base(self.pDraw,/CONTEXT_MENU,UNAME='Over_Menu')  ;CONTEXT MENU
  povercol   = widget_button(GOver_PMenu,value='Overtones Color',uname='GM_po',UValue = 'PlotColor_Over')
  poverthk   = widget_button(GOver_PMenu,value='Line Thickness',uname='GM_ol',UValue = 'PlotThick_Over')
  poverlin   = widget_button(GOver_PMenu,value='Overtones Linestyle',uname='GM_lf',UValue = 'PlotLine_Over',/menu)
  poin   = widget_button(poverlin,value='solid ',uname='GM_lo0',UValue = 'PlotLine_Over_0')
  poin   = widget_button(poverlin,value='.....',uname='GM_lo1',UValue = 'PlotLine_Over_1')
  poin   = widget_button(poverlin,value='- - -',uname='GM_lo2',UValue = 'PlotLine_Over_2')
  poin   = widget_button(poverlin,value='-.-.-',uname='GM_lo3',UValue = 'PlotLine_Over_3')
  poin   = widget_button(poverlin,value='-...-',uname='GM_lo4',UValue = 'PlotLine_Over_4')
  poin   = widget_button(poverlin,value='long dash',uname='GM_lo5',UValue = 'PlotLine_Over_5')



GAxis_PMenu  = widget_base(self.pDraw,/CONTEXT_MENU,UNAME='Axis_Menu')  ;CONTEXT MENU
  paxiscol   = widget_button(GAxis_PMenu,value='Axes Colors',uname='GM_ax',UValue = 'PlotColor_Axes')
GLabels_PMenu  = widget_base(self.pDraw,/CONTEXT_MENU,UNAME='Label_Menu')  ;CONTEXT MENU
  plabcol   = widget_button(GLabels_PMenu,value='Label Colors',uname='GM_lab',UValue = 'PlotColor_Labels')
GTitle_PMenu  = widget_base(self.pDraw,/CONTEXT_MENU,UNAME='Title_Menu')  ;CONTEXT MENU
  ptitlecol   = widget_button(GTitle_PMenu,value='Title Colors',uname='GM_title',UValue = 'PlotColor_Title')


void = widget_button(self.tlb,value = 'A N I M A T E',uname='DO_VIBS',$
        uvalue = 'DO_VIBS');{object:self,method:'DO_VIBS'})
;status_id = widget_text(self.tlb,value = '',uname = 'STATUS_TEXT')

;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
;fill in the PLOT tab
plot_base = widget_base(fTab,/row,title='PLOT',uname = 'PLOT_BASE',frame=0)
VIB_base=widget_base(plot_base,/column,uname = 'VIB_BASE',frame=0,/CONTEXT_EVENTS)
;create an info window
mode_base=widget_base(plot_base,/col,uname = 'MODE_BASE',frame=1)
mode_label=widget_label(mode_base,value='Modes cm-1')
mode_list=widget_list(mode_base,value=*self.freqlist_ptr,scr_ysize=70,scr_xsize=70,UNAME='MODE_LIST',$
      uvalue='Choose_Mode')
;create an object window
self.wDraw = Widget_Draw(VIB_BASE, $
    XSize = xsize, YSize = YSize, $
    /Button_Events, /Motion_Events, /Expose_Events, $
    Retain = 0, Renderer = Renderer, Graphics_Level = 2, $
    UName = 'draw', UValue = 'DrawWindow')

General_Menu  = widget_base(self.wDraw,/CONTEXT_MENU,UNAME='General_Menu')  ;CONTEXT MENU
  butbg   = widget_button(General_Menu,value='Background',uname='GM_bg',UValue = 'Color_Color'); ,/menu)
  DragQualGMMenu = Widget_Button(General_Menu,Value = 'Drag Quality', /Menu,UName =  'DragQualMenu')
  wDragQualGMLow = Widget_Button(DragQualGMMenu, $
    UName = 'Low', Value = 'Low', $
    UValue = 'Drag_0')
  wDragQualGMMedium = Widget_Button(DragQualGMMenu, $
    UName =  'Medium', Value='Medium', $
    UValue = 'Drag_1')
  wDragQualGMHigh = Widget_Button(DragQualGMMenu, $
    UName =  'High', Value = 'High', $
    UValue = 'Drag_2')
  ShowVectorGMMenu = Widget_Button(General_Menu,Value = 'Show Eigenvectors',UName='GM_showvector',uvalue='Vector_Show',sensitive=0)
  ToDefaltsGMMenu = Widget_Button(General_Menu,Value = 'Reset to Defaults',UName='GM_ResetDefaults',uvalue='Defaults_Do')
Vector_Menu  = widget_base(self.wDraw,/CONTEXT_MENU,UNAME='Vector_Menu')   ;CONTEXT MENU
  colvec   = widget_button(Vector_Menu,value='Change Color',uname='VM_col',uvalue='Vector_Color')
  hidevec   = widget_button(Vector_Menu,value='Hide Vectors',uname='VM_hide',uvalue='Vector_Hide')
  lengthvec   = widget_button(Vector_Menu,value='Size Vectors',uname='VM_Size',/menu);uvalue='Vector_Size')
       wLengthGMSmall = Widget_Button(lengthvec, $
         UName = 'VectorSmall', Value = 'Small', $
         UValue = 'Vector_SizeSmall')
       wLengthGMedium = Widget_Button(lengthvec, $
         UName =  'VectorMed', Value='Medium', $
         UValue = 'Vector_SizeMed')
       wLengthGMlong = Widget_Button(lengthvec, $
         UName =  'VectorLong', Value = 'Long', $
         UValue = 'Vector_SizeLong')

Bond_Menu  = widget_base(self.wDraw,/CONTEXT_MENU,UNAME='Bond_Menu')   ;CONTEXT MENU
  diabond   = widget_button(Bond_Menu,value='Change Diameter',uname='BM_dia',uvalue='Bond_Dia')
  colbond   = widget_button(Bond_Menu,value='Change Color',uname='BM_col',uvalue='Bond_Color')
  alphabond   = widget_button(Bond_Menu,value='Change Opacity',uname='BM_alpha',uvalue='Bond_Alpha')
  qualitybond   = widget_button(Bond_Menu,value='Change quality',uname='BM_quality',/menu); ,uvalue='Bond_Quality1')
       wLowGMQual = Widget_Button(qualitybond, $
         UName = 'Bond_QualityLow', Value = 'Low', $
         UValue = 'Bond_QualityLow')
       wMedGQual = Widget_Button(qualitybond, $
         UName =  'Bond_QualityLow', Value='Medium', $
         UValue = 'Bond_QualityMed')
       wHighGMQual = Widget_Button(qualitybond, $
         UName =  'Bond_QualityLow', Value = 'High', $
         UValue = 'Bond_QualityHigh')


Atom_Menu  = widget_base(self.wDraw,/CONTEXT_MENU,UNAME='Atom_Menu')   ;CONTEXT MENU
  thisatom   = widget_button(Atom_Menu,value='This Atom',uname='BM_thisatom',/menu)
  elatom     = widget_button(Atom_Menu,value='This Element',uname='BM_thisatom',/menu)
  allatom   = widget_button(Atom_Menu,value='All Atoms',uname='BM_allatom',/menu)
    atomradius   = widget_button(thisatom,value='Radius Factor',uname='BM_adia',uvalue='Atom_Dia_This')
    colatom   = widget_button(thisatom,value='Change Color',uname='BM_acol',uvalue='Atom_Color_This')
    alphaatom   = widget_button(thisatom,value='Change Opacity',uname='BM_aalpha',uvalue='Atom_Alpha_This')
    elradius   = widget_button(elatom,value='Radius Factor',uname='BM_edia',uvalue='Atom_Dia_Element')
    colel   = widget_button(elatom,value='Change Color',uname='BM_ecol',uvalue='Atom_Color_Element')
    alphael   = widget_button(elatom,value='Change Opacity',uname='BM_ealpha',uvalue='Atom_Alpha_Element')

    tatomradius   = widget_button(allatom,value='Radius Factor',uname='BM_adia',uvalue='Atom_Dia_All')
    tcolatom   = widget_button(allatom,value='Change Color',uname='BM_acol',uvalue='Atom_Color_All')
    talphaatom   = widget_button(allatom,value='Change Opacity',uname='BM_aalpha',uvalue='Atom_Alpha_All')
    tqualityatom   = widget_button(allatom,value='Change quality',uname='BM_aquality',/menu); ,uvalue='Bond_Quality1')
       wtLowGMQuala = Widget_Button(tqualityatom, $
         UName = 'Atom_QualityLow', Value = 'Low', $
         UValue = 'Atom_QualityLow_All')
       wtMedGQuala = Widget_Button(tqualityatom, $
         UName =  'Atom_QualityLow', Value='Medium', $
         UValue = 'Atom_QualityMed_All')
       wtHighGMQuala = Widget_Button(tqualityatom, $
         UName =  'Atom_QualityLow', Value = 'High', $
         UValue = 'Atom_QualityHigh_All')

;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx  finished widget creation
centertlb,self.tlb


widget_control,self.tlb,/realize
geomode=widget_info(mode_base,/geometry)
geomodelab=widget_info(mode_label,/geometry)
widget_control,mode_list,scr_ysize=($
  geomode.scr_ysize-geomodelab.scr_ysize-2*geomode.yoffset-2*geomodelab.yoffset-2*geomode.margin-2*geomodelab.margin)
Widget_Control, self.TLB, TLB_Get_Size = TLBSize
self.NonDrawDimensions = [TLBSize[0] - XSize, TLBSize[1] - YSize]

widget_control,self.tlb,set_uvalue = self,Kill_Notify = 'G3DVIEW_kill_notify'
register_name = 'G3DVIEW'

xmanager,register_name,self.tlb,event_handler = 'g3dview_events', $
   /no_block
return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
function g3dview::init,  group_leader = group_leader,     $
                              work_dir = work_dir,             $
                              data_dir = data_dir,             $
                              notifyId = notifyId,             $
                              Stationary = Stationary,         $
                              Scale = Scale,                   $   ; IN: (opt) Scale size of initial view.
                              DrawWidgetID = DrawWidgetID,     $
                              No_Rotate = No_Rotate,           $
                              Renderer = Renderer,             $
                              Vector = Vector



registerName = 'G3DVIEW'
if xregistered(registerName) then begin ;only allow one g3dview running
   FORWARD_FUNCTION LookupManagedWidget
   id = LookupManagedWidget(registername)
   widget_control,id,iconify=0
   return,0
endif

self.oTopLevelContainer = Obj_New('IDL_Container')
Widget_Control, /Hourglass
;oTestSurface = Obj_New()
;self.oTopLevelContainer->Add, oTestSurface


self.notifyIdPtr = ptr_new(/allocate_heap)
self.pgroup_leader = ptr_new(/allocate_heap)
if n_elements(notifyId) ne 0 then $
  *self.notifyIdPtr = notifyId
if n_elements(group_leader) ne 0 then begin
  *self.pgroup_leader = group_leader
  widget_control,group_leader,get_uvalue = statePtr
  self.daveptr=(*stateptr).daveptr
endif else begin
   self.daveptr = ptr_new(/allocate_heap)
endelse

if n_elements(work_dir) eq 0 then cd,current = work_dir
if n_elements(data_dir) eq 0 then cd,current = data_dir
if n_elements(data_dir) ne 0 then self.data_dir=data_dir
if n_elements(work_dir) ne 0 then self.work_dir=work_dir

self.freqlist_ptr=ptr_new('')
self.work_dir = work_dir
self.data_dir = data_dir
self.tlb = 0L
self.Bitmap_Subdir=['','']

self.stopvib=0
self.bondfactor=0.4
SELF.BONDFACETS=200
self.bondradius=0.1
self.vdwfactor=0.2
self.shininess=128
self.vibmode=0
self.bondcolor=[255,215,0]
self.vectorcolor=[255,0,0]
self.vectorscale=4.
self.bondalpha=1.0

self.scalefactor=1000.0            ;the 'calculated' intensity scalefactor
self.oversf=10.0                 ; scalefactor for overtones and comb.
self.Freqfactor=1.0              ;the 'calculated' freq scalefactor
self.flatbg=0.0                 ;background to be added
self.linearbg=0.0                 ;and a linear scaling with E
self.DWF=0.02                   ;debye-waller factor

;default values for [ticklength,symsize,thick,shading,coltable,xsize,ysize,legend gap]
self.default = [0.02,0.1,1.0,0.0,13.0,500,400,0.2]
ret = self->build_gui(No_Rotate = No_Rotate, Renderer = Renderer)
      ToolbarBase = Widget_Info(self.TLB, Find_by_UName ='ToolbarBase')
      Sibling  = Widget_Info(ToolbarBase, /Child)
      Repeat Begin
         UName = Widget_Info(Sibling, /UName)
         if UName ne 'label' then widget_control,sibling,sensitive=0
         Sibling = Widget_Info(Sibling, /Sibling)
       EndRep Until (not Widget_Info(Sibling, /Valid_ID))
       ;menus
       menu1=Widget_Info(self.TLB, Find_by_UName ='Export VRML')
       widget_control,menu1,sensitive=0
       menu2=Widget_Info(self.TLB, Find_by_UName ='Export FRAMES')
       widget_control,menu2,sensitive=0
       menu3=Widget_Info(self.TLB, Find_by_UName ='ViewMenu')
       widget_control,menu3,sensitive=0
       menu4=Widget_Info(self.TLB, Find_by_UName ='DO_VIBS')
       widget_control,menu4,sensitive=0
       menu5=Widget_Info(self.TLB, Find_by_UName ='Save Dave')
       widget_control,menu5,sensitive=1
       menu6=Widget_Info(self.TLB, Find_by_UName ='Save Ascii')
       widget_control,menu5,sensitive=1

geo=widget_info(self.tlb,/geometry)
self.TLBDimensions=[geo.xsize,geo.ysize]

self.color_ptr = ptr_new(/allocate_heap)
self.actual_atom_color_ptr = ptr_new(/allocate_heap)
self.default_atom_color_ptr = ptr_new(/allocate_heap)
self.bondsptr = ptr_new(/allocate_heap)

ret = self->init_colors()

Widget_Control, self.wDraw, Get_Value = o3DWindow
self.o3DWindow = o3DWindow
Widget_Control, self.pDraw, Get_Value = o2DWindow
self.o2DWindow = o2DWindow


self.Vector = Keyword_Set(Vector)
self.Scale = N_elements(Scale) eq 0 ? 0 : Scale     ; Factor applied to size view(s).
self->Build_Scene, Stationary = Stationary
self->Set_Cursor_Mode, Keyword_Set(No_Rotate) ? 'scale' : 'rotate'
self->Update_DragQual_Menu, 1
self->build_plot


return,1
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro g3dview__define
class =  {  G3dview,                 $
            tlb:0L,                             $   ; my top level base
            TLBDimensions:fltarr(2),            $   ; initial size
            oTopLevelContainer : Obj_New(),     $
            notifyIdPtr:ptr_new(),              $   ; incase I need to tell DAVE what is happening
            pgroup_leader:ptr_new(),            $   ; calling program ID
            lastselected : '',                  $
            Vector  : 0B,                       $
            data_dir:'',                        $
            work_dir:'',                        $
            daveptr:ptr_new(),                  $   ; the DAVE POINTER from calling program is available
            Bitmap_Subdir:['',''],              $
            do_destroy_view: 0B,                $
            oCurrentView: Obj_New(),            $
            o3DWindow: Obj_New(),               $
            ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
            o2DWindow: Obj_New(),                $
            oTopLevelPlotCont : Obj_New(),       $
            myplot: obj_new(),                   $
            dataplot: obj_new(),                 $
            overplot: obj_new(),                 $
            fundplot: obj_new(),                 $
            myxAxis: obj_new(),                  $   ;x axis
            myyAxis: obj_new(),                  $   ;y axis
            drawPlotView:Obj_New(),              $
            drawPlotModel : obj_new(),           $
            font: objarr(2),                     $
            symbol:obj_new(),                    $
            xtext:obj_new(),                     $
            ytext:obj_new(),                     $
            title:     obj_new(),                $   ;title
            xran:           [0,0],               $   ;xrange for the axis
            yran:           [0,0],               $   ;yrange
            xdatarange:[0,0],                    $   ;xrange for the data
            ydatarange:[0,0],                    $   ;xrange for the data
            totalthick:1.0,                      $   ;oplot thickness
            fundthick:1.0,                       $
            overthick:1.0,                       $
            thebox:obj_new(),                    $    ; Zoom box
            xs:0, $                              ; X static corner of the zoom box.
            ys:0, $                              ; Y static corner of the zoom box.
            xd:0, $                              ; X dynamic corner of the zoom box.
            yd:0, $                              ; Y dynamic corner of the zoom box.

     ;default values for [ticklength,symsize,thick,shading,coltable,xsize,ysize,legend gap]
            default : [0.02,0.1,1.0,0.0,13.0,500,400,0.2], $
            ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
            oScene: Obj_New(),                  $  ; The 3D view
            NonDrawDimensions : LonArr(2),      $
            dragq: 0,                           $
            scale: 0,                           $  ; Factor applied to size view(s).
            mode: '',                           $  ; 'scale', 'translate'...
            omodel:Obj_New(),                   $
            wDraw: 0L,                          $  ; 3D objects
            pDraw: 0L,                          $  ; 2D plotting
            color_ptr:ptr_new(),                $  ;  named color list
            actual_atom_color_ptr:ptr_new(),    $  ;  used to decide coloring
            default_atom_color_ptr:ptr_new(),   $  ;  default coloring
            bondfactor:0.4,                     $  ; in addition of covalent radius
            BONDFACETS:200,                     $  ; render quality of bonds
            bondradius:0.1,                     $  ; bond radius
            vdwfactor:0.2,                      $  ; ball size multiplier
            shininess:128,                      $  ; shiny things
            bondcolor:[255,215,0],              $  ; bond color
            bondalpha:1.0,                      $  ; alpha
            vectorcolor:[255,0,0],              $  ; vector color
            vectorscale:4.,                     $  ; vector length
            vibmode:0,                          $  ;index of freqptr to draw
            stopvib:0,                          $  ;flag to stop animation
            ;GAUSSIAN DATA
            gauss:Obj_New(),                    $ ; Gaussian Data Object
            scalefactor:1000.0,                 $ ;the 'calculated' intensity scalefactor
            oversf:100.0,                       $ ; scalefactor for overtones and comb.
            Freqfactor:1.0,                     $ ;the 'calculated' freq scalefactor
            flatbg:0.0,                         $ ;background to be added
            linearbg:0.0,                       $ ;and a linear scaling with E
            DWF:0.02,                           $ ;debye-waller factor
            bondsptr:ptr_new(),                 $ ;keep a list of who is bonded where.
            freqlist_ptr:ptr_new()              $ ; list widget values
         }
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
