import AssertionError from "../error/AssertionError"; import EtudeError from "../error/EtudeError"; import Direction from "./Direction"; export default class Mode { public static size: number = 0; private static _values: Mode[] = []; public static IONIAN = new Mode([2, 2, 1, 2, 2, 2, 1]); public static DORIAN = new Mode([2, 1, 2, 2, 2, 1, 2]); public static PHRYGIAN = new Mode([1, 2, 2, 2, 1, 2, 2]); public static LYDIAN = new Mode([2, 2, 2, 1, 2, 2, 1]); public static MIXOLYDIAN = new Mode([2, 2, 1, 2, 2, 1, 2]); public static AEOLIAN = new Mode([2, 1, 2, 2, 1, 2, 2]); public static LOCRIAN = new Mode([1, 2, 2, 1, 2, 2, 2]); private ascending: number[]; private descending: number[]; private constructor(private stepPattern: number[]) { ++Mode.size; Mode._values.push(this); this.ascending = stepPattern.slice(); this.descending = stepPattern.slice().reverse().map(a => -a); } public static values(): Mode[] { return Mode._values.slice(); } public ordinal(): number { return Mode._values.indexOf(this); } public static valueOf(modeString: string): Mode { const mode: Mode = Mode[modeString]; if (mode instanceof Mode) { return mode; } throw EtudeError.forInvalid(Mode, modeString); } public toString(): string { return Object.keys(Direction).find(d => Direction[d] === this); } public getStepPattern(direction: Direction = Direction.DEFAULT): number[] { switch (direction) { case Direction.ASCENDING: return this.ascending.slice(); case Direction.DESCENDING: return this.descending.slice(); default: throw new AssertionError("Invalid direction"); } } }