use image
use hui
use nix
use os

class MeltData
	quaternion q
	quaternion q2
	#float x, y, r, u
	void __init__(float _x, float _y, float _r, float _u)
		q.x = _x
		q.y = _y
		q.z = _r
		q.w = _u

class Note
	int pitch, start, end
	void __init__(int p, int a, int b)
		pitch = p
		start = a
		end = b

class Renderer
	Texture* tex
	Texture* mask
	Texture* tex_target
	FrameBuffer *fb
	Shader* shader
	float t, intensity, intensity2
	int frame
	UniformBuffer *ubo_melts
	MeltData[] melts
	Note[] notes
	
	

	void __init__()
		
		frame = 0
		t = 0
		intensity = 0
		intensity2 = 0

		for i in 0:60
			melts.add((rand(1), rand(1), 0.1 + rand(0.05), 0.01 + rand(0.01)))
		
		ubo_melts = new UniformBuffer()
		
		let f = Filesystem.open_text("notes")
		while !f.eof()
			string x
			f >> x
			let xx = x.explode(":")
			notes.add((int(xx[0]), int(xx[1]), int(xx[2])))
		del f
		
		tex_target = new Texture(1920, 1080, "rgb:i8")
		fb = new FrameBuffer([tex_target])
		
		tex = Texture.load("b2.png")
		mask = Texture.load("mask.png")
		vb_temp.create_rect(rect(-1,1, -1,1))
		shader = Shader.load("wobble.shader")
	void draw()
		ubo_melts.update(melts)
		SetZ(false, false)
		SetShader(shader)
		shader.set_float(shader.location("t"), t)
		shader.set_float(shader.location("intensity"), intensity)
		shader.set_float(shader.location("intensity2"), intensity2)
		shader.set_int(shader.location("num_melts"), len(melts))
		BindUniform(ubo_melts, 0)
		SetTextures([tex, mask])
		DrawTriangles(vb_temp)
		
		if note_start(67)
			intensity = 1
		else if in_note(67)
			#intensity = max(intensity, 0.7)
			intensity *= 0.99
		else
			intensity *= 0.9
			
		
		if note_start(72)
			intensity2 = 1
		else if in_note(72)
			intensity2 *= 0.99
		else
			intensity2 *= 0.9
		
		t += 0.04
		frame ++
	bool note_start(int p)
		for n in notes
			if frame == n.start and n.pitch == p
				return true
		return false
	bool in_note(int p)
		for n in notes
			if frame >= n.start and frame <= n.end and n.pitch == p
				return true
		return false

class PreviewWindow extends NixWindow
	Renderer* r
	void __init__()
		super.__init__("test", 1920, 1080)
		show()
		NixInit()
		
		r = new Renderer()
		
		event_x("nix-area", "hui:draw-gl", draw)
		RunRepeated(0.04, self, force_update)
	void force_update()
		redraw("nix-area")
	void draw()
		r.draw()

#const int N = 700

class RenderWindow extends NixWindow
	Renderer* r
	void __init__()
		super.__init__("test", 1920, 1080)
		show()
		NixInit()
		r = new Renderer()
	void render(int N)
		BindFrameBuffer(r.fb)
		Image im
		for frame in 0:N
			if frame%100 == 0
				print("frame {{frame|04}} / {{N}}")
			r.draw()
			r.tex_target.read(im)
			#ScreenShotToImage(im)
			im.save("out/{{frame|04}}.bmp")

void main(string[] arg)
	if "render" in arg
		let w = new RenderWindow()
		w.render(int(arg[1]))
	else
		let w = new PreviewWindow()
		w.run()
