pro Spurion2_event,event
    ;print,event.id
    widget_control,event.id,get_uvalue=obj
    obj->event,event
end;Spurion2_event
pro Spurion2::event,event

    case event.id of
    self.quit:begin
        widget_control,self.tlb,/destroy
    end;quit
    self.scanparms:begin
        etype = tag_names(event,/structure_name)
        case etype of
        'WIDGET_TAB':begin
            ;DO NOTHING WHEN USER SWITCHES TABS
        end;
        else:begin
            ret = self->calculateQPlot()
            if ret gt 0 then begin
                self->draw
            endif
        end
        endcase
    end;scanparms
    self.qcheckbox:begin
        ;print,'qcheckbox'
        widget_control,self.qcheckbox,get_value=val
        checked = val->getchecked()
        ;print,checked[0]
        obj = self.qplotobj->get(/all)
        for i = 0,n_elements(obj)-1 do begin
            obj[i]->getproperty,id=id
            if obj_isa(obj[i],'spurion_scanqpoint_data') gt 0 then $
                                    obj[i]->setcheckboxproperties,checked
            if obj_isa(obj[i],'spurion_2dlattice_data') gt 0 then $
                                    obj[i]->setcheckboxproperties,checked[8]

;;;            ;ADD THIS
;;;            ;071306
;;;            if obj_isa(obj[i],'spurion2_2dlattice_data') gt 0 then $
;;;                                    obj[i]->setcheckboxproperties,checked[8]


;            print,'YES'
;            print,'ID=',id
        endfor;i
        self.qplotobj->draw
    end;qcheckbox
    self.scancheckbox:begin
        print,'scancheckbox'
    end;scancheckbox
    self.echeckbox:begin
        print,'echeckbox'
    end;echeckbox
    else:begin
        ;print,'Spurion2::event'
    end;else
    endcase

end;event

pro Spurion2::draw
    self.qplotobj->defaultdraw  ;defaultDraw PROVIDES RESCALING BASED ON NEW DATA
    self.eplotobj->draw         ;draw DOES NOT RESCALE ON NEW DATA
    self.scanplotobj->draw
end;draw

function Spurion2::calculateQplot

    self->clearQPlot


    nobj     = self->calculateScanPoint()
    ret_lat = self->calculateLatticePoint()
    self->updateQPlot,nobj

    return,nobj*ret_lat
end;calculateQplot



pro Spurion2::clearQPlot
        qdata = self.qplotobj->get(/all)
        self.qplotobj->remove,/all
        if obj_valid(qdata[0]) then obj_destroy,qdata
end;clearQPlot
function Spurion2::calculateLatticePoint

    nobj = self.latticepointcalculator->create2dLattice()

    return,nobj
end;calculateLatticePoint
function Spurion2::calculateScanPoint

    ;EXAMINE CHECKBOXES FOR SHOWQ --- CHANGES TO THE CHECKBOXES SHOULD BE REGISTERED WITH THE
    ;                                 SPURION2 IN THE MVC (MODEL-VIEW-CONTROLLER) SETUP.
    ;                                 TO FACILITATE LATER MAINTENANCE AND UPGRADES.
    widget_control,self.qcheckbox,get_value=val
    checked = val->getchecked()
    showq = checked[0]

    nobj = self.scanpointscalculator->createScan(self.scanparmsobj,self.latparmsobj,showq=showq)

    return,nobj
end;Spurion2_calculateScanPoint

pro Spurion2::updateQPlot,nobj
        ;ADD THE QPLOT OBJECTS TO THE QPLOT AND REDRAW WITH RESCALING.
        widget_control,self.qcheckbox,get_value=val
        checked = val->getchecked()

        if nobj gt 0 then begin
            scan  = self.scanpointscalculator->get(/all)
            lat2d = self.latticepointcalculator->get(/all)
            for i=0,n_elements(scan)-1 do begin
                if obj_valid(scan[i]) gt 0 then begin
                    self.qplotobj->add,scan[i]
                    scan[i]->setcheckboxproperties,checked
                endif
            endfor;i
            for i=0,n_elements(lat2d)-1 do begin
                if obj_valid(lat2d[i]) gt 0 then begin
                    self.qplotobj->add,lat2d[i]
                    lat2d[i]->setcheckboxproperties,checked[8]
                endif
            endfor;i
        endif
        self.qplotobj->defaultDraw
end;updateQPlot
pro Spurion2::updateEPlot,nobj

end;updateEPlot

function Spurion2::EtoLambda,E

    h = 6.6262e-34 ;J.s
    m = 1.6747e-27 ;kg  neutron mass

    h2_2m = 2.07263484 ;mev.Å^2 (IS THIS NUMBER CORRECT????)

    return,sqrt(h2_2m/E)    ;LAMBDA IN Å

end;EtoLambda
function Spurion2::LambdaToE,lambda

    h = 6.6262e-34 ;J.s
    m = 1.6747e-27 ;kg  neutron mass

    h2_2m = 2.07263484 ;mev.Å^2 (IS THIS NUMBER CORRECT????)

    return,h2_2m*(2.0*!PI/lambda)^2.0    ;E in meV GIVEN lambda IN Å
                                         ;=(h^2k^2/2m)

end;LambdaToE

pro Spurion2::bufReader

    fn = dialog_pickfile(path = self.workdir,filter='*.buf')

    if fn ne '' then begin
        self.workdir = file_dirname(fn)

        lines = file_lines(fn)

        s = strarr(lines)

        openr,lun,fn,/get_lun
        readf,lun,s
        free_lun,lun


        comment = s[0]
        lattice = s[1]
        energy  = s[2]
        space   = s[3] ;??????
        orient  = s[4]
        tempH   = s[5]
        time    = s[6]


        ;GET abc,aabbcc
        segs = strsplit(s[1],' :',/extract) ;USE space AND : AS SEPARATORS.
        a  = double(segs[2])
        b  = double(segs[4])
        c  = double(segs[6])
        aa = double(segs[8])
        bb = double(segs[10])
        cc = double(segs[12])

        print,'a,b,c,aa,bb,cc:'
        print,a,b,c,aa,bb,cc
        lat = obj_new('lattice',a,b,c,aa,bb,cc)

        obj_destroy,lat

        ;GET ENERGY
        segs = strsplit(s[2],'= :',/extract)
        EC = double(segs[2])
        ES = double(segs[4])
        FE = double(segs[6])
        dm = double(segs[9])
        da = double(segs[11])

        print,'EC,ES,FE,dm,da'
        print,EC,ES,FE,dm,da

        ;GET SPACE

        ;GET ORIENTATION VECTORS
        segs = strsplit(s[4],', :',/extract)

        orient1 = double([segs[4], segs[5], segs[6]])
        orient2 = double([segs[12],segs[13],segs[14]])

        print,'[orient1],[orient2]'
        print,'['+string(orient1,format='(g10.5,g10.5,g10.5)')+ $
            '],['+string(orient2,format='(g10.5,g10.5,g10.5)')+']'



;USING THIS INFORMATION I CAN MAKE ASSUMPTIONS ABOUT THE UNIT CELL
;AND PRODUCE A 2D LATTICE


;Qbuffer No:  3   Comment: EuMnP  Xtal
;Lattice:  a: 4.1100  b: 4.1100  c: 6.9742  aa: 90.000  bb: 90.000  cc:120.000
;Energy:  EC: 0.0000 ES: 0.0000 FE: 34.493 (ANA)  dM= 1.2780   dA= 3.3542
;Space:   HC: 1.0000 KC: 1.0000 LC: 0.0000  HS: 0.0000  KS: 0.0000  LS: 0.0000
;Orient:  (h k l): 1, 1, 0  Angl:  0.000    (h k l)': 0, 0, 1
;Temp/H:  T0:1.2000  Inc-T.00000  Wait:  0  Err:.50  Hld0:  0  Hld:  0  Field
;Time:    Monit: 110000  Prefac:  1  M-typ:TIME  #pts:   1   AMON    POLA FKEY
;



    endif



end;bufReader


pro Spurion2::updateScanPlot,nobj

;    fn = dialog_pickfile(path='\\Charlotte\ICP Data\bt7\200605\bt7',filter='*.bt*')
    fn = dialog_pickfile(filter='*.bt*')



    print,fn

    if fn ne '' then begin
        line  = ''
        lines = file_lines(fn)

        print,'Spurion2::updateScanPlot'
 ;       print,'lines=',lines
        s = strarr(lines)
        openr,lun,fn,/get_lun
        readf,lun,s
        free_lun,lun


        ;GET MOTORS
        wh=where(stregex(s,'#Columns',/fold_case,/boolean) gt 0,count)
        if count gt 0 then begin
            line = s[wh]
            segs = strsplit(line,/extract)
            ;print,n_elements(segs)
            motors = segs[1:*]
            ;print,motors
        endif

        wh=where(stregex(s,'#ncolumns',/fold_case,/boolean) gt 0,count)
        if count gt 0 then begin
            line = s[wh]
            segs = strsplit(line,/extract)
            ;print,segs[1]
        endif

        for i=0,lines-1 do begin
            segs = strsplit(s[i],/extract)
            ;print,i,n_elements(segs)
        endfor;i
        ;print,lines


        ;GET ACTUAL NUMBER OF POINTS COLLECTED
        wh = where(stregex(s,'#',/fold_case,/boolean) gt 0,count)
        if count ne 0 then npts = lines - n_elements(wh)
        print,npts

        ;GET NOMINAL NUMBER OF POINTS COLLECTED
        wh = where(stregex(s,'#npoints',/fold_case,/boolean) gt 0,count)
        if count ne 0 then npoints = s[wh]
        print,npoints

        segs = strsplit(s[wh],/extract)
        npoints = fix(segs[1])
        if npoints eq npts then print,'SCAN COMPLETE' else print,'SCAN INCOMPLETE'


;NEED ARRAY OF STRUCTURES FOR THE DATA POINTS.

        wh = where(stregex(s,'#',/fold_case,/boolean) eq 0,count)

        if count gt 0 then begin

            ;CREATE A DATA STRUCTURE
            struct = create_struct('filename',file_basename(fn),'npts',npts,'motors',motors,'data',ptrarr(n_elements(motors)))
            for i=0,n_elements(motors)-1 do begin
                struct.data[i] = ptr_new(dblarr(npts))
            endfor;i
;            print,n_elements(wh)
;            print,npts
            for i=0,npts-1 do begin
                segs = strsplit(s[wh[i]],/extract)
                ;print,segs
                for j=0,n_elements(motors)-1 do begin

                    ;print,'segs['+string(j)+']=',segs[j]
                    if strcmp(segs[j],'N/A') eq 1 then $
                                    temp = double('NaN') else $
                                    temp = double(segs[j])
                    (*(struct.data[j]))[i] = temp
                endfor;j
            endfor;i
        endif


        newstruct = create_struct('motor','','data',dblarr(n_elements(struct.motors)))
        tablestruct = replicate(newstruct,n_elements(struct.motors))
;        tablestruct = ptrarr(n_elements(struct.motors))
        for i=0,n_elements(tablestruct)-1 do begin
            tablestruct[i].motor = struct.motors[i]
            tablestruct[i].data = *(struct.data[i])
        endfor;i



;        ;OUTPUT
;        print,struct.filename
;        print,struct.npts
;        for i=0,n_elements(motors)-1 do begin
;            print,struct.motors[i]
;            print,*(struct.data[i])
;        endfor;i



        svalue = strarr(npts+1)
        print,n_elements(value)
        nmotors = n_elements(struct.motors)

        motors = ''
        sdata = strarr(npts)
        for i=0,nmotors-1 do begin
            len = strlen(struct.motors[i])
            name = struct.motors[i]
            for ll=0,10-len do name = '_'+name
            ;motors += string(strtrim(string(struct.motors[i]),2),format='(a10)') + '|'
            motors += name + '|'
        endfor;i
        for j=0,npts-1 do begin
            for i=0,nmotors-1 do begin
                sdata[j] = sdata[j] + string(strtrim(string((*(struct.data[i]))[j]),2),format='(a10)') + '|'
            endfor;i
        endfor;j
        svalue[0]   = motors
        svalue[1:*] = sdata


        b = widget_base(xoffset=200,yoffset=200,title=file_basename(fn))
        ;l = widget_list(b,value=svalue,xsize = 80,ysize = 10,font='San Serif')

        value=dblarr(nmotors,npts)
        for i=0,nmotors-1 do begin
            value[i,*] = *(struct.data[i])
        endfor;i
        ;fc = [[255,0,0],[0,255,0],[0,0,255],[255,255,0],[255,0,255],[0,255,255]]

        fc = intarr(3,nmotors)
        fc[2,*] = fix(255*randomu(seed,nmotors))
        fc[1,*] = fix(255*randomu(seed,nmotors))
        fc[0,*] = fix(255*randomu(seed,nmotors))
        t = widget_table(b,column_labels=struct.motors,value=value,scr_xsize=600,$
                            foreground_color=fc)


        widget_control,b,/realize

        b2 = widget_base(xoffset=300,yoffset=300,title=file_basename(fn))
        comboy = widget_combobox(b2,xoffset=5,yoffset = 150,value=struct.motors)
        combox = widget_combobox(b2,xoffset=150,yoffset = 320,value=struct.motors)
        draw = widget_draw(b2,xoffset=100,yoffset=0,xsize=300,ysize=300)
        widget_control,b2,/realize
        widget_control,draw,get_value=winvis
        wset,winvis
        detindex = where(strcmp(struct.motors,'Detector') eq 1)
        monindex = where(strcmp(struct.motors,'Monitor') eq 1)
        print,detindex,monindex
        setcirclesymbol
;        plot,*(struct.data[8]),(*(struct.data[detindex[0]]))/(*(struct.data[monindex[0]]))
        plot,*(struct.data[8]),(*(struct.data[monindex[0]])),psym=8


    endif;fn ne ''




end;updateScanPlot



pro Spurion2_cleanup,id
    widget_control,id,get_uvalue=obj
    obj_destroy,obj
end;Spurion2_cleanup

pro Spurion2::cleanup
    print,'Spurion2::cleanup'

    if obj_valid(self.qplotobj) then obj_destroy,self.qplotobj

    if obj_valid(self.eplotobj) then obj_destroy,self.eplotobj

    if obj_valid(self.scanplotobj) then obj_destroy,self.scanplotobj

    o = self.scancontainer->get(/all)
    if obj_valid(o[0]) gt 0 then obj_destroy,o

    o = self.crystalcontainer->get(/all)
    if obj_valid(o[0]) gt 0 then obj_destroy,o


    if obj_valid(self.scanpointscalculator) then obj_destroy,self.scanpointscalculator
    if obj_valid(self.lattice) then obj_destroy,self.lattice
    if obj_valid(self.rescalculator) then obj_destroy,self.rescalculator

    if obj_valid(self.scanContainer) then obj_destroy,self.scanContainer
    if obj_valid(self.crystalContainer) then obj_destroy,self.crystalContainer

    if obj_valid(self.scanParmsObj) then obj_destroy,self.scanParmsObj

    if obj_valid(self.latparmsObj) then obj_destroy,self.latparmsObj

    if obj_valid(self.qcheckBoxObj) then obj_destroy,self.qcheckBoxObj
    if obj_valid(self.scancheckBoxObj) then obj_destroy,self.scancheckBoxObj
    if obj_valid(self.echeckBoxObj) then obj_destroy,self.echeckBoxObj

end;cleanup
function Spurion2::init


    self.tlb =  widget_base(xoffset=100,yoffset=100,/row,$
                            title='Spurion2: Your Roadmap to Reciprocal Space!',$
                            uname='SPURION2',mbar=bar,uvalue=self)


    ;MENU BAR
    filemenu = widget_button(bar,value='File',/menu,uvalue=self)
    self.open = widget_button(filemenu,value='Open',uname='SPURION2OPEN',uvalue=self)
    self.save = widget_button(filemenu,value='Save',uname='SPURION2SAVE',uvalue=self)
    self.quit = widget_button(filemenu,value='Quit',uname='SPURION2QUIT',uvalue=self)


    ;CONTROLS
    controlbase = widget_base(self.tlb,/col,uvalue=self)
    tab = widget_tab(controlbase,uvalue=self)
    scanparmsbase = widget_base(tab,title='ScanParms')
    self.scanparms    = cwo_scanparms(scanparmsbase,obj=scanparmsobj,uvalue=self)
    self.scanparmsobj = scanparmsobj

    latparmsbase = widget_base(tab,title='LatParms')
    self.latparms     = cwo_latparms(latparmsbase,/col,obj=latparmsobj,uvalue=self)
    self.latparmsobj = latparmsobj

    checkboxbase = widget_base(tab,title='Checkboxes',/col)
    self.qcheckbox = cwo_lk_multicheckbox(checkboxbase,obj=qcheckboxobj,$
                                         label=['Q Vec','Ki','Kf','Cut','Proj','Ellipse',$
                                                'Symbol','Al Spheres','Recip. Lat.'],$
                                         xsize=200,uvalue=self,uname='QPLOTCHECKBOXES')
    self.qcheckboxobj = qcheckboxobj
    self.qcheckboxobj->setChecked,[1,0,0,1,1,1,1,0,1]

    self.scancheckbox = cwo_lk_multicheckbox(checkboxbase,obj=scancheckboxobj,$
                                         label=['Data','Harmonics','Energy','Bragg Peak'],$
                                         xsize=200,uvalue=self,uname='SCANPLOTCHECKBOXES')
    self.scancheckboxobj = scancheckboxobj

    self.echeckbox = cwo_lk_multicheckbox(checkboxbase,obj=echeckboxobj,$
                                         label=['E transfer','Spurion Energy'],$
                                         xsize=200,uvalue=self,uname='EPLOTCHECKBOXES')
    self.echeckboxobj = echeckboxobj

    ;PLOTS
    qplotbase = widget_base(self.tlb,/col)
    self.qplot = cwo_drawplot(qplotbase,title='QPLOT',xtitle='U',ytitle='V',$
                                        xsize=400,ysize=400,$
                                        uvalue=self,obj=qplotobj)
    self.qplotobj = qplotobj


;GET THE showQ value
widget_control,self.qcheckbox,get_value=val
showq = (val->getchecked())[0]

    self.scanpointscalculator = obj_new('scanpoints',scanparmsobj,latparmsobj,showq=showq)

;UPDATE THE DIAGRAMS!!!!
    scanvals = scanparmsobj->get_values()
    latvals = latparmsobj->get_values()

    self.latticepointcalculator = obj_new('latticepoints',$
                                                o1=latvals.orient1,$
                                                o2=latvals.orient2)


    ret = self->calculateScanPoint()    ;ADDS DATA TO QPLOT


    ret = self->calculateLatticePoint() ;ADD 2d LATTICE TO QPLOT




;IS THERE A NEED FOR rescalculator IN Spurion2?
;SHOULD LATTICE AND RESCALCULATOR EXIST ONLY IN scanpoints OBJECT?
;


    lattice = obj_new('lattice',latvals.a,latvals.b,latvals.c,latvals.alpha,latvals.beta,latvals.gamma)



;NOTE:
;Rescal2_calculator GIVES rmtransformed NOW!!!
    rescalculator = obj_new('Rescal2_calculator',$
                                   lattice,$;a, b, c, alpha, beta, gamma,$           ;LATTICE PARAMETERS
                                   scanvals.horizontal,scanvals.collimatorh,scanvals.collimatorv,$    ;RESOLUTION PARAMETERS
                                   scanvals.mosaic,scanvals.dspacing,scanvals.instrument_orient,$
                                   scanvals.qetrans)

    rescalculator->calculate,rm,r0, horizontal=scanvals.horizontal,$
                                    collimatorh=scanvals.collimatorh,$
                                    collimatorv=scanvals.collimatorv,$
                                    mosaic=scanvals.mosaic,$
                                    dspacing=scanvals.dspacing,$
                                    instrument_orient=scanvals.instrument_orient,$
                                    qetrans=scanvals.qetrans,$
                                    lattice=lattice,closed=closed


;;;;;
;;;;;            rmtransformed=lattice->rtransform(latvals.orient1,latvals.orient2,$
;;;;;                                                             scanvals.qetrans,rm)
;;;;;
;;;;;
;;;;;            ;SET rm TO rmtransformed FOR THE DATA OBJECTS
;;;;;            rm = rmtransformed
;;;;;
;;;;;
;;;;;            ;SET UP DUMMY DATA FOR PLOTS
;;;;;            x = [0] & y = [0] & sy = [0]
;;;;;
;;;;;        ;    xydata = obj_new('rescut_data',x,y,sy,legend='XY',$
;;;;;            qdata = obj_new('spurion_scanqpoint_data',x,y,sy,legend='XY',$
;;;;;                                                 showdata=1,$
;;;;;                                                 showlegend=0,$
;;;;;                                                 rm=rm,$
;;;;;                                                 ro=ro,$
;;;;;                                                 /xy)
;;;;;
;;;;;            qdata->setproperty,$
;;;;;                        rm=rm,$
;;;;;                        r0=r0,$
;;;;;                        Q=scanvals.qetrans[0:2],$
;;;;;                        orient1=latvals.orient1,$
;;;;;                        orient2=latvals.orient2,$
;;;;;                        E=scanvals.qetrans[4],$
;;;;;                        astar=latvals.astar,$
;;;;;                        bstar=latvals.bstar,$
;;;;;                        cstar=latvals.cstar,$
;;;;;                        alphastar=latvals.alphastar,$
;;;;;                        betastar= latvals.betastar,$
;;;;;                        gammastar=latvals.gammastar
;;;;;            qdata->calculate
;;;;;
;;;;;            self.qplotobj->add,qdata
;;;;;    ;######################################################################################



    otherplotbase = widget_base(self.tlb,/col)
    self.scanplot = cwo_drawplot(otherplotbase,title='SCANPLOT',ytitle='INTENSITY [ARBITRARY UNITS]',xtitle='X AXIS',$
                                        xsize=300,ysize=200,$
                                        uvalue=self,obj=scanplotobj)
    self.scanplotobj = scanplotobj

    self.eplot = cwo_drawplot(otherplotbase,title='ENERGY PLOT',ytitle='Energy Transfer [meV]',xtitle='X AXIS',$
                                        xsize=300,ysize=200,$
                                        uvalue=self,obj=eplotobj)
    self.eplotobj = eplotobj


    self.scancontainer    = obj_new('IDL_Container')
    self.crystalcontainer = obj_new('IDL_Container')

    self.lattice = lattice
    self.rescalculator = rescalculator
    self.crystalcontainer->add,lattice
    self.scancontainer->add,rescalculator


    widget_control,self.tlb,/realize

    xmanager,'Spurion2',self.tlb,/no_block

    return,1
end;::init



pro Spurion2__define,class

    class = { Spurion2,$
                workdir:'',$
                tlb:0L,$
                open:0L,$
                save:0L,$
                quit:0L,$
                qplot:0L,$
                qplotobj:obj_new(),$
                eplot:0L,$
                eplotobj:obj_new(),$
                scanplot:0L,$
                scanplotobj:obj_new(),$
                scanContainer:obj_new(),$
                crystalContainer:obj_new(),$
                rescalculator:obj_new(),$
                lattice:obj_new(),$
                scanpointscalculator:obj_new(),$
                latticepointcalculator:obj_new(),$
                scanParms:0L,$
                scanParmsObj:obj_new(),$
                latParms:0L,$
                latparmsObj:obj_new(),$
                qcheckbox:0L,$
                qcheckBoxObj:obj_new(),$
                scancheckbox:0L,$
                scancheckBoxObj:obj_new(),$
                echeckbox:0L,$
                echeckBoxObj:obj_new(),$
                color:120L+256L*100L +256L*256L*170L,$
                backdraw:0L,$
                backwinvis:0,$
                backwinpix:0}

end;Spurion2__define
