package theGhastModding.midiPlayerGL.renderer;

import java.awt.Color;
import java.util.List;

import org.joml.Vector2f;
import org.joml.Vector3f;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;

import theGhastModding.midiPlayerGL.gui.MainWindow;
import theGhastModding.midiPlayerGL.models.NoteModel;
import theGhastModding.midiPlayerGL.shaders.NoteShader;
import theGhastModding.synthesizer.main.MidiEvent;
import theGhastModding.synthesizer.main.TGMSynthesizer;

public class NoteRenderer {
	
	private NoteShader shader;
	
	public NoteRenderer(NoteShader shader) {
		this.shader = shader;
	}
	
	public void prepare() {
		GL11.glClearColor(0, 0, 0, 1);
		GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
		shader.start();
	}
	
	/*public void renderNew(List<List<NoteModel>> notes) throws Exception {
		RawModel rm;
		for(int i = 0; i < notes.size(); i++) {
			if(notes.get(i).isEmpty()) continue;
			rm = mesh(notes.get(i));
			Color c = MainWindow.trackColors.get(i);
			shader.setBaseColor(new Vector3f((float)c.getRed() / 255f,(float)c.getGreen() / 255f, (float)c.getBlue() / 255f));
			GL30.glBindVertexArray(rm.getVaoID());
			GL20.glEnableVertexAttribArray(0);
			shader.setPosition(new Vector2f(0, 0));
			GL11.glDrawElements(GL11.GL_TRIANGLES, rm.getVertexCount(), GL11.GL_UNSIGNED_INT, 0);
			GL20.glDisableVertexAttribArray(0);
			rm.delete();
		}
		GL30.glBindVertexArray(0);
	}*/
	
	public void render(List<List<NoteModel>> notes) throws Exception {
		for(int j = 0; j < notes.size(); j++) {
			Color c = MainWindow.trackColors.get(j);
			shader.setBaseColor(new Vector3f((float)c.getRed() / 255f,(float)c.getGreen() / 255f, (float)c.getBlue() / 255f));
			for(int i = 0; i < notes.get(j).size(); i++) {
				NoteModel note = notes.get(j).get(i);
				if(note.getYPos() < -1.0f - note.getLength() && !note.getNote().isOffPlayed()) {
					if(!MainWindow.preloadAll) {
						notes.get(j).get(i).getModel().delete();
					}
					notes.get(j).remove(i);
					TGMSynthesizer.sendEvent(new MidiEvent(MidiEvent.MIDI_EVENT_NOTE, note.getNote().getChannel(), note.getNote().getPitch(), 0));
					i--;
					note.getNote().setOffPlayed(true);
					continue;
				}
				if(note.getYPos() < -1.0f && !note.getNote().isOnPlayed()) {
					if(MainWindow.poly <= 512) {
						TGMSynthesizer.sendEvent(new MidiEvent(MidiEvent.MIDI_EVENT_NOTE, note.getNote().getChannel(), note.getNote().getPitch(), note.getNote().getVelocity()));
						MainWindow.poly++;
					}
					note.getNote().setOnPlayed(true);
				}
				GL30.glBindVertexArray(note.getModel().getVaoID());
				GL20.glEnableVertexAttribArray(0);
				shader.setPosition(new Vector2f(note.getKey() * NoteModel.noteWidth - 1.0f, note.getYPos()));
				GL11.glDrawElements(GL11.GL_TRIANGLES, note.getModel().getVertexCount(), GL11.GL_UNSIGNED_INT, 0);
				GL20.glDisableVertexAttribArray(0);
			}
		}
		GL30.glBindVertexArray(0);
	}
	
	/*private RawModel mesh(List<NoteModel> notes) throws Exception {
		float[] vertices = new float[notes.size() * 8];
		int[] indices = new int[notes.size() * 6];
		int cntr = 0;
		for(int i = 0; i < notes.size(); i++) {
			NoteModel nm = notes.get(i);
			if(nm.getYPos() < -1.0f && !nm.getNote().isOnPlayed()) {
				if(MainWindow.poly <= 512) {
					TGMSynthesizer.sendEvent(new MidiEvent(MidiEvent.MIDI_EVENT_NOTE, nm.getNote().getChannel(), nm.getNote().getPitch(), nm.getNote().getVelocity()));
					MainWindow.poly++;
				}
				nm.getNote().setOnPlayed(true);
			}
			vertices[cntr * 8 + 0] = nm.getKey() * NoteModel.noteWidth - 1.0f;
			vertices[cntr * 8 + 1] = nm.getYPos();
			vertices[cntr * 8 + 2] = vertices[cntr * 8 + 0] + NoteModel.noteWidth;
			vertices[cntr * 8 + 3] = nm.getYPos();
			vertices[cntr * 8 + 4] = vertices[cntr * 8 + 0];
			vertices[cntr * 8 + 5] = nm.getYPos() + nm.getLength();
			vertices[cntr * 8 + 6] = vertices[cntr * 8 + 2];
			vertices[cntr * 8 + 7] = vertices[cntr * 8 + 5];
			
			indices[cntr * 6 + 0] = cntr * 4 + 2;
			indices[cntr * 6 + 1] = cntr * 4 + 0;
			indices[cntr * 6 + 2] = cntr * 4 + 3;
			indices[cntr * 6 + 3] = cntr * 4 + 3;
			indices[cntr * 6 + 4] = cntr * 4 + 0;
			indices[cntr * 6 + 5] = cntr * 4 + 1;
			cntr++;
			if(nm.getYPos() < -1.0f - nm.getLength()) {
				notes.get(i).getModel().delete();
				notes.remove(i);
				TGMSynthesizer.sendEvent(new MidiEvent(MidiEvent.MIDI_EVENT_NOTE, nm.getNote().getChannel(), nm.getNote().getPitch(), 0));
				i--;
				continue;
			}
		}
		return loader.loadToVAO(vertices, indices);
	}*/
	
	public void end() {
		shader.stop();
	}
	
}