// File:	Poly.cxx
// Created:	Mon Mar  6 11:02:24 1995
// Author:	Laurent PAINNOT
//		<lpa@metrox>

#include <Standard_Stream.hxx>
#include <Poly.ixx>
#include <gp_Pnt.hxx>
#include <gp_Pnt2d.hxx>
#include <Poly_Triangle.hxx>
#include <TColgp_Array1OfPnt.hxx>
#include <TColgp_Array1OfPnt.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <Poly_Array1OfTriangle.hxx>

#include <Poly_Polygon3D.hxx>
#include <Poly_Polygon2D.hxx>

//=======================================================================
//function : Write
//purpose  : 
//=======================================================================

void Poly::Write(const Handle(Poly_Triangulation)& T, 
		 Standard_OStream& OS, 
		 const Standard_Boolean Compact)
{
  OS << "Poly_Triangulation\n";
  if (Compact) {
    OS << T->NbNodes() << " " << T->NbTriangles() << " ";
    OS << ((T->HasUVNodes()) ? "1" : "0") << "\n";
  }
  else {
    OS << setw(8) << T->NbNodes() << " Nodes\n";
    OS << setw(8) << T->NbTriangles() << " Triangles\n";
    OS << ((T->HasUVNodes()) ? "with" : "without") << " UV nodes\n";
  }

  // write the deflection

  if (!Compact) OS << "Deflection : ";
  OS << T->Deflection() << "\n";

  // write the 3d nodes

  if (!Compact) OS << "\n3D Nodes :\n";

  Standard_Integer i, nbNodes = T->NbNodes();
  const TColgp_Array1OfPnt& Nodes = T->Nodes();
  for (i = 1; i <= nbNodes; i++) {
    if (!Compact) OS << setw(10) << i << " : ";
    if (!Compact) OS << setw(17);
    OS << Nodes(i).X() << " ";
    if (!Compact) OS << setw(17);
    OS << Nodes(i).Y() << " ";
    if (!Compact) OS << setw(17);
    OS << Nodes(i).Z() << "\n";
  }

  if (T->HasUVNodes()) {
    if (!Compact) OS << "\nUV Nodes :\n";
    const TColgp_Array1OfPnt2d& UVNodes = T->UVNodes();
    for (i = 1; i <= nbNodes; i++) {
      if (!Compact) OS << setw(10) << i << " : ";
    if (!Compact) OS << setw(17);
      OS << UVNodes(i).X() << " ";
    if (!Compact) OS << setw(17);
      OS << UVNodes(i).Y() << "\n";
    }
  }
      
  if (!Compact) OS << "\nTriangles :\n";
  Standard_Integer nbTriangles = T->NbTriangles();
  Standard_Integer n1, n2, n3;
  const Poly_Array1OfTriangle& Triangles = T->Triangles();
  for (i = 1; i <= nbTriangles; i++) {
    if (!Compact) OS << setw(10) << i << " : ";
    Triangles(i).Get(n1, n2, n3);
    if (!Compact) OS << setw(10);
    OS << n1 << " ";
    if (!Compact) OS << setw(10);
    OS << n2 << " ";
    if (!Compact) OS << setw(10);
    OS << n3 << "\n";
  }

}

//=======================================================================
//function : Write
//purpose  : 
//=======================================================================

void Poly::Write(const Handle(Poly_Polygon3D)& P, 
		 Standard_OStream&             OS, 
		 const Standard_Boolean        Compact)
{
  OS << "Poly_Polygon3D\n";
  if (Compact) {
    OS << P->NbNodes() << " ";
    OS << ((P->HasParameters()) ? "1" : "0") << "\n";
  }
  else {
    OS << setw(8) << P->NbNodes() << " Nodes\n";
    OS << ((P->HasParameters()) ? "with" : "without") << " parameters\n";
  }

  // write the deflection

  if (!Compact) OS << "Deflection : ";
  OS << P->Deflection() << "\n";

  // write the nodes

  if (!Compact) OS << "\nNodes :\n";

  Standard_Integer i, nbNodes = P->NbNodes();
  const TColgp_Array1OfPnt& Nodes = P->Nodes();
  for (i = 1; i <= nbNodes; i++) {
    if (!Compact) OS << setw(10) << i << " : ";
    if (!Compact) OS << setw(17);
    OS << Nodes(i).X() << " ";
    if (!Compact) OS << setw(17);
    OS << Nodes(i).Y() << " ";
    if (!Compact) OS << setw(17);
    OS << Nodes(i).Z() << "\n";
  }

  if (P->HasParameters()) {
    if (!Compact) OS << "\nParameters :\n";
    const TColStd_Array1OfReal& Param = P->Parameters();
    for (i = 1; i <= nbNodes; i++) {
      OS << Param(i) << " ";
    }
    OS <<"\n";
  }


}


//=======================================================================
//function : Write
//purpose  : 
//=======================================================================

void Poly::Write(const Handle(Poly_Polygon2D)& P, 
		 Standard_OStream&             OS, 
		 const Standard_Boolean        Compact)
{
  OS << "Poly_Polygon2D\n";
  if (Compact) {
    OS << P->NbNodes() << " ";
  }
  else {
    OS << setw(8) << P->NbNodes() << " Nodes\n";
  }

  // write the deflection

  if (!Compact) OS << "Deflection : ";
  OS << P->Deflection() << "\n";

  // write the nodes

  if (!Compact) OS << "\nNodes :\n";

  Standard_Integer i, nbNodes = P->NbNodes();
  const TColgp_Array1OfPnt2d& Nodes = P->Nodes();
  for (i = 1; i <= nbNodes; i++) {
    if (!Compact) OS << setw(10) << i << " : ";
    if (!Compact) OS << setw(17);
    OS << Nodes(i).X() << " ";
    if (!Compact) OS << setw(17);
    OS << Nodes(i).Y() << "\n";
  }
}



//=======================================================================
//function : Dump
//purpose  : 
//=======================================================================

void Poly::Dump(const Handle(Poly_Triangulation)& T, Standard_OStream& OS)
{
  Poly::Write(T,OS,Standard_False);
}


//=======================================================================
//function : Dump
//purpose  : 
//=======================================================================

void Poly::Dump(const Handle(Poly_Polygon3D)& P, Standard_OStream& OS)
{
  Poly::Write(P,OS,Standard_False);
}


//=======================================================================
//function : Dump
//purpose  : 
//=======================================================================

void Poly::Dump(const Handle(Poly_Polygon2D)& P, Standard_OStream& OS)
{
  Poly::Write(P,OS,Standard_False);
}


//=======================================================================
//function : ReadTriangulation
//purpose  : 
//=======================================================================

Handle(Poly_Triangulation) Poly::ReadTriangulation(Standard_IStream& IS)
{
  // Read a triangulation
  
  char line[100];
  IS >> line;
  if (strcmp(line,"Poly_Triangulation")) {
    cout << "Not a Triangulation in the file" << endl;
    return Handle(Poly_Triangulation)();
  }

  Standard_Integer nbNodes, nbTriangles;
  Standard_Boolean hasUV;
  IS >> nbNodes >> nbTriangles >> hasUV;

  Standard_Real d;
  IS >> d;

  // read the 3d nodes
  Standard_Real x,y,z;
  Standard_Integer i;
  TColgp_Array1OfPnt Nodes(1, nbNodes);
  TColgp_Array1OfPnt2d UVNodes(1, nbNodes);

  for (i = 1; i <= nbNodes; i++) {
    IS >> x >> y >> z;
    Nodes(i).SetCoord(x,y,z);
  }

  // read the UV points if necessary

  if (hasUV) {
    for (i = 1; i <= nbNodes; i++) {
      IS >> x >> y;
      UVNodes(i).SetCoord(x,y);
    }
  }


  // read the triangles
  Standard_Integer n1,n2,n3;
  Poly_Array1OfTriangle Triangles(1, nbTriangles);
  for (i = 1; i <= nbTriangles; i++) {
    IS >> n1 >> n2 >> n3;
    Triangles(i).Set(n1,n2,n3);
  }

  
  Handle(Poly_Triangulation) T;

  if (hasUV) T =  new Poly_Triangulation(Nodes,UVNodes,Triangles);
  else T = new Poly_Triangulation(Nodes,Triangles);

  T->Deflection(d);

  return T;
}


//=======================================================================
//function : ReadPolygon3D
//purpose  : 
//=======================================================================

Handle(Poly_Polygon3D) Poly::ReadPolygon3D(Standard_IStream& IS)
{
  // Read a 3d polygon
  
  char line[100];
  IS >> line;
  if (strcmp(line,"Poly_Polygon3D")) {
    cout << "Not a Polygon3D in the file" << endl;
    return Handle(Poly_Polygon3D)();
  }

  Standard_Integer nbNodes;
  IS >> nbNodes;

  Standard_Boolean hasparameters;
  IS >> hasparameters;

  Standard_Real d;
  IS >> d;

  // read the nodes
  Standard_Real x,y,z;
  Standard_Integer i;
  TColgp_Array1OfPnt Nodes(1, nbNodes);

  for (i = 1; i <= nbNodes; i++) {
    IS >> x >> y >> z;
    Nodes(i).SetCoord(x,y,z);
  }

  TColStd_Array1OfReal Param(1,nbNodes);
  if (hasparameters) {
    for (i = 1; i <= nbNodes; i++) {
      IS >> Param(i);
    }
  }

  Handle(Poly_Polygon3D) P;
  if (!hasparameters)
    P = new Poly_Polygon3D(Nodes);
  else 
    P = new Poly_Polygon3D(Nodes, Param);

  P->Deflection(d);

  return P;
}

//=======================================================================
//function : ReadPolygon3D
//purpose  : 
//=======================================================================

Handle(Poly_Polygon2D) Poly::ReadPolygon2D(Standard_IStream& IS)
{
  // Read a 2d polygon
  
  char line[100];
  IS >> line;
  if (strcmp(line,"Poly_Polygon2D")) {
    cout << "Not a Polygon2D in the file" << endl;
    return Handle(Poly_Polygon2D)();
  }

  Standard_Integer nbNodes;
  IS >> nbNodes;

  Standard_Real d;
  IS >> d;

  // read the nodes
  Standard_Real x,y;
  Standard_Integer i;
  TColgp_Array1OfPnt2d Nodes(1, nbNodes);

  for (i = 1; i <= nbNodes; i++) {
    IS >> x >> y;
    Nodes(i).SetCoord(x,y);
  }

  Handle(Poly_Polygon2D) P = 
    new Poly_Polygon2D(Nodes);
  
  P->Deflection(d);

  return P;
}

