//
// Copyright 2025 by Xavax, Inc. All Rights Reserved.
// Use of this software is allowed under the Xavax Open Software License.
// http://www.xavax.com/xosl.html
//

package com.xavax.dds;

/**
 * Note models a note on a piano keyboard. It consists of:
 *   position  the position on the keyboard (left to right).
 *   ideal     the ideal frequency for this note.
 *   computed  the computed frequency.
 *   variance  the amount the computed frequency varies from
 *             the ideal frequency.
 *   addend    the amount to add to the phase accumular each
 *             cycle to get the computed frequency.
 */
public class Note {

  private int addend;
  private int position;
  private double  ideal;
  private double  computed;
  private double  variance;

  /**
   * Construct a Note.
   *
   * @param position   the position of this note on the keyboard.
   * @param ideal      the ideal frequency for this note.
   */
  public Note(final int position, final double ideal) {
    this.position = position;
    this.ideal  = ideal;
    this.computed = 0.0;
    this.variance = 0.0;
    this.addend = 0;
  }

  /**
   * Get the addend for this note.
   *
   * @return the addend for this note.
   */
  public int getAddend() {
    return this.addend;
  }

  /**
   * Set the addend for this note.
   *
   * @param addend  the amount to be added to the phase accumulator.
   */
  public void setAddend(final int addend) {
    this.addend = addend;
  }

  /**
   * Get the computed frequency of this note.
   *
   * @return  the computed frequency of this note.
   */
  public double getComputed() {
    return computed;
  }

  /**
   * Set the computed frequency and compute the variance from the
   * ideal frequency.
   *
   * @param computed  the computed frequency for this note;
   */
  public void setComputed(final double computed) {
    this.computed = computed;
    double variance = computed / ideal;
    if ( variance >= 1.0 ) {
      variance -= 1.0;
    }
    else if ( variance > 0.0 ) {
      variance = 1 - variance;
    }
    else if ( variance < 0.0 ) {
      variance = Math.abs(variance);
    }
    this.variance = variance;
  }

  /**
   * Get the ideal frequency of this note.
   *
   * @return  the ideal frequency of this note.
   */
  public double getIdeal() {
    return ideal;
  }

  /**
   * Get the position of this note.
   *
   * @return  the position of this note.
   */
  public int getPosition() {
    return position;
  }

  /**
   * Returns the variance of the computed frequency from the
   * ideal frequency.
   *
   * @return  the variance.
   */
  public double getVariance() {
    return variance;
  }  
}
