import { MusicSheet } from "../MusicSheet" ; import { PartListEntry } from "../MusicSource/PartListEntry" ; import { Repetition } from "../MusicSource/Repetition" ; import { Fraction } from "../../Common/DataObjects/Fraction" ; import { MusicPartManagerIterator } from "./MusicPartManagerIterator" ; export class MusicPartManager { constructor ( musicSheet ) { this . musicSheet = musicSheet ; } private parts : PartListEntry [ ] ; private timestamps : TimestampTransform [ ] ; private musicSheet : MusicSheet ; private sheetStart : Fraction ; private sheetEnd : Fraction ; /**
     * This method is called from CoreContainer when the user changes a Repetitions's userNumberOfRepetitions.
     */ public reInit ( ) { this . init ( ) ; } /**
     * Main initialize method for MusicPartManager.
     */ public init ( ) { this . parts = this . musicSheet . Repetitions . slice ( ) ; this . sheetStart = this . musicSheet . SelectionStart = new Fraction ( 0 , 1 ) ; this . sheetEnd = this . musicSheet . SelectionEnd = this . musicSheet . SheetEndTimestamp ; this . calcMapping ( ) ; } public getCurrentRepetitionTimestampTransform ( curEnrolledTimestamp ) { let curTransform = undefined ; for ( let i = this . timestamps . length - 1 ; i >= 0 ; i -- ) { curTransform = this . timestamps [ i ] ; if ( curEnrolledTimestamp . gte ( curTransform . $from ) ) { return curTransform ; } } return this . timestamps [ 0 ] ; } public absoluteEnrolledToSheetTimestamp ( timestamp ) { if ( this . timestamps . length === 0 ) { return timestamp ; } const transform = this . getCurrentRepetitionTimestampTransform ( timestamp ) ; return Fraction . plus ( timestamp , Fraction . minus ( transform . to , transform . $from ) ) ; } public get Parts ( ) : PartListEntry [ ] { return this . parts ; } public get MusicSheet ( ) : MusicSheet { return this . musicSheet ; } public getIterator ( start ? ) { if ( ! start ) { return new MusicPartManagerIterator ( this . musicSheet , this . musicSheet . SelectionStart , this . musicSheet . SelectionEnd ) ; } return new MusicPartManagerIterator ( this . musicSheet , start , undefined ) ; } public setSelectionStart ( beginning ) { this . musicSheet . SelectionStart = beginning ; this . musicSheet . SelectionEnd = undefined ; } public setSelectionRange ( start , end ) { this . musicSheet . SelectionStart = start ?? this . sheetStart ; this . musicSheet . SelectionEnd = end ?? this . sheetEnd ; } private calcMapping ( ) { const timestamps = [ ] ; const iterator = this . getIterator ( ) ; let currentRepetition = iterator . CurrentRepetition ; let curTimestampTransform = new TimestampTransform ( iterator . CurrentEnrolledTimestamp . clone ( ) , iterator . CurrentSourceTimestamp . clone ( ) , undefined , 0 ) ; timestamps . push ( curTimestampTransform ) ; while ( ! iterator . EndReached ) { if ( iterator . JumpOccurred || currentRepetition !== iterator . CurrentRepetition ) { currentRepetition = iterator . CurrentRepetition ; if ( iterator . backJumpOccurred ) { const jumpRep = iterator . JumpResponsibleRepetition ; curTimestampTransform . nextBackJump = iterator . CurrentEnrolledTimestamp ; curTimestampTransform . curRepetition = jumpRep ; curTimestampTransform . curRepetitionIteration = iterator . CurrentJumpResponsibleRepetitionIterationBeforeJump ; for ( let i = this . timestamps . length - 2 ; i >= 0 ; i -- ) { if ( timestamps [ i ] . to . lt ( jumpRep . AbsoluteTimestamp ) || timestamps [ i ] . curRepetition ) { break ; } timestamps [ i ] . nextBackJump = curTimestampTransform . nextBackJump ; timestamps [ i ] . curRepetition = jumpRep ; timestamps [ i ] . curRepetitionIteration = curTimestampTransform . curRepetitionIteration ; } } curTimestampTransform = new TimestampTransform ( iterator . CurrentEnrolledTimestamp . clone ( ) , iterator . CurrentSourceTimestamp . clone ( ) , undefined , 0 ) ; timestamps . push ( curTimestampTransform ) ; } iterator . moveToNext ( ) ; } this . timestamps = timestamps ; } } export class TimestampTransform { constructor ( sourceTimestamp , enrolledTimestamp , repetition , curRepetitionIteration ) { this . $from = sourceTimestamp ; this . to = enrolledTimestamp ; this . curRepetition = repetition ; this . curRepetitionIteration = curRepetitionIteration ; this . nextBackJump = undefined ; this . nextForwardJump = undefined ; } public $from : Fraction ; public to : Fraction ; public nextBackJump : Fraction ; public nextForwardJump : Fraction ; public curRepetition : Repetition ; public curRepetitionIteration : number ; }