package gsingh.learnkirtan.keys; import gsingh.learnkirtan.Constants; import gsingh.learnkirtan.note.Note; import gsingh.learnkirtan.note.NoteList; import gsingh.learnkirtan.parser.exceptions.NoteOutOfBoundsException; import java.util.Arrays; public class KeyMapper { private static KeyMapper instance; /** The note names for all the notes on the keyboard */ private NoteList notes; /** An array of all of the keys */ private Key[] keys; private KeyMapper() { } public static KeyMapper getInstance() { if (instance == null) instance = new KeyMapper(); return instance; } /** * Sets the internal {@link NoteList} * * @param notes * the new {@link NoteList} */ public void setNotes(NoteList notes) { this.notes = notes; } /** @return the current {@link NoteList} */ public NoteList getNotes() { return notes; } /** * Sets the internal {@link Key} array * * @param keys * the array */ public void setKeys(Key keys[]) { this.keys = keys; } // TODO: This isn't immutable /** @return an immutable {@link Iterable} over the keys */ public final Iterable<Key> getKeys() { return Arrays.asList(keys); } /** @return the {@link Key} corresponding to {@code keyId}, otherwise null */ public Key getKey(int keyId) { if (keyId < Constants.MAX_KEYS && keyId >= 0) { return keys[keyId]; } else { return null; } } /** * Returns a key corresponding to a note * * @param note * the note to search for * @return the corresponding key * @throws NoteOutOfBoundsException */ public Key getKeyFromNote(Note note) throws NoteOutOfBoundsException { if (note.isUpperOctave()) { int index = notes.getUpperNoteIndex(note); if (index >= 0 && index < keys.length) { return keys[index]; } else { throw new NoteOutOfBoundsException(note.getNoteText()); } } else if (note.isLowerOctave()) { int index = notes.getLowerNoteIndex(note); if (index >= 0 && index < keys.length) { return keys[index]; } else { throw new NoteOutOfBoundsException(note.getNoteText()); } } else { int index = notes.getMiddleNoteIndex(note); if (index >= 0 && index < keys.length) { return keys[index]; } else { throw new NoteOutOfBoundsException(note.getNoteText()); } } } }