 #include "woutput_t.h"

void woutput_t_setup(void){
    
    pcWoutput_t = class_new(gensym("woutput~"),
            (t_newmethod)woutput_t_new, (t_method)woutput_t_delete,
            sizeof(sWoutput_t),
            CLASS_DEFAULT,
            A_DEFFLOAT, 0);
    
    class_addmethod(pcWoutput_t, (t_method)woutput_t_dsp, gensym("dsp"), 0);
    CLASS_MAINSIGNALIN(pcWoutput_t, sWoutput_t, fConstSignal);
    class_addbang(pcWoutput_t, woutput_t_bang);
    
    class_addmethod(pcWoutput_t, (t_method)woutput_t_open, gensym("open"), A_GIMME, 0);
    class_addmethod(pcWoutput_t, (t_method)woutput_t_close, gensym("close"), 0);    
    class_addmethod(pcWoutput_t, (t_method)woutput_t_set_threshold, gensym("set_threshold"), A_DEFFLOAT, 0);    
    
}

void *woutput_t_new(t_floatarg fThreshold){
    sWoutput_t *psW = (sWoutput_t *)pd_new(pcWoutput_t);
    
    psW->fConstSignal=0;
    
    psW->x_inC = inlet_new(&(psW->x_obj), &(psW->x_obj.ob_pd), &s_signal, &s_signal);
    psW->filepath[0]='\0';
    psW->myfile=NULL;
    psW->counter=0;
    psW->threshold=fThreshold;
    return (void *)psW;
}

void woutput_t_delete(sWoutput_t UNUSED *psW){
    if(psW->myfile) {
        fflush (psW->myfile);
    }
    fclose(psW->myfile);
    psW->myfile=NULL;        
     
}  

void woutput_t_open(sWoutput_t *psW, t_symbol UNUSED *s, t_int argc, t_atom *argv){
   if(argc<1) {
        post("Call with path as first parameter"); return;
    }
    atom_string(argv+0,psW->filepath,WABOR_T_MAXPATHLENGTH);
    psW->myfile = fopen(psW->filepath, "w");
    if(psW->myfile==NULL){
        fclose(psW->myfile);
    } 

}
void woutput_t_close(sWoutput_t *psW){
    fflush (psW->myfile);
    fclose(psW->myfile);
    psW->myfile=NULL;
}


void woutput_t_dsp(sWoutput_t* psW, t_signal **sp){
#define WOUTPUT_T_PERFORM_NUM_POINTERS (4)
    dsp_add(woutput_t_perform, WOUTPUT_T_PERFORM_NUM_POINTERS,
            psW,
            sp[0]->s_vec,
            sp[1]->s_vec
            );
}

t_int *woutput_t_perform(t_int *aw){
    sWoutput_t  *psW= (sWoutput_t *)(aw[1]);
    t_sample    *inG   =  (t_sample *)(aw[2]);
    t_sample    *inC   =  (t_sample *)(aw[3]);
    
    sWatom_Param* param=find_pointer_at_address(&inC[WABOR_T_WATOM_PARAM]);
    sWabor_Coeff **patc = find_pointer_at_address(&inG[WABOR_T_POINTER_TO_COEFF_BIN]);
    
    if(   psW->myfile==NULL || 
          patc==NULL ||
          param==NULL ||
          find_int_at_address(&inC[WABOR_T_MAGIC_NUMBER_BIN]) != WABOR_T_MAGIC_NUMBER_C  ||
          find_int_at_address(&inG[WABOR_T_MAGIC_NUMBER_BIN]) != WABOR_T_MAGIC_NUMBER_G  )
    {
        return aw + WOUTPUT_T_PERFORM_NUM_POINTERS + 1; //Wenn ich nicht mit wabor_t verbunden bin
    }
    
    //t_int q_sup=param->iq_compute_sup;
    //paf_type** paf_r = param->paf_r;
    //paf_type** paf_i = param->paf_i;
    
    t_int num_blocks=find_int_at_address(&inG[WABOR_T_NUM_BLOCKS_BIN]);
    for( t_int k=0; k<num_blocks; ++k){
        struct _sWabor_Coeff const * atc=patc[k];
        t_int iNumTC=atc[0].numCoeff;
        while(iNumTC--){
            struct _sWabor_Coeff const *tc=&(atc[iNumTC]);
            unsigned int q=tc->band;
            const sound_type val_r= tc->val_r; //damit ich unten das gesamte Signal mal 2 multiplizieren kann
            const sound_type val_i= tc->val_i;
            unsigned int startT=tc->start+psW->counter;
            if(fabsPAC(val_r)>psW->threshold || fabsPAC(val_i)>psW->threshold){
                unsigned int wl=param->paf_r[q][WABOR_T_LENGTH_BIN];
                fprintf(psW->myfile, "%i\t%i\t%.20f\t%.20f\t%i\n", startT,q,val_r,val_i,wl); //Time \t band\t val_r \t val_i \t windowlength;
            }
        }
    }
    psW->counter+=PD_BLOCKSIZE;
    
    return aw + WOUTPUT_T_PERFORM_NUM_POINTERS + 1; 
}

void woutput_t_bang(sWoutput_t *psW){
    if(psW->myfile!=NULL){
        post("File opened: %s",psW->filepath);
    } else {
        post("No open file.");
    }
    post("Threshold: %f",psW->threshold);
    return;
}

void woutput_t_set_threshold(sWoutput_t *psW, t_float fTreshold){
    psW->threshold=fTreshold;
}