// [VexFlow](http://vexflow.com) - Copyright (c) Mohit Muthanna 2010.
//
// ## Description
// This file implements the `TextDynamics` which renders traditional
// text dynamics markings, **ie: p, f, sfz, rfz, ppp**
//
// You can render any dynamics string that contains a combination of
// the following letters:  P, M, F, Z, R, S

import { Vex } from './vex';
import { Note } from './note';
import { Glyph } from './glyph';

// To enable logging for this class. Set `Vex.Flow.TextDynamics.DEBUG` to `true`.
function L() { if (TextDynamics.DEBUG) Vex.L('Vex.Flow.TextDynamics', arguments); }

export class TextDynamics extends Note {
  // The glyph data for each dynamics letter
  static get GLYPHS() {
    return {
      'f': {
        code: 'vba',
        width: 12,
      },
      'p': {
        code: 'vbf',
        width: 14,
      },
      'm': {
        code: 'v62',
        width: 17,
      },
      's': {
        code: 'v4a',
        width: 10,
      },
      'z': {
        code: 'v80',
        width: 12,
      },
      'r': {
        code: 'vb1',
        width: 12,
      },
    };
  }

  // A `TextDynamics` object inherits from `Note` so that it can be formatted
  // within a `Voice`.
  // Create the dynamics marking. `text_struct` is an object
  // that contains a `duration` property and a `sequence` of
  // letters that represents the letters to render
  constructor(text_struct) {
    super(text_struct);

    this.sequence = text_struct.text.toLowerCase();
    this.line = text_struct.line || 0;
    this.glyphs = [];

    Vex.Merge(this.render_options, {
      glyph_font_size: 40,
    });

    L('New Dynamics Text: ', this.sequence);
  }

  // Set the Stave line on which the note should be placed
  setLine(line) { this.line = line;  return this; }

  // Preformat the dynamics text
  preFormat() {
    let total_width = 0;
    // Iterate through each letter
    this.sequence.split('').forEach(function(letter) {
      // Get the glyph data for the letter
      const glyph_data = TextDynamics.GLYPHS[letter];
      if (!glyph_data) throw new Vex.RERR('Invalid dynamics character: ' + letter);

      const size =  this.render_options.glyph_font_size;
      const glyph = new Glyph(glyph_data.code, size);

      // Add the glyph
      this.glyphs.push(glyph);

      total_width += glyph_data.width;
    }, this);

    // Store the width of the text
    this.setWidth(total_width);
    this.preFormatted = true;
    return this;
  }

  // Draw the dynamics text on the rendering context
  draw() {
    const x = this.getAbsoluteX();
    const y = this.stave.getYForLine(this.line + (-3));

    L('Rendering Dynamics: ', this.sequence);

    let letter_x = x;
    this.glyphs.forEach(function(glyph, index) {
      const current_letter = this.sequence[index];
      glyph.render(this.context, letter_x, y);
      letter_x += TextDynamics.GLYPHS[current_letter].width;
    }, this);
  }
}

@@ -512,16 +512,23 @@
 ction L(
+...args
 ) %7B if (
@@ -585,13 +585,8 @@
  arg
-ument
 s); 
@@ -1736,16 +1736,20 @@
 (line) %7B
+%0A   
  this.li
@@ -1758,16 +1758,19 @@
  = line;
+%0A  
   return
@@ -1775,16 +1775,18 @@
 rn this;
+%0A 
  %7D%0A%0A  //
@@ -1930,24 +1930,17 @@
 ach(
-function(
 letter
-)
+ =%3E
  %7B%0A 
@@ -2331,22 +2331,16 @@
 h;%0A    %7D
-, this
 );%0A%0A    
@@ -2703,24 +2703,16 @@
 forEach(
-function
 (glyph, 
@@ -2717,16 +2717,19 @@
 , index)
+ =%3E
  %7B%0A     
@@ -2886,19 +2886,13 @@
 th;%0A
+
     %7D
-, this
 );%0A 

Fix remaining errors in textdynamics.js