#include "wabor_t_array_functions.h"


void wabor_setup(void){
    wabor_t_setup();
    winary_t_setup();
    invwabor_t_setup();
    welay_t_setup();
    wenerator_t_setup();
    watom_t_setup();
    woutput_t_setup();
    
    //TEST();    
    //wabor_test_compileparam();   
}

void TEST(void){
    
}

t_int wabor_test_compileparam(void){ 
    t_int iErrCount=0;
    //Folgende Tests brauch ich, damit alles richtig aligned ist
    if(DEBUG) post("sizeof pac_type: \t%i", sizeof(pac_type));
    if(DEBUG) post("sizeof paf_type: \t%i", sizeof(paf_type));
    if(7*sizeof(void*)>PD_BLOCKSIZE*sizeof(t_float)) {error ("wabor_t: 7*sizeof(void*)>PD_BLOCKSIZE*sizeof(t_float). Can't save pointer/gabor data in audio frame. Change Sourcecode."); }

    if(PD_BLOCKSIZE!=64) {error ("PD_BLOCKSIZE!=64"); ++iErrCount; }
    
    return iErrCount;
}

void* wabor_t_malloc0(size_t n){
#define ALIGNBYTE (sizeof(pac_type))
    //Aufbau meiner Fenster:
    //pointer p zeigt auf Begin von |Daten|
    //p[-7]-align=malloced pointer
    //p[-7]=align
    //p[-6]=Samplerate Factor
    //p[-5]=Laenge
    //p[-4]..p[-1]=0
    //p[L]..p[L+3]=0
    //0er davor und danach brauche ich nicht mehr, werden aber im Program alle auf 0 gesetzt (legacy))
    //p[0] ist align-bytealigned
    assert(n>0);


    n+=7*ALIGNBYTE+5*sizeof(pac_type); 
    char *p=malloc(n); //mit fftw_malloc allokieren, damit es aligned ist
    if(DEBUG){
        if(p!=NULL){
            memset(p,WABOR_T_MALLOC_VALUE,n);
        } else{
            assert(p!=NULL);
            post("Error, wabor_t_malloc0, memse");
        }   
    }
    t_int aligning=(((t_int)p)+7*ALIGNBYTE)%ALIGNBYTE;
    t_int align_shift=ALIGNBYTE-aligning;
    
    if(p==NULL) {
        error("Wabor_t: Out of Memory");
        return NULL;
    }
    p+=align_shift;
    p[0]=align_shift;
    return (void*)(p+7*ALIGNBYTE);
}

void wabor_t_free(void *p){

    if(p==NULL) {
        return;
    }
    char *pc = p;
    pc=pc-7*ALIGNBYTE;
    char align=*pc;
    pc=pc-align;
    if(DEBUG) { 
        p=NULL;
        memset(pc,WABOR_T_FREE_VALUE,WABOR_T_PADDING_LEFT);
    }
    free(pc);
    if(DEBUG) {
        pc=NULL;
    }
}

//Copyright © 2013 Block Of Codes All Right Reserved 
//http://blockofcodes.blogspot.co.at/2013/02/c-program-to-generate-prime-factor.html
PURE_FUNCTION t_int round_up_to_multiple_of_small_primes(t_int n, t_int maxprime){
    assert(maxprime>1);
    assert(n>0);
    if(maxprime==0) { return -1; }
    if(maxprime==1) { return n; }
    
    t_int number=n;
    int div;    
    t_int maxprimefactor;
    
    div = 2;
    
    while(number!=0){
        if(number%div!=0)
            div = div + 1;
        else {
            number = number / div;
            maxprimefactor=div;
            if(number==1){
                break;
            }
        }
    }
    
    if(maxprimefactor<=maxprime){
        return n;
    } else {
        return round_up_to_multiple_of_small_primes(++n,maxprime); 
    }

}