// ===================================================================
// $Id: texture.h,v 1.8 2003/06/17 08:44:15 havran Exp $
//
// texture.h
//     Header file for CTexture class hierarchy.
//
// Class: CTextureList, CTexture, CConstantTexture
//
// Licence and usage conditions in November 2003:
// This file can be used and modified only with written permission of
// Vlastimil Havran, Pohodli 27, 57001 Litomysl, the Czech Republic.
// This library is granted to be used by Polina Kondratieva within
// her MPI HIWI job working on BRDFLIB library. The usage condition
// may change in the next version of the library. At the moment,
// the library development is supported by Max-Planck-Institut for
// Informatik, Stuhlsatzenhausweg 85, 66123 Saarbruecken Germany
// See WWW: http://www.mpi-sb.mpg.de
// REPLACEMENT_STRING
//
// Initial coding by Vlastimil Havran + Petr Mladek + Jiri Liska, 1999
//
// Given for the use to BRDFLIB project for the Polina Kondratieva's
// HIWI JOB assignment in November 2003.


#ifndef __TEXTURE_H__
#define __TEXTURE_H__

// BRDFLIB headers
#include "configh.h"
#include "color.h"
#include "mappibas.h"

// standard headers
#include <vector>


__BEGIN_BRDFLIB_HEADER

// forward declarations
class CMapPointInfo;
class CTexture;

// ----------------------------------------------------------------
// CTextureList
//  List of textures; derives from CSimpleList and adds a function
//  to search for a given color and return nonzero if there.
// ----------------------------------------------------------------
class CTextureList:
  public vector<CTexture *>
{
public:
  // returns true, if the texture is already present in the list
  bool TextureThere(CTexture *probe);
};

// --------------------------------------------------------------------------
// This is general class for textures
// most important is metod GetValue which comes in for the mapInfo and 
// returns appropriate value
// --------------------------------------------------------------------------
class CTexture 
{
public:
  // this identifikator allows to identify real class of the object CImage *
  // 0x01xxxx classes which calculate mapInfo on the texture value
  // 0x02xxxx classes which operate with the value from the one texture
  // 0x04xxxx classes which operate with the values from the two textures
  // 0x08xxxx classes which operate with the values from many textures
  // 0x10xxxx classes which change mapInfo
  enum EClassId {
    // unknown, not recognized texture
    EE_UnknownTexture = 0,
    
    // classes which calculate mapInfo on the texture value
    EE_ConstantTexture = 0x010000,
    EE_GeneralImageTexture,
    EE_InterpolatedTexture,
    EE_MipMapTexture,
    EE_NearestNeighbourTexture,
    EE_RipMapTexture,
    EE_SummedAreaTexture,
  };

private:
  // these must not be used
  CTexture & operator=(const CTexture &texture);
  // copy constructor
  CTexture(const CTexture &);
protected:
  // if the type (dimensionality) of the texture is static then is true
  // by other words if the demand on the dimensionality of the mapping 
  // is static then this variable is true
  bool _isTypeStatic;  
public:
  // constructor
  CTexture(bool isTypeStatic = true) : _isTypeStatic(isTypeStatic) { }

  // explicitely virtual destructor
  virtual ~CTexture() { }

  // returns the type (dimensionality) of the texture (2D,3D, ...). 
  // It corresponds to the mapping that has to be performed to access the data 
  // from this texture. So the dimensionality of mapping performed has to be
  // larger or greater than the dimensionality of this texture.
  virtual CMappingBase::EDimType GetType() const = 0;

  // returns true if the type of the texture is static 
  // by other words it returns true if the demand on the dimensionality 
  // of the mapping is static 
  bool IsTypeStatic() const { return _isTypeStatic; }

  // returns identification of the class
  virtual EClassId GetClassId() const = 0;

  // returns one value for specifed mapInfo
  virtual void GetValue(CValues &value, const CMapPointInfo &mapInfo) = 0;

  // Returns one value for specifed array of mapInfos.
  // The class mapInfos defines area instead of only one point.
  // This function can better solve antialiasing.
  virtual void GetValue(CValues &value, const CMapPointInfo mapInfo[],
			int number) = 0;

  // Describes the texture to a given stream
  virtual void Describe(ostream &app, int ind, float multiplier = 1.0) const {
    indent(app, ind); multiplier = multiplier; app << "Not yet implemented";
  }
};

// --------------------------------------------------------------------------
// this is class for constant texture, this texture needn't mapping
// --------------------------------------------------------------------------
class CConstantTexture:
  public CTexture
{
public:
  // constructor
  CConstantTexture(CValues &value):
    CTexture(), _value(value) { }
  CConstantTexture(const CConstantTexture &masterTexture):
    CTexture(),
    _value(masterTexture._value) { }

  // returns the type (dimensionality) of the texture (2D,3D, ...). 
  virtual CMappingBase::EDimType GetType() const { return CMappingBase::EE_None; }

  // returns identification of the class
  virtual EClassId GetClassId() const { return EE_ConstantTexture; }

  // set the new color to constant texture
  void SetColor(CValues &newColor) {
    _value = newColor;
  }

  // set the new color to constant texture
  void GetColor(CValues &color) {
    color = _value;
  }
  
  // returns value for specifed mapInfo
  virtual void GetValue(CValues &value, const CMapPointInfo &) {
    value = _value;
  }

  virtual void GetValue(CValues &value, const CMapPointInfo [], int) {
    value = _value;
  }

  CConstantTexture & operator=(const CConstantTexture &texture) {
    if (this != &texture)
      this->_value = texture._value;
    return *this;
  }

  // Describes the texture to a given stream
  virtual void Describe(ostream &app, int ind, float multiplier = 1.0) const {
    indent(app, ind); app << _value * multiplier;
  }
protected:  
  // value of this texture for each texture coordinates
  CValues _value;
};

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

__END_BRDFLIB_HEADER

#endif // __TEXTURE_H__
