// File:	MeshTest_DrawableUVDomain.cxx
// Created:	Thu Aug  4 13:19:47 1994
// Author:	Modeling
//		<modeling@bravox>


#include <MeshTest_DrawableUVDomain.ixx>
#include <TColStd_MapIteratorOfMapOfInteger.hxx>
#include <gp_Pnt2d.hxx>
#include <Draw_Color.hxx>
#include <Draw_ColorKind.hxx>

#include <BRepMesh_DataStructureOfDelaun.hxx>
#include <MeshDS_DegreeOfFreedom.hxx>
#include <BRepMesh_Triangle.hxx>
#include <BRepMesh_Edge.hxx>
#include <BRepMesh_Vertex.hxx>

//=======================================================================
//function : MeshTest_DrawableUVDomain
//purpose  : 
//=======================================================================

MeshTest_DrawableUVDomain::MeshTest_DrawableUVDomain
  (const Handle(BRepMesh_Discret)& D, const Standard_Integer Dom) :
  myMesh(D), myDomain(Dom)
{
}

//=======================================================================
//function : Is3D
//purpose  : 
//=======================================================================

Standard_Boolean MeshTest_DrawableUVDomain::Is3D() const 
{
  return Standard_False;
}

//=======================================================================
//function : DrawOn
//purpose  : 
//=======================================================================

void MeshTest_DrawableUVDomain::DrawOn(Draw_Display& D) const 
{
  if (!myMesh.IsNull()) {
    Handle(BRepMesh_DataStructureOfDelaun) DS = myMesh->Result();
    
    Standard_Integer nbc;
    D.SetColor(Draw_vert);
    Standard_Integer e1, e2, e3;
    Standard_Boolean o1, o2, o3, i, iTri;
    
    const TColStd_MapOfInteger& elems = DS->ElemOfDomain(myDomain);
    TColStd_MapIteratorOfMapOfInteger it;
    for (it.Initialize(elems); it.More(); it.Next()) {
      iTri = it.Key();
      const BRepMesh_Triangle& triang = myMesh->Triangle(iTri);
      if (triang.Movability()!=MeshDS_Deleted) {
	triang.Edges(e1, e2, e3, o1, o2, o3);
	const BRepMesh_Edge& ed1=myMesh->Edge(e1);
	if (ed1.Movability()!=MeshDS_Deleted) {
	  nbc=DS->ElemConnectedTo(e1).Extent();
	  if (nbc<=0) D.SetColor(Draw_bleu);
	  else if (nbc==1) D.SetColor(Draw_jaune);
	  else if (nbc==2) D.SetColor(Draw_vert);
	  else D.SetColor(Draw_corail);
	  D.MoveTo(myMesh->Vertex(ed1.FirstNode()).Coord());
	  D.DrawTo(myMesh->Vertex(ed1.LastNode()).Coord());
	}
	const BRepMesh_Edge& ed2=myMesh->Edge(e2);
	if (ed2.Movability()!=MeshDS_Deleted) {
	  nbc=DS->ElemConnectedTo(e2).Extent();
	  if (nbc<=0) D.SetColor(Draw_bleu);
	  else if (nbc==1) D.SetColor(Draw_jaune);
	  else if (nbc==2) D.SetColor(Draw_vert);
	  else D.SetColor(Draw_corail);
	  D.MoveTo(myMesh->Vertex(ed2.FirstNode()).Coord());
	  D.DrawTo(myMesh->Vertex(ed2.LastNode()).Coord());
	}
	const BRepMesh_Edge& ed3=myMesh->Edge(e3);
	if (ed3.Movability()!=MeshDS_Deleted) {
	  nbc=DS->ElemConnectedTo(e3).Extent();
	  if (nbc<=0) D.SetColor(Draw_bleu);
	  else if (nbc==1) D.SetColor(Draw_jaune);
	  else if (nbc==2) D.SetColor(Draw_vert);
	  else D.SetColor(Draw_corail);
	  D.MoveTo(myMesh->Vertex(ed3.FirstNode()).Coord());
	  D.DrawTo(myMesh->Vertex(ed3.LastNode()).Coord());
	}
      }
    }


    // highlighted triangles
    D.SetColor(Draw_blanc);
    
    for (i = 1; i <= (unsigned int ) myTriangles.Length(); i++) {
      const BRepMesh_Triangle& tri=DS->GetElement(myTriangles(i));
      tri.Edges(e1, e2, e3, o1, o2, o3); 
      const BRepMesh_Edge& ed1=myMesh->Edge(e1);
      if (ed1.Movability()!=MeshDS_Deleted) {
	D.MoveTo(myMesh->Vertex(ed1.FirstNode()).Coord());
	D.DrawTo(myMesh->Vertex(ed1.LastNode()).Coord());
      }
      const BRepMesh_Edge& ed2=myMesh->Edge(e2);
      if (ed2.Movability()!=MeshDS_Deleted) {
	D.MoveTo(myMesh->Vertex(ed2.FirstNode()).Coord());
	D.DrawTo(myMesh->Vertex(ed2.LastNode()).Coord());
      }
      const BRepMesh_Edge& ed3=myMesh->Edge(e3);
      if (ed3.Movability()!=MeshDS_Deleted) {
	D.MoveTo(myMesh->Vertex(ed3.FirstNode()).Coord());
	D.DrawTo(myMesh->Vertex(ed3.LastNode()).Coord());
      }
    }
    
    // highlighted edges and vertices
    D.SetColor(Draw_rouge);
    for (i = 1; i <= (unsigned int ) myEdges.Length(); i++) {
      const BRepMesh_Edge& ed=myMesh->Edge(myEdges(i));
      if (ed.Movability()!=MeshDS_Deleted) {
	D.MoveTo(gp_Pnt2d(myMesh->Vertex(ed.FirstNode()).Coord()));
	D.DrawTo(gp_Pnt2d(myMesh->Vertex(ed.LastNode()).Coord()));
      }
    }
    for (i = 1; i <= (unsigned int ) myVertices.Length(); i++) {
      D.DrawMarker(gp_Pnt2d(myMesh->Vertex(myVertices(i)).Coord()),Draw_Losange);
    }

  }

}

//=======================================================================
//function : Copy
//purpose  : 
//=======================================================================

Handle(Draw_Drawable3D) MeshTest_DrawableUVDomain::Copy() const 
{
  Handle(MeshTest_DrawableUVDomain) D =
    new MeshTest_DrawableUVDomain(myMesh,myDomain);
  return D;
}

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

void MeshTest_DrawableUVDomain::Dump(Standard_OStream& S) const 
{
  S << "UV mesh of domain " << myDomain << endl;
}

//=======================================================================
//function : Whatis
//purpose  : 
//=======================================================================

void MeshTest_DrawableUVDomain::Whatis(Draw_Interpretor& S) const 
{
  S << " UV mesh of a domain";
}


//=======================================================================
//function : Edges
//purpose  : 
//=======================================================================

TColStd_SequenceOfInteger& MeshTest_DrawableUVDomain::Edges()
{
  return myEdges;
}


//=======================================================================
//function : Vertices
//purpose  : 
//=======================================================================

TColStd_SequenceOfInteger& MeshTest_DrawableUVDomain::Vertices()
{
  return myVertices;
}
//=======================================================================
//function : Triangles
//purpose  : 
//=======================================================================

TColStd_SequenceOfInteger& MeshTest_DrawableUVDomain::Triangles()
{
  return myTriangles;
}
