#include "opengl/opengl_renderer.hpp"
#include "opengl/opengl_render_path.hpp"
#include "opengl/opengl_render_paint.hpp"
#include "opengl_shaders.cpp"
#include <cassert>

using namespace rive;

GLuint createAndCompileShader(GLuint type, const char* source);

OpenGLRenderer::OpenGLRenderer() {}
OpenGLRenderer::~OpenGLRenderer()
{
	glDeleteProgram(m_Program);
	glDeleteShader(m_VertexShader);
	glDeleteShader(m_FragmentShader);
	glDeleteBuffers(1, &m_IndexBuffer);
	glDeleteBuffers(1, &m_BlitBuffer);
	glDeleteVertexArrays(1, &m_VertexArray);
}

bool OpenGLRenderer::initialize(void* data)
{
	assert(m_VertexShader == 0 && m_FragmentShader == 0 && m_Program == 0);

	m_VertexShader =
	    createAndCompileShader(GL_VERTEX_SHADER, vertexShaderSource);
	if (m_VertexShader == 0)
	{
		return false;
	}

	m_FragmentShader =
	    createAndCompileShader(GL_FRAGMENT_SHADER, fragmentShaderSource);
	if (m_FragmentShader == 0)
	{
		return false;
	}

	m_Program = glCreateProgram();
	glAttachShader(m_Program, m_VertexShader);
	glAttachShader(m_Program, m_FragmentShader);
	glLinkProgram(m_Program);
	GLint isLinked = 0;
	glGetProgramiv(m_Program, GL_LINK_STATUS, (int*)&isLinked);
	if (isLinked == GL_FALSE)
	{
		GLint maxLength = 0;
		glGetProgramiv(m_Program, GL_INFO_LOG_LENGTH, &maxLength);

		std::vector<GLchar> infoLog(maxLength);
		glGetProgramInfoLog(m_Program, maxLength, &maxLength, &infoLog[0]);
		fprintf(stderr, "Failed to link program %s\n", &infoLog[0]);
		return false;
	}

	// Create index buffer which we'll grow and populate as necessary.
	glGenBuffers(1, &m_IndexBuffer);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IndexBuffer);

	// Create vertex buffer for blitting to full viewport coordinates.
	float blitBuffer[8] = {
	    -1.0f,
	    1.0f,

	    1.0f,
	    1.0f,

	    1.0f,
	    -1.0f,

	    -1.0f,
	    -1.0f,
	};
	glGenBuffers(1, &m_BlitBuffer);
	glBindBuffer(GL_ARRAY_BUFFER, m_BlitBuffer);
	glBufferData(
	    GL_ARRAY_BUFFER, 8 * sizeof(float), &blitBuffer[0], GL_STATIC_DRAW);

	// Two triangles for bounds.
	m_Indices.emplace_back(0);
	m_Indices.emplace_back(1);
	m_Indices.emplace_back(2);
	m_Indices.emplace_back(2);
	m_Indices.emplace_back(3);
	m_Indices.emplace_back(0);

	glBufferData(GL_ELEMENT_ARRAY_BUFFER,
	             m_Indices.size() * sizeof(unsigned short),
	             &m_Indices[0],
	             GL_STATIC_DRAW);

	glGenVertexArrays(1, &m_VertexArray);
	glBindVertexArray(m_VertexArray);

	glUseProgram(m_Program);

	m_ProjectionUniformIndex = glGetUniformLocation(m_Program, "projection");
	m_TransformUniformIndex = glGetUniformLocation(m_Program, "transform");

	m_FillTypeUniformIndex = glGetUniformLocation(m_Program, "fillType");
	m_StopCountUniformIndex = glGetUniformLocation(m_Program, "count");
	m_StopColorsUniformIndex = glGetUniformLocation(m_Program, "colors");
	m_StopsUniformIndex = glGetUniformLocation(m_Program, "stops");
	m_ColorUniformIndex = glGetUniformLocation(m_Program, "color");
	m_GradientPositionUniformIndex =
	    glGetUniformLocation(m_Program, "position");
	m_ShapeTransformUniformIndex =
	    glGetUniformLocation(m_Program, "localTransform");

	float projection[16] = {0.0f};
	orthographicProjection(projection, 0.0f, 800, 800, 0.0f, 0.0f, 1.0f);
	modelViewProjection(projection);

	return true;
}

void OpenGLRenderer::drawPath(RenderPath* path, RenderPaint* paint)
{
	auto glPaint = static_cast<OpenGLRenderPaint*>(paint);
	// if (glPaint->style() == RenderPaintStyle::stroke || !glPaint->doesDraw())

	if (!glPaint->doesDraw())
	{
		return;
	}
	bool needsStencil = glPaint->style() == RenderPaintStyle::fill;

	glColorMask(false, false, false, false);
	// Set fill type to 0 so we don't perform any gradient fragment calcs.
	glUniform1i(fillTypeUniformIndex(), 0);

	if (isClippingDirty())
	{
		if (m_IsClipping)
		{
			// Clear previous clip.
			glStencilMask(0xFF);
			glClear(GL_STENCIL_BUFFER_BIT);

			// TODO: instead of clearing the entire buffer, as we clip we could
			// compute the combined clipping area set and clear that here.
		}
		auto clipLength = m_ClipPaths.size();
		if (clipLength > 0)
		{
			m_IsClipping = true;
			SubPath& firstClipPath = m_ClipPaths[0];

			glStencilMask(0xFF);
			glStencilFunc(GL_ALWAYS, 0x0, 0xFF);

			glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_INCR_WRAP);
			glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_DECR_WRAP);
			static_cast<OpenGLRenderPath*>(firstClipPath.path())
			    ->stencil(this, firstClipPath.transform());

			// Fail when not equal to 0 and replace with 0x80 (mark high bit as
			// included in clip). Require stencil mask (write mask) of 0xFF and
			// stencil func mask of 0x7F such that the comparison looks for 0
			// but write 0x80.
			glStencilMask(0xFF);
			glStencilFunc(GL_NOTEQUAL, 0x80, 0x7F);
			glStencilOp(GL_ZERO, GL_ZERO, GL_REPLACE);

			glBindBuffer(GL_ARRAY_BUFFER, m_BlitBuffer);
			glEnableVertexAttribArray(0);
			glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * 4, (void*)0);
			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IndexBuffer);

			float m4[16] = {1.0,
			                0.0,
			                0.0,
			                0.0,

			                0.0,
			                1.0,
			                0.0,
			                0.0,

			                0.0,
			                0.0,
			                1.0,
			                0.0,

			                0.0,
			                0.0,
			                0.0,
			                1.0};

			glUniformMatrix4fv(transformUniformIndex(), 1, GL_FALSE, m4);
			glUniformMatrix4fv(m_ProjectionUniformIndex, 1, GL_FALSE, m4);

			// Draw bounds.
			glDrawElements(GL_TRIANGLES, 2 * 3, GL_UNSIGNED_SHORT, (void*)(0));

			glUniformMatrix4fv(
			    m_ProjectionUniformIndex, 1, GL_FALSE, m_ModelViewProjection);
			for (int i = 1; i < clipLength; i++)
			// for (int i = 1; i < 0; i++)
			{

				// When already clipping we want to write only to the last/lower
				// 7 bits as our high 8th bit is used to mark clipping
				// inclusion.
				glStencilMask(0x7F);
				// Pass only if that 8th bit is set. This allows us to write our
				// new winding into the lower 7 bits.
				glStencilFunc(GL_EQUAL, 0x80, 0x80);
				SubPath& nextClipPath = m_ClipPaths[i];

				glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_INCR_WRAP);
				glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_DECR_WRAP);
				static_cast<OpenGLRenderPath*>(nextClipPath.path())
				    ->stencil(this, nextClipPath.transform());

				// Fail when not equal to 0 and replace with 0x80 (mark high bit
				// as included in clip). Require stencil mask (write mask) of
				// 0xFF and stencil func mask of 0x7F such that the comparison
				// looks for 0 but write 0x80.
				glStencilMask(0xFF);
				glStencilFunc(GL_NOTEQUAL, 0x80, 0x7F);
				glStencilOp(GL_ZERO, GL_ZERO, GL_REPLACE);

				glBindBuffer(GL_ARRAY_BUFFER, m_BlitBuffer);
				glEnableVertexAttribArray(0);
				glVertexAttribPointer(
				    0, 2, GL_FLOAT, GL_FALSE, 2 * 4, (void*)0);

				glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IndexBuffer);

				glUniformMatrix4fv(transformUniformIndex(), 1, GL_FALSE, m4);
				glUniformMatrix4fv(m_ProjectionUniformIndex, 1, GL_FALSE, m4);
				// Draw bounds.
				glDrawElements(
				    GL_TRIANGLES, 2 * 3, GL_UNSIGNED_SHORT, (void*)(0));

				glUniformMatrix4fv(m_ProjectionUniformIndex,
				                   1,
				                   GL_FALSE,
				                   m_ModelViewProjection);
			}
		}
		else
		{
			m_IsClipping = false;
		}
	}

	auto glPath = static_cast<OpenGLRenderPath*>(path);

	if (needsStencil)
	{
		// Set up stencil buffer.
		if (m_IsClipping)
		{
			glStencilMask(0x7F);
			glStencilFunc(GL_EQUAL, 0x80, 0x80);
		}
		else
		{
			glStencilMask(0xFF);
			glStencilFunc(GL_ALWAYS, 0x0, 0xFF);
		}

		glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_INCR_WRAP);
		glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_DECR_WRAP);

		auto xform = transform();
		glPath->stencil(this, xform);

		glColorMask(true, true, true, true);
		glStencilFunc(GL_NOTEQUAL, 0, m_IsClipping ? 0x7F : 0xFF);
		glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO);
	}
	else
	{
		if (m_IsClipping)
		{
			glStencilMask(0x7F);
			glStencilFunc(GL_EQUAL, 0x80, 0x80);
		}
		else
		{
			glStencilMask(0xFF);
			glStencilFunc(GL_ALWAYS, 0x0, 0xFF);
		}
		glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_KEEP);
		glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_KEEP);
		glColorMask(true, true, true, true);
		// glStencilFunc(GL_ALWAYS, 0x0, 0xFF);
		glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO);
	}
	glPaint->draw(this, transform(), glPath);

	// glPath->cover(this, transform());
}

void OpenGLRenderer::startFrame()
{
	LowLevelRenderer::startFrame();
	glUseProgram(m_Program);
	glEnableVertexAttribArray(0);
	glUniformMatrix4fv(
	    m_ProjectionUniformIndex, 1, GL_FALSE, m_ModelViewProjection);
	glEnable(GL_STENCIL_TEST);
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}

void OpenGLRenderer::endFrame() {}

RenderPaint* OpenGLRenderer::makeRenderPaint()
{
	return new OpenGLRenderPaint();
}
RenderPath* OpenGLRenderer::makeRenderPath() { return new OpenGLRenderPath(); }

void OpenGLRenderer::updateIndexBuffer(std::size_t contourLength)
{
	if (contourLength < 2)
	{
		return;
	}
	auto edgeCount = (m_Indices.size() - 6) / 3;
	auto targetEdgeCount = contourLength - 2;
	if (edgeCount < targetEdgeCount)
	{
		while (edgeCount < targetEdgeCount)
		{
			m_Indices.push_back(3);
			m_Indices.push_back(edgeCount + 4);
			m_Indices.push_back(edgeCount + 5);
			edgeCount++;
		}

		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IndexBuffer);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER,
		             m_Indices.size() * sizeof(unsigned short),
		             &m_Indices[0],
		             GL_STATIC_DRAW);
	}
}

GLuint createAndCompileShader(GLuint type, const char* source)
{
	GLuint shader = glCreateShader(type);
	glShaderSource(shader, 1, &source, nullptr);
	glCompileShader(shader);
	GLint isCompiled = 0;
	glGetShaderiv(shader, GL_COMPILE_STATUS, &isCompiled);
	if (isCompiled == GL_FALSE)
	{
		GLint maxLength = 0;
		glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &maxLength);

		std::vector<GLchar> infoLog(maxLength);
		glGetShaderInfoLog(shader, maxLength, &maxLength, &infoLog[0]);
		fprintf(stderr, "Failed to compile shader %s\n", &infoLog[0]);
		glDeleteShader(shader);

		return 0;
	}

	return shader;
}