#include <math.h>
#include "pvr.h"
#include "rspix.h"

PVR::cTexture::cTexture(uint16_t width, uint16_t height, uint8_t ucImageType)
{
	this->m_ucImageType = ucImageType;
	if (width <= 1024 && height <= 1024)
	{
		cTextureTile *pTile = new cTextureTile(width, height, ucImageType);
		pTile->m_pParentTexture = this;		
		m_szImageWidth += pTile->m_szImageWidth;
		m_szImageHeight += pTile->m_szImageHeight;
		m_szTextureWidth += pTile->m_szTileWidth;
		m_szTextureHeight += pTile->m_szTileHeight;		
		AddTile(pTile);		
	}
}


/// <summary>
/// Constructor
/// </summary>
PVR::cTexture::cTexture()
{
	// todo?
}

// todo: clean up
PVR::cTexture::cTexture(char *path, uint8_t columns, uint8_t rows, bool isAlpha)
{	
	SetGrid(columns, rows);
	
	for (int index = 0; index < columns * rows; index++)
	{		
		char filename[150];
		if (index < 10)
		{
			sprintf(filename, "%s/tile000%d.kmg", path, index);
		}
		else
		{
			sprintf(filename, "%s/tile00%d.kmg", path, index);
		}			
		
		cKmgImg *kosImg = new cKmgImg(filename);
		cTextureTile *tile = new cTextureTile(kosImg, isAlpha);
		
		tile->m_bIsARGB4 = isAlpha;
		AddTile(tile, index);
		delete kosImg;	
	}	
}

// todo: clean up
PVR::cTexture::cTexture(RResMgr *resMgr, char *path, uint8_t columns, uint8_t rows, bool isAlpha)
{		
	SetGrid(columns, rows);
	
	for (int index = 0; index < columns * rows; index++)
	{		
		cKmgImg *img;
		char filename[150];
		if (index < 10)
		{
			// todo: needed?
			sprintf(filename, "%s/tile000%d.kmg", path, index);
		}
		else
		{
			sprintf(filename, "%s/tile00%d.kmg", path, index);
		}			
		
		if (rspGetResource(
			resMgr,
			filename,
			&img) == 0)
		{				
			cTextureTile *tile = new cTextureTile(img, isAlpha);			
			AddTile(tile, index);		
			rspReleaseAndPurgeResource(resMgr, &img);
		}			
	}	
}

/// <summary>
/// Constructor
/// </summary>
PVR::cTexture::cTexture(RImage *image, uint8_t pNum)
{
	if (image->m_sWidth > 0 && image->m_sWidth <= 1024 && image->m_sHeight > 0 && image->m_sHeight <= 1024)
	{					
		cTextureTile *pTile = new cTextureTile(image, m_ucImageType, pNum);
		m_ucPaletteNum = pNum;		
		pTile->m_pParentTexture = this;
		m_szImageWidth += pTile->m_szImageWidth;
		m_szImageHeight += pTile->m_szImageHeight;
		m_szTextureWidth += pTile->m_szTileWidth;
		m_szTextureHeight += pTile->m_szTileHeight;
		AddTile(pTile);		
	}	
}

/// <summary>
/// Destructor
/// </summary>
PVR::cTexture::~cTexture()
{
	for (int8_t index = 0; index < m_sNumTiles; index++)
	{
		delete m_pTextureTiles[index];
	}

	free(m_pTextureTiles);
}

uint16_t PVR::cTexture::GetTextureWidth()
{
	return m_szTextureWidth;
}

uint16_t PVR::cTexture::GetTextureHeight()
{
	return m_szTextureHeight;
}

int16_t PVR::cTexture::GetImageWidth()
{
	return m_szImageWidth;
}

int16_t PVR::cTexture::GetImageHeight()
{
	return m_szImageHeight;
}

void PVR::cTexture::AddTile(PVR::cTextureTile* pTile, uint16_t index)
{
	pTile->m_pParentTexture = this;
	pTile->m_szId = index;
	// Single-tile texture.
	if (!m_bHasTileGrid)
	{
		m_szImageWidth = pTile->m_szImageWidth;
		m_szImageHeight = pTile->m_szImageHeight;
		m_szTextureWidth = pTile->m_szTileWidth;
		m_szTextureHeight = pTile->m_szTileHeight;		
		m_sNumTiles = 1;
		m_pTextureTiles = (cTextureTile**)malloc(sizeof(cTextureTile*));
	}	
	
	m_pTextureTiles[index] = pTile;	
}

void PVR::cTexture::SetGrid(uint8_t col, uint8_t row)
{			
	m_bHasTileGrid = true;
	m_szTextureWidth = col * TEXTURE_GRID_SIZE;
	m_szTextureHeight = row * TEXTURE_GRID_SIZE;
	m_sNumTiles = col * row;
	m_pTextureTiles = (cTextureTile**)malloc(m_sNumTiles * sizeof(cTextureTile*));
}
