/*
**  wt -- a 3d game engine
**
**  Copyright (C) 1994 by Chris Laurel
**  email:  claurel@mr.net
**  snail mail:  Chris Laurel, 5700 W Lake St #208,  St. Louis Park, MN  55416
**
**  This program is free software; you can redistribute it and/or modify
**  it under the terms of the GNU General Public License as published by
**  the Free Software Foundation; either version 2 of the License, or
**  (at your option) any later version.
**
**  This program is distributed in the hope that it will be useful,
**  but WITHOUT ANY WARRANTY; without even the implied warranty of
**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
**  GNU General Public License for more details.
**
**  You should have received a copy of the GNU General Public License
**  along with this program; if not, write to the Free Software
**  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include <stdlib.h>
#include <stdio.h>
#include "wt.h"
#include "wtmem.h"
#include "error.h"
#include "texture.h"


static int log2(int x);


Texture *new_texture(Texture_type type, int height, int width)
{
     Texture *t;

     if (height <= 0 || width <= 0)
	  fatal_error("new_width:  bad texture dimensions");

     t = wtmalloc(sizeof(Texture));
     t->texels = wtmalloc(height * width);

     t->width = width;
     t->height = height;
     t->type = type;
     t->base_color = 0;
     
     return t;
}


/* read zero or more textures from a file */
Texture *read_texture_file(char *filename)
{
     FILE *fp;
     int magic, n_textures;
     int i;
     Texture *t;

     if (!(fp = fopen(filename, "rb")))
	  fatal_error("Cannot open texture file %s.", filename);

     if (fread(&magic, sizeof(int), 1, fp) != 1)
	  fatal_error("Error reading texture file %s.", filename);

     if (magic != TEXTURE_MAGIC)
	  fatal_error("%s is not a texture file (bad magic number).",
		      filename);

     if (fread(&n_textures, sizeof(int), 1, fp) != 1)
	  fatal_error("Texture file %s has a bad header.", filename);

     t = wtmalloc(sizeof(Texture) * n_textures);

     for (i = 0; i < n_textures; i++) {
	  fread(&t[i].type, sizeof(Texture_type), 1, fp);
	  fread(&t[i].base_color, 1, 1, fp);
	  fread(&t[i].width, sizeof(int), 1, fp);
	  if (fread(&t[i].height, sizeof(int), 1, fp) != 1)
	       fatal_error("Error in reading texture %s.", filename);  
	  if (t[i].height <= 0 || t[i].width <= 0)
	       fatal_error("Bad texture map dimensions in %s.", filename);

	  /* The height and width should be powers of two for efficient
	  **   texture mapping.  Here, we enforce this.
	  */
	  t[i].log2width = log2(t[i].width);
	  if (t[i].log2width == -1)
	       fatal_error("Width of texture %s is %d (not a power of two)", 
			   filename, t[i].width);
	  if (log2(t[i].height) == -1)
	       fatal_error("Height of texture %s is %d (not a power of two)",
			   filename, t[i].height);

	  t[i].texels = wtmalloc(t[i].height * t[i].width);
	  if (fread(t[i].texels, 1, t[i].height * t[i].width, fp)
	      !=  t[i].height * t[i].width)
	       fatal_error("Error in texture file %s.", filename);
     }

     fclose(fp);

     return t;
}


/* Return the log base 2 of the argument, or -1 if the argument is not
**   an integer power of 2.
*/
int log2(int x)
{
     int i;
     unsigned int n;

     if (x <= 0)
	  return -1;
     else
	  n = (unsigned int) x;

     
     for (i = 0; (n & 0x1) == 0; i++, n >>= 1);

     if (n == 1)
	  return i;
     else
	  return -1;
}
