/** Class representing a set of details for playing an individual note */
export class NoteDetails {

   /** @type {number} */
   note;
   /** @type {number} */
   velocity;
   /** @type {number} */
   duration;
   /** @type {number} */
   startTimeOffset;
   /** @type {number} */
   usedDuration;
   /** @type {boolean} */
   wasWaitingNote;

   constructor(note, velocity, duration, startTimeOffset, usedDuration) {
      this.note = note;
      this.velocity = velocity;
      this.duration = duration;
      this.startTimeOffset = (startTimeOffset === undefined) ? 0.0 : startTimeOffset;
      this.usedDuration = (usedDuration === undefined) ? duration : usedDuration;
      this.wasWaitingNote = false;
   }
}

/** Class representing all base-level {@link WebAudioAPI} note modifications */
export class ModificationBase {

   // Reference to the original unmodified note and duration
   /** @type {Tempo} */
   tempo = null;
   /** @type {Key} */
   key = null;
   /** @type {NoteDetails} */
   unmodifiedDetails = null;

   /**
    * Called by a concrete modification instance to initialize the inherited {@link ModificationBase}
    * data structure.
    * 
    * @param {Tempo} tempo - Reference to the current global {@link Tempo}
    * @param {NoteDetails} details - Original unmodified details about the note to be played
    */
   constructor(tempo, key, details) {
      this.tempo = tempo;
      this.key = key;
      this.unmodifiedDetails = details;
   }

   /**
    * Returns a list of all modified notes, durations, and velocities as generated by the
    * corresponding modification class.
    * 
    * @param {Object|null} [details] - Optional details used to refine the requested modification
    * @returns {NoteDetails[]} List of {@link NoteDetails} to replace the original note
    */
   getModifiedNoteDetails(details) { return undefined; }
}