/*
 * Practica 1.
 *
 * Practicas Metodologia de la Programacion.
 * Curso 2008 - 2009
 *
 * Vicente Lujan Mansilla
 * Lorena Margareto Bisquert
 */

#include <stdlib.h>
#include <iostream>
#include <assert.h>

#include "Complejo.h"
using namespace std;

/** 
 * Diferencia maxima que se considera cero al comparar dos reales
 */
const float CERO = 0.0001;

Complejo::Complejo(float m, float a) 
{
   mod = m;
   arg = a;

   assert(inv());
} 

bool Complejo::operator==(const Complejo c) const 
{
    if(mod == 0 && c.mod == 0)
        return true;
    else
        return (mod - c.mod < CERO && arg - c.arg < CERO);
}

void Complejo::setRec(float re, float im) 
{
    mod = sqrt(re*re + im*im);

    if(re == 0 && im == 0)
        arg = 0;
    else
        arg = atan2(im, re);

    if(arg < 0)
        arg = arg + 2 * M_PI;

    assert(inv());
}

float Complejo::getReal() const 
{
    return (mod * cos(arg));
}

float Complejo::getImag() const 
{
    return (mod * sin(arg));
}

bool Complejo::inv() 
{
	return (arg >= 0 && arg <= (2 * M_PI) && mod >=0);
}

Complejo Complejo::operator+(const Complejo c) const 
{
	Complejo res;
	float real, imag;

	real = getReal() + c.getReal();
	imag = getImag() + c.getImag();
	
	res.setRec(real, imag);
	
	return res;
}

Complejo Complejo::operator*(const Complejo c) const 
{
	Complejo res;
	float modulo, argumento;
	
	modulo = mod * c.mod;
	argumento = arg + c.arg;
	
	if(argumento > (2 * M_PI))
	    argumento -= (2 * M_PI);
	
	res.set(modulo,argumento);
	
	assert(res.inv());
	
	return(res);
}

void Complejo::set(float m, float a) 
{
	mod = m;
	arg = a;
	
	assert(inv());	
}

void Complejo::print() const 
{
	cout << mod << "e^" << arg;
}

