#ifndef	CACHE_H
#define	CACHE_H

   /*
    * I think this is the best point to implement an _effective_ cache
    * the brute force method fills in an array of "struct cachedface *faceCache[numfaces][MIPMAP_MAX]"
    * next step: the definition of an cacheface holds the different mip-sizes
    */

struct bitmap {
  short int width, height;					/* */
  int size;							/* */
  unsigned char *data;						/* always 8bit indexed datas */
};

struct bitdim {
  short int width, height;					/* */
  int size;							/* */
};

struct faceextent {
  int u0, u1;							/* u0 is also the u for texture-gradients (except water/sky/..) */
  int v0, v1;							/* v0 is also the v for texture-gradients (except water/sky/..) */
  int u10, v10;							/* */
};

struct textgradient {
  float u, v;							/* same as u0/v0 or 0 subtracted by vec[j][3] */
  vec3_t uv0, uv1;						/* */
  vec3_t scaled;						/* */
  struct dplane_t *plane;					/* textures plane */
};

struct fastmipmap {
  struct bitmap rawBody;					/* */
  struct bitdim newBody;					/* */
  int step, shift, row;						/* */
  int y, x0;							/* */
  double rescale;						/* (8 >> mip) / 8.0 */
};

struct texture {
  bool texChanged;						/* interface to dynamic changing and updating */
  short int lastMip;						/*  */

  short int textureType;					/* the type of texture (constant) */
  unsigned char textureColor;					/* flat-color of the texture */
  struct fastmipmap mipMaps[MIPMAP_MAX];			/* four sizes and four pointer to the textures (allmost constant, except for animating textures) */

  short int *lightSString[MAXLIGHTMAPS];			/* the type of lighting (points directly into the lightstringtable) */
  short int lightSLength[MAXLIGHTMAPS];				/* the type of lighting (points directly into the lightlengthtable) */
  struct bitmap lightmap;					/* the buffer for holding the lightmap (constant size) */
  unsigned char *lightdata;					/* the raw lightmap (always 8bit alpha) */

  struct faceextent faceExtent;
  struct textgradient textGradient;

  void *tiled;							/* the buffer for holding the temporary datas in 8, 16 or 24 bit */
};

   /*
    */

extern struct texture **cachedFaces;

void InitFaceCache(__memBase);
struct texture *CacheFace(__memBase, int face);
void UnCacheFace(__memBase, int face);

static inline struct texture *GetCache(__memBase, int face);
static inline struct texture *GetCache(__memBase, int face)
{
  struct texture *ret;

  if (!(ret = cachedFaces[face]))
    ret = cachedFaces[face] = CacheFace(bspMem, face);

  return ret;
}

#endif
