Browse Source

Fixed indentation on SourceMeasure

Andrea Condoluci 9 years ago
parent
commit
7945c35a94

+ 6 - 6
src/MusicalScore/ScoreIO/InstrumentReader.ts

@@ -163,9 +163,9 @@ export class InstrumentReader {
           }
           let restNote: boolean = xmlNode.element("rest") !== undefined;
           let isGraceNote: boolean = xmlNode.element("grace") !== undefined || noteDivisions === 0 || isChord && lastNoteWasGrace;
-          let musicTimestamp: Fraction = Fraction.CreateFractionFromFraction(currentFraction);
+          let musicTimestamp: Fraction = currentFraction.clone();
           if (isChord) {
-            musicTimestamp = Fraction.CreateFractionFromFraction(previousFraction);
+            musicTimestamp = previousFraction.clone();
           }
           let out: {createdNewContainer: boolean, staffEntry: SourceStaffEntry} = this.currentMeasure.findOrCreateStaffEntry(
             musicTimestamp,
@@ -179,8 +179,8 @@ export class InstrumentReader {
             this.currentVoiceGenerator.createVoiceEntry(musicTimestamp, this.currentStaffEntry, !restNote);
           }
           if (!isGraceNote && !isChord) {
-            previousFraction = Fraction.CreateFractionFromFraction(currentFraction);
-            currentFraction.Add(Fraction.CreateFractionFromFraction(noteDuration));
+            previousFraction = currentFraction.clone();
+            currentFraction.Add(noteDuration);
           }
           if (
             isChord &&
@@ -308,7 +308,7 @@ export class InstrumentReader {
           //      expressionReader.readExpressionParameters(
           //        xmlNode, this.instrument, this.divisions, currentFraction, previousFraction, this.currentMeasure.MeasureNumber, true
           //      );
-          //      expressionReader.addOctaveShift(xmlNode, this.currentMeasure, Fraction.CreateFractionFromFraction(previousFraction));
+          //      expressionReader.addOctaveShift(xmlNode, this.currentMeasure, previousFraction.clone());
           //    }
           //    expressionReader.readExpressionParameters(
           //      xmlNode, this.instrument, this.divisions, currentFraction, previousFraction, this.currentMeasure.MeasureNumber, false
@@ -455,7 +455,7 @@ export class InstrumentReader {
     }
   }
   private isAttributesNodeAtBeginOfMeasure(parentNode: IXmlElement, attributesNode: IXmlElement): boolean {
-    let children: IXmlElement[] = parentNode.elements().slice();
+    let children: IXmlElement[] = parentNode.elements();
     let attributesNodeIndex: number = children.indexOf(attributesNode); // FIXME | 0
     if (attributesNodeIndex > 0 && children[attributesNodeIndex - 1].name === "backup") {
       return true;

+ 275 - 281
src/MusicalScore/VoiceData/SourceMeasure.ts

@@ -11,292 +11,286 @@ type MultiExpression = any;
 type MultiTempoExpression = any;
 
 export class SourceMeasure {
-  constructor(completeNumberOfStaves: number) {
-    this.completeNumberOfStaves = completeNumberOfStaves;
-    this.initialize();
-  }
-  public measureListIndex: number;
-  public endsPiece: boolean;
+    constructor(completeNumberOfStaves: number) {
+        this.completeNumberOfStaves = completeNumberOfStaves;
+        this.implicitMeasure = false;
+        this.breakSystemAfter = false;
+        this.endsPiece = false;
+        this.firstInstructionsStaffEntries = new Array(completeNumberOfStaves);
+        this.lastInstructionsStaffEntries = new Array(completeNumberOfStaves);
+        for (let i: number = 0; i < completeNumberOfStaves; i++) {
+            this.staffMeasureErrors.push(false);
+            this.staffLinkedExpressions.push([]);
+        }
+    }
+
+    public measureListIndex: number;
+    public endsPiece: boolean;
+
+    private measureNumber: number;
+    //private parentMusicPart: SourceMusicPart;
+    private absoluteTimestamp: Fraction;
+    private completeNumberOfStaves: number;
+    private duration: Fraction;
+    private staffLinkedExpressions: MultiExpression[] = [];
+    private tempoExpressions: MultiTempoExpression[] = [];
+    private verticalSourceStaffEntryContainers: VerticalSourceStaffEntryContainer[] = [];
+    private implicitMeasure: boolean;
+    private breakSystemAfter: boolean;
+    private staffMeasureErrors: boolean[] = [];
+    private firstInstructionsStaffEntries: SourceStaffEntry[];
+    private lastInstructionsStaffEntries: SourceStaffEntry[];
+    private firstRepetitionInstructions: RepetitionInstruction[] = [];
+    private lastRepetitionInstructions: RepetitionInstruction[] = [];
 
-  private measureNumber: number;
-  //private parentMusicPart: SourceMusicPart;
-  private absoluteTimestamp: Fraction;
-  private completeNumberOfStaves: number;
-  private duration: Fraction;
-  private staffLinkedExpressions: MultiExpression[] = [];
-  private tempoExpressions: MultiTempoExpression[] = [];
-  private verticalSourceStaffEntryContainers: VerticalSourceStaffEntryContainer[] = [];
-  private implicitMeasure: boolean;
-  private breakSystemAfter: boolean;
-  private staffMeasureErrors: boolean[] = [];
-  private firstInstructionsStaffEntries: SourceStaffEntry[] = [];
-  private lastInstructionsStaffEntries: SourceStaffEntry[] = [];
-  private firstRepetitionInstructions: RepetitionInstruction[] = [];
-  private lastRepetitionInstructions: RepetitionInstruction[] = [];
-  public get MeasureNumber(): number {
-    return this.measureNumber;
-  }
-  public set MeasureNumber(value: number) {
-    this.measureNumber = value;
-  }
-  public get AbsoluteTimestamp(): Fraction {
-    return this.absoluteTimestamp;
-  }
-  public set AbsoluteTimestamp(value: Fraction) {
-    this.absoluteTimestamp = value;
-  }
-  public get CompleteNumberOfStaves(): number {
-    return this.completeNumberOfStaves;
-  }
-  public get Duration(): Fraction {
-    return this.duration;
-  }
-  public set Duration(value: Fraction) {
-    this.duration = value;
-  }
-  public get ImplicitMeasure(): boolean {
-    return this.implicitMeasure;
-  }
-  public set ImplicitMeasure(value: boolean) {
-    this.implicitMeasure = value;
-  }
-  public get BreakSystemAfter(): boolean {
-    return this.breakSystemAfter;
-  }
-  public set BreakSystemAfter(value: boolean) {
-    this.breakSystemAfter = value;
-  }
-  public get StaffLinkedExpressions(): MultiExpression[] {
-    return this.staffLinkedExpressions;
-  }
-  public get TempoExpressions(): MultiTempoExpression[] {
-    return this.tempoExpressions;
-  }
-  public get VerticalSourceStaffEntryContainers(): VerticalSourceStaffEntryContainer[] {
-    return this.verticalSourceStaffEntryContainers;
-  }
-  public get FirstInstructionsStaffEntries(): SourceStaffEntry[] {
-    return this.firstInstructionsStaffEntries;
-  }
-  public get LastInstructionsStaffEntries(): SourceStaffEntry[] {
-    return this.lastInstructionsStaffEntries;
-  }
-  public get FirstRepetitionInstructions(): RepetitionInstruction[] {
-    return this.firstRepetitionInstructions;
-  }
-  public get LastRepetitionInstructions(): RepetitionInstruction[] {
-    return this.lastRepetitionInstructions;
-  }
-  public getErrorInMeasure(staffIndex: number): boolean {
-    return this.staffMeasureErrors[staffIndex];
-  }
-  public setErrorInStaffMeasure(staffIndex: number, hasError: boolean): void {
-    this.staffMeasureErrors[staffIndex] = hasError;
-  }
-  public getNextMeasure(measures: SourceMeasure[]): SourceMeasure {
-    if (this.measureListIndex + 1 < measures.length) {
-      return measures[this.measureListIndex + 1];
-    }
-    return undefined;
-  }
-  public getPreviousMeasure(measures: SourceMeasure[]): SourceMeasure {
-    if (this.measureListIndex > 1) {
-      return measures[this.measureListIndex - 1];
-    }
-    return undefined;
-  }
-  public findOrCreateStaffEntry(
-      inMeasureTimestamp: Fraction, inSourceMeasureStaffIndex: number, staff: Staff
-  ): {createdNewContainer: boolean, staffEntry: SourceStaffEntry} {
-    // FIXME Andrea: debug & Test
-    let createdNewContainer: boolean = false;
-    let staffEntry: SourceStaffEntry = undefined;
-    // Find:
-    let existingVerticalSourceStaffEntryContainer: VerticalSourceStaffEntryContainer = undefined;
-    for (let k: number = 0; k < this.verticalSourceStaffEntryContainers.length; k++) {
-      if (this.verticalSourceStaffEntryContainers[k].Timestamp === inMeasureTimestamp) {
-        existingVerticalSourceStaffEntryContainer = this.verticalSourceStaffEntryContainers[k];
-        break;
-      }
-    }
-    if (existingVerticalSourceStaffEntryContainer !== undefined) {
-      if (existingVerticalSourceStaffEntryContainer[inSourceMeasureStaffIndex] !== undefined) {
-        staffEntry = existingVerticalSourceStaffEntryContainer[inSourceMeasureStaffIndex];
-      } else {
-        staffEntry = new SourceStaffEntry(existingVerticalSourceStaffEntryContainer, staff);
-        existingVerticalSourceStaffEntryContainer[inSourceMeasureStaffIndex] = staffEntry;
-      }
-      return {createdNewContainer: createdNewContainer, staffEntry: staffEntry};
-    }
-    createdNewContainer = true;
-    let last: VerticalSourceStaffEntryContainer = this.verticalSourceStaffEntryContainers[this.verticalSourceStaffEntryContainers.length - 1];
-    if (this.verticalSourceStaffEntryContainers.length === 0 || last.Timestamp < inMeasureTimestamp) {
-      let container: VerticalSourceStaffEntryContainer = new VerticalSourceStaffEntryContainer(
-        this, Fraction.CreateFractionFromFraction(inMeasureTimestamp), this.completeNumberOfStaves
-      );
-      this.verticalSourceStaffEntryContainers.push(container);
-      staffEntry = new SourceStaffEntry(container, staff);
-      container[inSourceMeasureStaffIndex] = staffEntry;
-    } else {
-      for (
-        let i: number = this.verticalSourceStaffEntryContainers.length - 1;
-        i >= 0; i--
-      ) {
-        if (this.verticalSourceStaffEntryContainers[i].Timestamp < inMeasureTimestamp) {
-          let container: VerticalSourceStaffEntryContainer = new VerticalSourceStaffEntryContainer(
-            this, Fraction.CreateFractionFromFraction(inMeasureTimestamp), this.completeNumberOfStaves
-          );
-          this.verticalSourceStaffEntryContainers.splice(i + 1, 0, container);
-          staffEntry = new SourceStaffEntry(container, staff);
-          container[inSourceMeasureStaffIndex] = staffEntry;
-          break;
+    public get MeasureNumber(): number {
+        return this.measureNumber;
+    }
+    public set MeasureNumber(value: number) {
+        this.measureNumber = value;
+    }
+    public get AbsoluteTimestamp(): Fraction {
+        return this.absoluteTimestamp;
+    }
+    public set AbsoluteTimestamp(value: Fraction) {
+        this.absoluteTimestamp = value;
+    }
+    public get CompleteNumberOfStaves(): number {
+        return this.completeNumberOfStaves;
+    }
+    public get Duration(): Fraction {
+        return this.duration;
+    }
+    public set Duration(value: Fraction) {
+        this.duration = value;
+    }
+    public get ImplicitMeasure(): boolean {
+        return this.implicitMeasure;
+    }
+    public set ImplicitMeasure(value: boolean) {
+        this.implicitMeasure = value;
+    }
+    public get BreakSystemAfter(): boolean {
+        return this.breakSystemAfter;
+    }
+    public set BreakSystemAfter(value: boolean) {
+        this.breakSystemAfter = value;
+    }
+    public get StaffLinkedExpressions(): MultiExpression[] {
+        return this.staffLinkedExpressions;
+    }
+    public get TempoExpressions(): MultiTempoExpression[] {
+        return this.tempoExpressions;
+    }
+    public get VerticalSourceStaffEntryContainers(): VerticalSourceStaffEntryContainer[] {
+        return this.verticalSourceStaffEntryContainers;
+    }
+    public get FirstInstructionsStaffEntries(): SourceStaffEntry[] {
+        return this.firstInstructionsStaffEntries;
+    }
+    public get LastInstructionsStaffEntries(): SourceStaffEntry[] {
+        return this.lastInstructionsStaffEntries;
+    }
+    public get FirstRepetitionInstructions(): RepetitionInstruction[] {
+        return this.firstRepetitionInstructions;
+    }
+    public get LastRepetitionInstructions(): RepetitionInstruction[] {
+        return this.lastRepetitionInstructions;
+    }
+    public getErrorInMeasure(staffIndex: number): boolean {
+        return this.staffMeasureErrors[staffIndex];
+    }
+    public setErrorInStaffMeasure(staffIndex: number, hasError: boolean): void {
+        this.staffMeasureErrors[staffIndex] = hasError;
+    }
+    public getNextMeasure(measures: SourceMeasure[]): SourceMeasure {
+        return measures[this.measureListIndex + 1];
+    }
+    public getPreviousMeasure(measures: SourceMeasure[]): SourceMeasure {
+        if (this.measureListIndex > 1) {
+            return measures[this.measureListIndex - 1];
         }
-        if (i === 0) {
-          let container: VerticalSourceStaffEntryContainer = new VerticalSourceStaffEntryContainer(
-            this, Fraction.CreateFractionFromFraction(inMeasureTimestamp), this.completeNumberOfStaves
-          );
-          this.verticalSourceStaffEntryContainers.splice(i, 0, container);
-          staffEntry = new SourceStaffEntry(container, staff);
-          container[inSourceMeasureStaffIndex] = staffEntry;
-          break;
+        return undefined;
+    }
+    public findOrCreateStaffEntry(
+        inMeasureTimestamp: Fraction, inSourceMeasureStaffIndex: number, staff: Staff
+    ): {createdNewContainer: boolean, staffEntry: SourceStaffEntry} {
+        // FIXME Andrea: debug & Test
+        let createdNewContainer: boolean = false;
+        let staffEntry: SourceStaffEntry = undefined;
+        // Find:
+        let existingVerticalSourceStaffEntryContainer: VerticalSourceStaffEntryContainer = undefined;
+        for (let k: number = 0; k < this.verticalSourceStaffEntryContainers.length; k++) {
+            if (this.verticalSourceStaffEntryContainers[k].Timestamp.Equals(inMeasureTimestamp)) {
+                existingVerticalSourceStaffEntryContainer = this.verticalSourceStaffEntryContainers[k];
+                break;
+            }
         }
-      }
-    }
-    return {createdNewContainer: createdNewContainer, staffEntry: staffEntry};
-  }
-  public findOrCreateVoiceEntry(sse: SourceStaffEntry, voice: Voice): { createdVoiceEntry: boolean, voiceEntry: VoiceEntry } {
-    let ve: VoiceEntry = undefined;
-    let createdNewVoiceEntry: boolean = false;
-    for (let voiceEntry of sse.VoiceEntries) {
-      if (voiceEntry.ParentVoice === voice) {
-        ve = voiceEntry;
-        break;
-      }
-    }
-    if (ve === undefined) {
-      ve = new VoiceEntry(sse.Timestamp, voice, sse);
-      sse.VoiceEntries.push(ve);
-      createdNewVoiceEntry = true;
-    }
-    return { createdVoiceEntry: createdNewVoiceEntry, voiceEntry: ve };
-  }
-  public getPreviousSourceStaffEntryFromIndex(
-    verticalIndex: number, horizontalIndex: number
-  ): SourceStaffEntry {
-    for (let i: number = horizontalIndex - 1; i >= 0; i--) {
-      if (this.verticalSourceStaffEntryContainers[i][verticalIndex] !== undefined) {
-        return this.verticalSourceStaffEntryContainers[i][verticalIndex];
-      }
-    }
-    return undefined;
-  }
-  public getVerticalContainerIndexByTimestamp(musicTimestamp: Fraction): number {
-    let index: number = -1;
-    for (let idx: number = 0, len: number = this.VerticalSourceStaffEntryContainers.length; idx < len; ++idx) {
-      let verticalSourceStaffEntryContainer: VerticalSourceStaffEntryContainer = this.VerticalSourceStaffEntryContainers[idx];
-      if (verticalSourceStaffEntryContainer.Timestamp === musicTimestamp) {
-        return this.verticalSourceStaffEntryContainers.indexOf(verticalSourceStaffEntryContainer);
-      }
-    }
-    return index;
-  }
-  public getVerticalContainerByTimestamp(musicTimestamp: Fraction): VerticalSourceStaffEntryContainer {
-    for (let idx: number = 0, len: number = this.VerticalSourceStaffEntryContainers.length; idx < len; ++idx) {
-      let verticalSourceStaffEntryContainer: VerticalSourceStaffEntryContainer = this.VerticalSourceStaffEntryContainers[idx];
-      if (verticalSourceStaffEntryContainer.Timestamp === musicTimestamp) {
-        return verticalSourceStaffEntryContainer;
-      }
-    }
-    return undefined;
-  }
-  public checkForEmptyVerticalContainer(index: number): void {
-    let undefinedCounter: number = 0;
-    for (let i: number = 0; i < this.completeNumberOfStaves; i++) {
-      if (this.verticalSourceStaffEntryContainers[index][i] === undefined) {
-        undefinedCounter++;
-      }
-    }
-    if (undefinedCounter === this.completeNumberOfStaves) {
-      this.verticalSourceStaffEntryContainers.splice(index, 1);
-    }
-  }
-  public reverseCheck(musicSheet: MusicSheet, maxInstDuration: Fraction): Fraction {
-    let maxDuration: Fraction = new Fraction(0, 1);
-    let instrumentsDurations: Fraction[] = [];
-    for (let i: number = 0; i < musicSheet.Instruments.length; i++) {
-      let instrumentDuration: Fraction = new Fraction(0, 1);
-      let inSourceMeasureInstrumentIndex: number = musicSheet.getGlobalStaffIndexOfFirstStaff(musicSheet.Instruments[i]);
-      for (let j: number = 0; j < musicSheet.Instruments[i].Staves.length; j++) {
-        let lastStaffEntry: SourceStaffEntry = this.getLastSourceStaffEntryForInstrument(inSourceMeasureInstrumentIndex + j);
-        if (lastStaffEntry !== undefined && !lastStaffEntry.hasTie()) {
-          let verticalContainerIndex: number = this.verticalSourceStaffEntryContainers.indexOf(lastStaffEntry.VerticalContainerParent);
-          for (let m: number = verticalContainerIndex - 1; m >= 0; m--) {
-            let previousStaffEntry: SourceStaffEntry = this.verticalSourceStaffEntryContainers[m][inSourceMeasureInstrumentIndex + j];
-            if (previousStaffEntry !== undefined && previousStaffEntry.hasTie()) {
-              if (instrumentDuration.lt(Fraction.plus(previousStaffEntry.Timestamp, previousStaffEntry.calculateMaxNoteLength()))) {
-                instrumentDuration = Fraction.plus(previousStaffEntry.Timestamp, previousStaffEntry.calculateMaxNoteLength());
+        if (existingVerticalSourceStaffEntryContainer !== undefined) {
+            if (existingVerticalSourceStaffEntryContainer[inSourceMeasureStaffIndex] !== undefined) {
+                staffEntry = existingVerticalSourceStaffEntryContainer[inSourceMeasureStaffIndex];
+            } else {
+                staffEntry = new SourceStaffEntry(existingVerticalSourceStaffEntryContainer, staff);
+                existingVerticalSourceStaffEntryContainer[inSourceMeasureStaffIndex] = staffEntry;
+            }
+            return {createdNewContainer: createdNewContainer, staffEntry: staffEntry};
+        }
+        createdNewContainer = true;
+        let last: VerticalSourceStaffEntryContainer = this.verticalSourceStaffEntryContainers[this.verticalSourceStaffEntryContainers.length - 1];
+        if (this.verticalSourceStaffEntryContainers.length === 0 || last.Timestamp.lt(inMeasureTimestamp)) {
+            let container: VerticalSourceStaffEntryContainer = new VerticalSourceStaffEntryContainer(
+                this, inMeasureTimestamp.clone(), this.completeNumberOfStaves
+            );
+            this.verticalSourceStaffEntryContainers.push(container);
+            staffEntry = new SourceStaffEntry(container, staff);
+            container[inSourceMeasureStaffIndex] = staffEntry;
+        } else {
+            for (
+                let i: number = this.verticalSourceStaffEntryContainers.length - 1;
+                i >= 0; i--
+            ) {
+                if (this.verticalSourceStaffEntryContainers[i].Timestamp.lt(inMeasureTimestamp)) {
+                    let container: VerticalSourceStaffEntryContainer = new VerticalSourceStaffEntryContainer(
+                        this, inMeasureTimestamp.clone(), this.completeNumberOfStaves
+                    );
+                    this.verticalSourceStaffEntryContainers.splice(i + 1, 0, container);
+                    staffEntry = new SourceStaffEntry(container, staff);
+                    container[inSourceMeasureStaffIndex] = staffEntry;
+                    break;
+                }
+                if (i === 0) {
+                    let container: VerticalSourceStaffEntryContainer = new VerticalSourceStaffEntryContainer(
+                        this, inMeasureTimestamp.clone(), this.completeNumberOfStaves
+                    );
+                    this.verticalSourceStaffEntryContainers.splice(i, 0, container);
+                    staffEntry = new SourceStaffEntry(container, staff);
+                    container[inSourceMeasureStaffIndex] = staffEntry;
+                    break;
+                }
+            }
+        }
+        return {createdNewContainer: createdNewContainer, staffEntry: staffEntry};
+    }
+    public findOrCreateVoiceEntry(sse: SourceStaffEntry, voice: Voice): { createdVoiceEntry: boolean, voiceEntry: VoiceEntry } {
+        let ve: VoiceEntry = undefined;
+        let createdNewVoiceEntry: boolean = false;
+        for (let voiceEntry of sse.VoiceEntries) {
+            if (voiceEntry.ParentVoice === voice) {
+                ve = voiceEntry;
                 break;
-              }
             }
-          }
         }
-      }
-      instrumentsDurations.push(instrumentDuration);
-    }
-    for (let idx: number = 0, len: number = instrumentsDurations.length; idx < len; ++idx) {
-      let instrumentsDuration: Fraction = instrumentsDurations[idx];
-      if (maxDuration < instrumentsDuration) {
-        maxDuration = instrumentsDuration;
-      }
-    }
-    return Fraction.max(maxDuration, maxInstDuration);
-  }
-  public calculateInstrumentsDuration(musicSheet: MusicSheet, instrumentMaxTieNoteFractions: Fraction[]): Fraction[] {
-    let instrumentsDurations: Fraction[] = [];
-    for (let i: number = 0; i < musicSheet.Instruments.length; i++) {
-      let instrumentDuration: Fraction = new Fraction(0, 1);
-      let inSourceMeasureInstrumentIndex: number = musicSheet.getGlobalStaffIndexOfFirstStaff(musicSheet.Instruments[i]);
-      for (let j: number = 0; j < musicSheet.Instruments[i].Staves.length; j++) {
-        let lastStaffEntry: SourceStaffEntry = this.getLastSourceStaffEntryForInstrument(inSourceMeasureInstrumentIndex + j);
-        if (lastStaffEntry !== undefined && lastStaffEntry.Timestamp !== undefined) {
-          if (instrumentDuration.lt(Fraction.plus(lastStaffEntry.Timestamp, lastStaffEntry.calculateMaxNoteLength()))) {
-            instrumentDuration = Fraction.plus(lastStaffEntry.Timestamp, lastStaffEntry.calculateMaxNoteLength());
-          }
+        if (ve === undefined) {
+            ve = new VoiceEntry(sse.Timestamp, voice, sse);
+            sse.VoiceEntries.push(ve);
+            createdNewVoiceEntry = true;
+        }
+        return { createdVoiceEntry: createdNewVoiceEntry, voiceEntry: ve };
+    }
+    public getPreviousSourceStaffEntryFromIndex(
+        verticalIndex: number, horizontalIndex: number
+    ): SourceStaffEntry {
+        for (let i: number = horizontalIndex - 1; i >= 0; i--) {
+            if (this.verticalSourceStaffEntryContainers[i][verticalIndex] !== undefined) {
+                return this.verticalSourceStaffEntryContainers[i][verticalIndex];
+            }
+        }
+        return undefined;
+    }
+    public getVerticalContainerIndexByTimestamp(musicTimestamp: Fraction): number {
+        for (let idx: number = 0, len: number = this.VerticalSourceStaffEntryContainers.length; idx < len; ++idx) {
+            if (this.VerticalSourceStaffEntryContainers[idx].Timestamp.Equals(musicTimestamp)) {
+                return idx; // this.verticalSourceStaffEntryContainers.indexOf(verticalSourceStaffEntryContainer);
+            }
+        }
+        return -1;
+    }
+    public getVerticalContainerByTimestamp(musicTimestamp: Fraction): VerticalSourceStaffEntryContainer {
+        for (let idx: number = 0, len: number = this.VerticalSourceStaffEntryContainers.length; idx < len; ++idx) {
+            let verticalSourceStaffEntryContainer: VerticalSourceStaffEntryContainer = this.VerticalSourceStaffEntryContainers[idx];
+            if (verticalSourceStaffEntryContainer.Timestamp.Equals(musicTimestamp)) {
+                return verticalSourceStaffEntryContainer;
+            }
+        }
+        return undefined;
+    }
+    public checkForEmptyVerticalContainer(index: number): void {
+        let undefinedCounter: number = 0;
+        for (let i: number = 0; i < this.completeNumberOfStaves; i++) {
+            if (this.verticalSourceStaffEntryContainers[index][i] === undefined) {
+                undefinedCounter++;
+            }
+        }
+        if (undefinedCounter === this.completeNumberOfStaves) {
+            this.verticalSourceStaffEntryContainers.splice(index, 1);
         }
-      }
-      if (instrumentDuration < instrumentMaxTieNoteFractions[i]) {
-        instrumentDuration = instrumentMaxTieNoteFractions[i];
-      }
-      instrumentsDurations.push(instrumentDuration);
-    }
-    return instrumentsDurations;
-  }
-  public getEntriesPerStaff(staffIndex: number): SourceStaffEntry[] {
-    let sourceStaffEntries: SourceStaffEntry[] = [];
-    for (let idx: number = 0, len: number = this.VerticalSourceStaffEntryContainers.length; idx < len; ++idx) {
-      let container: VerticalSourceStaffEntryContainer = this.VerticalSourceStaffEntryContainers[idx];
-      let sse: SourceStaffEntry = container[staffIndex];
-      if (sse !== undefined) { sourceStaffEntries.push(sse); }
-    }
-    return sourceStaffEntries;
-  }
-  private initialize(): void {
-    for (let i: number = 0; i < this.completeNumberOfStaves; i++) {
-      this.firstInstructionsStaffEntries.push(undefined);
-      this.lastInstructionsStaffEntries.push(undefined);
-      this.staffMeasureErrors.push(false);
-      this.staffLinkedExpressions.push([]);
-    }
-    this.implicitMeasure = false;
-    this.breakSystemAfter = false;
-    this.endsPiece = false;
-  }
-  private getLastSourceStaffEntryForInstrument(instrumentIndex: number): SourceStaffEntry {
-    for (let i: number = this.verticalSourceStaffEntryContainers.length - 1; i >= 0; i--) {
-      if (this.verticalSourceStaffEntryContainers[i][instrumentIndex] !== undefined) {
-        return this.verticalSourceStaffEntryContainers[i][instrumentIndex];
-      }
-    }
-    //return undefined;
-  }
+    }
+    public reverseCheck(musicSheet: MusicSheet, maxInstDuration: Fraction): Fraction {
+        let maxDuration: Fraction = new Fraction(0, 1);
+        let instrumentsDurations: Fraction[] = [];
+        for (let i: number = 0; i < musicSheet.Instruments.length; i++) {
+            let instrumentDuration: Fraction = new Fraction(0, 1);
+            let inSourceMeasureInstrumentIndex: number = musicSheet.getGlobalStaffIndexOfFirstStaff(musicSheet.Instruments[i]);
+            for (let j: number = 0; j < musicSheet.Instruments[i].Staves.length; j++) {
+                let lastStaffEntry: SourceStaffEntry = this.getLastSourceStaffEntryForInstrument(inSourceMeasureInstrumentIndex + j);
+                if (lastStaffEntry !== undefined && !lastStaffEntry.hasTie()) {
+                    let verticalContainerIndex: number = this.verticalSourceStaffEntryContainers.indexOf(lastStaffEntry.VerticalContainerParent);
+                    for (let m: number = verticalContainerIndex - 1; m >= 0; m--) {
+                        let previousStaffEntry: SourceStaffEntry = this.verticalSourceStaffEntryContainers[m][inSourceMeasureInstrumentIndex + j];
+                        if (previousStaffEntry !== undefined && previousStaffEntry.hasTie()) {
+                            if (instrumentDuration.lt(Fraction.plus(previousStaffEntry.Timestamp, previousStaffEntry.calculateMaxNoteLength()))) {
+                                instrumentDuration = Fraction.plus(previousStaffEntry.Timestamp, previousStaffEntry.calculateMaxNoteLength());
+                                break;
+                            }
+                        }
+                    }
+                }
+            }
+            instrumentsDurations.push(instrumentDuration);
+        }
+        for (let idx: number = 0, len: number = instrumentsDurations.length; idx < len; ++idx) {
+            let instrumentsDuration: Fraction = instrumentsDurations[idx];
+            if (maxDuration.lt(instrumentsDuration)) {
+                maxDuration = instrumentsDuration;
+            }
+        }
+        return Fraction.max(maxDuration, maxInstDuration);
+    }
+    public calculateInstrumentsDuration(musicSheet: MusicSheet, instrumentMaxTieNoteFractions: Fraction[]): Fraction[] {
+        let instrumentsDurations: Fraction[] = [];
+        for (let i: number = 0; i < musicSheet.Instruments.length; i++) {
+            let instrumentDuration: Fraction = new Fraction(0, 1);
+            let inSourceMeasureInstrumentIndex: number = musicSheet.getGlobalStaffIndexOfFirstStaff(musicSheet.Instruments[i]);
+            for (let j: number = 0; j < musicSheet.Instruments[i].Staves.length; j++) {
+                let lastStaffEntry: SourceStaffEntry = this.getLastSourceStaffEntryForInstrument(inSourceMeasureInstrumentIndex + j);
+                if (lastStaffEntry !== undefined && lastStaffEntry.Timestamp !== undefined) {
+                    if (instrumentDuration.lt(Fraction.plus(lastStaffEntry.Timestamp, lastStaffEntry.calculateMaxNoteLength()))) {
+                        instrumentDuration = Fraction.plus(lastStaffEntry.Timestamp, lastStaffEntry.calculateMaxNoteLength());
+                    }
+                }
+            }
+            if (instrumentDuration.lt(instrumentMaxTieNoteFractions[i])) {
+                instrumentDuration = instrumentMaxTieNoteFractions[i];
+            }
+            instrumentsDurations.push(instrumentDuration);
+        }
+        return instrumentsDurations;
+    }
+    public getEntriesPerStaff(staffIndex: number): SourceStaffEntry[] {
+        let sourceStaffEntries: SourceStaffEntry[] = [];
+        for (let idx: number = 0, len: number = this.VerticalSourceStaffEntryContainers.length; idx < len; ++idx) {
+            let container: VerticalSourceStaffEntryContainer = this.VerticalSourceStaffEntryContainers[idx];
+            let sse: SourceStaffEntry = container[staffIndex];
+            if (sse !== undefined) { sourceStaffEntries.push(sse); }
+        }
+        return sourceStaffEntries;
+    }
+    private getLastSourceStaffEntryForInstrument(instrumentIndex: number): SourceStaffEntry {
+        for (let i: number = this.verticalSourceStaffEntryContainers.length - 1; i >= 0; i--) {
+            if (this.verticalSourceStaffEntryContainers[i][instrumentIndex] !== undefined) {
+                return this.verticalSourceStaffEntryContainers[i][instrumentIndex];
+            }
+        }
+        //return undefined;
+    }
 }

+ 27 - 24
test/MusicalScore/ScoreIO/MusicSheetReader.ts

@@ -8,6 +8,8 @@ describe("Music Sheet Reader Tests", () => {
     // Initialization
     let path: string = "/test/data/MuzioClementi_SonatinaOpus36No1_Part1.xml";
     let reader: MusicSheetReader = new MusicSheetReader();
+    let root: IXmlElement;
+    let sheet: MusicSheet;
 
     before((): void => {
         fixture.setBase("base");
@@ -15,41 +17,42 @@ describe("Music Sheet Reader Tests", () => {
 
     beforeEach((): void => {
       this.result = fixture.load(path);
+      // console.log(this.result[0].length, typeof this.result, typeof this.result[0], this.result[0].substr, this.result[0].getElementById);
+      let container: Element = document.getElementById("fixture_container");
+      let documentElement: IXmlElement = new IXmlElement(container);
+      chai.expect(documentElement.elements("score-partwise").length).to.equal(1);
+      root = documentElement.element("score-partwise");
+      chai.expect(root).to.not.be.undefined;
+      sheet = reader.createMusicSheet(root, path);
     });
 
     afterEach((): void => {
       fixture.cleanup();
     });
 
-    it("Test Sonatina Op.36 No. 1 - Pt. 1", (done: MochaDone) => {
-        let container: Element = document.getElementById("fixture_container");
-        let documentElement: IXmlElement = new IXmlElement(container);
-        chai.expect(documentElement.elements("score-partwise").length).to.equal(1);
-        let root: IXmlElement = documentElement.element("score-partwise");
-        //
-        // let elem: Element = (root as any).elem;
-        // console.log(
-        //   "@",
-        //   elem.getElementsByTagName("part")[0].getElementsByTagName("measure").length,
-        //   root.element("part").elements("measure").length
-        // );
-
-
-        chai.expect(root).to.not.be.undefined;
-        chai.expect(root.elements("part").length).to.equal(2);
-        chai.expect(root.element("part").elements("measure").length).to.equal(38);
-        let sheet: MusicSheet = reader.createMusicSheet(root, path);
+    it("Read title and composer", (done: MochaDone) => {
         chai.expect(sheet.TitleString).to.equal("Sonatina Op.36 No 1 Teil 1 Allegro");
         chai.expect(sheet.ComposerString).to.equal("Muzio Clementi");
-        //console.log("Sheet Object:", sheet);
-        console.log(reader.CompleteNumberOfStaves);
-        console.log(sheet.SheetErrors);
-        //console.log(container);
+        done();
+    });
+
+    it("Measures", (done: MochaDone) => {
+        // chai.expect(root.element("part").elements("measure").length).to.equal(38);
+        chai.expect(sheet.SourceMeasures.length).to.equal(38);
+        console.log("First Measure: ", sheet.SourceMeasures[0]);
+        //console.log("Notes on first Measure: ", sheet.SourceMeasures[0].VerticalSourceStaffEntryContainers[0].StaffEntries[0]);
+        // chai.expect(sheet.)
+        done();
+    });
+
+    it("Instruments", (done: MochaDone) => {
+        // chai.expect(root.elements("part").length).to.equal(2);
+        chai.expect(reader.CompleteNumberOfStaves).to.equal(2);
         chai.expect(sheet.Instruments.length).to.equal(2);
+        chai.expect(sheet.InstrumentalGroups.length).to.equal(2);
+        console.log(sheet.SheetErrors);
         chai.expect(sheet.Instruments[0].Name).to.equal("Piano (right)");
         chai.expect(sheet.Instruments[1].Name).to.equal("Piano (left)");
-        chai.expect(sheet.InstrumentalGroups.length).to.equal(2);
-        chai.expect(sheet.SourceMeasures.length).to.equal(38);
         done();
     });