# title: Add Path Digitizer
# label: Path Digitizer
# Click events are registered on the tab "digitizer," recording the X and Y positions.
# This also provides feedback showing the digitized data and the data points 
# selected in the digitizer tab using Das2 decorators, instead of another renderer,
# which can be confusing.
#

from org.das2.components import DataPointRecorder
from org.das2.dataset import DataSetUpdateListener
from org.das2.graph import Painter
from java.awt import BasicStroke,RenderingHints
from java.awt.geom import GeneralPath

dpr= DataPointRecorder()
dpr.setSorted(False)

addTab( 'digitizer', dpr )

pp= dom.plots[0].controller.dasPlot

dom.canvases[0].controller.dasCanvas.removeTopDecorators()
dom.canvases[0].controller.dasCanvas.removeBottomDecorators()

class UpdatesPainter( Painter ):
    def __init__(self,color,width):
        self.color= color
        self.width= width
        self.ds= None
    def setDs(self,ds):
        self.ds= ds
    def paint(self,g):
        g.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON )
        g.setColor(self.color)
        g.setStroke(BasicStroke(self.width))
        if ( self.ds!=None ):
            np= 0
            gp= GeneralPath()
            for ds1 in self.ds:
                x= int( pp.getXAxis().transform(datum(ds1.slice(0))) )
                y= int( pp.getYAxis().transform(datum(ds1.slice(1))) )
                if ( np==0 ):
                    gp.moveTo( x, y )    
                else:
                    gp.lineTo( x, y )
                np= np+1
            if ( np==1 ): 
                g.fillOval( x-self.width, y-self.width, self.width*2+1, self.width*2+1 )
            else:
                g.draw( gp )
            if ( self.ds.length()>1 and pp.getXAxis().getUnits().isConvertibleTo( pp.getYAxis().getUnits() ) ):
                xx= slice1(self.ds,0)
                yy= slice1(self.ds,1)
                totalLength= total( sqrt( (xx[1:]-xx[:-1])**2 + (yy[1:]-yy[:-1])**2 ) )
                ypos= 12
                if ( self.color==Color.YELLOW ): 
                    ypos= ypos-12
                    g.drawString( 'totalLength: %f' % totalLength, pp.getXAxis().getColumn().getDMinimum()+3, pp.getYAxis().getRow().getDMaximum()-ypos-3 )
                    g.setColor( Color.GRAY )
                g.drawString( 'totalLength: %f' % totalLength, pp.getXAxis().getColumn().getDMinimum()+5, pp.getYAxis().getRow().getDMaximum()-ypos-5 )

        
selectionPainter= UpdatesPainter( Color.YELLOW, 5 )
class MySelectionListener(DataSetUpdateListener):
   def dataSetUpdated(self,event):
        global selectionPainter
        ds= dpr.getSelectedDataPoints()
        selectionPainter.setDs(ds)
        dom.canvases[0].controller.dasCanvas.repaint()        
dpr.addSelectedDataSetUpdateListener( MySelectionListener() )
dom.canvases[0].controller.dasCanvas.addTopDecorator(selectionPainter)
                
updatesPainter= UpdatesPainter( Color.GRAY, 3 )
class MyUpdateListener( DataSetUpdateListener ):
    def dataSetUpdated( self, e ):
        global updatesPainter
        updatesPainter.setDs(dpr.getDataPoints())
        dom.canvases[0].controller.dasCanvas.repaint()
dpr.addDataSetUpdateListener( MyUpdateListener() )
dom.canvases[0].controller.dasCanvas.addTopDecorator(updatesPainter)

from org.das2.qds import DataSetUtil

def boxSelected(event):
    x= event.getFinishX()
    y= event.getFinishY()
    if ( not event.getStartX().equals(x) ):
        dpr.select( event.getXRange(), event.getYRange() )
    else:
        dpr.addDataPoint( x, y )

addMouseModule( dom.plots[0], 'path digitizer', boxSelected )    

showMessageDialog( 'Click to enter points on the plot, and they will be recorded on the digitizer tab')