package harmonicTable;

import java.util.Map;

import midiReference.NoteReference;
import processing.core.PApplet;
import processing.core.PFont;


//TODO: Assign a Note Name to drawHex to print the note name in the hexagon button

public class HarmonicTable extends PApplet {

	public static void main(String[] args) {
		//PApplet.main(new String[] { "--present", "processingMidi.ProcessingMidi" });
		PApplet.main(new String[] { "harmonicTable.HarmonicTable" });
	}

	int length=30;
	int space = 0;
	int initialOffset=length/2;
	float xOffset = (length*3);
	float a = length/2;
	float b = sin(radians(60))*length;
	float c = length;
	float screenWidth = 12*((2*a)+(2*c))+a+(14*space);
	float screenHeight = b*19+(8.5f*space);
	int rowNumber;

	static final NoteReference midiNote = NoteReference.getMidiReference();
	static final Map<String, Integer> noteNameMap = midiNote.getNoteNameMap();
	static final String[] noteNumberArray = midiNote.getNoteNumberArray();
	int noteNumber;
	
	PFont font;
	
	//Colors
	int whiteKey = 255;
	int blackKey = 0;
	int Gsharp = color(4,55,139);
	int D = color(188,228,246);
	
	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));
	}

	public void draw(){
		background(255);
		
		rowNumber=0;
		setNoteNumber(rowNumber);
		for (int j=2; j<20; j++){
			pushMatrix();
			translate(0+space, (height-(j*(b+space/2)+1)));
			drawHex(getNextNote());
			for (int i=1; i <12; i++){
				translate(space+(2*a)+(2*c), 0);
				drawHex(getNextNote());
			}
			popMatrix();
			
			j++;
			rowNumber++;
			setNoteNumber(rowNumber);
			
			pushMatrix();			
			translate(a+c+1.5f*space, (height-(j*(b+space/2))));
			drawHex(getNextNote());
			for (int i=1; i <12; i++){
				translate(space+(2*a)+(2*c), 0);
				drawHex(getNextNote());
			}
			popMatrix();
			
			rowNumber++;
			setNoteNumber(rowNumber);
			if (frameCount==1)
				save("harmonicTable.png");
		}
	}

	public void drawHex(String note){
		/* Decide on fill value based on Note name
		 * if string contains # or b then the note should be black
		 * most other notes white
		 * G# dark blue, D light blue
		 * Maybe some gray alternates in there to match the C-thru
		 */
		fill(255);	
		if (note.contains("G#")) {
			fill(Gsharp);
		} else if (note.contains("D") && !note.contains("#")) {
			fill(D);
		} else if (note.contains("#")) {
			fill(blackKey);
		}
		//draw hex shape
		beginShape();
			vertex(0,b);
			vertex(a,0);
			vertex(a+c,0);
			vertex(2*c,b);
			vertex(a+c,2*b);
			vertex(a+c,2*b);
			vertex(a,2*b);
			vertex(0,b);
		endShape();
		
		/* Decide on fill value based on Note name
		 * if string contains # or b then the text should be white
		 * most other notes white
		 * G# white, D black
		 */
		drawNote(note);
	}
	
	public void drawNote(String note){
		fill(0);
		String temp[] = null;
		String shortNote = "";
		
		if (note.contains("G#")) {
			fill(255);
		} else if (note.contains("D") && !note.contains("#")) {
			fill(0);
		} else if (note.contains("#")) {
			fill(255);
		}
		
		temp = note.split("/");
		
		if ((temp.length > 1) && (temp[1].contains("Bb") || temp[1].contains("Eb"))){
			shortNote=temp[1].substring(0, temp[1].length()-1);
		} else {
			shortNote=temp[0].substring(0, temp[0].length()-1);
		}
		//write the note name in the box, take the first note
		text(shortNote, c, c);
	}
	
	public String getNextNote(){
		String noteName = noteNumberArray[noteNumber];
		noteNumber++;
		return noteName;
	}
	
	public void setNoteNumber(int rowNumber){
		switch (rowNumber) {
			//TODO: There has to be a better way to decide row start values rather than have 
    		//them jammed in a switch case block
			case 0:  noteNumber = noteNameMap.get("C2"); break;
			case 1:  noteNumber = noteNameMap.get("E2"); break;
        	case 2:  noteNumber = noteNameMap.get("G2"); break;
        	case 3:  noteNumber = noteNameMap.get("B2"); break;
        	case 4:  noteNumber = noteNameMap.get("D3"); break;
        	case 5:  noteNumber = noteNameMap.get("F#3"); break;
        	case 6:  noteNumber = noteNameMap.get("A3"); break;
        	case 7:  noteNumber = noteNameMap.get("C#4"); break;
        	case 8:  noteNumber = noteNameMap.get("E4"); break;
        	case 9:  noteNumber = noteNameMap.get("G#4"); break;
        	case 10:  noteNumber = noteNameMap.get("B4"); break;
        	case 11:  noteNumber = noteNameMap.get("Eb5"); break;
        	case 12:  noteNumber = noteNameMap.get("F#5"); break;
        	case 13:  noteNumber = noteNameMap.get("Bb5"); break;
        	case 14:  noteNumber = noteNameMap.get("C#6"); break;
        	case 15:  noteNumber = noteNameMap.get("F6"); break;
        	case 16:  noteNumber = noteNameMap.get("G#6"); break;
        	case 17:  noteNumber = noteNameMap.get("C7"); break;
        	default: noteNumber = noteNameMap.get("C0"); break;
		}
	}
}

