from shortcrust.shader import ShaderProgram
from shortcrust.mesh import Mesh
from shortcrust.gl2 import *
from shortcrust.texture import Texture


class ChampionShader(ShaderProgram):
	vertex_shader = """
		attribute vec4 vPosition;
		varying vec4 texPosition;
		void main()
		{
			texPosition = (vPosition + vec4(1.0, 1.0, 0.0, 0.0)) / 2.0;
			gl_Position = vPosition;
		}
	"""

	fragment_shader = """
		/* precision mediump float; */

		uniform float beat;
		uniform sampler2D uSampler;
		varying vec4 texPosition;

		void main()
		{
			float waviness = (1.0 - smoothstep(0.0, 4.0, beat)) * 0.05;
			vec2 tex_offset = vec2(
				waviness * 0.5 * sin(texPosition.y * 30.0),
				waviness * sin(texPosition.x * 30.0)
			);
			vec4 texture_pix = texture2D(uSampler, texPosition.xy + tex_offset);
			gl_FragColor = vec4(texture_pix.rgb, 1.0 - length(tex_offset) * 20.0);
		}
	"""

	def __init__(self):
		check_gl_error()
		super(ChampionShader, self).__init__()
		check_gl_error()
		self.vertex_position_attr = glGetAttribLocation(self.program_object, 'vPosition')
		check_gl_error()
		self.beat_unif = glGetUniformLocation(self.program_object, 'beat')
		check_gl_error()
		self.sampler_unif = glGetUniformLocation(self.program_object, 'uSampler')
		check_gl_error()


class ChampionMesh(Mesh):
	mode = GL_TRIANGLE_STRIP
	vertices = [
		(-1.0, -1.0, -0.99),
		(-1.0, 1.0, -0.99),
		(1.0, -1.0, -0.99),
		(1.0, 1.0, -0.99),
	]


class ChampionLayer(object):
	def __init__(self, app):
		self.app = app

		self.shader = ChampionShader()
		self.mesh = ChampionMesh()
		self.texture = Texture('data/champion.png')

	def draw(self, time):
		self.shader.use()

		beat = time / self.app.beat_length
		if beat < 28:
			return
		glUniform1f(self.shader.beat_unif, beat - 28)
		self.texture.activate(GL_TEXTURE0)
		glUniform1i(self.shader.sampler_unif, 0)
		check_gl_error()

		self.mesh.draw(self.shader.vertex_position_attr)
