#pragma once

#ifndef __gx_basiceffect_h__
	#define __gx_basiceffect_h__

#include "effect.h"
#include "material.h"
#include "foundation/PxMat44.h"

using namespace physx;;

namespace Gx
{
	static const int EffectLightCount = 4;

	struct GX_API EffectLight
	{
		EffectLight() : enabled(false), position(PxVec3(1.0f)), ambient(PxVec4(0.0f)), diffuse(PxVec4(0.0f)), specular(PxVec4(0.0f)), attenuation(PxVec3(1, 0, 0)) { }
		EffectLight(bool enabled, PxVec3 position, PxVec4 ambient, PxVec4 diffuse, PxVec4 specular, PxVec3 attenuation = PxVec3(1, 0, 0))
			: enabled(enabled), position(position), ambient(ambient), diffuse(diffuse), specular(specular), attenuation(attenuation) { }

		bool enabled;
		PxVec3 position;
		PxVec4 ambient;
		PxVec4 diffuse;
		PxVec4 specular;
		PxVec3 attenuation; // const, linear, quad
	};

	class GX_API BasicEffect : public Effect
	{
	public:
		BasicEffect();

		void apply();

		void setModelMatrix(const PxMat44& model);
		void setViewMatrix(const PxMat44& view);
		void setProjMatrix(const PxMat44& proj);

		void setGlobalAmbientColor(const PxVec4& ambient);

		void setLightingEnabled(bool enabled);
		void setLight(int i, const EffectLight& light);
		void setLightEnabled(int i, bool enabled);
		void setLightPosition(int i, const PxVec3& position);
		void setLightAmbientColor(int i, const PxVec4& ambient);
		void setLightDiffuseColor(int i, const PxVec4& diffuse);
		void setLightSpecularColor(int i, const PxVec4& specular);

		void setLightAttenuation(int i, const PxVec3& attenuation);
		void setLightConstantAttenuation(int i, GxF32 constantAttenuation);
		void setLightLinearAttenuation(int i, GxF32 linearAttenuation);
		void setLightQuadraticAttenuation(int i, GxF32 quadAttenuation);
		
		void setMaterial(const Material& material);
		void setMaterialAmbient(const PxVec4& ambient);
		void setMaterialDiffuse(const PxVec4& diffuse);
		void setMaterialSpecular(const PxVec4& specular);
		void setMaterialShininess(GxF32 shininess);
		void setMaterialColor(const PxVec4& color);
		void setMaterialAlpha(GxF32 alpha);

		void setTexturingEnabled(bool enabled);
		void setTexture(GLint textureUnit);

	private:
		PxMat44 m_modelMatrix;
		PxMat44 m_viewMatrix;
		PxMat44 m_projMatrix;

		bool m_lightDirtyFlags[EffectLightCount];
		EffectLight m_lights[EffectLightCount];
	};
}


#endif /* __gx_basiceffect_h__ */