package game

import (
	"math"
	"time"

	"edgaru089.ink/go/gl01/internal/asset"
	"edgaru089.ink/go/gl01/internal/igwrap"
	"edgaru089.ink/go/gl01/internal/io"
	"edgaru089.ink/go/gl01/internal/util"
	"edgaru089.ink/go/gl01/internal/util/itype"
	"github.com/inkyblackness/imgui-go/v4"
)

const (
	timebarN = 700
)

var (
	colorset     = [...]imgui.PackedColor{4289753676, 4283598045, 4285048917, 4283584196, 4289950337, 4284512403, 4291005402, 4287401100, 4285839820, 4291671396}
	timebars     [timebarN][]int // height of each bar set
	timebari     int
	timebarScale int = 64
)

func (g *Game) renderDebugInfo() {
	// Render information
	if igwrap.Begin("F3", nil, 0) {
		igwrap.TextBlank()

		igwrap.TextBackground("WorldRender: lastframe %.3fms", float64(io.Diagnostics.Times.Render.Nanoseconds())/float64(time.Millisecond))
		igwrap.TextBackground("TimeBars:")
		pad := igwrap.Vec2f(imgui.CurrentStyle().ItemSpacing())
		imgui.SameLine()
		igwrap.TextBackgroundV(colorset[0], pad, "Depthmap")
		imgui.SameLine()
		igwrap.TextBackgroundV(colorset[1], pad, "Geometry")
		imgui.SameLine()
		igwrap.TextBackgroundV(colorset[2], pad, "SSAO")
		imgui.SameLine()
		igwrap.TextBackgroundV(colorset[3], pad, "Lighting")
		imgui.SameLine()
		igwrap.TextBackgroundV(colorset[4], pad, "Postfx")
		imgui.SameLine()
		igwrap.TextBackground("[Hover]")
		if imgui.IsItemHoveredV(imgui.HoveredFlagsAllowWhenDisabled) {
			_, wheely := imgui.CurrentIO().MouseWheel()
			if math.Abs(float64(wheely)) > 1e-3 {
				if wheely > 0 {
					timebarScale = util.Mini(timebarScale*2, 128)
				} else { // < 0
					timebarScale = util.Maxi(timebarScale/2, 1)
				}
			}
		}

		isize := asset.WorldTextureAtlas.ImageSize
		igwrap.TextBackground("Texture Atlas Size: (%dx%d)", isize[0], isize[1])
		imgui.SameLine()
		igwrap.TextBackground("[Scroll]")
		if imgui.IsItemHoveredV(imgui.HoveredFlagsAllowWhenDisabled) {
			_, wheely := imgui.CurrentIO().MouseWheel()
			if math.Abs(float64(wheely)) > 1e-3 {
				atlasScale = util.Maxf(1, atlasScale+wheely)
			}
			imgui.BeginTooltip()
			igwrap.Image(g.render.texture.Handle(), isize.ToFloat32().Multiply(atlasScale), itype.Rectf{0, 0, 1, 1})
			imgui.EndTooltip()
		}

		imgui.End()
	}

	// Draw Textures
	imgui.SetNextWindowPosV(imgui.Vec2{X: float32(g.render.lastDisplaySize[0]), Y: 0}, imgui.ConditionAlways, imgui.Vec2{X: 1, Y: 0})
	if igwrap.Begin("Renderer Textures/Outputs", nil, igwrap.WindowFlagsOverlay) {
		imgui.PushStyleVarVec2(imgui.StyleVarItemSpacing, imgui.Vec2{})

		imageSize := g.render.lastDisplaySize.ToFloat32().Multiply(0.25)
		imageSize[1] -= imgui.CurrentStyle().WindowPadding().Y / 2
		imageSize[0] = imageSize[1] / float32(g.render.lastDisplaySize[1]) * float32(g.render.lastDisplaySize[0])

		igwrap.Image(g.render.gbuffer.pos, imageSize, itype.Rectf{0, 0, 1, 1})
		igwrap.Image(g.render.gbuffer.norm, imageSize, itype.Rectf{0, 0, 1, 1})
		igwrap.Image(g.render.gbuffer.color, imageSize, itype.Rectf{0, 0, 1, 1})
		igwrap.Image(g.render.ssao.ambient, imageSize, itype.Rectf{0, 0, 1, 1})

		imgui.PopStyleVar()
		imgui.End()
	}

	// Push the next bar
	timebars[timebari] = []int{
		int(io.Diagnostics.Times.RenderPasses.Depthmap.Nanoseconds()),
		int(io.Diagnostics.Times.RenderPasses.Geometry.Nanoseconds()),
		int(io.Diagnostics.Times.RenderPasses.SSAO.Nanoseconds()),
		int(io.Diagnostics.Times.RenderPasses.Lighting.Nanoseconds()),
		int(io.Diagnostics.Times.RenderPasses.Postfx.Nanoseconds()),
	}
	timebari++
	if timebari >= len(timebars) {
		timebari = 0
	}

	// Draw time bars
	size := g.render.lastDisplaySize
	dl := imgui.BackgroundDrawList()
	for i, l := range timebars {
		ex := 0
		for j, d := range l {
			d = d * timebarScale / 1024 / 1024
			dl.AddLine(imgui.Vec2{X: float32(i), Y: float32(size[1] - ex)}, imgui.Vec2{X: float32(i), Y: float32(size[1] - ex - d)}, colorset[j])
			ex += d
		}
	}
}
