package gsingh.learnkirtan.note; import gsingh.learnkirtan.Constants; import gsingh.learnkirtan.parser.Parser; import gsingh.learnkirtan.parser.exceptions.NoteOutOfBoundsException; import java.util.Arrays; import java.util.LinkedList; import java.util.List; public class NoteList { /** The default key ID for sa */ private static final int DEFAULT_SA_KEY_ID = 10; /** The sargam note names for all the keys on the keyboard */ private List<String> notes = new LinkedList<String>( Arrays.asList(new String[] { "Re", "'Ga", "Ga", "Ma", "Ma'", "Pa", "'Dha", "Dha", "'Ni", "Ni", "Sa", "'Re", "Re", "'Ga", "Ga", "Ma", "Ma'", "Pa", "'Dha", "Dha", "'Ni", "Ni", "Sa", "'Re", "Re", "'Ga", "Ga", "Ma", "Ma'", "Pa", "'Dha", "Dha", "'Ni", "Ni", "Sa", "'Re" })); /** The key ID where the lower octave starts */ private int lowerStart; /** The key ID where the middle octave starts */ private int middleStart = DEFAULT_SA_KEY_ID; /** The key ID where the upper octave starts */ private int upperStart; public NoteList(int saKey) { shiftLabels(saKey); } /** * Shifts the sargam labels based on the new Sa key * * @param saKey * the new saKey to be used as a reference for the shift */ public void shiftLabels(int saKey) { int difference = saKey - middleStart; // Shift the sargam labels up or down if (difference > 0) { for (int i = 0; i < difference; i++) { notes.add(0, notes.remove((notes.size() - 1))); } } else if (difference < 0) { for (int i = 0; i < -1 * difference; i++) { notes.add(notes.size() - 1, notes.remove(0)); } } // Set the middle Sa position middleStart = saKey; // Set the upper Sa position upperStart = saKey + 12; if (upperStart >= Constants.MAX_KEYS) { upperStart = Constants.MAX_KEYS - 1; } // Set the lower Sa position lowerStart = saKey - 12; if (upperStart < 0) { upperStart = 0; } } /** * Gets the note name of the note at the specified key ID * * @param keyId * the ID of they to get the note name of * @return the name of the note */ public String getNoteNameFromId(int keyId) { return notes.get(keyId); } /** * Returns a {@link Note} corresponding to a specific key ID * * @param keyId * the key ID of the key from which to get a note * @return a {@link Note} corresponding to the key */ public Note getNoteFromKeyId(int keyId) { Parser parser = new Parser(); String note = getNoteNameFromId(keyId); if (keyId < middleStart) { note = "." + note; } else if (keyId >= upperStart) { note = note + "."; } return parser.parseNote(note); } /** * Returns the index of the note in the lower note section of the note list, * which is the key ID of the note * * @param note * the note to get the index of * @return the index of the note * @throws NoteOutOfBoundsException */ public int getLowerNoteIndex(Note note) throws NoteOutOfBoundsException { return getNoteIndex(note, lowerStart, middleStart); } /** * Returns the index of the note in the middle note section of the note * list, which is the key ID of the note * * @param note * the note to get the index of * @return the index of the note * @throws NoteOutOfBoundsException */ public int getMiddleNoteIndex(Note note) throws NoteOutOfBoundsException { return getNoteIndex(note, middleStart, upperStart); } /** * Returns the index of the note in the upper note section of the note list, * which is the key ID of the note * * @param note * the note to get the index of * @return the index of the note * @throws NoteOutOfBoundsException */ public int getUpperNoteIndex(Note note) throws NoteOutOfBoundsException { return getNoteIndex(note, upperStart, notes.size() - 1); } /** * Gets the index of the provided note in the note list. The note index is * equivalent to the key ID corresponding to the note. * * @param note * the note to look for * @param start * the starting index to look for the note * @param end * the ending index to look for the note * @return the index of the note * @throws NoteOutOfBoundsException */ private int getNoteIndex(Note note, int start, int end) throws NoteOutOfBoundsException { String name = getName(note); start = start < 0 ? 0 : start; end = end > notes.size() ? notes.size() : end; int index = notes.subList(start, end).indexOf(name); if (index == -1) throw new NoteOutOfBoundsException(note.getNoteText()); return index + start; } /** * Returns the name of a note including modifiers but not including octaves * * @param note * the note to get the name of * @return the name of the note */ private String getName(Note note) { String name = note.getName(); if (note.isTheevra()) name = name + "'"; else if (note.isKomal()) name = "'" + name; return name; } }