/*
 *
 *    soniK digital audio editor
 *    Copyright (C) 2003-2004, 2006  Robert Walker <rob@tenfoot.org.uk>
 *
 *    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 2 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, write to the Free Software
 *    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */
#ifndef SONIK_COMPLEX_H
#define SONIK_COMPLEX_H

#include <sonik/types.h>

#include <qtextstream.h>

namespace Sonik
{
  struct ComplexSample
  {
    float real;
    float imag;

    ComplexSample(float _r = 0.0, float _i = 0.0) : real(_r), imag(_i) { }

    bool operator==(const ComplexSample& rhs) const
    {
      return (real == rhs.real) && (imag == rhs.imag);
    }

    bool operator!=(const ComplexSample& rhs) const
    {
      return (real != rhs.real) || (imag != rhs.imag);
    }

    ComplexSample operator+(const ComplexSample& rhs) const
    {
      return ComplexSample(real + rhs.real, imag + rhs.imag);
    }

    ComplexSample operator-(const ComplexSample& rhs) const
    {
      return ComplexSample(real - rhs.real, imag - rhs.imag);
    }

    ComplexSample operator*(const ComplexSample& rhs) const
    {
      return ComplexSample((real * rhs.real), (imag * rhs.imag));
    }

    float abs() const
    {
      return sqrt(real * real + imag * imag);
    }
  };

  std::ostream& operator<<(std::ostream& o, const ComplexSample& s);
  QTextStream& operator<<(QTextStream& o, const ComplexSample& s);

  class ComplexSampleBuffer : public auto_buffer<ComplexSample>
  {
  public:
    ComplexSampleBuffer(std::size_t s)
      : auto_buffer<ComplexSample>(s) { }

    ComplexSampleBuffer(ComplexSample* p=0, std::size_t s=0)
      : auto_buffer<ComplexSample>(p, s) { }

    void real(SampleBuffer& buf) const;
    void imag(SampleBuffer& buf) const;
    void abs(SampleBuffer& buf) const;
  };
}


#endif // SONIK_COMPLEX_H
