/*
 =======================================================================================
  Name        : TexArray.c
  Author      : Gliglou corporation
  Description : manage array of texture data
 =======================================================================================
 */
 
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#include "PvObj_st.h"
#include "texture.h"
#include "TEX.h"
#include "DLLInter.h"
 
#include "TexArray.h"
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
/*
 =======================================================================================
    Globals
 =======================================================================================
 */

/*
 * memory
 */
extern unsigned long               GLI_gsCurrentMemoryChannel;
 
/*
 * array of texture / texture state
 */
GLI_tdstTexture *           gs_aDEFTableOfTextureAlreadyRead [ GLI_C_lNBMaxOfTextures ];
long                        gs_aDEFTableOfTextureMemoryChannels[ GLI_C_lNBMaxOfTextures ];
unsigned long               GLI_g_ulNumberOfLoadedTexture;
long                        gs_lNumberOfTextureToCreate;

/*
 =======================================================================================
    functions
 =======================================================================================
 */
 
/*
 ----------------------------------------------------------------------------------------
  Description   : set all texture in given channel as unallocated
                (called when memory block is freed )
 ----------------------------------------------------------------------------------------
 */
void GLI_fn_vUnallocTextureInChannel( unsigned char _ucChannel )
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    long lTextureCounter;
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
    for (lTextureCounter=0;lTextureCounter<GLI_C_lNBMaxOfTextures;lTextureCounter++)
    {
        if (gs_aDEFTableOfTextureMemoryChannels[lTextureCounter] == (long)_ucChannel )
        {
            gs_aDEFTableOfTextureMemoryChannels[lTextureCounter] = GLI_TEXIsUnallocated;
            gs_aDEFTableOfTextureAlreadyRead[lTextureCounter] = NULL; 
        }
    }
}
 
/*
 ----------------------------------------------------------------------------------------
  Description   : set all texture as unallocated
 ----------------------------------------------------------------------------------------
 */
void GLI_fn_vUnallocAllTextures( void )
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    long lTextureCounter;
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
    for (lTextureCounter=0;lTextureCounter<GLI_C_lNBMaxOfTextures;lTextureCounter++)
    {
        gs_aDEFTableOfTextureMemoryChannels[lTextureCounter] = GLI_TEXIsUnallocated;
        gs_aDEFTableOfTextureAlreadyRead[lTextureCounter] = NULL; 
    }
}
 
 
/*
 ----------------------------------------------------------------------------------------
  Description   : compute total of memory taken by texture allocated in array
 ----------------------------------------------------------------------------------------
 */
long GLI_lComputeTexturesSize()
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    long lTotalSize,lTextureCounter;
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    
    lTotalSize = 0;
    for (lTextureCounter = 0 ; lTextureCounter < GLI_C_lNBMaxOfTextures ; lTextureCounter ++ )
    {
        if ((gs_aDEFTableOfTextureMemoryChannels[lTextureCounter] != GLI_TEXIsUnallocated) && (gs_aDEFTableOfTextureAlreadyRead[lTextureCounter] != NULL))
            /*lTotalSize += GLI_lGetSizeOfTexture (gs_aDEFTableOfTextureAlreadyRead [lTextureCounter]);*/
            lTotalSize += GLI_DRV_lGetTextureSize( gs_aDEFTableOfTextureAlreadyRead [lTextureCounter] );
    }
    return lTotalSize ;
}
 
/*
 ----------------------------------------------------------------------------------------
  Description   : Get larger texture
 ----------------------------------------------------------------------------------------
 */
long GLI_lGetBigestSizeOfTexture()
{
    long lBigestSize,lSizeLocal;
    long lTextureCounter;
    
    for (lTextureCounter=0,lBigestSize = 0; lTextureCounter < GLI_C_lNBMaxOfTextures; lTextureCounter++)
    {
        if ( (gs_aDEFTableOfTextureMemoryChannels[lTextureCounter] != GLI_TEXIsUnallocated) && (gs_aDEFTableOfTextureAlreadyRead [lTextureCounter]) )
        {
            lSizeLocal = gs_aDEFTableOfTextureAlreadyRead [lTextureCounter] -> lRealHeight * gs_aDEFTableOfTextureAlreadyRead [lTextureCounter] -> lRealWidth * 6L;

            /* Special for texture maa: they have double height */
            if( gs_aDEFTableOfTextureAlreadyRead [lTextureCounter] -> lTextureCaps & GLI_C_lMAATexture )
                lSizeLocal *= 2;

            if (lBigestSize < lSizeLocal) lBigestSize = lSizeLocal;
        }
    }
    
    return (lBigestSize);
}
 
/*
 ----------------------------------------------------------------------------------------
  Description   : uncompress textures
  void                ->
  Returns (void )
 ----------------------------------------------------------------------------------------
 */
void GLI_vUnCompressExistantTexture(void)
{
    long lTextureCounter ;
    
    for  (lTextureCounter =0 ; lTextureCounter < GLI_C_lNBMaxOfTextures ; lTextureCounter ++)
    {
        if ( (gs_aDEFTableOfTextureMemoryChannels[lTextureCounter] != GLI_TEXIsUnallocated) && (gs_aDEFTableOfTextureAlreadyRead[lTextureCounter] != NULL))
        {
            gs_aDEFTableOfTextureAlreadyRead [ lTextureCounter ] -> lHeight = gs_aDEFTableOfTextureAlreadyRead [ lTextureCounter ] -> lRealHeight ;
            gs_aDEFTableOfTextureAlreadyRead [ lTextureCounter ] -> lWidth = gs_aDEFTableOfTextureAlreadyRead [ lTextureCounter ] -> lRealWidth ;
            gs_aDEFTableOfTextureAlreadyRead [ lTextureCounter ] -> lCompressionCounter = 0;
        }
    }
}

/*
 ----------------------------------------------------------------------------------------
  Description   : look throught the table to know if a texture alreqdy exist
 ----------------------------------------------------------------------------------------
 */
GLI_tdstTexture *TEX_fnpst_DoesTextureExist( char *_szFileName )
{
    long            lTextureCounter;
    GLI_tdstTexture *pst_Texture;
 
    for  (lTextureCounter =0 ; lTextureCounter < GLI_C_lNBMaxOfTextures; lTextureCounter ++)
    {
	    if (gs_aDEFTableOfTextureMemoryChannels[ lTextureCounter ] != GLI_TEXIsUnallocated)
        {
            pst_Texture = gs_aDEFTableOfTextureAlreadyRead [lTextureCounter];
            if (strcmp( pst_Texture->a255_cFileName, _szFileName ) == 0)
                return pst_Texture;
        }
    }
    return NULL;
};
 
/*
 ----------------------------------------------------------------------------------------
  Description   : add the picture name in the tree
 ----------------------------------------------------------------------------------------
 */
void TEX_fnv_MakeItExisting( GLI_tdstTexture *_pst_TextureCreated )
{
    /* add texture in array */
    gs_aDEFTableOfTextureAlreadyRead   [ gs_lNumberOfTextureToCreate ] = _pst_TextureCreated;
    gs_aDEFTableOfTextureMemoryChannels[ gs_lNumberOfTextureToCreate ] = GLI_gsCurrentMemoryChannel;
    gs_lNumberOfTextureToCreate++;
  
    while (
            (gs_aDEFTableOfTextureMemoryChannels[gs_lNumberOfTextureToCreate] != GLI_TEXIsUnallocated) && 
            (gs_lNumberOfTextureToCreate < GLI_C_lNBMaxOfTextures -1 )
          )
            gs_lNumberOfTextureToCreate++;
    
    /* we are in the end of arrays, come back to beginning to fill hole */ 
    if (gs_lNumberOfTextureToCreate == GLI_C_lNBMaxOfTextures -1 ) 
    {
        gs_lNumberOfTextureToCreate = 0;
        while (
                ( gs_aDEFTableOfTextureMemoryChannels[gs_lNumberOfTextureToCreate] != GLI_TEXIsUnallocated) && 
                ( gs_lNumberOfTextureToCreate < GLI_C_lNBMaxOfTextures - 1 )
              )
                gs_lNumberOfTextureToCreate++;
    }
}
