package commons.graph.view;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.JPanel;
import commons.graph.ClickGraph;
import commons.graph.GraphInitializer;
import commons.graph.Interaction;
import commons.graph.model.Edges;
import commons.graph.model.Nodes;
import commons.graph.worker.EdgesPainter;
import commons.graph.worker.GraphDataProvider;
import commons.graph.worker.NodesPainter;
import commons.graph.worker.WorkerController;
public class Draw extends JPanel
{

private static final long serialVersionUID = 1L;
Image                     offscreen;
Dimension                 offscreensize;
Graphics                  offgraphics;
FontMetrics               fontMetrics;
public ClickGraph              graph;
Edges                     edges;
Nodes                     nodes;
WorkerController          edgePainter;
Interaction               interaction;
int                       draggedx         = 0;
int                       draggedy         = 0;
double                    zoomFactor       = 1d;
public GraphDataProvider  provider;

public Draw(GraphInitializer graphInitializer, GraphDataProvider provider)
{
   interaction = new Interaction(this, graphInitializer, provider);
   addMouseMotionListener(interaction);
   addMouseListener(interaction);
   this.provider = provider;
}

public void redraw ()
{
   revalidate();
   repaint();
}

/**
 * input is a value received from the y-mouse-movement.
 * @param factor
 */
public void zoom (double length)
{
   if (length == 0) return;
   double factor = (length * 10) / getSize().getHeight();
   zoomFactor *= factor < 0 ? (1 / (factor * -1)) : factor;
   zoomFactor = zoomFactor == 0 ? 1 : zoomFactor;
//   OsUtl.trace("zoom: " + factor + " zoomFactor: " + zoomFactor);
}

public void update (ClickGraph graph)
{
   this.graph = graph;
   this.edges = this.graph.edges;
   this.nodes = this.graph.nodes;
   repaint();
}

public synchronized void paint (Graphics g)
{
   update(g);
}

public void drag (int x, int y)
{
   draggedx += x;
   draggedy += y;
   // OsUtl.trace("dx:" + draggedx + " dy:" + draggedy);
}

public void drag_reset ()
{
   draggedx = 0;
   draggedy = 0;
}

public synchronized void update (Graphics g)
{
   WorkerController painter = null;
   Dimension screensize = getSize();
   if ((offscreen == null) || (screensize.width != offscreensize.width) || (screensize.height != offscreensize.height))
   {
      offscreen = createImage(screensize.width, screensize.height);
      offscreensize = screensize;
      offgraphics = offscreen.getGraphics();
   }
   offgraphics.setColor(Color.white);
   offgraphics.fillRect(0, 0, screensize.width, screensize.height);
   if (edges != null && edges.size() > 0)
   {
      painter = new WorkerController(new EdgesPainter(this, offgraphics, draggedx, draggedy, zoomFactor), graph, edges, nodes);
      painter.start();
      painter = new WorkerController(new NodesPainter(this, offgraphics, draggedx, draggedy, provider, zoomFactor), graph, edges, nodes);
      painter.start();
   }
   paintComponents(offgraphics); // Paint any components that have been added to
   // this panel
   g.drawImage(offscreen, 0, 0, null);
}
}
