import { AbstractNotationInstruction } from "./AbstractNotationInstruction" ; import { SourceStaffEntry } from "../SourceStaffEntry" ; import { NoteEnum } from "../../../Common/DataObjects/Pitch" ; import { AccidentalEnum } from "../../../Common/DataObjects/Pitch" ; import { Pitch } from "../../../Common/DataObjects/Pitch" ; /**
 * A [[KeyInstruction]] is a key signature denoting which notes are to be sharpened or flattened.
 */ export class KeyInstruction extends AbstractNotationInstruction { constructor ( sourceStaffEntry = undefined , key = 0 , mode = KeyEnum . major ) { super ( sourceStaffEntry ) ; this . Key = key ; this . keyTypeOriginal = key ; this . mode = mode ; this . alteratedNotes = this . calcAlteratedNotes ( ) ; } private static sharpPositionList : NoteEnum [ ] = [ NoteEnum . F , NoteEnum . C , NoteEnum . G , NoteEnum . D , NoteEnum . A , NoteEnum . E , NoteEnum . B ] ; private static flatPositionList : NoteEnum [ ] = [ NoteEnum . B , NoteEnum . E , NoteEnum . A , NoteEnum . D , NoteEnum . G , NoteEnum . C , NoteEnum . F ] ; private keyType : number ; public keyTypeOriginal : number ; private mode : KeyEnum ; private alteratedNotes : NoteEnum [ ] ; /** The halftones this instruction was transposed by, compared to the original. */ public isTransposedBy : number = 0 ; public static copy ( keyInstruction ) { const newKeyInstruction = new KeyInstruction ( keyInstruction . parent , keyInstruction . Key , keyInstruction . Mode ) ; newKeyInstruction . keyTypeOriginal = keyInstruction . keyTypeOriginal ; return newKeyInstruction ; } public static getAllPossibleMajorKeyInstructions ( ) { const keyInstructionList = [ ] ; for ( let keyType = - 7 ; keyType < 7 ; keyType ++ ) { const currentKeyInstruction = new KeyInstruction ( undefined , keyType , KeyEnum . major ) ; keyInstructionList . push ( currentKeyInstruction ) ; } return keyInstructionList ; } public get Key ( ) : number { return this . keyType ; } public set Key ( value ) { this . keyType = value ; this . alteratedNotes = this . calcAlteratedNotes ( ) ; } public get Mode ( ) : KeyEnum { return this . mode ; } public set Mode ( value ) { this . mode = value ; } public get AlteratedNotes ( ) : NoteEnum [ ] { return this . alteratedNotes ; } private calcAlteratedNotes ( ) { const noteList = [ ] ; if ( this . keyType > 0 ) { for ( let i = 0 ; i < this . keyType ; i ++ ) { noteList . push ( KeyInstruction . sharpPositionList [ i ] ) ; } } else if ( this . keyType < 0 ) { for ( let i = 0 ; i < - this . keyType ; i ++ ) { noteList . push ( KeyInstruction . flatPositionList [ i ] ) ; } } return noteList ; } public willAlterateNote ( note ) { if ( this . alteratedNotes . indexOf ( note ) >= 0 ) { return true ; } return false ; } public getAlterationForPitch ( pitch ) { if ( this . keyType > 0 && this . alteratedNotes . indexOf ( pitch . FundamentalNote ) <= this . keyType ) { return AccidentalEnum . SHARP ; } else if ( this . keyType < 0 && this . alteratedNotes . indexOf ( pitch . FundamentalNote ) <= Math . abs ( this . keyType ) ) { return AccidentalEnum . FLAT ; } return AccidentalEnum . NONE ; } public ToString ( ) { return "Key: " + this . keyType + "" + this . mode ; } public OperatorEquals ( key2 ) { const key1 = this ; if ( key1 === key2 ) { return true ; } if ( ! key1 || ! key2 ) { return false ; } return ( key1 . Key === key2 . Key && key1 . Mode === key2 . Mode ) ; } public OperatorNotEqual ( key2 ) { return ! ( this . OperatorEquals ( key2 ) ) ; } } export class NoteEnumToHalfToneLink { constructor ( note , halftone ) { this . note = note ; this . halfTone = halftone ; } public note : NoteEnum ; public halfTone : number ; } export enum KeyEnum { major = 0 , minor = 1 , none = 2 , dorian = 3 , phrygian = 4 , lydian = 5 , mixolydian = 6 , aeolian = 7 , ionian = 8 , locrian = 9 }