; $Id: panmaskeditor.pro,v 1.2 2007/06/06 15:59:20 kneller Exp $

pro panmaskeditor_event,event

    catch, catchError
    if (catchError ne 0) then begin
        ;;print, 'Error handled!'
        eTitle = 'panmaskeditor_event: Error encountered'
        eMsg = 'An error or unusual condition was encountered!'
        eMsg = [eMsg,'Please, report the following to the DAVE team:']
        eMsg = [eMsg,!error_state.msg]
        void = dialog_message(/error,eMsg,title=eTitle,dialog_parent=event.top)
        catch, /cancel
    endif

    widget_control,event.handler,get_uvalue=pstate


    case event.id of
    (*pstate).tlb:begin
        width = event.x
        height = event.y
        xsize = (width-20)/2
        ysize = (height-45)

        (*pstate).plotobj->resize,xsize,ysize
        (*pstate).imageobj->resize,xsize,ysize

    end;tlb
    (*pstate).slider:begin
        ;UPDATE THE PLOT
        panmaskeditor_updatePlot,pstate,/newgroup

    end;slider
    (*pstate).apply:begin
;        print,'apply'
        ;CLOSE THE APPLICATION AND RETURN THE NEW MASK
        widget_control,(*pstate).tlb,/destroy
    end;apply
    (*pstate).plot:begin
;        print,'plot'
;        print,tag_names(event)
;        print,event
        if event.mode eq 1 then begin
            if (*pstate).ngroups gt 1 then begin
                widget_control,(*pstate).slider,get_value=group
                ybeg = group-1
                diffs = sqrt((*(*pstate).x - event.xbeg)^2)
                dum = min(diffs,xbeg)

            endif else begin
                group = 1
                ybeg = 0
                diffs = sqrt((*(*pstate).x - event.xbeg)^2)
                dum = min(diffs,xbeg)
            endelse

            ;CHANGE THE MASK
            panmaskeditor_updateMask,{handler:event.handler,xbeg:xbeg,ybeg:ybeg}
            ;UPDATE THE PLOT
            panmaskeditor_updatePlot,pstate
            ;UPDATE THE IMAGE
            panmaskeditor_updateImage,pstate

        endif



    end;plot
    (*pstate).image:begin
;        print,'image'
;        print,tag_names(event)
;        print,event



        names = tag_names(event)
        wh = where(strlowcase(names) eq 'mode',count)
        if count eq 1 then begin
            if event.mode eq 1 then begin
                if event.press eq 1 then begin

                    xindex = floor(event.xbeg)
                    yindex = floor(event.ybeg)
;                    print,'xindex,yindex=',xindex,yindex
;                    bitsmask = (*(*pstate).bitsmask)
;                    szbits = size(bitsmask)
;                    if szbits[0] eq 1 then begin
;                        if xindex ge szbits[1] then return
;                        if yindex ge 1 then return
;                    endif else begin
;                        if xindex ge szbits[1] then return
;                        if yindex ge szbits[2] then return
;                    endelse
;                    if xindex lt 0 then return
;                    if yindex lt 0 then return

                    ;CHANGE THE MASK
                    panmaskeditor_updateMask,event
                    ;UPDATE THE IMAGE
                    panmaskeditor_updateImage,pstate
                    ;UPDATE THE PLOT
                    panmaskeditor_updatePlot,pstate
                endif;event.press
            endif;event.mode
        endif;count
    end;image
    else:
    endcase

end;panmaskeditor_event


function panmaskeditor_maskQty,qty,bitsmask

    ;CREATE A DATA SET WITH THE MASKED POINTS SET TO !values.d_nan
    qty_masked = qty
    wh = where(bitsmask le 0, count)
;print,'wh=',wh
    if count gt 0 then begin
        qty_masked[wh] = min(qty) - max(qty);!values.d_nan;!values.d_nan;-1000000;
    endif

    return,qty_masked
end;panmaskeditor_maskQty



pro panmaskeditor_updateMask,event
    widget_control,event.handler,get_uvalue=pstate
;print,'panmaskeditor_updateMask,event'
    xindex = floor(event.xbeg)
    yindex = floor(event.ybeg)

    sz = size((*(*pstate).bitsmask))
    if xindex ge sz[1] then return
    if xindex lt 0 then return
    if yindex lt 0 then return
    if sz[0] eq 2 then begin
        if yindex ge sz[2] then return
    endif else if yindex ge 1 then return

    val = (*(*pstate).bitsmask)[xindex,yindex]
	valorig = (*(*pstate).bitsmaskorig)[xindex,yindex]


	;PROTECT THE POINTS MASKED BY THE ORIGINAL INPUT
	if valorig eq 1 then begin
    	newval = ((val eq 0) ? 1 : 0)
	endif else newval = valorig
;print,'xindex,yindex,val,newval=',xindex,yindex,val,newval
    (*(*pstate).bitsmask)[xindex,yindex] = newval

    newQty = panmaskeditor_maskQty(*(*pstate).qty,*(*pstate).bitsmask)

    *(*pstate).qty_masked = newQty
;print,    (*(*pstate).bitsmask)


end;panmaskeditor_updateMask

function panmaskeditor_getMaskedGroup,qty_masked,group,bitsmask,ngroups=ngroups,npts=npts,$
                                        xgroup=xgroup

    ;GET THE MASKED GROUP DATA GIVEN THE MASKED qty ARRAY AND THE GROUP #

    sz = size(qty_masked)

    index = group-1

    dumqty = qty_masked
    wh = where(bitsmask le 0,count)

    if count ne 0 then dumqty[wh] = !values.d_nan

    if sz[0] eq 1 then begin
        ngroups = 1
        npts = sz[1]
        qty0 = reform(dumqty[*],n_elements(dumqty[*]))
    endif else begin
        npts = sz[1]
        ngroups = sz[2]
        qty0 = reform(dumqty[*,index],n_elements(dumqty[*,index]))
    endelse

    return,qty0
end;panmaskeditor_getMaskedGroup


pro panmaskeditor_updatePlot,pstate,newgroup=newgroup

    if n_elements(newgroup) eq 0 then newgroup = 0

    (*pstate).plotobj->cleardata
    if (*pstate).slider ne 0 then begin
        widget_control,(*pstate).slider,get_value=group
    endif else begin
        group = 1
    endelse

    if group ge (*pstate).ngroups then group = 1 ;IN CASE OF ONLY ONE GROUP


    y = panmaskeditor_getMaskedGroup(*(*pstate).qty_masked,group,*(*pstate).bitsmask)
    yorig = panmaskeditor_getMaskedGroup(*(*pstate).qty,group,*(*pstate).bitsmaskorig)


    x = *(*pstate).x

;    print,'panmaskeditor_updatePlot y=',y
;    print,'min(y),max(y)=',min(y),max(y)

    ;print,*(*pstate).qty_masked

;    whnan = where(finite(y,/nan) ne 0,ncount)
;    if ncount ne 0 then begin
;        x = x[whnan]
;        y = y[whnan]
;    endif

    ;print,'x,y=',x,y


;    (*pstate).plotobj->setdata,x,y,psym=4,legend='Group '+strtrim(string(group),2)

    (*pstate).plotobj->add,x=x,y=yorig,psym=4,legend='Group '+strtrim(string(group),2),color=256L*255L
    (*pstate).plotobj->add,x=x,y=y,psym=4,legend='Group '+strtrim(string(group),2),color=0L

    if newgroup eq 1 then begin
        (*pstate).plotobj->defaultdraw
    endif else begin
        (*pstate).plotobj->draw
    endelse

;pro cwo_drawplot::setData,x,y,sy,legend=legend,psym=psym,color=color,$
;                  rescale=rescale,ebshow=ebshow,showlegend=showlegend,$
;                  showdata=showdata,xtitle=xtitle,ytitle=ytitle,title=title,$
;                  _Extra=extra
end;panmaskeditor_updatePlot
pro panmaskeditor_updateImage,pstate
    if obj_valid((*pstate).imageobj) gt 0 then begin
        (*pstate).imageobj->cleardata
        (*pstate).imageobj->adddata,bytscl(*(*pstate).qty_masked)
        (*pstate).imageobj->draw
    endif
end;panmaskeditor_updateImage


pro panmaskeditor_cleanup,id

;    widget_control,id,get_uvalue=pstate
;    ptr_free,pstate

;FREE MEMORY ON RETURN TO CALLING PROGRAM.

end;pro panmaskeditor_cleanup




function panmaskeditor,qty=qty,err=err,x=x,y=y,pan_mask=pan_mask,$
                        group_leader=group_leader,mode=mode,$
                        filler=filler,currentgroup=currentgroup,$
                        _extra=extra

    ;PROVIDE BASIC EDITOR FOR PAN MASK

;help,qty
;help,err
;help,x
;help,y
;help,pan_mask

    if n_elements(qty) eq 0 then qty = dindgen(20,20)
    qty_masked = qty

    if n_elements(pan_mask) eq 0 then pan_mask=(byte(0*qty) + 1b)
    if n_elements(pan_mask) ne n_elements(qty) then begin
        bitsmask = bytes2bits(pan_mask)
        bytesflag = 1
    endif else begin
        bitsmask = pan_mask
        bytesflag = 0
    endelse

    ;SAVE A COPY OF THE ORIGINAL MASK
    bitsmaskOrig = bitsmask



    startgroup = 1
    qty_masked = panmaskeditor_maskQty(qty,bitsmask)

    qty0 = panmaskeditor_getMaskedGroup(qty_masked,startgroup,bitsmask,ngroups=ngroups,npts=npts)

    if n_elements(x) eq 0 then x = findgen(npts)
    if n_elements(y) eq 0 then y = findgen(ngroups)

    tlb = widget_base(title='Edit Pan Mask',$
                        /row,/tlb_size_events)

    llb1 = widget_base(tlb,/col)
    llb2 = widget_base(tlb,/col)

    if ngroups gt 1 then begin
        slider = widget_slider(llb1,minimum = 1,maximum=ngroups)
    endif else begin
        slider = 0L
    endelse


    ;SET THE PLOT AND IMAGE MODES TO POINT SELECT
    mode = 1
    plot = cwo_selectable_drawplot(llb1,obj=plotobj,xsize=300,ysize=300,$
                                    title='Group Data',xtitle='X',ytitle='Y',$
                                    mode=mode)

;    plotobj->setdata,x,qty0

    apply = widget_button(llb2,value='Apply and Exit')

;    if ngroups gt 1 then begin
;        image = cwo_drawimage(llb2,obj=imageobj,image=bytscl(qty_masked),$
;                                title='Pan Mask',$
;                                xtitle='Point number',ytitle='Group Number',$
;                                xsize=300,ysize=300,$
;                                mode=mode)
;    endif else begin
        image = 0L
        imageobj = obj_new()
;    endelse


    state = {tlb:tlb,$
             plot:plot,plotobj:plotobj,$
             image:image,imageobj:imageobj,$
             slider:slider,apply:apply,$
             qty:ptr_new(qty),$
             bitsmask:ptr_new(bitsmask),$
             qty_masked:ptr_new(qty_masked),$
             bitsmaskOrig:ptr_new(bitsmaskOrig),$
             x:ptr_new(x),$
             y:ptr_new(y),$
             bytesflag:bytesflag,$
             npts:npts,ngroups:ngroups}

    pstate = ptr_new(state)
    widget_control,tlb,/realize,set_uvalue=pstate

    panmaskeditor_updatePlot,pstate,/newgroup
    panmaskeditor_updateImage,pstate


    xmanager,'panmaskeditor',tlb,no_block=0



    bitsmask = *((*pstate).bitsmask)
    ptr_free,(*pstate).bitsmask
    ptr_free,(*pstate).qty
    ptr_free,(*pstate).qty_masked
    ptr_free,(*pstate).bitsmaskOrig
    ptr_free,(*pstate).x
    ptr_free,(*pstate).y

    if bytesflag eq 1 then newmask = bits2bytes(bitsmask) else newmask = bitsmask

    return,newmask

end;panmaskeditor

