// Created on: 2017-06-16
// Created by: Natalia ERMOLAEVA
// Copyright (c) 2017 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 <inspector/DFBrowser_OpenApplication.hxx>

#include <BinDrivers.hxx>
#include <BinLDrivers.hxx>
#include <BinXCAFDrivers.hxx>
#include <PCDM_ReadWriter.hxx>
#include <StdDrivers.hxx>
#include <StdLDrivers.hxx>
#include <STEPCAFControl_Reader.hxx>
#include <STEPCAFControl_Controller.hxx>
#include <TPrsStd_DriverTable.hxx>
#include <XCAFApp_Application.hxx>
#include <XCAFPrs_Driver.hxx>
#include <XmlDrivers.hxx>
#include <XmlLDrivers.hxx>
#include <XmlXCAFDrivers.hxx>
#include <UTL.hxx>

namespace DFBrowser_OpenApplication
{

// =======================================================================
// function : OpenApplication
// purpose :
// =======================================================================
Handle(TDocStd_Application) OpenApplication(const TCollection_AsciiString& theFileName,
                                            bool&                          isSTEPFile)
{
  Handle(TDocStd_Application) anApplication = CreateApplicationBySTEPFile(theFileName);
  if (!anApplication.IsNull())
  {
    isSTEPFile = true;
    return anApplication;
  }

  // Load static variables for STEPCAF (ssv; 16.08.2012)
  STEPCAFControl_Controller::Init();

  anApplication = new TDocStd_Application();
  // Initialize standard document formats at creation - they should
  // be available even if this DRAW plugin is not loaded by pload command
  StdLDrivers::DefineFormat(anApplication);
  BinLDrivers::DefineFormat(anApplication);
  XmlLDrivers::DefineFormat(anApplication);
  StdDrivers::DefineFormat(anApplication);
  BinDrivers::DefineFormat(anApplication);
  XmlDrivers::DefineFormat(anApplication);

  // Initialize XCAF formats
  BinXCAFDrivers::DefineFormat(anApplication);
  XmlXCAFDrivers::DefineFormat(anApplication);

  // Register driver in global table for displaying XDE documents
  // in 3d viewer using OCAF mechanics
  TPrsStd_DriverTable::Get()->AddDriver(XCAFPrs_Driver::GetID(), new XCAFPrs_Driver);

  Handle(TDocStd_Document) aDocument;
  PCDM_ReaderStatus        aStatus = anApplication->Open(theFileName, aDocument);
  if (aStatus != PCDM_RS_OK)
    return Handle(TDocStd_Application)();
  return anApplication;
}

// =======================================================================
// function : CreateApplicationBySTEPFile
// purpose :
// =======================================================================
Handle(TDocStd_Application) CreateApplicationBySTEPFile(const TCollection_AsciiString& theFileName)
{
  if (!theFileName.EndsWith(".step") && !theFileName.EndsWith(".stp"))
    return Handle(TDocStd_Application)();

  Handle(TDocStd_Application) aTmpApplication = XCAFApp_Application::GetApplication();
  STEPCAFControl_Reader       aStepReader;

  const TCollection_AsciiString aStr(theFileName);
  IFSelect_ReturnStatus         aStatus = aStepReader.ReadFile(aStr.ToCString());
  if (aStatus != IFSelect_RetDone)
    return Handle(TDocStd_Application)();

  aStepReader.SetColorMode(Standard_True);
  aStepReader.SetLayerMode(Standard_True);
  aStepReader.SetNameMode(Standard_True);

  Handle(TDocStd_Document) aDocument;
  aTmpApplication->NewDocument("BinOcaf", aDocument);
  return aStepReader.Transfer(aDocument) ? aTmpApplication : Handle(TDocStd_Application)();
}
} // namespace DFBrowser_OpenApplication