#ifndef COMPLEXSAMPLET_HPP
#define COMPLEXSAMPLET_HPP

#include <iostream>

template <class T> class complexsample {
	public:
	T re;
	T im;

	complexsample() {
	}

	template <class C> complexsample(const C& x) {
		re = x;
		im = 0.;
	}
	template <class C1, class C2> complexsample(const C1& x, const C2& y) {
		re = x;
		im = y;
	}

	friend complexsample operator+(const complexsample& x, const complexsample& y) {
		complexsample r;

		r.re = x.re + y.re;
		r.im = x.im + y.im;

		return r;
	}

	template <class C> friend complexsample operator+(const complexsample& x, const C& y) {
		complexsample r;

		r.re = x.re + y;
		r.im = x.im;

		return r;
	}

	template <class C> friend complexsample operator+(const C& x, const complexsample& y) {
		complexsample r;

		r.re = x + y.re;
		r.im = y.im;

		return r;
	}

	friend complexsample& operator+=(complexsample& x, const complexsample& y) {
		x = x + y;
		return x;
	}

	template <class C> friend complexsample& operator+=(complexsample& x, const C& y) {
		x.re += y;
		return x;
	}

	friend complexsample operator-(const complexsample& x, const complexsample& y) {
		complexsample r;

		r.re = x.re - y.re;
		r.im = x.im - y.im;

		return r;
	}

	template <class C> friend complexsample operator-(const complexsample& x, const C& y) {
		complexsample r;

		r.re = x.re - y;
		r.im = x.im;

		return r;
	}

	template <class C> friend complexsample operator-(const C& x, const complexsample& y) {
		complexsample r;

		r.re = x - y.re;
		r.im = - y.im;

		return r;
	}

	friend complexsample& operator-=(complexsample& x, const complexsample& y) {
		x = x - y;
		return x;
	}

	template <class C> friend complexsample& operator-=(complexsample& x, const C& y) {
		x.re -= y;
		return x;
	}

	friend complexsample operator-(const complexsample& x) {
		complexsample r;

		r.re = - x.re;
		r.im = - x.im;

		return r;
	}

	friend complexsample operator*(const complexsample& x, const complexsample& y) {
		complexsample r;

		r.re = x.re * y.re - x.im * y.im;
		r.im = x.re * y.im + x.im * y.re;

		return r;
	}

	template <class C> friend complexsample operator*(const complexsample& x, const C& y) {
		complexsample r;

		r.re = x.re * y;
		r.im = x.im * y;

		return r;
	}

	template <class C> friend complexsample operator*(const C& x, const complexsample& y) {
		complexsample r;

		r.re = x * y.re;
		r.im = x * y.im;

		return r;
	}

	friend complexsample& operator*=(complexsample& x, const complexsample& y) {
		x = x * y;
		return x;
	}

	template <class C> friend complexsample& operator*=(complexsample& x, const C& y) {
		x.re *= y;
		x.im *= y;
		return x;
	}

	friend complexsample sqr(const complexsample& x) {
		complexsample r;

		r.re = x.re * x.re - x.im * x.im;
		r.im = 2. * x.re * x.im;

		return r;
	}

	friend std::ostream& operator<<(std::ostream& s, const complexsample& x) {
		s << '(' << x.re << '+' << x.im << "i)";
		return s;
	}
};

#endif // COMPLEXSAMPLET_HPP
