#include "PhongEffect.h"
#include "InputLayouts.h"
#include "Util.h"
#include "Lights.h"

HRESULT PhongEffect::init()
{
	HRESULT hr = S_OK;

    DWORD dwShaderFlags = D3D10_SHADER_ENABLE_STRICTNESS;
	#if defined( DEBUG ) || defined( _DEBUG )
		dwShaderFlags |= D3D10_SHADER_DEBUG;
	#endif

	ID3D10Blob *pErrorMsg;
	string s = Util::intToString(NROFLIGHTS,0);
	D3D10_SHADER_MACRO Shader_Macros[] = { 
		{"NROFLIGHTS", s.c_str() },
		NULL };
		
	hr = D3DX10CreateEffectFromFile( L"../../shaders/Phong.fx", Shader_Macros, NULL, "fx_4_0", dwShaderFlags, 0, DXUTGetD3D10Device(), NULL,
                                         NULL, &effect, &pErrorMsg, NULL );

	if(pErrorMsg)
	{
		 _RPT1(_CRT_WARN, "compilation error : %s\n", (char*) pErrorMsg->GetBufferPointer()); 
		  SAFE_RELEASE(pErrorMsg);

	}
    if( FAILED( hr ) )
    {
        MessageBox( NULL,
                    L"The FX file cannot be located.  Please run this executable from the directory that contains the FX file.", L"Error", MB_OK );
		V_RETURN(hr);
    }
	technique = effect->GetTechniqueByName("Render");
	modelMatrixVariable = effect->GetVariableByName( "modelMatrix" )->AsMatrix();

	viewMatrixVariable = effect->GetVariableByName( "viewMatrix" )->AsMatrix();
    projectionMatrixVariable = effect->GetVariableByName( "projectionMatrix" )->AsMatrix();
	lightViewMatrixVariable = effect->GetVariableByName( "lightView" )->AsMatrix();
    lightProjectionMatrixVariable = effect->GetVariableByName( "lightProj" )->AsMatrix();

    eyePointVariable = effect->GetVariableByName( "eye" )->AsVector();

	diffuseTexture = effect->GetVariableByName("diffuseTexture")->AsShaderResource();
	normalMapTexture = effect->GetVariableByName("normalMap")->AsShaderResource();
	shadowMap = effect->GetVariableByName("shadowMap")->AsShaderResource();
		
	materialVariable = effect->GetVariableByName("material");
	hasNormalMapVariable = effect->GetVariableByName("hasNormalMap")->AsScalar();
	
	pcfOffsetsVariable = effect->GetVariableByName("pcfOffsets");

	ID3D10Device* pd3dDevice = DXUTGetD3D10Device();
	
	D3D10_PASS_DESC PassDesc;
	technique->GetPassByIndex( 0 )->GetDesc( &PassDesc );
    pd3dDevice->CreateInputLayout( layout, numElements, PassDesc.pIAInputSignature,
    PassDesc.IAInputSignatureSize, &vertexLayout);
	pd3dDevice->IASetInputLayout( vertexLayout );

	return S_OK;
}

void PhongEffect::setModelMatrix(D3DXMATRIX* modelMatrix)
{
	modelMatrixVariable->SetMatrix((float*)modelMatrix);
}

void PhongEffect::setViewMatrix(D3DXMATRIX* viewMatrix)
{
	viewMatrixVariable->SetMatrix((float*)viewMatrix);
}

void PhongEffect::setProjectionMatrix(D3DXMATRIX* projMatrix)
{
	projectionMatrixVariable->SetMatrix((float*)projMatrix);
}

void PhongEffect::setDiffuseTexture(ID3D10ShaderResourceView* textureResrc)
{
	diffuseTexture->SetResource(textureResrc);
}

void PhongEffect::setEyePoisition(D3DXVECTOR3* eye)
{
	eyePointVariable->SetFloatVector((float*)eye);
}

ID3D10Effect* PhongEffect::getEffectVariable()
{
	return effect;
}

ID3D10EffectTechnique* PhongEffect::getTechniqueVariable()
{
	return technique;
}

void PhongEffect::setMaterial(MaterialPack material)
{
	materialVariable->SetRawValue(&material,0,sizeof(MaterialPack));
}

void PhongEffect::setHasNormalMap(BOOL hasNormalMap)
{
	hasNormalMapVariable->SetBool(hasNormalMap);
}

void PhongEffect::setNormalMap(ID3D10ShaderResourceView* normalMapResrc)
{
	normalMapTexture->SetResource(normalMapResrc);
}

void PhongEffect::setInputLayout()
{
	DXUTGetD3D10Device()->IASetInputLayout( vertexLayout );
}

void PhongEffect::setLightViewMatrix(D3DXMATRIX* viewMatrix)
{
	lightViewMatrixVariable->SetMatrix((float*)viewMatrix);
}

void PhongEffect::setLightProjectionMatrix(D3DXMATRIX* projMatrix)
{
	lightProjectionMatrixVariable->SetMatrix((float*)projMatrix);
}

void PhongEffect::setShadowMapTexture(ID3D10ShaderResourceView* textureResrc)
{
	shadowMap->SetResource(textureResrc);
}

void PhongEffect::setPCFOffsets(D3DXVECTOR2* pcfOffsets)
{
	pcfOffsetsVariable->SetRawValue(pcfOffsets,0,sizeof(D3DXVECTOR2)*8);
}

PhongEffect::~PhongEffect()
{
	SAFE_RELEASE(effect);
	SAFE_RELEASE(vertexLayout);

}