// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.


#include <BRep_Builder.hxx>
#include <Interface_CheckIterator.hxx>
#include <Interface_CheckTool.hxx>
#include <Interface_InterfaceModel.hxx>
#include <Interface_Protocol.hxx>
#include <Message_Messenger.hxx>
#include <Message_ProgressScope.hxx>
#include <Standard_Transient.hxx>
#include <TopoDS_Compound.hxx>
#include <TopoDS_Shape.hxx>
#include <Transfer_ActorOfTransientProcess.hxx>
#include <Transfer_TransferOutput.hxx>
#include <Transfer_TransientProcess.hxx>
#include <TransferBRep.hxx>
#include <TransferBRep_Reader.hxx>

TransferBRep_Reader::TransferBRep_Reader ()
    : theDone (Standard_False) , theFilest (0) , theNewpr (Standard_False)
      {    theShapes = new TopTools_HSequenceOfShape();  theTransi = new TColStd_HSequenceOfTransient();  }

    void  TransferBRep_Reader::SetProtocol
  (const Handle(Interface_Protocol)& protocol)
      {  theProto = protocol;  }

    Handle(Interface_Protocol)  TransferBRep_Reader::Protocol () const
      {  return theProto;  }

    void  TransferBRep_Reader::SetActor
  (const Handle(Transfer_ActorOfTransientProcess)& actor)
      {  theActor = actor;  }

    Handle(Transfer_ActorOfTransientProcess) TransferBRep_Reader::Actor () const
      {  return theActor;  }

    void  TransferBRep_Reader::SetFileStatus (const Standard_Integer status)
      {  theFilest = status;  }

    Standard_Integer  TransferBRep_Reader::FileStatus () const
      { return theFilest;  }

    Standard_Boolean  TransferBRep_Reader::FileNotFound () const
      {  return (theFilest < 0);  }

    Standard_Boolean  TransferBRep_Reader::SyntaxError () const
      {  return (theFilest > 0);  }


    void  TransferBRep_Reader::SetModel
  (const Handle(Interface_InterfaceModel)& model)
{
  theModel = model;
  Clear();
}

    Handle(Interface_InterfaceModel)  TransferBRep_Reader::Model () const
      {  return theModel;  }


    void  TransferBRep_Reader::Clear ()
{
  theDone = Standard_False;
  theShapes->Clear();  theTransi->Clear();
}

    Standard_Boolean  TransferBRep_Reader::CheckStatusModel
  (const Standard_Boolean withprint) const
{
  Interface_CheckTool cht (theModel,theProto);
  Interface_CheckIterator chl = cht.CompleteCheckList();
  if (withprint
  && !theProc.IsNull()
  && !theProc->Messenger().IsNull())
  {
    Message_Messenger::StreamBuffer aBuffer = theProc->Messenger()->SendInfo();
    chl.Print (aBuffer, theModel, Standard_False);
  }
  return chl.IsEmpty(Standard_True);
}

    Interface_CheckIterator  TransferBRep_Reader::CheckListModel () const
{
  Interface_CheckTool cht (theModel,theProto);
  Interface_CheckIterator chl = cht.CompleteCheckList();
  return chl;
}

    Standard_Boolean&  TransferBRep_Reader::ModeNewTransfer ()
      {  return theNewpr;  }

    Standard_Boolean  TransferBRep_Reader::BeginTransfer ()
{
  theDone = Standard_False;
  if (theModel.IsNull()) return Standard_False;

  if (theNewpr || theProc.IsNull())
    theProc = new Transfer_TransientProcess (theModel->NbEntities());
  else theProc->Clear();
  theProc->SetErrorHandle(Standard_True);
  theProc->SetModel (theModel);
  PrepareTransfer();
  theProc->SetActor (theActor);
  return Standard_True;
}

    void  TransferBRep_Reader::EndTransfer ()
{
  theShapes->Append ( TransferBRep::Shapes (theProc,Standard_True) );
  Standard_Integer i,nb = theProc->NbRoots();
  for (i = 1; i <= nb; i ++) {
    Handle(Standard_Transient) ent = theProc->Root(i);
    Handle(Standard_Transient) res = theProc->FindTransient(ent);
    if (!res.IsNull()) theTransi->Append (res);
  }
  theDone = Standard_True;
}


    void  TransferBRep_Reader::PrepareTransfer ()    {  }

    void  TransferBRep_Reader::TransferRoots (const Message_ProgressRange& theProgress)
{
  Clear();
  if (!BeginTransfer()) return;
  Transfer_TransferOutput TP (theProc,theModel);

  TP.TransferRoots(theProto, theProgress);
  EndTransfer();
}

    Standard_Boolean TransferBRep_Reader::Transfer (const Standard_Integer num,
                                                    const Message_ProgressRange& theProgress)
{
  if (!BeginTransfer()) return Standard_False;
  if (num <= 0 || num > theModel->NbEntities()) return Standard_False;
  Handle(Standard_Transient) ent = theModel->Value(num);
  Transfer_TransferOutput TP (theProc,theModel);

  if (theProc->TraceLevel() > 1) {
    Message_Messenger::StreamBuffer sout = theProc->Messenger()->SendInfo();
    sout<<"--  Transfer(Read) : ";  
    theModel->Print (ent, sout);
    sout<<std::endl;
  }
  TP.Transfer(ent, theProgress);
  theProc->SetRoot(ent);
  EndTransfer();
  return Standard_True;
}

    void  TransferBRep_Reader::TransferList
  (const Handle(TColStd_HSequenceOfTransient)& list,
   const Message_ProgressRange& theProgress)
{
  if (!BeginTransfer()) return;
  if (list.IsNull()) return;
  Transfer_TransferOutput TP (theProc,theModel);
  Standard_Integer i, nb = list->Length();
  Message_Messenger::StreamBuffer sout = theProc->Messenger()->SendInfo();

  if (theProc->TraceLevel() > 1) 
    sout<<"--  Transfer(Read-List) : "<<nb<<" Items"<<std::endl;
  Message_ProgressScope aPS(theProgress, NULL, nb);
  for (i = 1; i <= nb && aPS.More(); i++) {
    Message_ProgressRange aRange = aPS.Next();
    Handle(Standard_Transient) ent = list->Value(i);
    if (theModel->Number(ent) == 0) continue;

    if (theProc->TraceLevel() > 1) 
    {
      sout<<"--  Transfer(Read-List), Item "<<i<<" : ";
      theModel->Print (ent, sout);
      sout<<std::endl;
    }
    TP.Transfer (ent, aRange);
    theProc->SetRoot(ent);
  }
  EndTransfer();
}

    Standard_Boolean  TransferBRep_Reader::IsDone () const
      {  return theDone;  }

//   ######    RESULTAT : SHAPES    ######

    Standard_Integer  TransferBRep_Reader::NbShapes () const
      {  return theShapes->Length();  }

    Handle(TopTools_HSequenceOfShape)  TransferBRep_Reader::Shapes () const
      {  return theShapes;  }

    const TopoDS_Shape&  TransferBRep_Reader::Shape
  (const Standard_Integer num) const
      {  return theShapes->Value(num);  }

    TopoDS_Shape  TransferBRep_Reader::OneShape () const
{
  TopoDS_Shape res;
  Standard_Integer nb = theShapes->Length();
  if (nb == 0) return res;
  else if (nb == 1) return theShapes->Value(1);
  else {
    TopoDS_Compound C;
    BRep_Builder B;
    B.MakeCompound(C);
    for (Standard_Integer i = 1; i <= nb; i ++)  B.Add (C,theShapes->Value(i));
    return C;
  }
}

    TopoDS_Shape  TransferBRep_Reader::ShapeResult
  (const Handle(Standard_Transient)& ent) const
      {  return TransferBRep::ShapeResult (theProc,ent);  }

//   ######    RESULTAT : TRANSIENTS    ######

    Standard_Integer  TransferBRep_Reader::NbTransients () const
      {  return theTransi->Length();  }

    Handle(TColStd_HSequenceOfTransient)  TransferBRep_Reader::Transients () const
      {  return theTransi;  }

    Handle(Standard_Transient)  TransferBRep_Reader::Transient
  (const Standard_Integer num) const
      {  return theTransi->Value(num);  }


//   ######    CHECKS    ######

    Standard_Boolean  TransferBRep_Reader::CheckStatusResult
  (const Standard_Boolean withprint) const
{
  Interface_CheckIterator chl;
  if (!theProc.IsNull()) chl = theProc->CheckList(Standard_False);
  if (withprint
  && !theProc.IsNull()
  && !theProc->Messenger().IsNull())
  {
    Message_Messenger::StreamBuffer aBuffer = theProc->Messenger()->SendInfo();
    chl.Print (aBuffer, theModel, Standard_False);
  }
  return chl.IsEmpty(Standard_True);
}

    Interface_CheckIterator  TransferBRep_Reader::CheckListResult () const
{
  if (!theProc.IsNull()) return theProc->CheckList(Standard_False);
  Interface_CheckIterator chbid;  return chbid;
}

    Handle(Transfer_TransientProcess)  TransferBRep_Reader::TransientProcess
  () const
      {  return theProc;  }

TransferBRep_Reader::~TransferBRep_Reader()
{}
     
