// File:	ShapeProcessAPI_ApplySequence.cxx
// Created:	Tue Jun 22 11:41:11 1999
// Author:	data exchange team
//		<det@friendox>


#include <ShapeProcessAPI_ApplySequence.ixx>
#include <TCollection_AsciiString.hxx>
#include <TopoDS_Iterator.hxx>
#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
#include <Message_Msg.hxx>
#include <Resource_Manager.hxx>
#include <ShapeProcess.hxx>
#include <ShapeProcess_OperLibrary.hxx>

//=======================================================================
//function : ShapeProcessAPI_ApplySequence
//purpose  : 
//=======================================================================

ShapeProcessAPI_ApplySequence::ShapeProcessAPI_ApplySequence(const Standard_CString rscName, 
							 const Standard_CString seqName)
{

  myContext = new ShapeProcess_ShapeContext(rscName);
  myContext->SetDetalisation ( TopAbs_FACE );
  TCollection_AsciiString str ( seqName );

  // initialize operators
  ShapeProcess_OperLibrary::Init ();
  
  mySeq = str;
}

//=======================================================================
//function : Context
//purpose  : 
//=======================================================================

Handle(ShapeProcess_ShapeContext)& ShapeProcessAPI_ApplySequence::Context()
{
  return myContext;
}

//=======================================================================
//function : PrepareShape
//purpose  : 
//=======================================================================

TopoDS_Shape ShapeProcessAPI_ApplySequence::PrepareShape(const TopoDS_Shape& shape,
                                                         const Standard_Boolean /*fillmap*/,
                                                         const TopAbs_ShapeEnum /*until*/)
{
  Handle(Resource_Manager) rsc = myContext->ResourceManager();
  myContext->Init(shape);
  
  TCollection_AsciiString str(mySeq);
  str += ".exec.op";
  if ( rsc->Find ( str.ToCString() ) ) {
    ShapeProcess::Perform ( myContext, mySeq.ToCString() );
  }
  
  return myContext->Result();
}

//=======================================================================
//function : ClearMap
//purpose  : 
//=======================================================================

 void ShapeProcessAPI_ApplySequence::ClearMap() 
{
  //myContext->Map().Clear();
}

//=======================================================================
//function : Map
//purpose  : 
//=======================================================================

const TopTools_DataMapOfShapeShape& ShapeProcessAPI_ApplySequence::Map() const
{
  return myContext->Map();
}

//=======================================================================
//function : PrintPreparationResult
//purpose  : 
//=======================================================================

 void  ShapeProcessAPI_ApplySequence::PrintPreparationResult (const Handle(Message_Printer)& printer) const
{
  Standard_Integer SS = 0, SN = 0, FF = 0, FS = 0, FN = 0;
  for (TopTools_DataMapIteratorOfDataMapOfShapeShape It (myContext->Map()); It.More(); It.Next()) {
    TopoDS_Shape keyshape = It.Key(), valueshape = It.Value();
    if (keyshape.ShapeType() == TopAbs_SHELL)
      if (valueshape.IsNull()) SN++;
      else SS++;
    else if (keyshape.ShapeType() == TopAbs_FACE)
      if (valueshape.IsNull()) FN++;
      else if (valueshape.ShapeType() == TopAbs_SHELL) FS++;
      else FF++;
  }
  
  // mapping
  Message_Msg EPMSG100 ("PrResult.Print.MSG100"); //Mapping:
  printer->SendEver (EPMSG100);
  Message_Msg TPMSG50 ("PrResult.Print.MSG50"); //  Shells:
  printer->SendEver (TPMSG50);
  Message_Msg EPMSG110 ("PrResult.Print.MSG110"); //    Result is Shell                 : %d
  EPMSG110.AddInteger (SS);
  printer->SendEver (EPMSG110);
  Message_Msg EPMSG150 ("PrResult.Print.MSG150"); //    No Result                       : %d
  EPMSG150.AddInteger (SN);
  printer->SendEver (EPMSG150);
  
  TCollection_AsciiString tmp110 (EPMSG110.Original()), tmp150  (EPMSG150.Original());
  EPMSG110.SetOriginal (tmp110.ToCString());
  EPMSG150.SetOriginal (tmp150.ToCString());

  Message_Msg TPMSG55 ("PrResult.Print.MSG55"); //  Faces:
  printer->SendEver (TPMSG55);
  Message_Msg EPMSG115 ("PrResult.Print.MSG115"); //    Result is Face                  : %d
  EPMSG115.AddInteger (FF);
  printer->SendEver (EPMSG115);
  EPMSG110.AddInteger (FS);
  printer->SendEver (EPMSG110);
  EPMSG150.AddInteger (FN);
  printer->SendEver (EPMSG150);
  
  // preparation ratio
  Standard_Real SPR = 1, FPR = 1;
  Standard_Integer STotalR = SS, FTotalR  = FF + FS;
  Standard_Integer NbS = STotalR + SN, NbF = FTotalR + FN;
  if (NbS > 0) SPR = 1. * (NbS - SN) / NbS;
  if (NbF > 0) FPR = 1. * (NbF - FN) / NbF;
  Message_Msg PMSG200 ("PrResult.Print.MSG200"); //Preparation ratio:
  printer->SendEver (PMSG200);
  Message_Msg PMSG205 ("PrResult.Print.MSG205"); //  Shells: %d per cent
  PMSG205.AddInteger ((Standard_Integer) (100 * SPR));
  printer->SendEver (PMSG205);
  Message_Msg PMSG210 ("PrResult.Print.MSG210"); //  Faces : %d per cent
  PMSG210.AddInteger ((Standard_Integer) (100 * FPR));
  printer->SendEver (PMSG210);
}

