// Programación en C++ para Ingenieros, Ed. Thomson Paraninfo, 2006
// Capítulo 8: Diseño descendente

// Fichero complejo.cpp
// Funciones y operadores de la clase Complejo

#include"complejo.h"
#include<math.h>

// Constructor por defecto
Complejo::Complejo() {
    real = 0.0;
    imag = 0.0;
}

// Constructor general
Complejo::Complejo(double re, double im) {
    real = re;
    imag = im;
}

// Constructor de copia
Complejo::Complejo(const Complejo& c) {
    real = c.real;
    imag = c.imag;
}

// Método para modificar la parte real
void Complejo::setReal(double re) {
    real = re;
}

// Método para modificar la parte imaginaria
void Complejo::setImag(double im) {
    imag = im;
}

// Método para devolver la parte real
double Complejo::getReal() {
    return real;
}

// Método para devolver la parte imaginaria
double Complejo::getImag() {
    return imag;
}

// Método para el cálculo del conjugado de un
//complejo
Complejo Complejo::conjugado() {
    return Complejo(real,-imag);
}

// Métodos para la representación polar:
// Cálculo del módulo de un complejo
double Complejo::modulo() {
    return sqrt(real*real+imag*imag);
}

// Método para el cálculo del argumento de
// un complejo
double Complejo::angulo() {
    return atan(imag/real);
}

// Método para el cálculo del inverso de un complejo
Complejo Complejo::inverso() {
    double aux = real*real + imag*imag;
    return Complejo(real/aux,-imag/aux);
}

// Método para el cálculo del opuesto de un complejo
Complejo Complejo::operator-() {
    return Complejo(-real,-imag);
}

// Operadores binarios
// Operador miembro de + sobrecargado
Complejo Complejo::operator+ (const Complejo &c) {
    return Complejo(real+c.real,imag+c.imag);
}

// Operador miembro de - sobrecargado
Complejo Complejo::operator-(const Complejo &c) {
    return Complejo(real-c.real,imag-c.imag);
}

// Operador miembro de * sobrecargado
Complejo Complejo::operator* (const Complejo &c) {
    return Complejo(real*c.real-imag*c.imag,real*c.imag+c.real*imag);
}

// Operador miembro de / sobrecargado
Complejo Complejo::operator/ (const Complejo &c) {
double aux = c.real*c.real + c.imag*c.imag;
    return Complejo((real*c.real + imag*c.imag)/aux,
                    (-real*c.imag + imag*c.real)/aux);
}

// Operador miembro de asignación sobrecargado
Complejo& Complejo::operator= (const Complejo &c) {
    real = c.real;
    imag = c.imag;
    return (*this);
}

// Operador friend de test de igualdad sobrecargado
bool operator== (const Complejo& c1, const Complejo &c2) {
    return c1.real == c2.real && c1.imag == c2.imag;
}

// Operador friend de test de desigualdad sobrecargado
bool operator!= (const Complejo& c1, const Complejo &c2) {
    return c1.real != c2.real || c1.imag != c2.imag;
}

// Operador friend << sobrecargado
ostream& operator<< (ostream &co, const Complejo &c) {
    co << "("<< c.real;
    if (c.imag >= 0) co << "+" ;
    co << c.imag << "i)";
    return co;
}

// Operador friend >> sobrecargado
istream& operator>> (istream &ci, Complejo &c) {
    ci >> c.real >> c.imag;
    return ci;
}