/*--------------------------------------------------------------------------
 * File: texture.c
 * Written by: Fredrik Kling, 1997-05-18
 * Description: Texture manager...
 *
 * Updates:
 * -- Date -- | ----- Name ----- |-- Did what....
 * 1997-05-18 | Fredrik Kling    | Implementation
 *
 *
 -------------------------------------------------------------------------------*/

#include "system/xstdio.h"
#include "system/xstring.h"
#include "formats/v3o.h"
#include "formats/vio.h"
#include "system/xstdlib.h"

typedef struct s_TLIST TLIST;
struct s_TLIST
{
	TLIST *next,*prev;
	V3OTEXTURE *t;
};
TLIST *list=NULL;

void static addtolist (V3OTEXTURE *t)
{
	TLIST *tmp;
	if (list==NULL)
	{
		list=(TLIST *)xmalloc (sizeof (TLIST));
		list -> next = list -> prev = NULL;
		list -> t = t;
	} else {
					 tmp = xmalloc (sizeof (TLIST));
					 tmp -> t = t;
					 tmp -> next = list;
					 tmp -> prev = NULL;
					 list -> prev = tmp;
					 list = tmp;
				 }
}
/******************************************************************
 * Function  : texture_load                                       *
 * Input     : char *name                                         *
 * Return    : A pointer to a loaded texture                      *
 * Effect    : Loads a texture and puts it in the cache table     *
 * Comments  : -                                                  *
 ******************************************************************/

static V3OTEXTURE *texture_load (char *fn)
{
	V3OTEXTURE *tex;
  tex=(V3OTEXTURE *) xmalloc (sizeof (V3OTEXTURE));
  tex->flags=V3OTEXTUREFLAG_LOADED;
	if ((tex->image=vio_load (fn))==NULL)
	{
		xfree (tex);
		return NULL;
	}

	strcpy (tex->filename,fn);
	return tex;
}
/******************************************************************
 * Function  : texture_fetch                                      *
 * Input     : char *name                                         *
 * Return    : A pointer to a preloaded or loaded texture         *
 * Effect    : Gets a texture from cache or disk                  *
 * Comments  : -                                                  *
 ******************************************************************/
VIO *texture_fetch (char *name)
{
	TLIST *l;
	V3OTEXTURE *t;

	// Check list for equal name...

	l=list;
	for (l=list;l!=NULL;l=l->next)
		if (!strcmp (name,l->t->filename)) break;

	if (l==NULL)
	{
		if ((t=texture_load (name))!=NULL) addtolist (t);
			else return NULL;
	} else {
					 if (!strcmp (name,l->t->filename))
					 {
					   t=l->t;
					 }
					 		else return( NULL);//xerror ("Texture failure: '%s'\n",name);
				 }
	return t->image;
}
/******************************************************************
 * Function  : texture_clearcache                                 *
 * Input     : -                                                  *
 * Return    : -                                                  *
 * Effect    : Clear all cached textures from system...           *
 * Comments  : -                                                  *
 ******************************************************************/
void texture_clearcache (void)
{
	TLIST *l,*next;

	for (l=list;l!=NULL;l=l->next)
	{
		next=l->next;		// Save next
	 	xfree (l);				// Clear current
		l=next;					// Move one step forward in list...
	}
}
/******************************************************************
 * Function  : texture_dumpcache                                  *
 * Input     : -                                                  *
 * Return    : -                                                  *
 * Effect    : Prints the name of all texture and their attribute *
 * Comments  : -                                                  *
 ******************************************************************/
void texture_dumpcache (void)
{
	TLIST *l;
	int i;
	printf ("-þ- Dumping texture cache -þ-\n");
	for (i=1,l=list;l!=NULL;l=l->next,i++)
	{
		printf ("Texture: %i\n",i);
		printf ("Name...: %s\n",l->t->filename);
		printf ("Width..: %i\n",l->t->image->width);
		printf ("Height.: %i\n",l->t->image->height);
		printf ("Type...: ");
		if (l->t->image->flags & VIOFLAG_8BIT) printf ("8-bit\n");
			else if (l->t->image->flags & VIOFLAG_24BIT) printf ("24-bit\n");
			  else if (l->t->image->flags & VIOFLAG_32BIT) printf ("32-bit\n");
		printf ("Zbuffer: ");
		if (l->t->image->flags & VIOFLAG_ZBUFFER) printf ("yes\n");
			else printf ("no\n");
		printf ("Ytable.: ");
		if (l->t->image->flags & VIOFLAG_YTAB) printf ("yes\n");
			else printf ("no\n");
		printf ("----------------------------\n");
	}
}
