/*===========================================================================
 *
 * File:	Dftexture.H
 * Author:	Dave Humphrey (uesp@m0use.net)
 * Created On:	Thursday, June 28, 2001
 *
 * Defines the CDFTextureFile class for handling a single Daggerfall
 * texture file.
 *
 *=========================================================================*/
#ifndef __DFTEXTURE_H
#define __DFTEXTURE_H


/*===========================================================================
 *
 * Begin Required Include Files
 *
 *=========================================================================*/
  #include "dftextimg.h"
  #include "images/rgbpal.h"
/*===========================================================================
 *		End of Required Include Files
 *=========================================================================*/


/*===========================================================================
 *
 * Begin Definitions
 *
 *=========================================================================*/

 	/* Number of images allowed per texture file. Code introduced limit,
	 * not nessecarily a DF texture file limit */
  #define DFTEXTURE_MAX_IMAGES 256

  	/* Size in bytes of the texture name string */
  #define DFTEXTURE_NAME_SIZE 24

  	/* Maximum number of texture files (DF limited) */
  #define DFTEXTURE_MAXFILES 512

/*===========================================================================
 *		End of Definitions
 *=========================================================================*/


/*===========================================================================
 *
 * Type and Structure Definitions
 *
 *=========================================================================*/
#pragma pack(push, 1)

	/* Texture offset record description */
  typedef struct {
    short Type1;
    long  HeaderOffset;
    short Type2;
    long  Unknown1;
    long  NullValue1;
    long  NullValue2;
   } dftextureoffset_t;

#pragma pack(pop)
/*===========================================================================
 *		End of Type and Structure Definitions
 *=========================================================================*/


/*===========================================================================
 *
 * Class CDFTextureFile Definition
 *
 * Manipulates a single Daggerfall texture file.
 *
 *=========================================================================*/
class CDFTextureFile : public CGenFile { 

  /*---------- Begin Protected Class Members ----------------------*/
protected:
  char			m_Name[DFTEXTURE_NAME_SIZE];	/* Texture identifying string */
  dftextureoffset_t*	m_pOffsets;			/* Offset record information */

  CDFTextureImage*	m_pImages;			/* Texture image array */
  int			m_NumImages;			/* Total number of images */

  int			m_Tag;				/* Used for user data */


  /*---------- Begin Protected Class Methods ----------------------*/
protected:

	/* Creates the image and offset arrays */
  void AllocateArrays (const int NumImages);

	/* Load method helper functions */
  boolean Read        (void);
  boolean ReadHeader  (void);
  boolean ReadImages  (void);
  boolean ReadOffsets (void);


  /*---------- Begin Public Class Methods -------------------------*/
public:

	/* Class Constructor and Destructor */
  CDFTextureFile();
  virtual ~CDFTextureFile() { Destroy(); }
  virtual void Destroy (void);

	/* Resets the tags for all the texture sub-images */
  void ClearTags (void);

	/* Class get member methods */
  char* GetName         (void) const;
  int   GetNumImages    (void) const;
  int   GetNumSubImages (const int Index) const;
  short GetWidth        (const int Index, const int SubIndex = 0) const;
  short GetHeight       (const int Index, const int SubIndex = 0) const;
  byte* GetImageData    (const int Index, const int SubIndex = 0) const;
  int   GetTag		(void) const;
  CDFTextureImage* GetImage (const int Index) const;

	/* Get offset record data */
  dftextureoffset_t* GetOffsetData (const int Index) const;

	/* Checks an image index for validity */
  boolean IsValidImageIndex (const int Index) const;

	/* Attempt to load the given texture file */
  boolean Load (const char* pFilename);
  boolean Load (FILE*	    pFileHandle);

	/* Class set members */
  void SetName (const char* pString); 
  void SetTag  (const int Value = 1);

 };
/*===========================================================================
 *		End of Class CDFTexture Definition
 *=========================================================================*/


/*===========================================================================
 *
 * Begin CDFTextureFile Inline Methods
 *
 *=========================================================================*/

	/* Class get members */
inline char* CDFTextureFile::GetName         (void) const { return (char *)(&m_Name[0]); }
inline int   CDFTextureFile::GetNumImages    (void) const { return (m_NumImages); }
inline int   CDFTextureFile::GetNumSubImages (const int Index) const { if (IsValidImageIndex(Index)) return (m_pImages[Index].GetNumSubImages()); return(0); }
inline short CDFTextureFile::GetWidth        (const int Index, const int SubIndex) const { if (IsValidImageIndex(Index)) return (m_pImages[Index].GetWidth(SubIndex));     return(0); }
inline short CDFTextureFile::GetHeight       (const int Index, const int SubIndex) const { if (IsValidImageIndex(Index)) return (m_pImages[Index].GetHeight(SubIndex));    return(0); }
inline byte* CDFTextureFile::GetImageData    (const int Index, const int SubIndex) const { if (IsValidImageIndex(Index)) return (m_pImages[Index].GetImageData(SubIndex)); return(NULL); }
inline int   CDFTextureFile::GetTag	     (void) const { return (m_Tag); }
inline CDFTextureImage* CDFTextureFile::GetImage (const int Index) const { return (IsValidImageIndex(Index) ? (CDFTextureImage *)&m_pImages[Index] : NULL); } 

	/* Get the offset record data */
inline dftextureoffset_t* CDFTextureFile::GetOffsetData (const int Index) const {
  if (IsValidImageIndex(Index)) return (&(m_pOffsets[Index])); 
  return (NULL);
 }

	/* Ensures the given texture index is a valid array object */
inline boolean CDFTextureFile::IsValidImageIndex (const int Index) const { 
  if (Index >= 0 && Index < m_NumImages) {
    IASSERT(m_pImages != NULL);
    return (TRUE);
   }

  return (FALSE); 
 }

	/* Class set members */
inline void CDFTextureFile::SetTag  (const int Value) { m_Tag = Value; }

inline void CDFTextureFile::SetName (const char* pString) { 
  if (pString == NULL)
    m_Name[0] = NULL_CHAR;
  else
    strnncpy(m_Name, pString, DFTEXTURE_NAME_SIZE);
 }

/*===========================================================================
 *		End of CDFTextureFile Inline Methods
 *=========================================================================*/


/*===========================================================================
 *
 * Begin Function Definitions
 *
 *=========================================================================*/

	/* Return a RGB color from a special solid color texture */
  rgbpalraw_t GetDFTextureSolidColor  (const int TextureIndex, const int ImageIndex);
  
	/* Determine if a texture index represents a solid color texture */
  boolean IsDFTextureSolidColor (const int Index);

	/* Checks to ensure a texture index is valid or not */
  boolean IsValidDFTextureIndex (const int Index);
  
/*===========================================================================
 *		End of Function Definitions
 *=========================================================================*/


#endif
/*===========================================================================
 *		End of File DFTexture.h
 *=========================================================================*/