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

float complex_abs( const Complex * c ) {
    return sqrt( pow( c->re, 2 ) + pow( c->im, 2 ) );
}

float complex_arg( const Complex * a )
{
    return atan2( a->im, a->re );
}

Complex complex_comjunction( const Complex * a ) {
    Complex c = { a->re, - a->im };
    return c;
}

float complex_phi( const Complex * c ) {
    float phi = 0.0;

    // quadrant I
    if ( c->re >= 0 && c->im >= 0 ) phi = atan( c->im / c->re );
    // quadrant II, III
    if ( c->re  < 0 ) phi = atan( c->im / c->re ) + M_PI;
    // quadrant IV
    if ( c->re  > 0 && c->im  < 0 ) phi = atan( c->im / c->re ) + 2 * M_PI;

    return phi * 180.0 / M_PI;
}

Complex complex_scalar_mul( const Complex * a, const float b ) {
    Complex c = { 0.0, 0.0 };
    float o_re = b;
    float o_im = 0.0;

    c.re = a->re * o_re - a->im * o_im;
    c.im = a->re * o_im + o_re * a->im;

    return c;
}

Complex complex_mul( const Complex * a, const Complex * b ) {
    Complex c = { 0.0, 0.0 };
    float o_re = b->re;
    float o_im = b->im;

    c.re = a->re * o_re - a->im * o_im;
    c.im = a->re * o_im + o_re * a->im;

    return c;
}

Complex complex_add( const Complex * a, const Complex * b ) {
    Complex c = { 0.0, 0.0 };
    c.re = a->re + b->re;
    c.im = a->im + b->im;

    return c;
}

Complex complex_sub( const Complex * a, const Complex * b ) {
    Complex c = { 0.0, 0.0 };
    c.re = a->re - b->re;
    c.im = a->im - b->im;

    return c;
}

Complex complex_polar( float roh, float theta )
{
    Complex c = { roh * cos( theta ), roh * sin( theta ) };

    return c;
}

Complex complex_pow( const Complex * a, int n )
{
    float roh   = pow( complex_abs( a ), n );
    float theta = complex_arg( a );

    return complex_polar( roh, ( float )( n ) * theta );
}

