// File:	TNaming_NamingTool.cxx
// Created:	Mon Feb 14 16:00:07 2000
// Author:	Denis PASCAL
//		<dp@dingox.paris1.matra-dtv.fr>


#include <TNaming_NamingTool.ixx>
#include <TNaming_NewShapeIterator.hxx> 
#include <TNaming_Iterator.hxx>


//=======================================================================
//function : IsForbiden
//purpose  : ANaming voir NamingTool
//=======================================================================

static Standard_Boolean IsForbiden(const TDF_LabelMap& Forbiden,
				   const TDF_Label&    Lab)
{
  if (Lab.IsRoot()) {
    return Standard_False;
  }
  if (Forbiden.Contains(Lab)) 
    return Standard_True;
  else {
    return IsForbiden(Forbiden,Lab.Father());
  }
}

//=======================================================================
//function : LastModif 
//purpose  : ANaming 
//=======================================================================

static void LastModif(      TNaming_NewShapeIterator& it,
		      const TopoDS_Shape&             S,
		            TopTools_MapOfShape&      MS,
		      const TDF_LabelMap&             Updated,
		      const TDF_LabelMap&             Forbiden)
{ 
  Standard_Boolean YaModif = Standard_False;
  
  for (; it.More(); it.Next()) {
    const TDF_Label&    Lab = it.Label();
    if (!Updated.IsEmpty() && !Updated.Contains(Lab))  continue;
    if (IsForbiden(Forbiden, Lab))                     continue;

    if (it.IsModification()) {
      YaModif = Standard_True;
      TNaming_NewShapeIterator it2(it);
      if (!it2.More()) {
	const TopoDS_Shape& S   = it.Shape();
	MS.Add (S);  // Modified
      }
      else
	LastModif(it2,it.Shape(),MS,Updated,Forbiden);
    }
  }
  if (!YaModif) MS.Add(S);  
}

//=======================================================================
//function : CurrentShape
//purpose  : ANaming
//=======================================================================

void TNaming_NamingTool::CurrentShape(const TDF_LabelMap&               Valid,
				      const TDF_LabelMap&               Forbiden,
				      const Handle(TNaming_NamedShape)& Att,
				      TopTools_MapOfShape&              MS)
{
  TDF_Label Lab = Att->Label();
  if (!Valid.IsEmpty() && !Valid.Contains(Lab)) {
    return;
  }
  TNaming_Iterator itL (Att);
  for (; itL.More(); itL.Next()) {
    const TopoDS_Shape& S = itL.NewShape();
    if (S.IsNull()) continue;
    TNaming_NewShapeIterator it(itL);
    if (!it.More()) {
      MS.Add(S);
    }
    else {
      LastModif(it, S, MS, Valid, Forbiden);
    }
  }
}

//=======================================================================
//function : CurrentShapeFromShape
//purpose  : ANaming
//=======================================================================
             
void TNaming_NamingTool::CurrentShapeFromShape(const TDF_LabelMap&               Valid,
					       const TDF_LabelMap&               Forbiden,
					       const TDF_Label&                  Acces,
					       const TopoDS_Shape&               S,
					       TopTools_MapOfShape&              MS)
{
  //Handle(TNaming_UsedShapes) US;
  //Acces.Root().FindAttribute(TNaming_UsedShapes::GetID(),US);
  //TNaming_NewShapeIterator it(S,US);
  TNaming_NewShapeIterator it(S,Acces);
  if (!it.More()) {
    MS.Add(S);
  }
  else {
    LastModif(it, S, MS, Valid, Forbiden);
  }
}

//=======================================================================
//function : MakeDescendants
//purpose  : ANaming
//=======================================================================

static void MakeDescendants (TNaming_NewShapeIterator&         it,
			     TDF_LabelMap&                     Descendants)
{
  for (; it.More(); it.Next()) {
    Descendants.Add(it.Label());
    if (!it.Shape().IsNull()) {
      TNaming_NewShapeIterator it2(it);
      MakeDescendants (it2,Descendants);
    }
  }
}

//=======================================================================
//function : BuildDescendants
//purpose  : ANaming
//=======================================================================

void TNaming_NamingTool::BuildDescendants (const Handle(TNaming_NamedShape)& NS,
					   TDF_LabelMap&                     Descendants)
{
  if (NS.IsNull()) return;
  Descendants.Add(NS->Label());
  TNaming_NewShapeIterator it(NS); 
  MakeDescendants (it,Descendants);
}
