/*
 * Copyright 2016 - 2025 Gary Talent (gary@drinkingtea.net). All rights reserved.
 */

#pragma once

#include <glutils/glutils.hpp>
#include <studio/studio.hpp>

#include <nostalgia/gfx/tilesheet.hpp>

namespace nostalgia::gfx {

class TileSheetGrid {

	private:
		static constexpr auto VertexVboRows = 1;
		static constexpr auto VertexVboRowLength = 7;
		static constexpr auto VertexVboLength = VertexVboRows * VertexVboRowLength;

		static constexpr auto VShad = R"glsl(
		{}
		in vec2 vPt1;
		in vec2 vPt2;
		in vec3 vColor;
		out vec2 gPt2;
		out vec3 gColor;
		void main() {
			gColor = vColor;
			gl_Position = vec4(vPt1, 0.0, 1.0);
			gPt2 = vPt2;
		})glsl";

		static constexpr auto FShad = R"glsl(
		{}
		in vec3 fColor;
		out vec4 outColor;
		void main() {
			outColor = vec4(fColor, 1);
			//outColor = vec4(0.4431, 0.4901, 0.4941, 1.0);
		})glsl";

		static constexpr auto GShad = R"glsl(
		{}
		layout(points) in;
		layout(line_strip, max_vertices = 2) out;
		in vec3 gColor[];
		in vec2 gPt2[];
		out vec3 fColor;
		uniform vec2 gScroll;
		void main() {
			fColor = gColor[0];
			gl_Position = gl_in[0].gl_Position + vec4(gScroll, 0, 0);
			EmitVertex();
			gl_Position = vec4(gPt2[0] + gScroll, 0, 1);
			EmitVertex();
			EndPrimitive();
		})glsl";

		glutils::GLProgram m_shader;
		glutils::BufferSet m_bufferSet;
		float m_pixelSizeMod = 1;

	public:
		void setPixelSizeMod(float sm) noexcept;

		ox::Error buildShader() noexcept;

		void draw(bool update, ox::Vec2 const &scroll) noexcept;

		void initBufferSet(ox::Vec2 const &paneSize, TileSheet::SubSheet const &subsheet) noexcept;

		void update(ox::Vec2 const &paneSize, TileSheet::SubSheet const &subsheet) noexcept;

	private:
		static void setBufferObject(
			ox::Point pt1, ox::Point pt2, Color32 c, ox::Span<float> vbo, ox::Vec2 const &pixSize) noexcept;

		void setBufferObjects(ox::Vec2 const &paneSize, TileSheet::SubSheet const &subsheet) noexcept;

		[[nodiscard]]
		ox::Vec2 pixelSize(ox::Vec2 const &paneSize) const noexcept;

};

}
