#include "MSPd.h"

static t_class *poltocar_class;

/* Pd version of poltocar~ */

#define OBJECT_NAME "poltocar~"
typedef struct _poltocar
{
  t_object x_obj;
  t_float x_f;
} t_poltocar;

static void *poltocar_new(t_symbol *msg, int argc, t_atom *argv);
static void poltocar_free(t_poltocar *x);
static void poltocar_dsp(t_poltocar *x, t_signal **sp);


void poltocar_tilde_setup(void) {
  poltocar_class = class_new(gensym("poltocar~"), (t_newmethod)poltocar_new,
                             0, sizeof(t_poltocar),0,A_GIMME,0);
  CLASS_MAINSIGNALIN(poltocar_class, t_poltocar, x_f);
  class_addmethod(poltocar_class, (t_method)poltocar_dsp, gensym("dsp"), A_CANT, 0);
  potpourri_announce(OBJECT_NAME);
}

void *poltocar_new(t_symbol *msg, int argc, t_atom *argv)
{
  t_poltocar *x = (t_poltocar *)pd_new(poltocar_class);
  inlet_new(&x->x_obj, &x->x_obj.ob_pd,gensym("signal"), gensym("signal"));
  outlet_new(&x->x_obj, gensym("signal"));
  outlet_new(&x->x_obj, gensym("signal"));
  return x;
}

t_int *poltocar_perform(t_int *w)
{
  int i;
  t_float *mag_in = (t_float *) w[2];
  t_float *phase_in = (t_float *) w[3];
  t_float *real_out = (t_float *) w[4];
  t_float *imag_out = (t_float *) w[5];
  t_float real, imag;

  int n = (int) w[6]; // obj, func, 1 inlet
  int N2 = n/2;

  for(i = 0; i < N2 + 1; i++) {
    real = mag_in[i] * cos( phase_in[i] );
    if(i == N2) {
      imag = 0;
    } else{
      imag = -mag_in[i] * sin( phase_in[i] );
    }
    real_out[i] = real;
    imag_out[i] = imag;
  }

  return (w + 7);
}

void poltocar_dsp(t_poltocar *x, t_signal **sp)
{
  dsp_add(poltocar_perform,6, x,
          sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec, (t_int)sp[0]->s_n);
}
