// __author__ = Juan Carlos De Abreu (jcabreur@gmail.com)

/**
 * This class define a Material property, that define how will be displayed a
 * geometry.
 */

// TODO: The Material structure can store the normalMap and heightMap for 
//       make paralax mappping for instance, also can store the path of a
//       shader file.

#ifndef MATERIAL_H__
#define MATERIAL_H__

#include "../global.h"
#include "../util/string.h"
#include "../Includes/OpenGL.h"
#include "../Math/Vector.h"
#include "../Base/Memory/MMObject.h"
#include "../Base/Memory/SmartPointer.h"

BEGIN_TEG_NAMESPACE();

#define BEGIN_MATERIAL(pMaterial, renderMode) pMaterial->begin(renderMode)
#define END_MATERIAL(pMaterial, renderMode) pMaterial->end(renderMode)

class Material : public IMMObject {
protected:
  // Lighting types.
  enum TypesIllum {
    NO_SPECULAR_HIGHLIGHTS = 1, // Don't use the specular component(Ks).
    SPECULAR_HIGHLIGHTS         // Use the specular component(Ks).
  };

public:
  // Attributes.
  Vec4f ambient;         // Ambient component.
  Vec4f diffuse;         // Diffuse component.
  Vec4f specular;        // Specular component.
  Vec4f emission;        // Emission component.
  int illum;             // Lighting type.
  float alpha;           // Alpha component.
  float shininess;       // Shininess component.
  std::tstring name;     // Material name.
  std::tstring fileName; // Texture path file.
  GLuint textureId;      // Texture identifier.
  int wrap_option;       // How to wrap the texture.

  // Material constructor and destructor.
  Material();
  ~Material();

  // Methods.
  void setAlpha(const float& alpha_);

  // begin and end methods delimit the material properties.
  void begin(const int& renderMode) const;
  void end(const int& renderMode) const;
  void apply(void) const;

  // Method to make a copy of this material.
  SmartPointer<Material> copy(void) const;

  AUTO_SIZE();
};

END_TEG_NAMESPACE();

#endif  // MATERIAL_H__
