-- this is done only once, when the demo starts
local gridrot

function effu_load() 
end

-- done just before first _paint
function effu_init(millis)
	effu_start = millis
	gridrot = 0
end

-- millis = milliseconds in song
function effu_paint(millis, timedelta, params)
	spectrum = engine_spectrum()

	local beatcount = 64

	low = 0
	for i = 0, 64 do
		low = low + spectrum[i]
	end

	low = low / beatcount

	mid = 0
	for i = 65, 65+64 do
		mid = mid + spectrum[i]
	end

	mid = mid / beatcount

	hi = 0
	for i = 65+64, 65+64+64 do
		hi = hi + spectrum[i]
	end

	hi = hi / beatcount

	glClearColor(0.0,0.0,0.0,1);
        glClear(GL_COLOR_BUFFER_BIT + GL_DEPTH_BUFFER_BIT)

	if params.delta then
                millis = time + params.delta
        end


	glDisable(GL_TEXTURE_2D)
	glLoadIdentity()
	glPushMatrix()
	glEnable(GL_BLEND)
	glEnable(GL_MULTISAMPLE)
		glOrtho(0, glutGet(GLUT_WINDOW_WIDTH), 0, glutGet(GLUT_WINDOW_HEIGHT), 0, 100)
		glMatrixMode(GL_MODELVIEW)

		local width = glutGet(GLUT_WINDOW_WIDTH)
		local height = glutGet(GLUT_WINDOW_HEIGHT)

		if params.part ~= 9 then
			if low > 0.01 then
				glBlendFunc(GL_SRC_COLOR, GL_DST_ALPHA)
			else
				glBlendFunc(GL_ONE_MINUS_SRC_COLOR, GL_DST_ALPHA)
			end
		else
				glBlendFunc(GL_SRC_COLOR, GL_DST_ALPHA)
		end

		if params.part == 10 then
				glBlendFunc(GL_SRC_COLOR, GL_DST_ALPHA)
		end

		if params.part == 1 or params.part == 2 or params.part == 3 or params.part == 7 then

			if params.part == 1 then gridrot = gridrot + low*300+mid*200 end
			if params.part == 2 then gridrot = gridrot - low*300+mid*200 end
			if params.part == 3 then gridrot = gridrot + low*300+mid*200 end
			if params.part == 7 then gridrot = gridrot - low*300+mid*200 end

			for i = 0, 4 do
				if params.gridcolor == 0 then glColor4d(0.0,0.0,0.0,0.5+math.tan(low*millis)*0.5) end
				if params.gridcolor == 1 then glColor4d(0.5+math.cos(low*100)*0.5,0.0,0.0,0.5+math.tan(low*millis)*0.5) end
				if params.gridcolor == 2 then glColor4d(0.5+math.sin(low*100)*0.5,1.0,0.0,0.5+math.tan(low*millis)*0.5) end
				glPushMatrix()
				glTranslated(width/2,height/2,-0.2+math.cos(millis*0.002)*0.2)
				if params.part == 1 then glRotated(i*(360/4)+millis*0.001+gridrot, 0, 0, 1) end
				if params.part == 2 then glRotated(i*(360/4)-millis*0.001+gridrot, 0, 0, 1) end
				glTranslated(-width/2,-height/2,0)
				if params.part == 1 then xoff = math.tan(millis*0.001+i*100*hi)*width/2 end
				if params.part == 2 then xoff = math.tan(millis*0.0005+i*50*low)*width/2 end
				yoff = math.cos(millis*0.001+i*100*mid)*height/2
				glBegin(GL_QUADS)
					glVertex3d(xoff,yoff,0)
					glVertex3d(width-xoff,yoff,0)
					glVertex3d(width-xoff,height/16+yoff,0)
					glVertex3d(xoff,height/16+yoff,0)
				glEnd()
				glPopMatrix()
			end
	
			if params.part == 3 then
				for i = 0, 4 do
					glColor4d(0.5+math.sin(low*100)*0.5,1.0,0.0,0.5+math.tan(low*millis)*0.5)
					glPushMatrix()
					glTranslated(width/2,height/2,-0.2+math.cos(millis*0.002)*0.2)
					glRotated(i*(360/4)-millis*0.001+gridrot, 0, 0, 1)
					glTranslated(-width/2,-height/2,0)
					xoff = math.tan(millis*0.0005+i*50*low)*width/2
					yoff = math.cos(millis*0.001+i*100*mid)*height/2
					glBegin(GL_QUADS)
						glVertex3d(xoff,yoff,0)
						glVertex3d(width-xoff,yoff,0)
						glVertex3d(width-xoff,height/16+yoff,0)
						glVertex3d(xoff,height/16+yoff,0)
					glEnd()
					glPopMatrix()
				end
			end
			if params.part == 7 then
				for i = 0, 4 do
					glColor4d(0.5+math.sin(low*100)*0.5,1.0,0.0,0.5+math.tan(low*millis)*0.5)
					glPushMatrix()
					glTranslated(width/2,height/2,-0.2+math.cos(millis*0.002)*0.2)
					glRotated(i*(360/4)-millis*0.001+gridrot, 0, 0, 1)
					glTranslated(-width/2,-height/2,0)
					xoff = math.tan(millis*0.0005+i*50*low)*width/2
					yoff = math.cos(millis*0.001+i*100*mid)*height/2
					glBegin(GL_QUADS)
						glVertex3d(xoff,yoff,0)
						glVertex3d(width-xoff,yoff,0)
						glVertex3d(width-xoff,height/16+yoff,0)
						glVertex3d(xoff,height/16+yoff,0)
					glEnd()
					glPopMatrix()
				end
			end

		end

		if params.part == 0 or params.part == 1 or params.part == 2 or params.part == 5 then

			drawoff = math.cos(low*100+mid*100+hi*100)*128
			if params.part == 2 then drawoff = math.sin(low*200+mid*150)*128 end

			for i = 64+drawoff, 254-drawoff do
				xoff = math.tan(millis*0.001+i*100*hi)*width/2
				yoff = math.cos(millis*0.001+i*100*mid)*height/2
				xoff2 = math.sin(millis*0.0001)*width/4
				yoff2 = math.cos(millis*0.0001)*height/4
				glPushMatrix()
				glTranslated(width/2-xoff2,height/2-yoff2,0)
				glRotated(i*(360/254)*math.tan(i*low)+xoff2, mid*100, math.cos(millis*0.0001), 1)
				glTranslated(-width/2+xoff2,-height/2+xoff2,0)
				glColor4d(1-i/254+low*50,0.5,0.5+math.tan(i*0.05+millis*0.0001)*0.5,1)
				glBegin(GL_TRIANGLES)
					glVertex3d(xoff,yoff,0)
					glVertex3d(width-xoff,yoff,0)
					glVertex3d(width-xoff,height/16,0)
				glEnd()
				glPopMatrix()
			end
		end

		if params.part == 3 then

			for i = 64, 254 do
				glPushMatrix()
				glTranslated(width/2,height/2,0)
				glRotated(i*(360/254), 0, math.cos(millis*0.0001), math.tan(millis*0.001+i))
				glTranslated(-width/2,-height/2,0)
				glColor4d(1-i/254+hi*50,0.5,0.5+math.tan(i*0.05+millis*0.0001)*0.5,1)
				xoff = math.sin(millis*0.001+low*100)*width/2
				glBegin(GL_TRIANGLES)
					glVertex3d(0+xoff,xoff,0)
					glVertex3d(width-xoff,xoff,0)
					glVertex3d(width-xoff,height/16,0)
				glEnd()
				glPopMatrix()
			end
		end

		if params.part == 4 then

			for i = 64, 254 do
				glPushMatrix()
				glTranslated(width/2,height/2,0)
				glRotated(i*(360/254), math.cos(millis*0.0001),0, math.tan(millis*0.001+i))
				glTranslated(-width/2,-height/2,0)
				glColor4d(1,0,0,1)
				xoff = math.cos(millis*0.0015+mid*100)*width/4
				glBegin(GL_TRIANGLES)
					glVertex3d(0+xoff,xoff,0)
					glVertex3d(width-xoff,xoff,0)
					glVertex3d(width-xoff,height/4,0)
				glEnd()
				glPopMatrix()
			end
		end
		if params.part == 5 then
			glDisable(GL_BLEND)
			for i = 64, 254 do
				glPushMatrix()
				glTranslated(width/2,height/2,0)
				glRotated(i*(360/254), math.sin(millis*0.001+low*150),0.5, math.tan(millis*0.0015+i+low*100))
				glTranslated(-width/2,-height/2,0)
				glColor4d(0,0,0,1)
				xoff = math.sin(millis*0.0012+mid*100)*width/8
				glBegin(GL_TRIANGLES)
					glVertex3d(0+xoff,xoff,0)
					glVertex3d(width-xoff,-xoff,0)
					glVertex3d(width-xoff,height/8,0)
				glEnd()
				glPopMatrix()
			end
			glEnable(GL_BLEND)
		end
		if params.part == 6 then
			for i = 64, 254 do
				pushrot = math.cos(millis*0.0001+low*100)*width
				glPushMatrix()
				glTranslated(width/2,height/2,0)
				glRotated(i*(360/254)+pushrot, math.sin(millis*0.001+low*150),0.5, math.tan(millis*0.0015+i+low*100))
				glTranslated(-width/2,-height/2,0)
				glColor4d(math.cos(millis*0.00001),0,1-(i/254),1-(i/254))
				xoff = math.sin(millis*0.0012+low*100)*width/8
				glBegin(GL_TRIANGLES)
					glVertex3d(0+xoff+pushrot,xoff,0)
					glVertex3d(width-xoff,-xoff+pushrot,0)
					glVertex3d(width-xoff,height/8,0)
				glEnd()
				glPopMatrix()
			end
		end
		if params.part == 7 then
			for i = 64, 254 do
				pushrot = math.cos(millis*0.0001+low*100)*width/8
				glPushMatrix()
				glTranslated(width/2,height/2,0)
				glRotated(i*(360/254)+pushrot, math.cos(millis*0.0015+low*250),0.3, math.tan(millis*0.0015+i+hi*100))
				glTranslated(-width/2,-height/2,0)
				glColor4d(math.sin(millis*0.00015),0,0.5-(i/254),1-(i/254))
				xoff = math.sin(millis*0.0012+low*100)*width/16
				glBegin(GL_TRIANGLES)
					glVertex3d(0+xoff+pushrot,xoff,0)
					glVertex3d(width-xoff,-xoff+pushrot,0)
					glVertex3d(width-xoff,height/8,0)
				glEnd()
				glPopMatrix()
			end
		end
		if params.part == 8 then
			for i = 0, 15 do
				glPushMatrix()
				glTranslated(width/2,height/2,0)
				glRotated(i*(360/15)+low*100,1,1,1)
				glTranslated(-width/2,-height/2,0)
				glColor4d(1,1,1,1)
				glBegin(GL_TRIANGLES)
					glVertex3d(0,0,0)
					glVertex3d(width,0,0)
					glVertex3d(width,height/8,0)
				glEnd()
				glPopMatrix()
			end
		end
		if params.part == 9 then
			for i = 0, 15 do
				glPushMatrix()
				glTranslated(width/2,height/2,0)
				glRotated(millis*0.05+i*(360/15)-low*600,1,1,1)
				glTranslated(-width/2,-height/2,0)
				glColor4d(1,1,1,1)
				glBegin(GL_TRIANGLES)
					glVertex3d(0,0,0)
					glVertex3d(width,0,0)
					glVertex3d(width,height/8,0)
				glEnd()
				glPopMatrix()
			end
		end
		if params.part == 10 then
			for i = 0, 15 do
				glPushMatrix()
				glTranslated(width/2,height/2,0)
				glRotated(millis*0.05+i*(360/15)+hi*600,1,1,1)
				glTranslated(-width/2,-height/2,0)
				glColor4d(1,1,1,1)
				glBegin(GL_TRIANGLES)
					glVertex3d(0,0,0)
					glVertex3d(width,0,0)
					glVertex3d(width,height/8,0)
				glEnd()
				glColor4d(0,1,0,1)
				glBegin(GL_QUADS)
					glVertex3d(0,0,0)
					glVertex3d(width,0,0)
					glVertex3d(width,height/8,0)
					glVertex3d(0,height/8,0)
				glEnd()
				glPopMatrix()
			end
		end

	glDisable(GL_MULTISAMPLE)
	glPopMatrix()
end

-- called after last _paint
function effu_deinit()
	--print("effu_deinit")
end

function effu_unload()
	--print("effu_unload")
end
