// File:	GeomInt_LineTool.cxx
// Created:	Wed Feb  8 10:00:15 1995
// Author:	Jacques GOUSSARD
//		<jag@topsn2>


#include <GeomInt_LineTool.ixx>


#include <IntPatch_TheWLineOfIntersection.hxx>
#include <IntPatch_TheRLineOfIntersection.hxx>
#include <IntPatch_TheALineOfIntersection.hxx>
#include <IntPatch_TheGLineOfIntersection.hxx>
#include <Precision.hxx>

//=======================================================================
//function : NbVertex
//purpose  : 
//=======================================================================
  Standard_Integer GeomInt_LineTool::NbVertex(const Handle(IntPatch_Line)& L)
{
  IntPatch_IType typl = L->ArcType();
  switch (typl) {
  case IntPatch_Analytic:
    return Handle(IntPatch_TheALineOfIntersection)::DownCast(L)->NbVertex();
  case IntPatch_Restriction:
    return Handle(IntPatch_TheRLineOfIntersection)::DownCast(L)->NbVertex();
  case IntPatch_Walking:
    return Handle(IntPatch_TheWLineOfIntersection)::DownCast(L)->NbVertex();
  default:
    return Handle(IntPatch_TheGLineOfIntersection)::DownCast(L)->NbVertex();
  }
}


//=======================================================================
//function : Vertex
//purpose  : 
//=======================================================================
  const IntPatch_ThePointOfIntersection & GeomInt_LineTool::Vertex
   (const Handle(IntPatch_Line)& L,
    const Standard_Integer I)
{
  IntPatch_IType typl = L->ArcType();
  switch (typl) {
  case IntPatch_Analytic:
    return Handle(IntPatch_TheALineOfIntersection)::DownCast(L)->Vertex(I);
  case IntPatch_Restriction:
    return Handle(IntPatch_TheRLineOfIntersection)::DownCast(L)->Vertex(I);
  case IntPatch_Walking:
    return Handle(IntPatch_TheWLineOfIntersection)::DownCast(L)->Vertex(I);
  default:
    return Handle(IntPatch_TheGLineOfIntersection)::DownCast(L)->Vertex(I);
  }
}


//=======================================================================
//function : FirstParameter
//purpose  : 
//=======================================================================
  Standard_Real GeomInt_LineTool::FirstParameter (const Handle(IntPatch_Line)& L)
{
  Standard_Real firstp=0;
  IntPatch_IType typl = L->ArcType();
  switch (typl) {
  case IntPatch_Analytic:
    {
      Handle(IntPatch_TheALineOfIntersection) alin = 
	Handle(IntPatch_TheALineOfIntersection)::DownCast(L);
      if (alin->HasFirstPoint()) {
	firstp = alin->FirstPoint().ParameterOnLine();
      }
      else {
	Standard_Boolean included;
	firstp = alin->FirstParameter(included);
	if (!included) {
	  firstp +=Epsilon(firstp);
	}
      }
      return firstp;
    }

  case IntPatch_Restriction:
    {
      Handle(IntPatch_TheRLineOfIntersection) rlin = 
	Handle(IntPatch_TheRLineOfIntersection)::DownCast(L);
      if (rlin->HasFirstPoint()) {
	firstp = rlin->FirstPoint().ParameterOnLine();
      }
      else {
	firstp = -Precision::Infinite(); // a voir selon le type de la ligne 2d
      }
      return firstp;
    }
   case IntPatch_Walking:
    {
      Handle(IntPatch_TheWLineOfIntersection) wlin = 
	Handle(IntPatch_TheWLineOfIntersection)::DownCast(L);
      if (wlin->HasFirstPoint()) {
	firstp = wlin->FirstPoint().ParameterOnLine();
      }
      else {
	firstp = 1.;
      }
      return firstp;
    }
	
  default:
    {
      Handle(IntPatch_TheGLineOfIntersection) glin = 
	Handle(IntPatch_TheGLineOfIntersection)::DownCast(L);
      if (glin->HasFirstPoint()) {
	firstp = glin->FirstPoint().ParameterOnLine();
      }
      else {
	switch (typl) {
	case IntPatch_Lin:
	case IntPatch_Parabola:
	case IntPatch_Hyperbola:
	  firstp = -Precision::Infinite();
	  break;

	case IntPatch_Circle:
	case IntPatch_Ellipse:
	  firstp = 0.;
	  break;
	default:
	  {
	  }
	}
      }
      return firstp;
    }
  }
}


//=======================================================================
//function : LastParameter
//purpose  : 
//=======================================================================
  Standard_Real GeomInt_LineTool::LastParameter (const Handle(IntPatch_Line)& L)
{
  Standard_Real lastp=0;
  IntPatch_IType typl = L->ArcType();
  switch (typl) {
  case IntPatch_Analytic:
    {
      Handle(IntPatch_TheALineOfIntersection) alin = 
	Handle(IntPatch_TheALineOfIntersection)::DownCast(L);
      if (alin->HasLastPoint()) {
	lastp = alin->LastPoint().ParameterOnLine();
      }
      else {
	Standard_Boolean included;
	lastp = alin->LastParameter(included);
	if (!included) {
	  lastp -=Epsilon(lastp);
	}
      }
      return lastp;
    }

  case IntPatch_Restriction:
    {
      Handle(IntPatch_TheRLineOfIntersection) rlin = 
	Handle(IntPatch_TheRLineOfIntersection)::DownCast(L);
      if (rlin->HasLastPoint()) {
	lastp = rlin->LastPoint().ParameterOnLine();
      }
      else {
	lastp = Precision::Infinite(); // a voir selon le type de la ligne 2d
      }
      return lastp;
    }
   case IntPatch_Walking:
    {
      Handle(IntPatch_TheWLineOfIntersection) wlin = 
	Handle(IntPatch_TheWLineOfIntersection)::DownCast(L);
      if (wlin->HasLastPoint()) {
	lastp = wlin->LastPoint().ParameterOnLine();
      }
      else {
	lastp = wlin->NbPnts();
      }
      return lastp;
    }
	
  default:
    {
      Handle(IntPatch_TheGLineOfIntersection) glin = 
	Handle(IntPatch_TheGLineOfIntersection)::DownCast(L);
      if (glin->HasLastPoint()) {
	lastp = glin->LastPoint().ParameterOnLine();
      }
      else {
	switch (typl) {
	case IntPatch_Lin:
	case IntPatch_Parabola:
	case IntPatch_Hyperbola:
	  lastp = Precision::Infinite();
	  break;

	case IntPatch_Circle:
	case IntPatch_Ellipse:
	  lastp = 2.*PI;
	  break;
	default:
	  {
	  }
	}
      }
      return lastp;
    }
  }
}


