package main

import (
	"fmt"
	"runtime"
	"time"

	"edgaru089.ink/go/gl01/internal/game"
	gio "edgaru089.ink/go/gl01/internal/io"
	_ "edgaru089.ink/go/gl01/internal/render/gpu_preference"
	"edgaru089.ink/go/gl01/internal/util/itype"
	"github.com/go-gl/gl/all-core/gl"
	"github.com/go-gl/glfw/v3.3/glfw"
)

var (
	frameTick *time.Ticker
)

func init() {
	runtime.LockOSThread()
}

func main() {

	err := gio.LoadConfig()
	if err != nil {
		panic(err)
	}

	if err := glfw.Init(); err != nil {
		panic(err)
	}
	defer glfw.Terminate()

	// framerate limit ticker
	if gio.MainConfig.FramerateLimit > 0 {
		frameTick = time.NewTicker(time.Second / time.Duration(gio.MainConfig.FramerateLimit))
	}

	glfw.WindowHint(glfw.Resizable, 1)
	glfw.WindowHint(glfw.ContextVersionMajor, 3)
	glfw.WindowHint(glfw.ContextVersionMinor, 3)
	glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile)
	glfw.WindowHint(glfw.OpenGLForwardCompatible, 1)
	win, err := glfw.CreateWindow(gio.MainConfig.WindowWidth, gio.MainConfig.WindowHeight, itype.ProjectName, nil, nil)
	if err != nil {
		panic(err)
	}
	win.MakeContextCurrent()
	// vsync
	if gio.MainConfig.FramerateLimit == 0 {
		glfw.SwapInterval(1)
	} else {
		glfw.SwapInterval(0)
	}

	err = gl.Init()
	if err != nil {
		panic(err)
	}

	fmt.Println("OpenGL Version: ", gl.GoStr(gl.GetString(gl.VERSION)))

	game := game.NewGame()
	game.Init(win)

	gio.ClearColor = itype.Vec4f{0, 0, 0, 1.0}
	gio.FogColor = itype.Vec4f{0, 0, 0, 1.0}
	gl.ClearColor(gio.ClearColor[0], gio.ClearColor[1], gio.ClearColor[2], gio.ClearColor[3])
	gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
	win.SwapBuffers()
	winClock := time.Now()

	fpsClock := time.Now()
	fpsCounter := 0

	for !win.ShouldClose() {

		deltaTime := time.Since(winClock)
		winClock = time.Now()
		game.Update(win, deltaTime)

		gl.ClearColor(gio.ClearColor[0], gio.ClearColor[1], gio.ClearColor[2], gio.ClearColor[3])
		gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)

		game.Render(win)

		win.SwapBuffers()
		glfw.PollEvents()

		if time.Since(fpsClock) >= time.Second {
			win.SetTitle(fmt.Sprintf(itype.ProjectName+" %dFPS", fpsCounter))
			fpsCounter = 0
			fpsClock = time.Now()
		} else {
			fpsCounter++
		}

		if gio.MainConfig.FramerateLimit > 0 {
			<-frameTick.C
		}
	}
}
