//    tonalisa - software to look at overtone-structures
//    Copyright (C) 2016  Dominik Schmidt-Philipp
//
//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
#ifndef DISSONANCE_H
#define DISSONANCE_H

#include <QObject>
#include <QVector>
#include <math.h>

class Dissonance : public QObject
{
  Q_OBJECT
  Q_PROPERTY(QList<double> freqs READ freqs WRITE setFreqs NOTIFY peaksChanged)
  Q_PROPERTY(QList<double> amps READ amps WRITE setAmps NOTIFY peaksChanged)
  Q_PROPERTY(float from READ from WRITE setFrom NOTIFY fromChanged)
  Q_PROPERTY(float to READ to WRITE setTo NOTIFY toChanged)
  //Q_PROPERTY(float fromHz READ fromHz NOTIFY fromHzChanged)
  //Q_PROPERTY(float toHz READ toHz NOTIFY toHzChanged)
  Q_PROPERTY(float resolution READ resolution WRITE setResolution NOTIFY resolutionChanged)
  Q_PROPERTY(QList<double> peaks READ peaks WRITE setPeaks NOTIFY peaksChanged)
  Q_PROPERTY(QList<double> dissonanceCurve READ dissonanceCurve NOTIFY dissonanceChanged)

 public:
  Dissonance(QObject *parent=0);

  // getter:
  void setFreqs(QList<double> &freqs);
  void setAmps(QList<double> &amps);
  QList<double> freqs() const;
  QList<double> amps() const;
  float from() const;
  float to() const;
  //float fromHz() const;
  //  float toHz() const;
  float resolution() const;
  QList<double> peaks();
  QList<double> dissonanceCurve();

  // setter:
  void setFrom(const float &from);
  void setTo(const float &to);
  void setResolution(const float &resolution);
  void setPeaks(QList<double> &peaks);

 signals:
  void fromChanged();
  void toChanged();
  void resolutionChanged();
  void dissonanceChanged();
  void peaksChanged();
  
 private:
  QList<double> m_freqs;
  QList<double> m_amps;
  QList<double> m_dissonance;
  float m_curve_start; // ratios
  float m_curve_end; // ratios
  float m_resolution; // linear

  double calculateDissonance(QList<double> freqs, QList<double> amps);
  void calculateCurve();
  double roughness(double f1, double f2, double a1, double a2);
  
};

#endif // DISSONANCE_H
