#include<LEDA/graph_alg.h>
#include<LEDA/graphwin.h>



void fix_node(GraphWin& gw, const point&)
{ // position no used
  node v = gw.get_found_node();
  if (gw.get_color(v) != red) 
     gw.set_color(v,red);
  else
     gw.set_color(v,yellow);
 }


void update_drawing(GraphWin& gw, int steps=400)
{ const graph& G = gw.get_graph();
  double xleft   = gw.get_xmin();
  double xright  = gw.get_xmax();
  double ybottom = gw.get_ymin();
  double ytop    = gw.get_ymax();
  node_array<double> xpos(G);
  node_array<double> ypos(G);
  node v;
  forall_nodes(v,G) {
    point p = gw.get_position(v);
    xpos[v] = p.xcoord();
    ypos[v] = p.ycoord();
  }

  //list<node> fixed = gw.get_selected_nodes();

  list<node> fixed;
  forall_nodes(v,G)
      if (gw.get_color(v) == red) fixed.append(v);
 
  SPRING_EMBEDDING(G,fixed,xpos,ypos,xleft,xright,ybottom,ytop,steps);
  gw.set_position(xpos,ypos);
}




void move0_node_handler(GraphWin& GW, node v) { GW.set_color(v,red); }
void move1_node_handler(GraphWin& GW, node v) { GW.set_color(v,yellow); }
void move_node_handler(GraphWin& GW, node v) { update_drawing(GW,4); }
void del_node_handler(GraphWin& GW)          { update_drawing(GW); }
void new_edge_handler(GraphWin& GW, edge e)  { update_drawing(GW); }
void del_edge_handler(GraphWin& GW)          { update_drawing(GW); }


main()
{
  graph G;
  GraphWin GW("Spring Embedding");
  GW.set_action(A_LEFT|A_NODE|A_CTRL,fix_node);
  GW.display();
  GW.set_animation_steps(6);

  panel P("Usage");
  P.text_item("This program demonstrates SPRING EMBEDDING of graphs.");
  P.text_item("");
  P.text_item("Some designated nodes of the graph have fixed positions,");
  P.text_item("");
  P.text_item("Edit a graph and select some nodes by clicking with the left");
  P.text_item("mouse button while simultaneously holding down the CTRL key.");
  P.text_item("The selected nodes will become red and be the fixed nodes as");
  P.text_item("described above. Now, move the red nodes or change the graph.");
  P.text_item("");
  P.text_item("You get the best results for sparse planar graphs");
  P.button("ok");
  P.open(GW.get_window());

  //GW.set_start_move_node_handler(move0_node_handler);
  //GW.set_end_move_node_handler(move1_node_handler);
  //GW.set_move_node_handler(move_node_handler);
  GW.set_del_node_handler(del_node_handler);
  GW.set_new_edge_handler(new_edge_handler);
  GW.set_del_edge_handler(del_edge_handler);

  return GW.edit();
}
