//---------------------------------------------------------------------------
// ŠNikolai V. Shokhirev, 2004-2008  <nikolai@shokhirev.com> http://www.shokhirev.com/nikolai.html
// Variant 1 - "Classical"
//---------------------------------------------------------------------------

#ifndef complex_H
#define complex_H
#include "MathUtils.h"

//---------------------------------------------------------------------------

class Complex {

public:
  real Re, Im;

  Complex(const Complex& c); //copy-constructor

  Complex( real r = 0.0, real i = 0.0 );     //constructor

// Assignment overloading
  Complex& operator=(const Complex& c);
  Complex& operator=(const real r);
//  const Complex& operator=(const Complex& c);
//  const Complex& operator=(const real r);

// Compound assignment overloading
  Complex& operator+=(const Complex& c);
  Complex& operator-=(const Complex& c);
  Complex& operator*=(const Complex& c);
  Complex& operator/=(const Complex& c);

// Binary arithmetic operators Complex-Complex
  Complex operator*(const Complex& c); // can be implemented as a global friend
  Complex operator/(const Complex& c); // can be implemented as a global friend
  Complex operator-(const Complex& c); // can be implemented as a global friend
  Complex operator+(const Complex& c); // can be implemented as a global friend

//scalar math
  Complex operator*(real r);
  Complex operator/(real r);
  Complex operator-(real r);
  Complex operator+(real r);

//scalar math where scalars come first, have to use global friends
  friend Complex operator*(real r, const Complex& c);
  friend Complex operator/(real r, const Complex& c);
  friend Complex operator-(real r, const Complex& c);
  friend Complex operator+(real r, const Complex& c);

// Unary operators
  Complex operator+() {return Complex( Re,  Im); };
  Complex operator-() {return Complex(-Re, -Im); };

//private:
};

// Complex library

Complex conjug(Complex c);

real mod2(const Complex& c);

real mod(const Complex& c);

bool Equal(Complex c1, Complex c2, real eps = eps0);

bool Equal(Complex c1, real r, real i, real eps = eps0);

bool IsZero(const Complex& c);

Complex exp(const Complex& c);

// result = sqrt(z), result.Re > 0
Complex Csqrt(Complex z);

#endif