package ru.dbotthepony.kstarbound.client.gl.shader

import ru.dbotthepony.kommons.util.IStruct4f
import ru.dbotthepony.kommons.math.RGBAColor
import ru.dbotthepony.kommons.matrix.Matrix3f
import ru.dbotthepony.kstarbound.client.StarboundClient
import ru.dbotthepony.kstarbound.client.gl.vertex.GeometryType
import ru.dbotthepony.kstarbound.client.gl.vertex.StreamVertexBuilder
import ru.dbotthepony.kstarbound.client.gl.vertex.VertexAttributes
import ru.dbotthepony.kstarbound.client.render.FONT_VERTEX_FORMAT

private fun shaders(name: String): List<GLShader> {
	val client = StarboundClient.current()
	return listOf(client.internalVertex("shaders/$name.vsh"), client.internalFragment("shaders/$name.fsh"))
}

private fun shaders1(name: String): List<GLShader> {
	val client = StarboundClient.current()
	return listOf(client.internalVertex("shaders/vertex/$name.vsh"), client.internalFragment("shaders/fragment/$name.fsh"))
}

class FontProgram : GLShaderProgram(shaders1("font"), FONT_VERTEX_FORMAT) {
	var viewMatrix: Matrix3f by F3x3Uniform("viewMatrix")
	var modelMatrix: Matrix3f by F3x3Uniform("modelMatrix")
	var colorMultiplier: IStruct4f by F4Uniform("colorMultiplier")

	var texture by IUniform("texture0")

	init {
		viewMatrix = Matrix3f.identity()
		modelMatrix = Matrix3f.identity()
		colorMultiplier = RGBAColor.WHITE
	}
}

class GLLiquidProgram : GLShaderProgram(shaders("liquid"), VertexAttributes.POSITION) {
	var baselineColor by F4Uniform("baselineColor")
	var transform by F3x3Uniform("transform")
	val builder = StreamVertexBuilder(attributes, GeometryType.QUADS)
}

class GLPrograms {
	val position by lazy(LazyThreadSafetyMode.NONE) { UberShader.Builder().build() }
	val positionTexture by lazy(LazyThreadSafetyMode.NONE) { UberShader.Builder().withTexture().build() }
	val positionTextureLightmap by lazy(LazyThreadSafetyMode.NONE) { UberShader.Builder().withTexture().withLightMap().build() }
	val positionColor by lazy(LazyThreadSafetyMode.NONE) { UberShader.Builder().withColor().build() }
	val tile by lazy(LazyThreadSafetyMode.NONE) { UberShader.Builder().withTexture().withHueShift().withLightMap().build() }
	val font by lazy(LazyThreadSafetyMode.NONE) { FontProgram() }
	val liquid by lazy(LazyThreadSafetyMode.NONE) { GLLiquidProgram() }
}
