#ifdef ASURA_USE_PRAGMA_ONCE
#pragma once
#endif

#ifndef __ASURA_PS3_FP_LIST_H__
#define __ASURA_PS3_FP_LIST_H__

#include "Rendering/Asura_PS3_ScratchRenderMemory.h"

class Asura_PS3_FP_List
{
	struct ASURA_PS3_FP 
	{
		Asura_PS3_FragmentShaderCopy	m_pxFP;
	};

public:
	Asura_PS3_FP_List( void* uStartProgram, u_int uProgramSize, Asura_PS3_FP_Handles* pxHandles, u_int uiNumberOfElements )
	{
		m_uiProgramSize					= uProgramSize;
		m_pxBaseProgram					= new char[ uProgramSize ];
		m_pxHandles						= pxHandles;
		m_uiIncreaseNumberOfElements	= uiNumberOfElements;
		m_uiCurrentElement				= 0;
		m_uiElementsInPool				= 0;

		Asura_Mem::Copy( m_pxBaseProgram, uStartProgram, uProgramSize );
		m_pxBaseShader					= new Asura_PS3_FragmentShaderBase( m_pxBaseProgram, m_uiProgramSize, pxHandles );
		for( int i = 0 ; i < ASURA_MAXIMUM_NUMBER_OF_POOLS; ++i )
		{
			m_pxPool[ i ] = NULL;
		}
	}

	~Asura_PS3_FP_List()
	{
		ClearAll();
	}

	Asura_PS3_FragmentShaderCopy* GetShader( void )
	{
		int iPool = m_uiCurrentElement / m_uiIncreaseNumberOfElements;
		int iPoolElement = m_uiCurrentElement % m_uiIncreaseNumberOfElements;

		Asura_Assert( iPool < ASURA_MAXIMUM_NUMBER_OF_POOLS, "Need to increase the number of pools!" );
		iPool = iPool % ASURA_MAXIMUM_NUMBER_OF_POOLS;

		if( m_uiCurrentElement >= m_uiElementsInPool )
		{
			InitPool( iPool );
		}

		++m_uiCurrentElement;
		return &m_pxPool[ iPool ][ iPoolElement ].m_pxFP;
	}

	void EndFrame( void )
	{
		m_uiCurrentElement	= 0;
		m_uiElementsInPool	= 0;
	}

	void ClearAll( void )
	{
		delete		m_pxBaseShader;
		delete		m_pxHandles;
		delete[]	m_pxBaseProgram;

		m_uiCurrentElement	= 0;
		m_uiElementsInPool	= 0;
		m_pxBaseShader		= NULL;
		m_pxHandles			= NULL;
		m_pxBaseProgram		= NULL;
	}

private:
	char*							m_pxBaseProgram;
	Asura_PS3_FragmentShaderBase*	m_pxBaseShader;
	Asura_PS3_FP_Handles*			m_pxHandles;
	ASURA_PS3_FP*					m_pxPool[ ASURA_MAXIMUM_NUMBER_OF_POOLS ];
	u_int							m_uiElementsInPool;
	u_int							m_uiCurrentElement;
	u_int							m_uiIncreaseNumberOfElements;
	u_int							m_uiProgramSize;

	void InitPool( int iPool )
	{
		m_pxPool[ iPool ] = static_cast<ASURA_PS3_FP*>( Asura_PS3_ScratchRenderMemory::AllocMainVideoMemory( sizeof( ASURA_PS3_FP ) * m_uiIncreaseNumberOfElements ) );
		for( u_int i = 0; i < m_uiIncreaseNumberOfElements; ++i )
		{
			m_pxPool[ iPool ][ i ].m_pxFP.Initialise( m_pxBaseShader, m_pxBaseProgram, m_uiProgramSize );
		}
		m_uiElementsInPool += m_uiIncreaseNumberOfElements;
	}
};

#endif //#ifndef __ASURA_PS3_FP_LIST_H__
