#include "Mix/Tool/Win32/Core/Graphics/VertexBuffer.h"
#include "Mix/Tool/Win32/Core/Graphics/Manager.h"

namespace Mix{ namespace Tool{ namespace Win32{ namespace Graphics{

VertexBuffer* VertexBuffer::CreateInstance( unsigned int stride, unsigned int count, const void* initialData )
{
	return new VertexBuffer( stride, count, initialData );
}

VertexBuffer::VertexBuffer( unsigned int stride, unsigned int count, const void* initialData ) :
m_pD3DBuffer( NULL )
{
	m_bLock = false;
	m_Stride = stride;
	m_Count = count;
	m_Size = stride * count;

	m_Buffer.resize( m_Size, 0 );
	if( initialData != NULL )
	{
		::CopyMemory( &( m_Buffer[0] ), initialData, m_Size );
	}
}

VertexBuffer::~VertexBuffer( void )
{
	MIX_RELEASE( m_pD3DBuffer );
}

void* VertexBuffer::Lock( void )
{
	if( m_bLock == true )
	{
		return NULL;
	}

	m_bLock = true;

	return &( m_Buffer[0] );
}

void VertexBuffer::Unlock( void )
{
	if( m_bLock == false )
	{
		return;
	}

	if( m_pD3DBuffer != NULL )
	{
		unsigned char* pDst = NULL;

		if( m_pD3DBuffer->Lock( 0, 0, reinterpret_cast<void**>( &pDst ), 0 ) == D3D_OK )
		{
			::CopyMemory( pDst, &( m_Buffer[0] ), m_Size );

			m_pD3DBuffer->Unlock();
		}
	}

	m_bLock = false;
}

unsigned int VertexBuffer::GetCount( void ) const
{
	return m_Count;
}

const void* VertexBuffer::GetBuffer( void ) const
{
	return ( m_Buffer.size() > 0 )? &( m_Buffer[0] ) : NULL;
}

unsigned int VertexBuffer::GetBufferSize( void ) const
{
	return m_Buffer.size();
}

IDirect3DVertexBuffer9* VertexBuffer::GetInterfacePtr( void )
{
	return m_pD3DBuffer;
}

unsigned int VertexBuffer::GetStride( void ) const
{
	return m_Stride;
}

void VertexBuffer::OnInvalidate( void )
{
	MIX_RELEASE( m_pD3DBuffer );
}

void VertexBuffer::OnValidate( void )
{
	Mix::Tool::Win32::Graphics::Manager* pManager = Manager::GetInstance();
	if( pManager == NULL )
	{
		return;
	}

	unsigned char* pDst = NULL;

	m_pD3DBuffer = pManager->D3D_CreateVertexBuffer( m_Size );

	if( ( m_pD3DBuffer != NULL ) &&
		( m_pD3DBuffer->Lock( 0, 0, reinterpret_cast<void**>( &pDst ), 0 ) == D3D_OK ) )
	{
		::CopyMemory( pDst, &( m_Buffer[0] ), m_Size );

		m_pD3DBuffer->Unlock();
	}
}

Mix::Tool::Win32::Object::TYPE VertexBuffer::GetType( void ) const
{
	return Mix::Tool::Win32::Object::GRAPHICS__VERTEX_BUFFER;
}

}}}}
