/// This file is part of the X3DToolKit library
/// Copyright (C) 2002-2004  Yannick Le Goc (legoc@imag.fr)

/// http://artis.imag.fr/Members/Yannick.Legoc/X3D/

/// 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, or (at your option) any later version.

/// 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
#ifndef SIMPLEX3DGLSCENE_H
#define SIMPLEX3DGLSCENE_H

#include "X3DTypes.h"
#include "BBox.h"
#include "X3D_Scene.h"

namespace X3DTK {

class MemReleaser;

namespace X3D {

class Loader;
class InlineLoader;
class BBoxUpdater;
class GLBuilder;
class FileValidator;

}

namespace GL {

class Scene;
class Renderer;

}

/*! 
 *  \brief Class declared in <b><X3DTK/simplex3dglscene.h></b> defining a facade to allow an easy load and display of an X3D scene. 
 *
 *  It encapsulates basic operations or processors such as: 
 *  \li the loading of the file into an X3D scene graph (X3DTK::X3D::Loader)
 *  \li the validation of the X3D scene graph (X3DTK::X3D::FileValidator)
 *  \li the computation of the bounding box of the scene (X3DTK::X3D::BBoxUpdater)
 *  \li the building of the GL scene graph (X3D::GLBuilder) from the X3D scene graph
 *  \li the rendering of the GL scene graph (X3DTK::GL::Renderer) 
 *  \li the release of the different trees (X3DTK::MemReleaser).
 *
 *  In the case of adding a new node to the 
 *  X3D language, the X3D::Loader can be accessed to be customized by setting a new 
 *  X3DTK::X3D::X3DComponentCreator. Same for the processors.
 *
 *  \code 
 *   X3DTK::SimpleX3DGLScene scene;
 *   scene.getLoader()->setComponentCreator(new X3DTK::MyComponentCreator());
 *  \endcode
 *
 *  Examples: \ref X3DViewer, \ref glNormalViewer, \ref newNodeViewer, \ref icosahedronViewer,
 *  \ref simpleAnimationViewer
 */
 
class SimpleX3DGLScene
{
public:
  /// Constructor.
  SimpleX3DGLScene();
  /// Destructor.
  virtual ~SimpleX3DGLScene();
  
  /// Loads the scene from the file.
  virtual void load(const char *file, bool fileValidation = true);
  /// Draws the scene in an OpenGL context.
  virtual void draw();
  /// Draws the scene in an OpenGL selection context.
  virtual void select(double x, double y);
  /// Gets the bounding box minimum.
  inline const SFVec3f &getBBoxMin() const {return min;};
  /// Gets the bounding box maximum.
  inline const SFVec3f &getBBoxMax() const {return max;};
  /// Releases the memory.
  void release();

  /// Sets the loader.
  void setLoader(X3D::Loader *loader);
  /// Sets the BBoxUpdater.
  void setBBoxUpdater(X3D::BBoxUpdater *bboxUpdater);  
  /// Sets the GLBuilder.
  void setGLBuilder(X3D::GLBuilder *builder);  
  /// Sets the GLRenderer.
  void setGLRenderer(GL::Renderer *renderer);  
  /// Sets the MemReleaser.
  void setMemReleaser(MemReleaser *memReleaser);  
  /// Sets the FileValidator.
  void setFileValidator(X3D::FileValidator *fileValidator);  
  
  /// Gets the loader.
  inline X3D::Loader *getLoader() const {return _loader;};
  /// Gets the BBoxUpdater.
  inline X3D::BBoxUpdater *getBBoxUpdater() const {return _bboxupdater;};  
  /// Gets the GLBuilder.
  inline X3D::GLBuilder *getGLBuilder() const {return _builder;};  
  /// Gets the GLRenderer.
  inline GL::Renderer *getGLRenderer() const {return _renderer;};  
  /// Gets the MemReleaser.
  inline MemReleaser *getMemReleaser() const {return _releaser;};  

protected:
  X3D::Scene *scene;
  GL::Scene *glscene;
  
  SFVec3f min;
  SFVec3f max;
  
  /// Loads the file in an X3D scene graph.
  void loadFile(const char *file, bool fileValidation);
  /// Computes the bounding boxes of the shapes of the scene. Updates the minimum min and 
  /// the maximum max of the bounding box.
  void computeBBox();
  /// Builds the GL scene graph from the X3D scene graph.
  void buildGLScene();

private:
  X3D::Loader *_loader;
  X3D::InlineLoader *_inlineLoader;
  X3D::BBoxUpdater *_bboxupdater;
  X3D::GLBuilder *_builder;
  GL::Renderer *_renderer;
  MemReleaser *_releaser;
};

}

#endif
