Repetition.ts 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. export class Repetition extends PartListEntry implements IRepetition {
  2. constructor(musicSheet: MusicSheet) {
  3. super(musicSheet);
  4. this.musicSheet = musicSheet;
  5. }
  6. constructor(musicSheet: MusicSheet, virtualOverallRepetition: boolean) {
  7. super(musicSheet);
  8. this.musicSheet = musicSheet;
  9. this.virtualOverallRepetition = virtualOverallRepetition;
  10. }
  11. private backwardJumpInstructions: List<RepetitionInstruction> = new List<RepetitionInstruction>();
  12. private endingParts: List<RepetitionEndingPart> = new List<RepetitionEndingPart>();
  13. private endingIndexDict: Dictionary<number, RepetitionEndingPart> = new Dictionary<number, RepetitionEndingPart>();
  14. private userNumberOfRepetitions: number = 0;
  15. private visibles: List<boolean> = new List<boolean>();
  16. private fromWords: boolean = false;
  17. private musicSheet: MusicSheet;
  18. private repetitonIterationOrder: List<number> = new List<number>();
  19. private numberOfEndings: number = 1;
  20. private virtualOverallRepetition: boolean;
  21. public StartMarker: RepetitionInstruction;
  22. public EndMarker: RepetitionInstruction;
  23. public ForwardJumpInstruction: RepetitionInstruction;
  24. public get BackwardJumpInstructions(): List<RepetitionInstruction> {
  25. return this.backwardJumpInstructions;
  26. }
  27. public get EndingIndexDict(): Dictionary<number, RepetitionEndingPart> {
  28. return this.endingIndexDict;
  29. }
  30. public get EndingParts(): List<RepetitionEndingPart> {
  31. return this.endingParts;
  32. }
  33. public get Visibles(): List<boolean> {
  34. return this.visibles;
  35. }
  36. public set Visibles(value: List<boolean>) {
  37. this.visibles = value;
  38. }
  39. public get DefaultNumberOfRepetitions(): number {
  40. var defaultNumber: number = 2;
  41. if (this.virtualOverallRepetition)
  42. defaultNumber = 1;
  43. return Math.Max(Math.Max(defaultNumber, this.endingIndexDict.Count), this.checkRepetitionForMultipleLyricVerses());
  44. }
  45. public get UserNumberOfRepetitions(): number {
  46. return this.userNumberOfRepetitions;
  47. }
  48. public set UserNumberOfRepetitions(value: number) {
  49. this.userNumberOfRepetitions = value;
  50. this.repetitonIterationOrder.Clear();
  51. var endingsDiff: number = this.userNumberOfRepetitions - this.NumberOfEndings;
  52. for (var i: number = 1; i <= this.userNumberOfRepetitions; i++) {
  53. if (i <= endingsDiff)
  54. this.repetitonIterationOrder.Add(1);
  55. else {
  56. this.repetitonIterationOrder.Add(i - endingsDiff);
  57. }
  58. }
  59. }
  60. public getForwardJumpTargetForIteration(iteration: number): number {
  61. var endingIndex: number = this.repetitonIterationOrder[iteration - 1];
  62. if (this.endingIndexDict.ContainsKey(endingIndex))
  63. return this.endingIndexDict[endingIndex].part.StartIndex;
  64. return -1;
  65. }
  66. public getBackwardJumpTarget(): number {
  67. return this.StartMarker.MeasureIndex;
  68. }
  69. public SetEndingStartIndex(endingNumbers: List<number>, startIndex: number): void {
  70. var part: RepetitionEndingPart = new RepetitionEndingPart(new SourceMusicPart(this.musicSheet, startIndex, startIndex));
  71. this.endingParts.Add(part);
  72. for (var idx: number = 0, len = endingNumbers.Count; idx < len; ++idx) {
  73. var endingNumber: number = endingNumbers[idx];
  74. try {
  75. this.endingIndexDict.Add(endingNumber, part);
  76. part.endingIndices.Add(endingNumber);
  77. if (this.numberOfEndings < endingNumber)
  78. this.numberOfEndings = endingNumber;
  79. }
  80. catch (err) {
  81. }
  82. }
  83. }
  84. public SetEndingStartIndex(endingNumber: number, startIndex: number): void {
  85. var part: RepetitionEndingPart = new RepetitionEndingPart(new SourceMusicPart(this.musicSheet, startIndex, startIndex));
  86. this.endingParts.Add(part);
  87. this.endingIndexDict.Add(endingNumber, part);
  88. part.endingIndices.Add(endingNumber);
  89. if (this.numberOfEndings < endingNumber)
  90. this.numberOfEndings = endingNumber;
  91. }
  92. public setEndingEndIndex(endingNumber: number, endIndex: number): void {
  93. if (this.endingIndexDict.ContainsKey(endingNumber)) {
  94. this.endingIndexDict[endingNumber].part.setEndIndex(endIndex);
  95. }
  96. }
  97. public get NumberOfEndings(): number {
  98. return this.numberOfEndings;
  99. }
  100. public get FromWords(): boolean {
  101. return this.fromWords;
  102. }
  103. public set FromWords(value: boolean) {
  104. this.fromWords = value;
  105. }
  106. public get AbsoluteTimestamp(): Fraction {
  107. return new Fraction(this.musicSheet.SourceMeasures[this.StartMarker.MeasureIndex].AbsoluteTimestamp);
  108. }
  109. public get StartIndex(): number {
  110. return this.StartMarker.MeasureIndex;
  111. }
  112. public get EndIndex(): number {
  113. if (this.BackwardJumpInstructions.Count == 0)
  114. return this.StartIndex;
  115. var result: number = this.BackwardJumpInstructions.Last().MeasureIndex;
  116. if (this.endingIndexDict.ContainsKey(this.NumberOfEndings))
  117. result = Math.Max(this.endingIndexDict[this.NumberOfEndings].part.EndIndex, result);
  118. return result;
  119. }
  120. private checkRepetitionForMultipleLyricVerses(): number {
  121. var lyricVerses: number = 0;
  122. var start: number = this.StartIndex;
  123. var end: number = this.EndIndex;
  124. for (var measureIndex: number = start; measureIndex <= end; measureIndex++) {
  125. var sourceMeasure: SourceMeasure = this.musicSheet.SourceMeasures[measureIndex];
  126. for (var i: number = 0; i < sourceMeasure.CompleteNumberOfStaves; i++) {
  127. for (var j: number = 0; j < sourceMeasure.VerticalSourceStaffEntryContainers.Count; j++) {
  128. if (sourceMeasure.VerticalSourceStaffEntryContainers[j][i] != null) {
  129. var sourceStaffEntry: SourceStaffEntry = sourceMeasure.VerticalSourceStaffEntryContainers[j][i];
  130. var verses: number = 0;
  131. for (var idx: number = 0, len = sourceStaffEntry.VoiceEntries.Count; idx < len; ++idx) {
  132. var voiceEntry: VoiceEntry = sourceStaffEntry.VoiceEntries[idx];
  133. verses += voiceEntry.LyricsEntries.Count;
  134. }
  135. lyricVerses = Math.Max(lyricVerses, verses);
  136. }
  137. }
  138. }
  139. }
  140. return lyricVerses;
  141. }
  142. public get FirstSourceMeasureNumber(): number {
  143. return getFirstSourceMeasure().MeasureNumber;
  144. }
  145. public get LastSourceMeasureNumber(): number {
  146. return getLastSourceMeasure().MeasureNumber;
  147. }
  148. }
  149. export module Repetition {
  150. export class RepetitionEndingPart {
  151. constructor(endingPart: SourceMusicPart) {
  152. this.part = endingPart;
  153. }
  154. public part: SourceMusicPart;
  155. public endingIndices: List<number> = new List<number>();
  156. public ToString(): string {
  157. var result: string = "";
  158. if (this.endingIndices.Count > 0)
  159. result += this.endingIndices[0];
  160. for (var i: number = 1; i < this.endingIndices.Count; i++) {
  161. result += ", " + this.endingIndices[i];
  162. }
  163. return result;
  164. }
  165. }
  166. }