//
// Asura_Chunk_ResourceFile.cpp
//
// Created by Kevin Lea - 14/09/2001 15:00:23
// 
// Copyright (C) 2001 Rebellion, All Rights Reserved.
//

#include "Core/Asura.h"

#include "ChunkSystem/Asura_Chunk_ResourceFile.h"

#include "ChunkSystem/Asura_Chunk_Loaders.h"
#include "ChunkSystem/Asura_Chunk_Macros.h"
#include "ChunkSystem/Asura_Chunk_Stream.h"
#include "ChunkSystem/Asura_SaveBlock.h"
#include "Core/Asura_TextureManagement.h"
#include "Core/Asura_LocalisedText.h"
#include "Debugging/Asura_Assert.h"
#include "Debugging/Asura_Logfile.h"
#include "FileAccess/Asura_FileAccess.h"
#include "Sound/Asura_Audio_System.h"
#include "Sound/Asura_Sound.h"
#include "Streaming/Asura_Streaming_System.h"

DEBUGVAR bool dbg_bLogResourcefileContents = false;

bool Asura_Chunk_ResourceFile::Process(Asura_Handle iFileHandle)
{
	const Asura_Char* const szFilename = Asura_FileAccess::ReadString(iFileHandle);

    if (dbg_bLogResourcefileContents)
    {
        Asura_Logfile_Retail(("logfiles\\loads.txt", "resourcefile loaded: '%s' (Type %d)\n", szFilename, int( Type)));
    }

    bool bProcessedEntireChunk;

    switch(Type)
	{
		case ASURA_RESOURCEFILE_TYPE_PLATFORMSPECIFIC:
		{
            bProcessedEntireChunk = Platform_Process( iFileHandle, szFilename );
			break;
		}

		case ASURA_RESOURCEFILE_TYPE_PROJECTSPECIFIC:
		{
			// No project specific resource file chunks for now so just skip.
            bProcessedEntireChunk = false;
			break;
		}

		case ASURA_RESOURCEFILE_TYPE_TEXTURE:
		{
			// (AW - 01.09.2003) - Note on assertion: This happened when someone used
			// the texture-tiler without having DxTex.exe in the relevant folder.
			Asura_Assertf(FileSize, ("Resource file texture %s is of 0 size.", szFilename)); 
			if (FileSize)
			{
				//RAR 15/05/2006 SubType is now used for texture flags
				Asura_Texture_Management::LoadTextureFromResourceFile(iFileHandle,FileSize,szFilename,SubType,Flags);
			}
            bProcessedEntireChunk = true;
			break;
		}
		
		case ASURA_RESOURCEFILE_TYPE_SOUND:
		{
#if defined(ASURA_USE_AUDIO_SYSTEM)
			Asura_Chunk_File_Stream xStream( iFileHandle );
			bProcessedEntireChunk = Asura_Audio_System::LoadWave( xStream, FileSize, SubType, Flags, szFilename );
#else
			bProcessedEntireChunk = Asura_Sound_System::LoadSoundFromResourceFile( iFileHandle, FileSize, SubType, szFilename );
#endif
			break;
		}

		case ASURA_RESOURCEFILE_TYPE_SOUNDPROPERTIES :
		{
			#ifdef ASURA_USE_AUDIO_SYSTEM
			bProcessedEntireChunk = false;
			Asura_Assert( false, "Sound properties chunks are obsolete" );
			#else
			bProcessedEntireChunk = LoadSoundPropertiesFromResource( iFileHandle );
			#endif
			break;
		}

		case ASURA_RESOURCEFILE_TYPE_SOUNDMAPPING :
		{
			#ifdef ASURA_USE_AUDIO_SYSTEM
			bProcessedEntireChunk = false;
			Asura_Assert( false, "Sound mapping chunks are obsolete" );
			#else
            bProcessedEntireChunk = LoadSoundMappingsFromResource( iFileHandle );
			#endif
			break;
		}

		case ASURA_RESOURCEFILE_TYPE_ASURAFILENAME :
		{
			bProcessedEntireChunk = true;
			char szFilenameCopy[200];
			//copy the filename to a new buffer , because it will get altered by subsequent calls to 
			//ReadString when loading the next asura file.
			Asura_PrintfToBfr( szFilenameCopy, "%s", 199, true, szFilename );

			if(Flags & FRF_LOCALISE_FILENAME)
			{
				//replace the extension by the code for the current language
				char* pcExtension = strrchr(szFilenameCopy,'.');
				if(!pcExtension)
				{
					pcExtension = &szFilenameCopy[strlen(szFilenameCopy)];
					*pcExtension = '.';
				}
				
				
				pcExtension++;	
				strcpy(pcExtension, Asura_LocalisedText::GetTwoCharCodeForCurLang());

				#ifdef ASURA_PLATFORM_IS_BIG_ENDIAN
				pcExtension += 2;
				strcpy(pcExtension,ASURA_STANDARD_FILE_EXTENSION_BE_SUFFIX);
				#endif

			}

			LoadAsuraFile(szFilenameCopy);
			break;
		}

		default:
		{
			Asura_Assert(0,"Unknown Resource Type");
            bProcessedEntireChunk = false;
			break;
		}
	}

	return bProcessedEntireChunk;
}

#ifdef ASURA_TOOLS
void Asura_Chunk_ResourceFile::Create(int size, int flags, unsigned int type, unsigned int subtype, unsigned int filesize, int iVersion)
{
	ID = ASURA_CHUNK_RESOURCEFILE;
	ASURA_CHUNK_VERIFY(ID, int);
	Size = size;
	ASURA_CHUNK_VERIFY(Size, int);
	Version = iVersion;
	ASURA_CHUNK_VERIFY(Version, int);
	Flags = flags;
	ASURA_CHUNK_VERIFY(Flags, int);
	Type = type;
	ASURA_CHUNK_VERIFY(Type, unsigned int);
	SubType = subtype;
	ASURA_CHUNK_VERIFY(SubType, unsigned int);
	FileSize = filesize;
	ASURA_CHUNK_VERIFY(FileSize, unsigned int);
}


#endif



void Asura_Texture_Management::LoadTextureFromResourceFile(Asura_Handle fileHandle,int fileSize, const Asura_Char* szFileName, int iTextureFlagsToAdd, u_int uChunkFlags)
{
	// DLH - Skip the Data load on error
	bool bSkipFileLoad = false;
	
    // (MP - 19.09.2002) On the PS2, the texture data is aligned to a QW
    // boundary. I padded the beginning of the name with spaces to do this.
    // We therefore need to skip the leading spaces here.
    while( ' ' == *szFileName )
    {
        ++szFileName;
    }

// (MP - 19.09.2002) Okay. Apparently we can't assert about this because
// sometimes there's no leading slash. I would have thought it should only
// skip 8 characters in that case but somehow it still works...
//    Asura_Assert( !strncmp(szTextureName, "\\graphics", 9), "Texture resource name doesn't begin with \"graphics\\\"." );
	int index = AddTexture( szFileName + 9 ); // skip '\graphics'

	if(index < 0)
	{
		Asura_Assertf(false, ("Failed to add texture \"%s\" from resource-file.", szFileName));
		bSkipFileLoad = true;
	}
	else
	{
		//RAR 15/05/2006 Add texture flags
		if(iTextureFlagsToAdd)
		{
#ifdef ASURA_TOOLS
			//Clear the texture usage flags , since these will be generated as the materials are loaded. RAR 08/05/2006
			iTextureFlagsToAdd &=~ ASURA_TEXTURE_USAGE_FLAGS;
#endif
			int iTextureFlags = Asura_Texture_Management::GetTextureFlags(index);
			Asura_Texture_Management::SetTextureFlags(index,iTextureFlags|iTextureFlagsToAdd);
		}




		if (IsTextureLoaded(index))
		{
			// Kevin Lea - 14/09/2001 16:37:23 - texture already loaded, skip data
			bSkipFileLoad = true;
		}
		else
		{
			Loaded[index] = s_uCurResetGroup;
			Platform_LoadTextureFromResource(fileHandle, fileSize, index, uChunkFlags);
		}
	}
	
	if( true == bSkipFileLoad)
	{
		Asura_FileAccess::SkipData(fileHandle,fileSize);
	}
}


#ifndef ASURA_USE_AUDIO_SYSTEM

bool Asura_Chunk_ResourceFile::LoadSoundPropertiesFromResource(Asura_Handle iFileHandle)
{
	//get the version number
	int iVersion;
	ASURA_CHUNK_FILEEXTRACT(iFileHandle,iVersion,int);
	Asura_Assert(iVersion<=0,"Unknown chunk version.");

	//get the number of sounds we have properties for
	int iNumberOfSounds;
	ASURA_CHUNK_FILEEXTRACT(iFileHandle,iNumberOfSounds,int);

	//and read them all in
	int iSoundID;
	float fDefaultInnerRadius,fDefaultOuterRadius,fPitchScale,fVolumeScale;
	for(int i=0;i<iNumberOfSounds;i++)
	{
		ASURA_CHUNK_FILEEXTRACT(iFileHandle,iSoundID,int);
		ASURA_CHUNK_FILEEXTRACT(iFileHandle,fPitchScale,float);
		ASURA_CHUNK_FILEEXTRACT(iFileHandle,fVolumeScale,float);
		ASURA_CHUNK_FILEEXTRACT(iFileHandle,fDefaultInnerRadius,float);
		ASURA_CHUNK_FILEEXTRACT(iFileHandle,fDefaultOuterRadius,float);

		Asura_SoundProperties* pxProperties = Asura_Sound_System::GetSoundPropertiesByID((Asura_Sound_ID)iSoundID);
		if(pxProperties)
		{
			if(fPitchScale>=0)
			{
				pxProperties->m_fPitchScale = fPitchScale;
			}
			if(fVolumeScale>=0)
			{
				pxProperties->m_fVolumeScale = fVolumeScale;
			}
			if(fDefaultInnerRadius>=0)
			{
				pxProperties->m_fDefaultInnerRadius = fDefaultInnerRadius;
			}
			if(fDefaultOuterRadius>=0)
			{
				pxProperties->m_fDefaultOuterRadius = fDefaultOuterRadius;
			}
		}
	}

	return true;
	
}

bool Asura_Chunk_ResourceFile::LoadSoundMappingsFromResource(Asura_Handle iFileHandle)
{
	//get the version number
	int iVersion;
	ASURA_CHUNK_FILEEXTRACT(iFileHandle,iVersion,int);
	Asura_Assert(iVersion<=ASURA_RESOURCEFILE_SOUNDMAPPING_VERSION,"Unknown chunk version.");

	//get the number of sounds we have remappings for
	int iNumberOfSounds;
	ASURA_CHUNK_FILEEXTRACT(iFileHandle,iNumberOfSounds,int);

	//and read them all in
	int iNewSoundID,iExistingSoundID;
	Asura_Hash_ID uExistingSoundHash = 0;
	for(int i=0;i<iNumberOfSounds;i++)
	{
		ASURA_CHUNK_FILEEXTRACT(iFileHandle,iNewSoundID,int);
		ASURA_CHUNK_FILEEXTRACT(iFileHandle,iExistingSoundID,int);
		if(iVersion>=1)
		{
			ASURA_CHUNK_FILEEXTRACT(iFileHandle,uExistingSoundHash,Asura_Hash_ID);
		}


		Asura_Sound_System::LoadSoundIDMapping((Asura_Sound_ID)iNewSoundID,(Asura_Sound_ID)iExistingSoundID,uExistingSoundHash);
	}

	return true;
	
}

#endif	// #ifndef ASURA_USE_AUDIO_SYSTEM

//eof
