#include "client/render/shader/BulletShader.h"

namespace blitz {
namespace shader {

static const std::string vertexSource = ShaderProgram::GetShaderHeader() + R"(

layout(location = 0) in vec3 position;

uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;
uniform mat4 modelMatrix;

out float pass_position;

void main(void){
	vec4 worldPos = modelMatrix * vec4(position, 1.0);
	pass_position = position.z;
	gl_Position = projectionMatrix * viewMatrix * worldPos;
}
)";

static const std::string fragmentSource = ShaderProgram::GetShaderHeader() + R"(

in float pass_position;

out vec4 out_color;

uniform float alpha;

void main(void){
	float red = cos(pass_position * 100.0 - alpha * 100.0);
	float capped = (red + 1.0) / 2.0 + 0.5;
	out_color = vec4(1.0, 0.0, 0.0, alpha * capped);
}
)";

BulletShader::BulletShader() : ShaderProgram() {}

bool BulletShader::LoadShader() {
	return ShaderProgram::LoadProgram(vertexSource, fragmentSource);
}

void BulletShader::GetAllUniformLocation() {
	m_LocationViewMatrix = static_cast<unsigned int>(GetUniformLocation("viewMatrix"));
	m_LocationProjectionMatrix = static_cast<unsigned int>(GetUniformLocation("projectionMatrix"));
	m_LocationTransform = static_cast<unsigned int>(GetUniformLocation("modelMatrix"));
	m_LocationAlpha = static_cast<unsigned int>(GetUniformLocation("alpha"));
}

void BulletShader::SetProjectionMatrix(const Mat4f& proj) const {
	LoadMat4(m_LocationProjectionMatrix, proj);
}

void BulletShader::SetViewMatrix(const Mat4f& view) const {
	LoadMat4(m_LocationViewMatrix, view);
}

void BulletShader::SetDecay(float alpha) const {
	LoadFloat(m_LocationAlpha, alpha);
}

void BulletShader::SetTransform(const Mat4f& trans) const {
	LoadMat4(m_LocationTransform, trans);
}

}  // namespace shader
}  // namespace blitz