//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
//
//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2.1 of the License.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
//
//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//

//  VISU OBJECT : interactive object for VISU entities implementation
//  File   : VISUConfig.hh
//  Author : Alexey PETROV
//  Module : VISU
//
#ifndef __VISU_CONFIG_H__
#define __VISU_CONFIG_H__

#include "VISU_I.hxx"

// IDL headers
#include "SALOMEconfig.h"
#include CORBA_SERVER_HEADER(VISU_Gen)
#include CORBA_SERVER_HEADER(MED)
#include CORBA_SERVER_HEADER(SALOMEDS)
#include CORBA_SERVER_HEADER(SALOMEDS_Attributes)

#include "SALOME_NamingService.hxx"
#include "SALOME_LifeCycleCORBA.hxx"
#include "Utils_CorbaException.hxx"
#include "utilities.h"

#include "SALOMEDSClient_SObject.hxx"
#include "SALOMEDSClient_Study.hxx"

// QT headers
#include <QString>
#include <QThread>
#include <QFileInfo>
#include <QApplication>
#include <QMutex>

// standard C++ headers
#include <stdio.h>

// STL headers
#include <map>
#include <deque>
#include <string>
#include <sstream>
#include <iostream>
#include <stdexcept>

class SUIT_Session;
class SUIT_ResourceMgr;
class SalomeApp_Study;


namespace VISU
{

  VISU_I_EXPORT SUIT_Session *GetSession();
  VISU_I_EXPORT SUIT_ResourceMgr *GetResourceMgr();

  //===========================================================================

  class VISU_Gen_i;

  class VISU_I_EXPORT Base_i : public virtual POA_VISU::Base,
			       public virtual PortableServer::RefCountServantBase
  {
  public:
    typedef VISU::Base TInterface;

    Base_i();
    virtual ~Base_i();
    virtual char* GetID();
    virtual VISU::VISUType GetType() = 0;

  protected:
    std::string myID;

  protected:
    static QMutex* myMutex;
    static CORBA::ORB_var myOrb;
    static PortableServer::POA_var myPoa;
    static SALOME_NamingService* myNamingService;
    static VISU_Gen_i* myVisuGenImpl;
    static SALOME_LifeCycleCORBA* myEnginesLifeCycle;

  public:
    static CORBA::ORB_var GetORB() { return myOrb;}
    static PortableServer::POA_var GetPOA() { return myPoa;}
    static SALOME_NamingService* GetNS() { return myNamingService;}
    static SALOME_LifeCycleCORBA* GetLCC() { return myEnginesLifeCycle;}
    static VISU_Gen_i* GetVisuGenImpl() { return myVisuGenImpl;}
  };


  //===========================================================================
  class VISU_I_EXPORT Mutex
  {
    QMutex* myMutex;
    int isQAppLocked;
  public:
    Mutex(QMutex* theMutex);
    ~Mutex();
  };


  //===========================================================================
  class VISU_I_EXPORT Storable : public virtual Base_i 
  {
  public:
    std::string
    ToString();

    virtual
    const char* 
    GetComment() const = 0;


    //---------------------------------------------------------------
    typedef std::map<std::string, QString> TRestoringMap;

    typedef Storable* (*TStorableEngine)(SALOMEDS::SObject_ptr theSObject,
					 const TRestoringMap& theMap,
					 const std::string& thePrefix,
					 CORBA::Boolean theIsMultiFile);

    typedef std::map<std::string, TStorableEngine> TStorableEngineMap;

    static 
    void
    RegistryStorableEngine(const std::string& theComment, 
			   TStorableEngine theEngine);

    static
    Storable* 
    Create(SALOMEDS::SObject_ptr theSObject,
	   const std::string& theLocalPersistentID, 
	   const std::string& thePrefix,
	   CORBA::Boolean theIsMultiFile);


    //---------------------------------------------------------------
    static 
    VISU::VISUType
    Comment2Type(const std::string& theComment);

    static 
    VISU::VISUType
    RestoringMap2Type(const TRestoringMap& theRestoringMap);

    static 
    VISU::VISUType
    Stream2Type(const std::string& thePersistentString);

    static 
    VISU::VISUType
    SObject2Type(const _PTR(SObject)& theSObject);

    static 
    std::string
    CorrectPersistentString(const std::string& thePersistentString);

    static 
    std::string 
    FindEntry(SALOMEDS::Study_ptr theStudyDocument, 
	      const std::string& theStartEntry,
	      const TRestoringMap& theRestoringMap, 
	      int IsAllLevels = true);
  
    static 
    QString 
    FindValue(const TRestoringMap& theMap, 
	      const std::string& theArg, 
	      bool* theIsFind = NULL);

    static 
    QString
    FindValue(const TRestoringMap& theMap, 
	      const std::string& theArg, 
	      const QString& theDefaultValue);

    static
    void
    StringToMap(const QString& theString, 
		TRestoringMap& theMap);

    static
    TRestoringMap
    GetStorableMap(_PTR(SObject) theSObject);

    static
    SALOMEDS::SObject_ptr 
    GetResultSO(SALOMEDS::SObject_ptr theSObject);

    static
    void
    DataToStream(std::ostringstream& theStr, 
		 const QString& theName, 
		 const QString& theVal);

    static 
    void
    DataToStream(std::ostringstream& theStr, 
		 const QString& theName, 
		 int theVal);

    static 
    void
    DataToStream(std::ostringstream& theStr, 
		 const QString& theName, 
		 long theVal);

    static
    void
    DataToStream(std::ostringstream& theStr, 
		 const QString& theName, 
		 double theVal);

    //---------------------------------------------------------------
    virtual 
    CORBA::Boolean 
    CanCopy(SALOMEDS::SObject_ptr theObject);

    typedef std::string TFileName;
    typedef std::vector<TFileName> TFileNames;

    virtual 
    bool 
    CopyFrom(SALOMEDS::SObject_ptr theObject, 
	     CORBA::Long& theObjectID,
	     const std::string& theTmpDir,
	     TFileNames& theFileNames);


    //---------------------------------------------------------------
  protected:
    virtual 
    void 
    ToStream(std::ostringstream& theStr) = 0;

  private:
    static TStorableEngineMap myStorableEngineMap;
  };

  //===========================================================================
  VISU_I_EXPORT
  QString
  GenerateName(const std::string& theFmt, int theId);

  VISU_I_EXPORT 
  PortableServer::ServantBase_var 
  GetServant(CORBA::Object_ptr theObject);

  VISU_I_EXPORT
  CORBA::Object_var
  ClientSObjectToObject(_PTR(SObject) theSObject);

  VISU_I_EXPORT
  CORBA::Object_var
  SObjectToObject(SALOMEDS::SObject_ptr);

  VISU_I_EXPORT
  _PTR(SComponent) 
  ClientFindOrCreateVisuComponent(_PTR(Study) theStudyDocument);

  VISU_I_EXPORT 
  SALOMEDS::SComponent_var 
  FindOrCreateVisuComponent(SALOMEDS::Study_ptr theStudyDocument);

  const char* const NO_ICON = "";
  const char* const NO_IOR = "";
  const char* const NO_NAME = "";
  const char* const NO_PERFSITENT_REF = "";
  const char* const NO_COMMENT = "";

  VISU_I_EXPORT
  std::string 
  CreateAttributes(SALOMEDS::Study_ptr theStudyDocument,
		   const std::string& theFatherEntry, 
		   const std::string& theIconName,
		   const std::string& theIOR, 
		   const std::string& theName,
		   const std::string& thePersistentRef, 
		   const std::string& theComment,
		   CORBA::Boolean theCreateNew = true);

  VISU_I_EXPORT
  std::string 
  CreateAttributes(_PTR(Study) theStudyDocument,
		   const std::string& theFatherEntry, 
		   const std::string& theIconName,
		   const std::string& theIOR, 
		   const std::string& theName,
		   const std::string& thePersistentRef, 
		   const std::string& theComment,
		   CORBA::Boolean theCreateNew = true);

  VISU_I_EXPORT
  SALOMEDS::SObject_var
  GetSObject(_PTR(SObject));

  VISU_I_EXPORT
  _PTR(SObject) 
  GetClientSObject(SALOMEDS::SObject_ptr theSObject, 
		   _PTR(Study) theStudy);

  VISU_I_EXPORT
  SALOMEDS::Study_var 
  GetDSStudy(_PTR(Study) theStudy);

  VISU_I_EXPORT
  SalomeApp_Study* 
  GetGUIStudy(SALOMEDS::Study_ptr theStudy);

  VISU_I_EXPORT
  _PTR(Study) 
  GetStudy(SALOMEDS::Study_ptr theStudy);

  VISU_I_EXPORT
  void
  RemoveFromStudy(SALOMEDS::SObject_ptr theSObject,
		  bool theIsAttrOnly = true,
		  bool theDestroySubObjects = false);
  VISU_I_EXPORT
  void 
  RemoveFromStudy(_PTR(SObject) theSObject,
		  bool theIsAttrOnly = true,
		  bool theDestroySubObjects = false);
}

#endif
