// Author: Juan Carlos De Abreu (jcabreur@gmail.com)
//
// This file define a class that contain all the information neccessary for
// each object to create a shadow using the technique of volume shadows.

#ifndef SHADOW_SHADOW_INSTANCE_H__
#define SHADOW_SHADOW_INSTANCE_H__

#include "../Includes/Basic.h"
#include "../Math/Matrix.h"
#include "../Math/Plane/Plane-inl.h"
#include "../Model/Face.h"
#include "../Model/Model.h"
#include "../Model/ModelObj.h"
#include "../Math/Vector.h"
#include "../Base/Memory/SmartPointer.h"

BEGIN_TEG_NAMESPACE();

class ShadowPlane {
public:
  // Attributes
  math::Plane plane;					// Plane where are the vertex ...
  math::Vec3<unsigned int> neigh;		// face adyacents ...
  bool visible;						// To know if the face is front a light or not

  // Operators
  void operator = (const ShadowPlane& s);

  // Method to load and save the information related to a shadow plane.
  bool load(FILE* f);
  bool save(FILE* f) const;
};

class ShadowInstance {
public:
  // Attributes
  std::vector<std::vector<ShadowPlane>> faceList;
  Vec4f lp;	// Light Position in coord object

  Mat4f prevModelView;     // Last modelView related to the geometry.
  Vec4f prevLightPosition; // Last position related to the light.

  GLuint shadow2DL;			// Display List for the shadow2
  GLuint shadow3DL;			// Display List for the shadow2
  bool calculateShadow;		// To recalculte the shadow, in case that the object or the light is moved ...

  // ShadowInstance constructor and destructor.
  ShadowInstance();
  ShadowInstance(const SmartPointer<IModel>& model);
  ~ShadowInstance();

  void init(const SmartPointer<IModel>& model);

  // Methods to load and save the information necessary to create a volume
  // shadow for a geometry.
  bool load(const std::tstring& path);
  bool save(const std::tstring& path) const;
};

END_TEG_NAMESPACE();

#endif  // SHADOW_SHADOW_INSTANCE_H__
