// Author: Juan Carlos De Abreu (jcabreur@gmail.com)
//
// This file define a class inherent from SceneNode that allow have geometries
// in the scene tree.
//
// An use of this class can be;
//
// 1.- Create the geometry.
// const bool kDrawGeometry = true;
// const bool kCastGemetryShadows = true;
// const string kGeometryPath = "...";
// SmartPointer<ISceneNode> geometry_node = new GeometryNode(
//     LOAD_MODEL(geometryPath), 
//     kDrawGeometry,
//     kCastGemetryShadows);
//
// 2.- call the method apply tp update the model view matrix of the geometry.
// geometry_node->apply();
//
// 3.- Display the geometry.
// geometry_node->render(SOLID);

#ifndef SCENE_GEOMETRY_NODE_H__
#define SCENE_GEOMETRY_NODE_H__

#include "../../global.h"
#include "scene_node.h"
#include "../../Math/Matrix.h"
#include "../../Base/Memory/SmartPointer.h"
#include "../../Model/Model.h"
#include "../../Material/Material.h"

BEGIN_TEG_NAMESPACE();

class GeometryNode : public ISceneNode {
public:
  // GeometryNode constructors and destructor.
  GeometryNode();
  GeometryNode(SmartPointer<IModel> model, bool draw, bool cast_shadows);
  ~GeometryNode();

  // Accessor and mutator methods to GeometryNode attributes.
  bool draw() const;
  bool cast_shadows() const;
  bool use_default_material() const;
  float dist() const;
  const Mat4f& model_view() const;
  const SmartPointer<IModel>& model() const;
  const SmartPointer<Material>& custom_material() const;
  void set_draw(bool draw);
  void set_cast_shadows(bool cast_shadows);
  void set_use_default_material(bool use_default_material);
  void set_custom_material(const SmartPointer<Material>& custom_material);

  // Method to get the modelview for the geometry.
  virtual void apply();

  // Method to display the geometry.
  void render(int renderMode);
  
  // Method to copy the ISceneNode.
  virtual SmartPointer<ISceneNode> copy();
  AUTO_SIZE();

 private:
  // Pointer to the geometry and flags to know if draw the geometry and if the
  // geometry produce shadows.
  SmartPointer<IModel> model_;
  bool draw_;
  bool cast_shadows_;

  // Pointer to a custom material for render the geometry and a flag to know 
  // if use the default material.
  bool use_default_material_;
  SmartPointer<Material> custom_material_;

  // Distance to the vertex more near to the aye, transformation matrix of the 
  // geometry. This values are updated when the apply() method is called.
  float dist_;
  Mat4f model_view_;
  
  DISALLOW_COPY_AND_ASSIGN(GeometryNode);
};

END_TEG_NAMESPACE();

#endif  // SCENE_GEOMETRY_NODE_H__
