package harmonicTable;

import java.util.ArrayList;
import java.util.Map;
import midiReference.NoteReference;
import processing.core.PApplet;
import processing.core.PFont;
import rwmidi.MidiOutput;
import rwmidi.RWMidi;


//TODO: Discover mouse position relative to the starting point for each hexagon and its sizes based on length 

public class HarmonicTable extends PApplet {

	/**
	 * 
	 */
	private static final long serialVersionUID = -1512978966491270400L;

	public static void main(String[] args) {
		//PApplet.main(new String[] { "--present", "processingMidi.ProcessingMidi" });
		PApplet.main(new String[] { "harmonicTable.HarmonicTable" });
	}
	int length = 35; //length of one side of the hexagon
	int space = 0; //space between hexagons (currently not working)
	float a = length/2;
	float b = sin(radians(60))*length;  
	float c = length; 
	
	int xOffset = parseInt((2*c)+(2*a)); //How far left from 0 to move for each hexagon
	float screenWidth = 12*((2*a)+(2*c))+a+(14*space); //based on hexagon sizes
	float screenHeight = b*19+(8.5f*space); //based on hexagon sizes
	
	int rowNumber; //Used for detecting which note to start from
	int whiteKey = 255; //color of all white keys
	int blackKey = 0; //color of all black keys
	int Gsharp = color(4,55,139); //color for G#
	int D = color(188,228,246); //color for D

	MidiOutput midiOutput;
	static final NoteReference midiNote = NoteReference.getMidiReference();
	static final Map<String, Integer> noteNameMap = midiNote.getNoteNameMap();
	static final String[] noteNumberArray = midiNote.getNoteNumberArray();
	String startingNote = "A2";
	int previousNote;
	int noteNumber;
	ArrayList<Integer> activeNotes = new ArrayList<Integer>();
	
	PFont font;
	
	ArrayList<HexButton> hexButtons;
	
	public void setup(){
		size(ceil(screenWidth),ceil(screenHeight));
		smooth();
		stroke(148, 149, 150);
		strokeWeight(2);
		textAlign(CENTER);
		font = loadFont("Myriad-Web-48.vlw");
		textFont(font, ceil(length * 0.66f)); //calculate font size based on hexagon size
		
		
		//initialize and fill an array of hex buttons
		hexButtons = new ArrayList<HexButton>(); 
		
//		MidiOutputDevice devices[] = RWMidi.getOutputDevices();
//		  for (int i = 0; i < devices.length; i++) {
//		    println(i + ": " + devices[i].getName());
//		  }
		
		midiOutput = RWMidi.getOutputDevices()[2].createOutput();
		
		for (int j=2; j <20; j++){
			resetNoteNumber(rowNumber);
			for (int i=0; i<12; i++){
				hexButtons.add(new HexButton(this, space+(i*xOffset), parseInt(height-(j*b)), length, noteNumber));
				noteNumber++;
			}
		
			j++;
			rowNumber++;
			resetNoteNumber(rowNumber);
			
			for (int i=0; i<12; i++){
				hexButtons.add(new HexButton(this, space+parseInt(a+c)+(i*xOffset), parseInt(height-(j*b)), length, noteNumber));
				noteNumber++;
			}
			
			rowNumber++;
		}
	}

	public void draw(){
		background(255);
		for (int i = 0; i < hexButtons.size(); i++){
			HexButton button = (HexButton) hexButtons.get(i);
			button.drawHex(false);
		}
		if (frameCount == 10){
			saveFrame("HarmonicTableA2.jpg");
		}
	}
	
	public void mousePressed(){
		for (int i = 0; i < hexButtons.size(); i++){
			HexButton button = (HexButton) hexButtons.get(i);
			if (mouseX >= button.startX+a && mouseX <= button.startX+a+c
					&& mouseY >= button.startY && mouseY <= button.startY+(2*b)){
				println(button.note);
				activeNotes.add(button.thisNoteNumber);
				midiOutput.sendNoteOn(0, button.thisNoteNumber, 100);
			}
		}
	}
	
	public void mouseDragged(){
		for (int i = 0; i < hexButtons.size(); i++){
			HexButton button = (HexButton) hexButtons.get(i);
			if (mouseX >= button.startX+a && mouseX <= button.startX+a+c
					&& mouseY >= button.startY && mouseY <= button.startY+(2*b)){
				if (!activeNotes.contains(button.thisNoteNumber)){
					activeNotes.add(button.thisNoteNumber);
					midiOutput.sendNoteOn(0, button.thisNoteNumber, 100);
				}
			}
		}
	}
	
	public void mouseReleased(){
		for (int i = activeNotes.size()-1; i >= 0; i--){
			println("releasingNote");
			midiOutput.sendNoteOff(0, activeNotes.get(i), 0);
			activeNotes.remove(i);
		}
	}
		
	public void resetNoteNumber(int rowNumber){
		if (rowNumber == 0){
			noteNumber = noteNameMap.get(startingNote);
			previousNote = noteNumber;
		} else if (rowNumber % 2 == 0){
			noteNumber = previousNote + 3;
			previousNote = noteNumber;
		} else {
			noteNumber = previousNote + 4;
			previousNote = noteNumber;
		}
	}
}

