package org.concord.datagraph.ui;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Stroke;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;

import org.concord.datagraph.engine.DataGraphable;
import org.concord.framework.data.stream.DataListener;
import org.concord.framework.data.stream.DataProducer;
import org.concord.framework.data.stream.DataStreamEvent;
import org.concord.framework.startable.StartableEvent;
import org.concord.framework.startable.StartableListener;
import org.concord.graph.engine.CoordinateSystem;
import org.concord.graph.engine.DefaultGraphable;
import org.concord.graph.engine.Graphable;
import org.concord.graph.engine.GraphableList;

public class VerticalPlaybackLine extends DefaultGraphable implements DataAnnotation {
    private DataGraphable graphable;
    private GraphableList otherGraphables;
    private DataProducer playbackProducer;
    private float currentX = 0;
    
    private static Stroke stroke = new BasicStroke(1.5f,       // Width
                                                   BasicStroke.CAP_SQUARE,     // End cap
                                                   BasicStroke.JOIN_MITER,     // Join style
                                                   1.0f);
    
    public VerticalPlaybackLine(DataProducer playbackDataProducer) {
        super();
        this.playbackProducer = playbackDataProducer;
        this.playbackProducer.addDataListener(new DataListener() {
            public void dataReceived(DataStreamEvent dataEvent) {
                updateX(dataEvent);
            }
            
            public void dataStreamEvent(DataStreamEvent dataEvent) {
                updateX(dataEvent);
            }

            private void updateX(DataStreamEvent dataEvent) {
                if (dataEvent.numSamples > 0) {
                    // System.out.println("Setting current x to: " + dataEvent.data[0]);
                    currentX = dataEvent.data[0];
                    VerticalPlaybackLine.this.setVisible(true);
                    VerticalPlaybackLine.this.notifyChange();
                }
            }
        });
        
        this.playbackProducer.addStartableListener(new StartableListener() {
            public void startableEvent(StartableEvent event) {
                if (event.getType().equals(StartableEvent.StartableEventType.RESET)) {
                    setVisible(false);
                    currentX = 0;
                } else {
                    setVisible(true);
                }
            }
        });
        
        this.setVisible(false);
    }

    public DataGraphable getDataGraphable() {
        return graphable;
    }

    public void setDataGraphable(DataGraphable dataGraphable) {
        graphable = dataGraphable;
    }

    public void setGraphableList(GraphableList gList) {
        otherGraphables = gList;
    }

    public Graphable getCopy() {
        return null;
    }

    public void draw(Graphics2D g) {
        double top = graphArea.getUpperRightCornerWorld().getY();
        double bottom = graphArea.getLowerLeftCornerWorld().getY();
        
        CoordinateSystem cs = graphArea.getCoordinateSystem();
        Point2D lineStart = cs.transformToDisplay(new Point2D.Double(currentX, bottom));
        Point2D lineEnd = cs.transformToDisplay(new Point2D.Double(currentX, top));
        
        g.setColor(Color.GREEN);
        g.setStroke(stroke);
        g.draw(new Line2D.Double(lineStart, lineEnd));
    }

}

@@ -28,16 +28,48 @@
 ph.ui;%0A%0A
+import java.awt.AlphaComposite;%0A
 import j
@@ -112,16 +112,43 @@
 .Color;%0A
+import java.awt.Composite;%0A
 import j
@@ -1047,17 +1047,21 @@
  Stroke 
-s
+lineS
 troke = 
@@ -1076,17 +1076,17 @@
 cStroke(
-1
+2
 .5f,    
@@ -1338,16 +1338,190 @@
  1.0f);%0A
+    private static Color lineColor = new Color(0x00ff00); // 0x5058ba%0A    private static Composite lineComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f);%0A
     %0A   
@@ -3615,32 +3615,188 @@
 top));%0A        %0A
+        Color originalColor = g.getColor();%0A        Stroke originalStroke = g.getStroke();%0A        Composite originalComposite = g.getComposite();%0A        %0A
         g.setCol
@@ -3802,19 +3802,17 @@
 lor(
+line
 Color
-.GREEN
 );%0A 
@@ -3830,17 +3830,21 @@
 tStroke(
-s
+lineS
 troke);%0A
@@ -3857,50 +3857,322 @@
   g.
-draw(new Line2D.Double(lineStart, lineEnd)
+setComposite(lineComposite);%0A        %0A        g.draw(new Line2D.Double(lineStart, lineEnd));%0A        %0A        // TODO Draw indicators (with values?) at each graphables y point for this x value%0A        %0A        g.setColor(originalColor);%0A        g.setStroke(originalStroke);%0A        g.setComposite(originalComposite
 );%0A 

Store and restore color, stroke and composite after drawing playback line. Add alpha blending to playback line. Make playback line slightly thicker.