// @(#)root/hist:$Id$
// Author: Olivier Couet 13/07/09

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "TGraph.h"
#include "TArrow.h"
#include "TPolyLine.h"
#include "TGraphEdge.h"
#include "TGraphNode.h"  

#include <gvc.h>

ClassImp(TGraphEdge)

//______________________________________________________________________________
/* Begin_Html
<center><h2>Graph Edge class</h2></center>
TGraphEdge is an edge object connecting two nodes which can be added in a
TGraphStruct.
End_Html */


//______________________________________________________________________________
TGraphEdge::TGraphEdge(): TObject(), TAttLine()
{
   // Graph Edge default constructor.

   fNode1  = 0;
   fNode2  = 0;
   fGVEdge = 0;
   fX      = 0;
   fY      = 0;
   fN      = 0;
   fArrX   = 0;
   fArrY   = 0;
}


//______________________________________________________________________________
TGraphEdge::TGraphEdge(TGraphNode *n1, TGraphNode *n2)
           :TObject(), TAttLine()
{
   // Graph Edge normal constructor.

   fNode1  = n1;
   fNode2  = n2;
   fGVEdge = 0;
   fX      = 0;
   fY      = 0;
   fN      = 0;
   fArrX   = 0;
   fArrY   = 0;
}


//______________________________________________________________________________
TGraphEdge::~TGraphEdge()
{
   // Graph Edge default destructor.

   if (fNode1) delete fNode1;
   if (fNode2) delete fNode2;
   if (fX) delete [] fX; fX = 0;
   if (fY) delete [] fY; fY = 0;
   if (fN) delete [] fN; fN = 0;
}


//______________________________________________________________________________
void TGraphEdge::CreateGVEdge(GVizAgraph_t *gv)
{
   // Create the GraphViz edge into the GraphViz data structure gv.           

   if (gv) {
      Agnode_t *n1 = (Agnode_t*)fNode1->GetGVNode();
      Agnode_t *n2 = (Agnode_t*)fNode2->GetGVNode();
#ifdef WITH_CGRAPH
      fGVEdge = (GVizAgedge_t*)agedge((Agraph_t *)gv, n1, n2, NULL, 1);
#else
      fGVEdge = (GVizAgedge_t*)agedge((Agraph_t *)gv, n1, n2);
#endif
   } else {
      Error("CreateGVEdge","Invalid graphviz graph");
   }
}


//______________________________________________________________________________
Int_t TGraphEdge::DistancetoPrimitive(Int_t px, Int_t py)
{
   // Compute distance from point px,py to an edge.

   Int_t i,n,a,dist=999;
   
   TPolyLine *polyline;
   a = 0;

   for (i=1; i<=fN[0]; i++) {
      n = fN[i];
      polyline = new TPolyLine(n, &fX[a], &fY[a], "L");
      dist = polyline->DistancetoPrimitive(px, py);
      a = a+n;
   }

   return dist;
}


//______________________________________________________________________________
void TGraphEdge::ExecuteEvent(Int_t event, Int_t px, Int_t py)
{
   // Execute action corresponding to one event.

   Int_t i,n,a;

   TPolyLine *polyline;
   a = 0;

   for (i=1; i<=fN[0]; i++) {
      n = fN[i];
      polyline = new TPolyLine(n, &fX[a], &fY[a], "L");
      polyline->ExecuteEvent(event, px, py);
      a = a+n;
   }
}


//______________________________________________________________________________
void TGraphEdge::Layout()
{
   // Layout this edge in the GraphViz space. This is done after gvLayout
   // has been performed.

   bezier bz;
   Int_t i,j;

   if (fX) delete [] fX; fX = 0;
   if (fY) delete [] fY; fY = 0;
   if (fN) delete [] fN; fN = 0;

   Int_t np = ED_spl((Agedge_t*)fGVEdge)->size;
   fN       = new Int_t[np+1];
   fN[0]    = np;
   Int_t nb = 0;

   // Compute the total size of the splines arrays
   for (i=0; i<np; i++) {
      bz      = ED_spl((Agedge_t*)fGVEdge)->list[i];
      fN[i+1] = bz.size;
      nb      = nb+fN[i+1];
   }

   // Create the vectors holding all the splines' points.
   fX = new Double_t[nb];
   fY = new Double_t[nb];

   // Fill the vectors with the splines' points.
   Int_t k=0;
   for (i=0; i<np; i++) {
      bz    = ED_spl((Agedge_t*)fGVEdge)->list[i];
      fArrX =  bz.ep.x;
      fArrY =  bz.ep.y;
      for (j=0; j<fN[i+1]; j++) {
         fX[k] = bz.list[j].x;
	 fY[k] = bz.list[j].y;
	 k++;
      }
   }
}


//______________________________________________________________________________
void TGraphEdge::Paint(Option_t *)
{
   // Paint this edge with its current attributes.

   Int_t i,n,a;

   TArrow arrow;
   TGraph graph;

   graph.SetLineColor(GetLineColor());
   graph.SetLineStyle(GetLineStyle());
   graph.SetLineWidth(GetLineWidth());
   arrow.SetAngle(38);
   arrow.SetFillColor(GetLineColor());
   arrow.SetLineColor(GetLineColor());

   a = 0;

   for (i=1; i<=fN[0]; i++) {

      // Draw the edge body
      n = fN[i];
      graph.PaintGraph(n, &fX[a], &fY[a], "L");

      // Draw the edge arrow
      arrow.PaintArrow(fX[a+n-1], fY[a+n-1], fArrX, fArrY, 0.03, "|>");

      a = a+n;
   }
}


//______________________________________________________________________________
void TGraphEdge::SavePrimitive(std::ostream &, Option_t *)
{
   // Save primitive as a C++ statement(s) on output stream out   
}

//______________________________________________________________________________
void TGraphEdge::SaveAttributes(std::ostream &out, const char* name)
{
   // Save attributes as a C++ statement(s) on output stream out
   // called by TGraphStruct::SavePrimitive.
	       
   SaveLineAttributes(out,name,1,1,1);
}


//______________________________________________________________________________
void TGraphEdge::Streamer(TBuffer &/*b*/)
{
}
 TGraphEdge.cxx:1
 TGraphEdge.cxx:2
 TGraphEdge.cxx:3
 TGraphEdge.cxx:4
 TGraphEdge.cxx:5
 TGraphEdge.cxx:6
 TGraphEdge.cxx:7
 TGraphEdge.cxx:8
 TGraphEdge.cxx:9
 TGraphEdge.cxx:10
 TGraphEdge.cxx:11
 TGraphEdge.cxx:12
 TGraphEdge.cxx:13
 TGraphEdge.cxx:14
 TGraphEdge.cxx:15
 TGraphEdge.cxx:16
 TGraphEdge.cxx:17
 TGraphEdge.cxx:18
 TGraphEdge.cxx:19
 TGraphEdge.cxx:20
 TGraphEdge.cxx:21
 TGraphEdge.cxx:22
 TGraphEdge.cxx:23
 TGraphEdge.cxx:24
 TGraphEdge.cxx:25
 TGraphEdge.cxx:26
 TGraphEdge.cxx:27
 TGraphEdge.cxx:28
 TGraphEdge.cxx:29
 TGraphEdge.cxx:30
 TGraphEdge.cxx:31
 TGraphEdge.cxx:32
 TGraphEdge.cxx:33
 TGraphEdge.cxx:34
 TGraphEdge.cxx:35
 TGraphEdge.cxx:36
 TGraphEdge.cxx:37
 TGraphEdge.cxx:38
 TGraphEdge.cxx:39
 TGraphEdge.cxx:40
 TGraphEdge.cxx:41
 TGraphEdge.cxx:42
 TGraphEdge.cxx:43
 TGraphEdge.cxx:44
 TGraphEdge.cxx:45
 TGraphEdge.cxx:46
 TGraphEdge.cxx:47
 TGraphEdge.cxx:48
 TGraphEdge.cxx:49
 TGraphEdge.cxx:50
 TGraphEdge.cxx:51
 TGraphEdge.cxx:52
 TGraphEdge.cxx:53
 TGraphEdge.cxx:54
 TGraphEdge.cxx:55
 TGraphEdge.cxx:56
 TGraphEdge.cxx:57
 TGraphEdge.cxx:58
 TGraphEdge.cxx:59
 TGraphEdge.cxx:60
 TGraphEdge.cxx:61
 TGraphEdge.cxx:62
 TGraphEdge.cxx:63
 TGraphEdge.cxx:64
 TGraphEdge.cxx:65
 TGraphEdge.cxx:66
 TGraphEdge.cxx:67
 TGraphEdge.cxx:68
 TGraphEdge.cxx:69
 TGraphEdge.cxx:70
 TGraphEdge.cxx:71
 TGraphEdge.cxx:72
 TGraphEdge.cxx:73
 TGraphEdge.cxx:74
 TGraphEdge.cxx:75
 TGraphEdge.cxx:76
 TGraphEdge.cxx:77
 TGraphEdge.cxx:78
 TGraphEdge.cxx:79
 TGraphEdge.cxx:80
 TGraphEdge.cxx:81
 TGraphEdge.cxx:82
 TGraphEdge.cxx:83
 TGraphEdge.cxx:84
 TGraphEdge.cxx:85
 TGraphEdge.cxx:86
 TGraphEdge.cxx:87
 TGraphEdge.cxx:88
 TGraphEdge.cxx:89
 TGraphEdge.cxx:90
 TGraphEdge.cxx:91
 TGraphEdge.cxx:92
 TGraphEdge.cxx:93
 TGraphEdge.cxx:94
 TGraphEdge.cxx:95
 TGraphEdge.cxx:96
 TGraphEdge.cxx:97
 TGraphEdge.cxx:98
 TGraphEdge.cxx:99
 TGraphEdge.cxx:100
 TGraphEdge.cxx:101
 TGraphEdge.cxx:102
 TGraphEdge.cxx:103
 TGraphEdge.cxx:104
 TGraphEdge.cxx:105
 TGraphEdge.cxx:106
 TGraphEdge.cxx:107
 TGraphEdge.cxx:108
 TGraphEdge.cxx:109
 TGraphEdge.cxx:110
 TGraphEdge.cxx:111
 TGraphEdge.cxx:112
 TGraphEdge.cxx:113
 TGraphEdge.cxx:114
 TGraphEdge.cxx:115
 TGraphEdge.cxx:116
 TGraphEdge.cxx:117
 TGraphEdge.cxx:118
 TGraphEdge.cxx:119
 TGraphEdge.cxx:120
 TGraphEdge.cxx:121
 TGraphEdge.cxx:122
 TGraphEdge.cxx:123
 TGraphEdge.cxx:124
 TGraphEdge.cxx:125
 TGraphEdge.cxx:126
 TGraphEdge.cxx:127
 TGraphEdge.cxx:128
 TGraphEdge.cxx:129
 TGraphEdge.cxx:130
 TGraphEdge.cxx:131
 TGraphEdge.cxx:132
 TGraphEdge.cxx:133
 TGraphEdge.cxx:134
 TGraphEdge.cxx:135
 TGraphEdge.cxx:136
 TGraphEdge.cxx:137
 TGraphEdge.cxx:138
 TGraphEdge.cxx:139
 TGraphEdge.cxx:140
 TGraphEdge.cxx:141
 TGraphEdge.cxx:142
 TGraphEdge.cxx:143
 TGraphEdge.cxx:144
 TGraphEdge.cxx:145
 TGraphEdge.cxx:146
 TGraphEdge.cxx:147
 TGraphEdge.cxx:148
 TGraphEdge.cxx:149
 TGraphEdge.cxx:150
 TGraphEdge.cxx:151
 TGraphEdge.cxx:152
 TGraphEdge.cxx:153
 TGraphEdge.cxx:154
 TGraphEdge.cxx:155
 TGraphEdge.cxx:156
 TGraphEdge.cxx:157
 TGraphEdge.cxx:158
 TGraphEdge.cxx:159
 TGraphEdge.cxx:160
 TGraphEdge.cxx:161
 TGraphEdge.cxx:162
 TGraphEdge.cxx:163
 TGraphEdge.cxx:164
 TGraphEdge.cxx:165
 TGraphEdge.cxx:166
 TGraphEdge.cxx:167
 TGraphEdge.cxx:168
 TGraphEdge.cxx:169
 TGraphEdge.cxx:170
 TGraphEdge.cxx:171
 TGraphEdge.cxx:172
 TGraphEdge.cxx:173
 TGraphEdge.cxx:174
 TGraphEdge.cxx:175
 TGraphEdge.cxx:176
 TGraphEdge.cxx:177
 TGraphEdge.cxx:178
 TGraphEdge.cxx:179
 TGraphEdge.cxx:180
 TGraphEdge.cxx:181
 TGraphEdge.cxx:182
 TGraphEdge.cxx:183
 TGraphEdge.cxx:184
 TGraphEdge.cxx:185
 TGraphEdge.cxx:186
 TGraphEdge.cxx:187
 TGraphEdge.cxx:188
 TGraphEdge.cxx:189
 TGraphEdge.cxx:190
 TGraphEdge.cxx:191
 TGraphEdge.cxx:192
 TGraphEdge.cxx:193
 TGraphEdge.cxx:194
 TGraphEdge.cxx:195
 TGraphEdge.cxx:196
 TGraphEdge.cxx:197
 TGraphEdge.cxx:198
 TGraphEdge.cxx:199
 TGraphEdge.cxx:200
 TGraphEdge.cxx:201
 TGraphEdge.cxx:202
 TGraphEdge.cxx:203
 TGraphEdge.cxx:204
 TGraphEdge.cxx:205
 TGraphEdge.cxx:206
 TGraphEdge.cxx:207
 TGraphEdge.cxx:208
 TGraphEdge.cxx:209
 TGraphEdge.cxx:210
 TGraphEdge.cxx:211
 TGraphEdge.cxx:212
 TGraphEdge.cxx:213
 TGraphEdge.cxx:214
 TGraphEdge.cxx:215
 TGraphEdge.cxx:216
 TGraphEdge.cxx:217
 TGraphEdge.cxx:218
 TGraphEdge.cxx:219
 TGraphEdge.cxx:220
 TGraphEdge.cxx:221
 TGraphEdge.cxx:222
 TGraphEdge.cxx:223
 TGraphEdge.cxx:224
 TGraphEdge.cxx:225
 TGraphEdge.cxx:226
 TGraphEdge.cxx:227
 TGraphEdge.cxx:228
 TGraphEdge.cxx:229
 TGraphEdge.cxx:230
 TGraphEdge.cxx:231