#include "graph_displayer_canvas.h"
#include "broken_edge.h"
#include <math.h>


int GraphDisplayerCanvas::changeNodeRadius (std::string mapname, Graph::Node node)
{
  Graph::NodeMap<double> * actual_map;
  double min, max;
  if(mapname=="Default")
    {
      min=node_property_defaults[N_RADIUS];
      max=node_property_defaults[N_RADIUS];
      actual_map=new Graph::NodeMap<double>(mapstorage.graph,node_property_defaults[N_RADIUS]);
    }
  else
    {
      min=mapstorage.minOfNodeMap(mapname);
      max=mapstorage.maxOfNodeMap(mapname);
      actual_map=(mapstorage.nodemap_storage)[mapname];
    }

  if(node==INVALID)
    {
      for (NodeIt i(mapstorage.graph); i!=INVALID; ++i)
	{
	  double v=abs((*actual_map)[i]);
	  int w;
	  if(min==max)
	    {
	      w=(int)(node_property_defaults[N_RADIUS]);
	    }
	  else
	    {
	      w=(int)(MIN_NODE_RADIUS+(v-min)/(max-min)*(MAX_NODE_RADIUS-MIN_NODE_RADIUS));
	    }
	  if(w>=0)
	    {
	      double x1, y1, x2, y2;
	      x1=nodesmap[i]->property_x1().get_value();
	      x2=nodesmap[i]->property_x2().get_value();
	      y1=nodesmap[i]->property_y1().get_value();
	      y2=nodesmap[i]->property_y2().get_value();
	      nodesmap[i]->property_x1().set_value((x1+x2)/2-w);
	      nodesmap[i]->property_x2().set_value((x1+x2)/2+w);
	      nodesmap[i]->property_y1().set_value((y1+y2)/2-w);
	      nodesmap[i]->property_y2().set_value((y1+y2)/2+w);
	    }
	}
    }
  else
    {
      //I think only new nodes use this case
//       int w=(int)(*actual_map)[node];
      int w=(int)(node_property_defaults[N_RADIUS]);
      if(w>=0)
	{
	  double x1, y1, x2, y2;
	  x1=nodesmap[node]->property_x1().get_value();
	  x2=nodesmap[node]->property_x2().get_value();
	  y1=nodesmap[node]->property_y1().get_value();
	  y2=nodesmap[node]->property_y2().get_value();
	  nodesmap[node]->property_x1().set_value((x1+x2)/2-w);
	  nodesmap[node]->property_x2().set_value((x1+x2)/2+w);
	  nodesmap[node]->property_y1().set_value((y1+y2)/2-w);
	  nodesmap[node]->property_y2().set_value((y1+y2)/2+w);
	}
    }
  return 0;
};

int GraphDisplayerCanvas::changeNodeColor (std::string mapname, Graph::Node node)
{  

  //function maps the range of the maximum and
  //the minimum of the nodemap to the range of
  //green in RGB

  Graph::NodeMap<double> * actual_map;
  if(mapname=="Default")
    {
      actual_map=new Graph::NodeMap<double>(mapstorage.graph,node_property_defaults[N_COLOR]);
    }
  else
    {
      actual_map=(mapstorage.nodemap_storage)[mapname];
    }

  double max, min;

  if(mapname!="Default")
    {
      max=mapstorage.maxOfNodeMap(mapname);
      min=mapstorage.minOfNodeMap(mapname);
    }
  else
    {
      max=node_property_defaults[N_COLOR];
      min=node_property_defaults[N_COLOR];
    }


  if(node==INVALID)
    {

      for (NodeIt i(mapstorage.graph); i!=INVALID; ++i)
	{
	  Gdk::Color color;

	  double w=(*actual_map)[i];

	  if(max!=min)
	    {
	      color.set_rgb_p (0, 0, 100*(w-min)/(max-min));
	    }
	  else
	    {
	      color.set_rgb_p (0, 0, 100);
	    }

	  nodesmap[i]->property_fill_color_gdk().set_value(color);
	}
    }
  else
    {
      Gdk::Color color;

      double w=(*actual_map)[node];

      if(max!=min)
	{
	  color.set_rgb_p (0, 0, 100*(w-min)/(max-min));
	}
      else
	{
	  color.set_rgb_p (0, 0, 100);
	}

      nodesmap[node]->property_fill_color_gdk().set_value(color);
    }
  return 0;
};

int GraphDisplayerCanvas::changeNodeText (std::string mapname, Graph::Node node)
{

  //the number in the map will be written on the node
  //EXCEPT when the name of the map is Text, because
  //in that case empty string will be written, because
  //that is the deleter map

  Graph::NodeMap<double> * actual_map=NULL;
  if(mapname!="Default")
    {
      actual_map=(mapstorage.nodemap_storage)[mapname];
    }

  if(node==INVALID)
    {
      for (NodeIt i(mapstorage.graph); i!=INVALID; ++i)
	{
	  if(mapname!="Default")
	    {
	      nodemap_to_edit=mapname;
	      double number=(*actual_map)[i];

	      std::ostringstream ostr;
	      ostr << number;
	      
      	      nodetextmap[i]->property_text().set_value(ostr.str());
	    }
	  else
	    {
	      nodemap_to_edit="";
	      nodetextmap[i]->property_text().set_value("");
	    }
	}
    }
  else
    {
      if(mapname!="Default")
	{
	  double number=(*actual_map)[node];

	  std::ostringstream ostr;
	  ostr << number;
	      
	  nodetextmap[node]->property_text().set_value(ostr.str());
	}
      else
	{
	  nodetextmap[node]->property_text().set_value("");
	}
    }
  return 0;
};
