package commons.graph;

import java.awt.Color;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import javax.swing.event.MouseInputListener;
import basics.utl.SysUtl;
import commons.graph.model.Node;
import commons.graph.view.DEFAULTS;
import commons.graph.view.Design;
import commons.graph.view.Draw;
import commons.graph.worker.GraphDataProvider;
import commons.graph.worker.NodeByMousePositionFinder;
import commons.graph.worker.WorkerController;
import commons.ui.toolbox.GU;

public class Interaction implements MouseMotionListener, MouseInputListener
{

GraphDataProvider provider = null;
Draw              draw;
GraphInitializer  graphInitializer;
boolean           dragging = false;
int               dragx;
int               dragy;

public Interaction(Draw draw, GraphInitializer graphInitializer, GraphDataProvider provider)
{
   this.provider = provider;
   this.graphInitializer = graphInitializer;
   this.draw = draw;
}

public void mouseDragged(MouseEvent e)
{
   if(dragging)
      return;
   dragx = e.getX();
   dragy = e.getY();
   dragging = true;
}

public void mouseMoved(MouseEvent e)
{
   Node n = findMouseOver(e.getPoint());
   if(n != null)
   {
      Design design = new Design(DEFAULTS.FONT, provider.hasRelated(n.label) ? Color.blue : Color.black, DEFAULTS.BACKGROUND, DEFAULTS.BORDER);
      GU.paintNode(n, draw.getGraphics(), design);
   }
}

private synchronized Node findMouseOver(Point mousePos)
{
   if(draw.graph == null || draw.graph.edges == null || draw.graph.edges.size() == 0)
      return null;
   NodeByMousePositionFinder w = new NodeByMousePositionFinder(mousePos.x, mousePos.y);
   WorkerController c = new WorkerController(w, draw.graph, draw.graph.edges, draw.graph.nodes);
   c.start();
   return w.getNode();
}

public void mouseClicked(MouseEvent e)
{
   if(e.getClickCount() == 2)
   {
      //      SysUtl.trace("DB CLICK");
      draw.drag_reset();
   }
   else
   {
      Node n = findMouseOver(e.getPoint());
      if(n != null)
      {
         draw.drag_reset();
         SysUtl.trace("LOAD NEW GRAPH, ROOT: " + n.label);
         graphInitializer.newGraph(n.label);
      }
   }
   dragging = false;
}

public void mouseEntered(MouseEvent e)
{
}

public void mouseExited(MouseEvent e)
{
}

public void mousePressed(MouseEvent e)
{
}

public void mouseReleased(MouseEvent e)
{
   if(dragging)
   {
      int dx = e.getX() - dragx;
      int dy = e.getY() - dragy;
      //      OsUtl.trace("DXY("+dx+","+dy+")");
      if(e.isMetaDown())
      {
         draw.zoom(dy * -1);
         draw.redraw();
      }
      else
      {
         draw.drag(dx, dy);
         draw.redraw();
      }
      dragging = false;
   }
}
}
