//
// Asura_Chunk_ResourceFile_PC_Environment.cpp
//
// Created by KJL - 03/03/2003 18:08:40
//
// Copyright (C) 2003 Rebellion, All Rights Reserved.
//

#include "Core/Asura.h"

// This file's header.
#include "ChunkSystem/Asura_Chunk_ResourceFile_PC_Environment.h"

#include "Core/Asura_Material_System.h"
#include "FileAccess/Asura_FileAccess.h"
#include "Core/Memory/Asura_ResourceAllocator.h"

#include "Rendering/Asura_PlatformRenderEnvironment.h"

bool Asura_Chunk_ResourceFile_PC_Environment::Process( Asura_Handle hFile )
{
	if(Version < 1)
	{
		Asura_Assert(0, "Old PC export chunks not supported");
		return false;
	}

	Asura_ResourcePushType(ASURA_RESOURCE_ENVIRONMENT_MESH);
	{
		Asura_Direct3D_Env_Zone&	xZone	= Asura_Direct3D_EnvRenderer::GetCurrentZone();

		Asura_Assert(Flags & ASURA_CHUNK_PC_ENV_FLAG_DUALTEXTURE, "This export format is no longer supported. Please re-export this level.");
		if(!(Flags & ASURA_CHUNK_PC_ENV_FLAG_DUALTEXTURE)) return false;

		u_int uTotalNumberOfVertexBuffers;

		Asura_FileAccess::ReadData(hFile, &xZone.m_uNumberOfMeshes, sizeof(u_int));
		Asura_FileAccess::ReadData(hFile, &xZone.m_uNumberOfStrips, sizeof(u_int));
		Asura_FileAccess::ReadData(hFile, &uTotalNumberOfVertexBuffers, sizeof(u_int));

		xZone.m_uTotalNumberOfVertexBuffers = uTotalNumberOfVertexBuffers;

		Asura_ResourceAllocateArray(xZone.m_pxMeshes, xZone.m_uNumberOfMeshes);
		Asura_ResourceAllocateArray(xZone.m_pxStrips, xZone.m_uNumberOfStrips);

		Asura_ResourceAllocateArray(xZone.m_ppxVertexBuffer, uTotalNumberOfVertexBuffers);
		Asura_ResourceAllocateArray(xZone.m_ppxIndexBuffer, uTotalNumberOfVertexBuffers);

		Asura_FileAccess::ReadData(hFile, xZone.m_pxMeshes, sizeof(Asura_Direct3D_Env_Mesh)*xZone.m_uNumberOfMeshes);

		for (u_int u=0; u<xZone.m_uNumberOfStrips; u++)
		{
			Asura_FileAccess::ReadData(hFile, &xZone.m_pxStrips[u], sizeof(Asura_Direct3D_Env_Strip) - (sizeof(u_int)*2));
			xZone.m_pxStrips[u].m_iMaterialIndex = Asura_Material_System::ConvertIndex(xZone.m_pxStrips[u].m_iMaterialIndex);
		}

		for (u_int u=0; u<uTotalNumberOfVertexBuffers; u++)
		{
			u_int uNumberOfVertices;
			u_int uNumberOfIndices;
			Asura_FileAccess::ReadData(hFile, &uNumberOfVertices, sizeof(u_int));
			Asura_FileAccess::ReadData(hFile, &uNumberOfIndices, sizeof(u_int));

			if (uNumberOfVertices)
			{
				Asura_Direct3D::D3DDevice->CreateVertexBuffer
					(
					uNumberOfVertices*sizeof(Asura_Direct3D_Env_Vertex),
					D3DUSAGE_WRITEONLY,
					0,
					D3DPOOL_MANAGED,
					&xZone.m_ppxVertexBuffer[u],
					0
					);

				Asura_Direct3D_Env_Vertex* pxVertexData;
				if (SUCCEEDED(xZone.m_ppxVertexBuffer[u]->Lock(0,sizeof(Asura_Direct3D_Env_Vertex)*uNumberOfVertices,(void**)&pxVertexData,0)))
				{
					Asura_FileAccess::ReadData(hFile, pxVertexData, sizeof(Asura_Direct3D_Env_Vertex)*uNumberOfVertices);
					xZone.m_ppxVertexBuffer[u]->Unlock();
				} else {
					Asura_Assert(false,	"Failed to lock vertex buffer");
					Asura_FileAccess::SkipData(hFile, sizeof(Asura_Direct3D_Env_Vertex)*uNumberOfVertices);
				}

			}
			else
			{
				xZone.m_ppxVertexBuffer[u] = 0;
			}

			if (uNumberOfIndices)
			{
				Asura_Direct3D::D3DDevice->CreateIndexBuffer
					(
					uNumberOfIndices*sizeof(unsigned short),
					D3DUSAGE_WRITEONLY,
					D3DFMT_INDEX16,
					D3DPOOL_MANAGED,
					&xZone.m_ppxIndexBuffer[u],
					0
					);


				unsigned short* pusIndexData;
				if (SUCCEEDED(xZone.m_ppxIndexBuffer[u]->Lock(0,sizeof(u_short)*uNumberOfIndices, (void**)&pusIndexData,0)))
				{
					Asura_FileAccess::ReadData(hFile, pusIndexData, sizeof(u_short)*uNumberOfIndices);
					xZone.m_ppxIndexBuffer[u]->Unlock();
				} else {
					Asura_Assert(false,	"Failed to lock index buffer");
					Asura_FileAccess::SkipData(hFile, sizeof(u_short)*uNumberOfIndices);
				}


			}
			else
			{
				xZone.m_ppxIndexBuffer[u] = 0;
			}
		}
		xZone.m_bUsingPrecomputedStrips = true;
		xZone.m_bUsingPrecomputedData = true;

		// generate strip vertex buffer IDs
		for(u_int u = 0; u < xZone.m_uNumberOfMeshes; ++u)
		{
			for(u_int uStrip = 0; uStrip < xZone.m_pxMeshes[u].m_uNumberOfStrips; ++uStrip)
			{
				xZone.m_pxStrips[xZone.m_pxMeshes[u].m_uStartStripIndex + uStrip].m_uVertexBufferID = xZone.m_pxMeshes[u].m_uVertexBufferID;
				xZone.m_pxStrips[xZone.m_pxMeshes[u].m_uStartStripIndex + uStrip].m_iModuleIndex = u;
			}
		}
	}
	Asura_ResourcePopType();

	return true;
}
