#include <d3d9.h>
#include <windows.h>

// include required OCCT headers
#include <Standard_Version.hxx>
#include <Message_ProgressIndicator.hxx>
//for OCC graphic
#include <WNT_Window.hxx>
#include <WNT_WClass.hxx>
#include <Graphic3d_CView.hxx>
#include <Graphic3d_Camera.hxx>
#include <Graphic3d_TextureParams.hxx>
#include <D3DHost_GraphicDriver.hxx>
#include <D3DHost_View.hxx>
//for object display
#include <V3d_Viewer.hxx>
#include <V3d_View.hxx>
#include <AIS_InteractiveContext.hxx>
#include <AIS_Shape.hxx>
//topology
#include <TopoDS_Shape.hxx>
#include <TopoDS_Compound.hxx>
//brep tools
#include <BRep_Builder.hxx>
#include <BRepTools.hxx>
// iges I/E
#include <IGESControl_Reader.hxx>
#include <IGESControl_Controller.hxx>
#include <IGESControl_Writer.hxx>
#include <IFSelect_ReturnStatus.hxx>
#include <Interface_Static.hxx>
//step I/E
#include <STEPControl_Reader.hxx>
#include <STEPControl_Writer.hxx>
//for stl export
#include <StlAPI_Writer.hxx>
//for vrml export
#include <VrmlAPI_Writer.hxx>
//wrapper of pure C++ classes to ref classes
#include <NCollection_Haft.h>

#include <vcclr.h>

// list of required OCCT libraries
#pragma comment(lib, "TKernel.lib")
#pragma comment(lib, "TKMath.lib")
#pragma comment(lib, "TKBRep.lib")
#pragma comment(lib, "TKXSBase.lib")
#pragma comment(lib, "TKService.lib")
#pragma comment(lib, "TKV3d.lib")
#pragma comment(lib, "TKOpenGl.lib")
#pragma comment(lib, "TKD3dHost.lib")
#pragma comment(lib, "TKIGES.lib")
#pragma comment(lib, "TKSTEP.lib")
#pragma comment(lib, "TKStl.lib")
#pragma comment(lib, "TKVrml.lib")

#pragma comment(lib, "D3D9.lib")

//! Auxiliary tool for converting C# string into UTF-8 string.
static TCollection_AsciiString toAsciiString (String^ theString)
{
  if (theString == nullptr)
  {
    return TCollection_AsciiString();
  }

  pin_ptr<const wchar_t> aPinChars = PtrToStringChars (theString);
  const wchar_t* aWCharPtr = aPinChars;
  if (aWCharPtr == NULL
  || *aWCharPtr == L'\0')
  {
    return TCollection_AsciiString();
  }
  return TCollection_AsciiString (aWCharPtr);
}

/// <summary>
/// Proxy class encapsulating calls to OCCT C++ classes within
/// C++/CLI class visible from .Net (CSharp)
/// </summary>
public ref class OCCTProxyD3D
{
public:

  OCCTProxyD3D() {}

  // ============================================
  // Viewer functionality
  // ============================================

  /// <summary>
  ///Initialize a viewer
  /// </summary>
  /// <param name="theWnd">System.IntPtr that contains the window handle (HWND) of the control</param>
  bool InitViewer()
  {
    myGraphicDriver() = new D3DHost_GraphicDriver();
    myGraphicDriver()->ChangeOptions().buffersNoSwap = true;
    //myGraphicDriver()->ChangeOptions().contextDebug = true;

    myViewer() = new V3d_Viewer (myGraphicDriver());
    myViewer()->SetDefaultLights();
    myViewer()->SetLightOn();
    myView() = myViewer()->CreateView();

    static Handle(WNT_WClass) aWClass = new WNT_WClass ("OCC_Viewer", NULL, CS_OWNDC);
    Handle(WNT_Window) aWNTWindow = new WNT_Window ("OCC_Viewer", aWClass, WS_POPUP, 64, 64, 64, 64);
    aWNTWindow->SetVirtual (Standard_True);
    myView()->SetWindow(aWNTWindow);
    myAISContext() = new AIS_InteractiveContext (myViewer());
    myAISContext()->UpdateCurrentViewer();
    myView()->MustBeResized();
    return true;
  }

  /// <summary> Resizes custom FBO for Direct3D output. </summary>
  System::IntPtr ResizeBridgeFBO (int theWinSizeX,
                                  int theWinSizeY)
  {
    Handle(WNT_Window) aWNTWindow = Handle(WNT_Window)::DownCast (myView()->Window());
    aWNTWindow->SetPos (0, 0, theWinSizeX, theWinSizeY);
    myView()->MustBeResized();
    myView()->Invalidate();
    return System::IntPtr(Handle(D3DHost_View)::DownCast (myView()->View())->D3dColorSurface());
  }

  /// <summary>
  /// Make dump of current view to file
  /// </summary>
  /// <param name="theFileName">Name of dump file</param>
  bool Dump (const TCollection_AsciiString& theFileName)
  {
    if (myView().IsNull())
    {
      return false;
    }
    myView()->Redraw();
    return myView()->Dump (theFileName.ToCString()) != Standard_False;
  }

  /// <summary>
  ///Redraw view
  /// </summary>
  void RedrawView()
  {
    if (!myView().IsNull())
    {
      myView()->Redraw();
    }
  }

  /// <summary>
  ///Update view
  /// </summary>
  void UpdateView(void)
  {
    if (!myView().IsNull())
    {
      myView()->MustBeResized();
    }
  }

  /// <summary>
  ///Set computed mode in false
  /// </summary>
  void SetDegenerateModeOn()
  {
    if (!myView().IsNull())
    {
      myView()->SetComputedMode (Standard_False);
      myView()->Redraw();
    }
  }

  /// <summary>
  ///Set computed mode in true
  /// </summary>
  void SetDegenerateModeOff()
  {
    if (!myView().IsNull())
    {
      myView()->SetComputedMode (Standard_True);
      myView()->Redraw();
    }
  }

  /// <summary>
  ///Fit all
  /// </summary>
  void WindowFitAll (int theXmin, int theYmin,
                     int theXmax, int theYmax)
  {
    if (!myView().IsNull())
    {
      myView()->WindowFitAll (theXmin, theYmin, theXmax, theYmax);
    }
  }

  /// <summary>
  ///Current place of window
  /// </summary>
  /// <param name="theZoomFactor">Current zoom</param>
  void Place (int theX, int theY, float theZoomFactor)
  {	
    Standard_Real aZoomFactor = theZoomFactor;
    if (!myView().IsNull())
    {
      myView()->Place (theX, theY, aZoomFactor);
    }
  }

  /// <summary>
  ///Set Zoom
  /// </summary>
  void Zoom (int theX1, int theY1, int theX2, int theY2)
  {
    if (!myView().IsNull())
    {
      myView()->Zoom (theX1, theY1, theX2, theY2);
    }
  }

  /// <summary>
  ///Set Pan
  /// </summary>
  void Pan (int theX, int theY)
  {
    if (!myView().IsNull())
    {
      myView()->Pan (theX, theY);
    }
  }

  /// <summary>
  ///Rotation
  /// </summary>
  void Rotation (int theX, int theY)
  {
    if (!myView().IsNull())
    {
      myView()->Rotation (theX, theY);
    }
  }

  /// <summary>
  ///Start rotation
  /// </summary>
  void StartRotation (int theX, int theY)
  {
    if (!myView().IsNull())
    {
      myView()->StartRotation (theX, theY);
    }
  }

  /// <summary>
  ///Select by rectangle
  /// </summary>
  void Select (int theX1, int theY1, int theX2, int theY2)
  {
    if (!myAISContext().IsNull())
    {
      myAISContext()->Select (theX1, theY1, theX2, theY2, myView(), Standard_True);
    }
  }

  /// <summary>
  ///Select by click
  /// </summary>
  void Select()
  {
    if (!myAISContext().IsNull())
    {
      myAISContext()->Select (Standard_True);
    }
  }

  /// <summary>
  ///Move view
  /// </summary>
  void MoveTo (int theX, int theY)
  {
    if (!myAISContext().IsNull() && !myView().IsNull())
    {
      myAISContext()->MoveTo (theX, theY, myView(), Standard_True);
    }
  }

  /// <summary>
  ///Select by rectangle with pressed "Shift" key
  /// </summary>
  void ShiftSelect (int theX1, int theY1, int theX2, int theY2)
  {
    if (!myAISContext().IsNull() && !myView().IsNull())
    {
      myAISContext()->ShiftSelect (theX1, theY1, theX2, theY2, myView(), Standard_True);
    }
  }

  /// <summary>
  ///Select by "Shift" key
  /// </summary>
  void ShiftSelect()
  {
    if (!myAISContext().IsNull())
    {
      myAISContext()->ShiftSelect (Standard_True);
    }
  }

  /// <summary>
  ///Set background color
  /// </summary>
  void BackgroundColor (int& theRed, int& theGreen, int& theBlue)
  {
    if (!myView().IsNull())
    {
      Quantity_Color aColor = myView()->BackgroundColor();
      theRed   = (int )aColor.Red()   * 255;
      theGreen = (int )aColor.Green() * 255;
      theBlue  = (int )aColor.Blue()  * 255;
    }
  }

  /// <summary>
  ///Get background color Red
  /// </summary>
  int GetBGColR()
  {
    int anRgb[3];
    BackgroundColor (anRgb[0], anRgb[1], anRgb[2]);
    return anRgb[0];
  }

  /// <summary>
  ///Get background color Green
  /// </summary>
  int GetBGColG()
  {
    int anRgb[3];
    BackgroundColor (anRgb[0], anRgb[1], anRgb[2]);
    return anRgb[1];
  }

  /// <summary>
  ///Get background color Blue
  /// </summary>
  int GetBGColB()
  {
    int anRgb[3];
    BackgroundColor (anRgb[0], anRgb[1], anRgb[2]);
    return anRgb[2];
  }

  /// <summary>
  ///Update current viewer
  /// </summary>
  void UpdateCurrentViewer()
  {
    if (!myAISContext().IsNull())
    {
      myAISContext()->UpdateCurrentViewer();
    }
  }

  /// <summary>
  ///Front side
  /// </summary>
  void FrontView()
  {
    if (!myView().IsNull())
    {
      myView()->SetProj (V3d_Yneg);
    }
  }

  /// <summary>
  ///Top side
  /// </summary>
  void TopView()
  {
    if (!myView().IsNull())
    {
      myView()->SetProj (V3d_Zpos);
    }
  }

  /// <summary>
  ///Left side
  /// </summary>
  void LeftView()
  {
    if (!myView().IsNull())
    {
      myView()->SetProj (V3d_Xneg);
    }
  }

  /// <summary>
  ///Back side
  /// </summary>
  void BackView()
  {
    if (!myView().IsNull())
    {
      myView()->SetProj (V3d_Ypos);
    }
  }

  /// <summary>
  ///Right side
  /// </summary>
  void RightView()
  {
    if (!myView().IsNull())
    {
      myView()->SetProj (V3d_Xpos);
    }
  }

  /// <summary>
  ///Bottom side
  /// </summary>
  void BottomView()
  {
    if (!myView().IsNull())
    {
      myView()->SetProj (V3d_Zneg);
    }
  }

  /// <summary>
  ///Axo side
  /// </summary>
  void AxoView()
  {
    if (!myView().IsNull())
    {
      myView()->SetProj (V3d_XposYnegZpos);
    }
  }

  /// <summary>
  ///Scale
  /// </summary>
  float Scale()
  {
    return myView().IsNull()
         ? -1.0f
         : float(myView()->Scale());
  }

  /// <summary>
  ///Zoom in all view
  /// </summary>
  void ZoomAllView()
  {
    if (!myView().IsNull())
    {
      myView()->FitAll();
      myView()->ZFitAll();
    }
  }

  /// <summary>
  ///Reset view
  /// </summary>
  void Reset()
  {
    if (!myView().IsNull())
    {
      myView()->Reset();
    }
  }

  /// <summary>
  ///Set display mode of objects
  /// </summary>
  /// <param name="theMode">Set current mode</param>
  void SetDisplayMode (int theMode)
  {
    if (myAISContext().IsNull())
    {
      return;
    }

    AIS_DisplayMode aCurrentMode = theMode == 0
                                 ? AIS_WireFrame
                                 : AIS_Shaded;
    if (myAISContext()->NbSelected() == 0)
    {
       myAISContext()->SetDisplayMode (aCurrentMode, Standard_False);
    }
    else
    {
       for (myAISContext()->InitSelected(); myAISContext()->MoreSelected(); myAISContext()->NextSelected())
       {
         myAISContext()->SetDisplayMode (myAISContext()->SelectedInteractive(), theMode, Standard_False);
       }
    }
    myAISContext()->UpdateCurrentViewer();
  }

  /// <summary>
  ///Set color
  /// </summary>
  void SetColor (int theR, int theG, int theB)
  {
    if (myAISContext().IsNull())
    {
      return;
    }

    Quantity_Color aCol (theR / 255.0, theG / 255.0, theB / 255.0, Quantity_TOC_RGB);
    for (; myAISContext()->MoreSelected(); myAISContext()->NextSelected())
    {
      myAISContext()->SetColor (myAISContext()->SelectedInteractive(), aCol, false);
    }
    myAISContext()->UpdateCurrentViewer();
  }

  /// <summary>
  ///Get object color red
  /// </summary>
  int GetObjColR()
  {
    int anRgb[3];
    ObjectColor (anRgb[0], anRgb[1], anRgb[2]);
    return anRgb[0];
  }

  /// <summary>
  ///Get object color green
  /// </summary>
  int GetObjColG()
  {
    int anRgb[3];
    ObjectColor (anRgb[0], anRgb[1], anRgb[2]);
    return anRgb[1];
  }

  /// <summary>
  ///Get object color blue
  /// </summary>
  int GetObjColB()
  {
    int anRgb[3];
    ObjectColor (anRgb[0], anRgb[1], anRgb[2]);
    return anRgb[2];
  }

  /// <summary>
  ///Get object color R/G/B
  /// </summary>
  void ObjectColor (int& theRed, int& theGreen, int& theBlue)
  {
    if (myAISContext().IsNull())
    {
      return;
    }

    theRed   = 255;
    theGreen = 255;
    theBlue  = 255;
    myAISContext()->InitSelected();
    if (!myAISContext()->MoreSelected())
    {
      return;
    }

    Handle(AIS_InteractiveObject) aCurrent = myAISContext()->SelectedInteractive();
    if (aCurrent->HasColor())
    {
      Quantity_Color anObjCol;
      myAISContext()->Color (aCurrent, anObjCol);
      theRed   = int(anObjCol.Red()   * 255.0);
      theGreen = int(anObjCol.Green() * 255.0);
      theBlue  = int(anObjCol.Blue()  * 255.0);
    }
  }

  /// <summary>
  ///Set background color R/G/B
  /// </summary>
  void SetBackgroundColor (int theRed, int theGreen, int theBlue)
  {
    if (!myView().IsNull())
    {
      myView()->SetBackgroundColor (Quantity_TOC_RGB, theRed / 255.0, theGreen / 255.0, theBlue / 255.0);
    }
  }

  /// <summary>
  ///Erase objects
  /// </summary>
  void EraseObjects()
  {
    if (myAISContext().IsNull())
    {
      return;
    }

    myAISContext()->EraseSelected (Standard_False);
    myAISContext()->ClearSelected (Standard_True);
  }

  /// <summary>
  ///Get version
  /// </summary>
  float GetOCCVersion()
  {
    return (float )OCC_VERSION;
  }

  /// <summary>
  ///set material
  /// </summary>
  void SetMaterial (int theMaterial)
  {
    if (myAISContext().IsNull())
    {
      return;
    }
    for (myAISContext()->InitSelected(); myAISContext()->MoreSelected(); myAISContext()->NextSelected())
    {
      myAISContext()->SetMaterial (myAISContext()->SelectedInteractive(), (Graphic3d_NameOfMaterial )theMaterial, Standard_False);
    }
    myAISContext()->UpdateCurrentViewer();
  }

  /// <summary>
  ///set transparency
  /// </summary>
  void SetTransparency (int theTrans)
  {
    if (myAISContext().IsNull())
    {
      return;
    }
    for (myAISContext()->InitSelected(); myAISContext()->MoreSelected(); myAISContext()->NextSelected())
    {
      myAISContext()->SetTransparency (myAISContext()->SelectedInteractive(), ((Standard_Real )theTrans) / 10.0, Standard_False);
    }
    myAISContext()->UpdateCurrentViewer();
  }

  /// <summary>
  ///Return true if object is selected
  /// </summary>
  bool IsObjectSelected()
  {
    if (myAISContext().IsNull())
    {
      return false;
    }
    myAISContext()->InitSelected();
    return myAISContext()->MoreSelected() != Standard_False;
  }

  /// <summary>
  ///Return display mode
  /// </summary>
  int DisplayMode()
  {
    if (myAISContext().IsNull())
    {
      return -1;
    }

    bool isOneOrMoreInShading   = false;
    bool isOneOrMoreInWireframe = false;
    for (myAISContext()->InitSelected(); myAISContext()->MoreSelected(); myAISContext()->NextSelected())
    {
      if (myAISContext()->IsDisplayed (myAISContext()->SelectedInteractive(), AIS_Shaded))
      {
        isOneOrMoreInShading = true;
      }
      if (myAISContext()->IsDisplayed (myAISContext()->SelectedInteractive(), AIS_WireFrame))
      {
        isOneOrMoreInWireframe = true;
      }
    }
    if (isOneOrMoreInShading
     && isOneOrMoreInWireframe)
    {
      return 10;
    }
    else if (isOneOrMoreInShading)
    {
      return 1;
    }
    else if (isOneOrMoreInWireframe)
    {
      return 0;
    }
    return -1;
  }

  /// <summary>
  ///Set AISContext
  /// </summary>
  bool SetAISContext (OCCTProxyD3D^ theViewer)
  {
     this->myAISContext() = theViewer->GetContext();
     if (myAISContext().IsNull())
     {
       return false;
     }
    return true;
  }

  /// <summary>
  ///Get AISContext
  /// </summary>
  Handle(AIS_InteractiveContext) GetContext()
  {
    return myAISContext();
  }

public:
  // ============================================
  // Import / export functionality
  // ============================================

  /// <summary>
  ///Import BRep file
  /// </summary>
  /// <param name="theFileName">Name of import file</param>
  bool ImportBrep (System::String^ theFileName)
  {
    return ImportBrep (toAsciiString (theFileName));
  }

  /// <summary>
  ///Import BRep file
  /// </summary>
  /// <param name="theFileName">Name of import file</param>
  bool ImportBrep (const TCollection_AsciiString& theFileName)
  {
    TopoDS_Shape aShape;
    BRep_Builder aBuilder;
    if (!BRepTools::Read (aShape, theFileName.ToCString(), aBuilder))
    {
      return false;
    }

    Handle(AIS_Shape) aPrs = new AIS_Shape (aShape);
    myAISContext()->SetMaterial   (aPrs, Graphic3d_NOM_GOLD, Standard_False);
    myAISContext()->SetDisplayMode(aPrs, AIS_Shaded, Standard_False);
    myAISContext()->Display (aPrs, Standard_True);
    return true;
  }

  /// <summary>
  ///Import Step file
  /// </summary>
  /// <param name="theFileName">Name of import file</param>
  bool ImportStep (const TCollection_AsciiString& theFileName)
  {
    STEPControl_Reader aReader;
    if (aReader.ReadFile (theFileName.ToCString()) != IFSelect_RetDone)
    {
      return false;
    }

    bool isFailsonly = false;
    aReader.PrintCheckLoad( isFailsonly, IFSelect_ItemsByEntity );

    int aNbRoot = aReader.NbRootsForTransfer();
    aReader.PrintCheckTransfer (isFailsonly, IFSelect_ItemsByEntity);
    for (Standard_Integer aRootIter = 1; aRootIter <= aNbRoot; ++aRootIter)
    {
      aReader.TransferRoot (aRootIter);
      int aNbShap = aReader.NbShapes();
      if (aNbShap > 0)
      {
        for (int aShapeIter = 1; aShapeIter <= aNbShap; ++aShapeIter)
        {
          myAISContext()->Display (new AIS_Shape (aReader.Shape (aShapeIter)), Standard_False);
        }
        myAISContext()->UpdateCurrentViewer();
      }
    }
    return true;
  }

  /// <summary>
  ///Import Iges file
  /// </summary>
  /// <param name="theFileName">Name of import file</param>
  bool ImportIges (const TCollection_AsciiString& theFileName)
  {
    IGESControl_Reader aReader;
    if (aReader.ReadFile (theFileName.ToCString()) != IFSelect_RetDone)
    {
      return false;
    }

    aReader.TransferRoots();
    TopoDS_Shape aShape = aReader.OneShape();
    myAISContext()->Display (new AIS_Shape (aShape), Standard_False);
    myAISContext()->UpdateCurrentViewer();
    return true;
  }

  /// <summary>
  ///Export BRep file
  /// </summary>
  /// <param name="theFileName">Name of export file</param>
  bool ExportBRep (const TCollection_AsciiString& theFileName)
  {
    myAISContext()->InitSelected();
    if (!myAISContext()->MoreSelected())
    {
      return false;
    }

    Handle(AIS_Shape) anIS = Handle(AIS_Shape)::DownCast (myAISContext()->SelectedInteractive());
    return !anIS.IsNull()
         && BRepTools::Write (anIS->Shape(), theFileName.ToCString());
  }

  /// <summary>
  ///Export Step file
  /// </summary>
  /// <param name="theFileName">Name of export file</param>
  bool ExportStep (const TCollection_AsciiString& theFileName)
  {
    STEPControl_StepModelType aType = STEPControl_AsIs;
    STEPControl_Writer        aWriter;
    for (myAISContext()->InitSelected(); myAISContext()->MoreSelected(); myAISContext()->NextSelected())
    {
      Handle(AIS_Shape) anIS = Handle(AIS_Shape)::DownCast (myAISContext()->SelectedInteractive());
      if (anIS.IsNull())
      {
        return false;
      }

      TopoDS_Shape aShape = anIS->Shape();
      if (aWriter.Transfer (aShape, aType) != IFSelect_RetDone)
      {
        return false;
      }
    }
    return aWriter.Write (theFileName.ToCString()) == IFSelect_RetDone;
  }

  /// <summary>
  ///Export Iges file
  /// </summary>
  /// <param name="theFileName">Name of export file</param>
  bool ExportIges (const TCollection_AsciiString& theFileName)
  {
    IGESControl_Controller::Init();
    IGESControl_Writer aWriter (Interface_Static::CVal ("XSTEP.iges.unit"),
                                Interface_Static::IVal ("XSTEP.iges.writebrep.mode"));
    for (myAISContext()->InitSelected(); myAISContext()->MoreSelected(); myAISContext()->NextSelected())
    {
      Handle(AIS_Shape) anIS = Handle(AIS_Shape)::DownCast (myAISContext()->SelectedInteractive());
      if (anIS.IsNull())
      {
        return false;
      }

      aWriter.AddShape (anIS->Shape());
    }

    aWriter.ComputeModel();
    return aWriter.Write (theFileName.ToCString()) != Standard_False;
  }

  /// <summary>
  ///Export Vrml file
  /// </summary>
  /// <param name="theFileName">Name of export file</param>
  bool ExportVrml (const TCollection_AsciiString& theFileName)
  {
    TopoDS_Compound aRes;
    BRep_Builder    aBuilder;
    aBuilder.MakeCompound (aRes);
    for (myAISContext()->InitSelected(); myAISContext()->MoreSelected(); myAISContext()->NextSelected())
    {
      Handle(AIS_Shape) anIS = Handle(AIS_Shape)::DownCast (myAISContext()->SelectedInteractive());
      if (anIS.IsNull())
      {
        return false;
      }
      aBuilder.Add (aRes, anIS->Shape());
    }

    VrmlAPI_Writer aWriter;
    aWriter.Write (aRes, theFileName.ToCString());
    return true;
  }

  /// <summary>
  ///Export Stl file
  /// </summary>
  /// <param name="theFileName">Name of export file</param>
  bool ExportStl (const TCollection_AsciiString& theFileName)
  {
    TopoDS_Compound aComp;
    BRep_Builder    aBuilder;
    aBuilder.MakeCompound (aComp);
    for (myAISContext()->InitSelected(); myAISContext()->MoreSelected(); myAISContext()->NextSelected())
    {
      Handle(AIS_Shape) anIS = Handle(AIS_Shape)::DownCast (myAISContext()->SelectedInteractive());
      if (anIS.IsNull())
      {
        return false;
      }
      aBuilder.Add (aComp, anIS->Shape());
    }

    StlAPI_Writer aWriter;
    aWriter.Write (aComp, theFileName.ToCString());
    return true;
  }

  /// <summary>
  ///Define which Import/Export function must be called
  /// </summary>
  /// <param name="theFileName">Name of Import/Export file</param>
  /// <param name="theFormat">Determines format of Import/Export file</param>
  /// <param name="theIsImport">Determines is Import or not</param>
  bool TranslateModel (System::String^ theFileName, int theFormat, bool theIsImport)
  {
    bool  isResult  = false;
    const TCollection_AsciiString aFilename = toAsciiString (theFileName);
    if (theIsImport)
    {
      switch (theFormat)
      {
        case 0: isResult = ImportBrep  (aFilename); break;
        case 1: isResult = ImportStep  (aFilename); break;
        case 2: isResult = ImportIges  (aFilename); break;
      }
    }
    else 
    {
      switch (theFormat)
      {
        case 0: isResult = ExportBRep (aFilename); break;
        case 1: isResult = ExportStep (aFilename); break;
        case 2: isResult = ExportIges (aFilename); break;
        case 3: isResult = ExportVrml (aFilename); break;
        case 4: isResult = ExportStl  (aFilename); break;
        case 5: isResult = Dump (aFilename);      break;
      }
    }
    return isResult;
  }

  /// <summary>
  ///Initialize OCCTProxyD3D
  /// </summary>
  void InitOCCTProxy()
  {
    myGraphicDriver().Nullify();
    myViewer().Nullify();
    myView().Nullify();
    myAISContext().Nullify();
  }

private:

  NCollection_Haft<Handle(V3d_Viewer)>             myViewer;
  NCollection_Haft<Handle(V3d_View)>               myView;
  NCollection_Haft<Handle(AIS_InteractiveContext)> myAISContext;
  NCollection_Haft<Handle(D3DHost_GraphicDriver)>  myGraphicDriver;

};
