// Complex.cpp: implementation of the Complex class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include <assert.h>
#include "Complex.h"
#include <math.h>
#include <iostream>

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

Complex::Complex():m_real(0), m_imaginary(0)
{
}

Complex::Complex(double real, double imaginary)
    : m_real(real), m_imaginary(imaginary)
{
}

Complex::~Complex()
{

}

void Complex::setValue(double real, double imaginary)
{
    m_real = real;
    m_imaginary = imaginary;
}

void Complex::add(Complex rhs)
{
    m_real += rhs.m_real;
	m_imaginary += rhs.m_imaginary;
}

void Complex::subtract(Complex rhs)
{
    m_real -= rhs.m_real;
	m_imaginary -= rhs.m_imaginary;
}

// (a + b i) * (c + d i) = (ac-bd) + (ad+bc) i
void Complex::multiply(Complex rhs)
{
	double real = m_real, imaginary = m_imaginary;
    m_real = real*rhs.m_real-imaginary*rhs.m_imaginary;
	m_imaginary = real*rhs.m_imaginary+imaginary*rhs.m_real;
}

// (a + b i) / (c + d i) = (ac+bd)/(c*c+d*d) + (-ad+bc)/(c*c+d*d) i 
bool Complex::divide(Complex rhs)
{
    double divisor = rhs.m_real*rhs.m_real+
		             rhs.m_imaginary*rhs.m_imaginary;
	if (divisor < 1e-10) return false;
	double real = m_real, imaginary = m_imaginary;

    m_real = (real*rhs.m_real+imaginary*rhs.m_imaginary)/divisor;
	m_imaginary = (-real*rhs.m_imaginary+imaginary*rhs.m_real)/divisor;
	return true;
}

// | a + b i | = (a*a+b*b)^0.5
double Complex::magnitue()
{
    return sqrt(m_real*m_real+m_imaginary*m_imaginary);
}

bool Complex::equal(Complex rhs, double precision)
{
    double dx = m_real - rhs.m_real;
	double dy = m_imaginary - rhs.m_imaginary;
	if (dx*dx+dy*dy < precision*precision)
		return true;
	else
		return false;
}

void Complex::print()
{
    std::cout << m_real;
    if (m_imaginary >= 0)
    	std::cout << " + " << m_imaginary << " i";
    else
    	std::cout << " - " << -m_imaginary << " i";
}

void Complex::print(std::ostream &os)
{
    os << m_real;
    if (m_imaginary >= 0)
    	os << " + " << m_imaginary << " i";
    else
    	os << " - " << -m_imaginary << " i";
}

std::ostream& operator<<(std::ostream& os, Complex &src)
{
    src.print(os);
    return os;
}

std::ostream* operator<<(std::ostream* os, Complex src)
{
    src.print(*os);
    return os;
}

void Complex::unitTest()
{
    Complex x1, x2, x3;
    x1.setValue(7, 3);
    x2.setValue(1, 1);
    x3.setValue(5, -2);
    assert(x1.divide(x2));
    assert(x1.equal(x3, 1e-10));
    x2.setValue(0, 0);
    assert(!x1.divide(x2));
}


CPoint Complex::convertPoint()
{
    return CPoint((int)(m_real*100), (int)(m_imaginary*100));
}