#ifndef WATOM_T_H
#define WATOM_T_H

//Funktionen fuer PD-Externals

#include "wabor_t_definitions.h"
#include "wabor_t_array_functions.h" 
#include "wabor_t_theta_functions.h"

static t_class *pcWatom_t;

struct _sWatom_t {
	t_object x_obj; //t_object has to be the first entry in the structure!!

	t_inlet *x_in; //Inlet fuer Messages
	
	t_outlet *x_outC; //Outlet fuer Datenweitergabe an iwabor_t
	t_outlet *x_outM; //Outlet fuer Messages

	sWatom_Param sParam;

	pac_type **pac;  //Pointer to array (of numbers) - Compute;
	t_float var;

};
typedef struct _sWatom_t sWatom_t;

void watom_t_set_pointers_to_NULL(sWatom_t *psW);
void watom_t_set_start_values(sWatom_t *psW);
void *watom_t_new(t_floatarg fArg); //constructor
void watom_t_delete(sWatom_t* psWatom_t);
void watom_t_dsp(sWatom_t *psW, t_signal **sp);
t_int *watom_t_perform(t_int *aw);
thread_return_type watom_t_perform_thread( void* _sthread_param );
void watom_t_bang(sWatom_t const * const psW);
void watom_t_make_receive_list(sWatom_t *psW, t_symbol *s, int argc, t_atom *argv);

t_int watom_t_test_compileparam(); //Testet alle Parameter die nicht geaendert werden koennen zur Laufzeit ob sie richtig sind
t_int watom_t_test_param(sWatom_t const * const psW, const t_int iPrintOutput); //Testet alle Parameter anderen Parameter ob sie richtig sind

void watom_t_initialize(sWatom_t* psW, t_float override);
void watom_t_initialize_pac(sWatom_t* psW);
void watom_t_initialize_paf(sWatom_t* psW);
void watom_t_initialize_patc(sWatom_t* psW);
void watom_t_initialize_patp(sWatom_t* psW);
void watom_t_initialize_sSound(sWatom_t* psW);
void watom_t_initialize_diverse_vectors(sWatom_t* psW);

void watom_t_make(sWatom_t *psW, t_float fAN);
void watom_t_shorten(sWatom_t *psW, t_float fAN);
void watom_t_test(sWatom_t *psW, t_float fPrintOut);
void watom_t_make_windows(sWatom_t *psW, t_int iAN);
void watom_t_shorten_windows(sWatom_t *psW, t_int iAN);
t_int watom_t_test_windows(sWatom_t const * const psW, t_int iPrintOutput);
pac_type_real watom_t_frequency_shift(pac_type_real dF, pac_type_real dSR);

void watom_t_copy_pac2paf(sWatom_t *psW, t_float fAN);
void watom_t_copy_paf2pac(sWatom_t *psW, t_float fAN);
void watom_t_paf2list(sWatom_t const * const psW, t_symbol *s, t_int argc, t_atom *argv);
void watom_t_send_windows(sWatom_t const * const psW, t_symbol *s UNUSED, t_int argc UNUSED, t_atom *argv UNUSED);

t_int watom_t_get_q_compute_sup(sWatom_t const * const psW);


t_int watom_t_find_longest_frame_paf(sWatom_t const * const psW);
t_int watom_t_find_shortest_frame_paf(sWatom_t const * const psW);
t_int watom_t_find_longest_frame_pac(sWatom_t const * const psW);
t_int watom_t_find_shortest_frame_pac(sWatom_t const * const psW);

void watom_t_set_compute_coefficients(sWatom_t *psW, t_float fCompute);

//Allgemeine Funktionen
void watom_t_set_window_type(sWatom_t *psW, t_float fWindowType);
void watom_t_set_theta_type(sWatom_t *psW, t_symbol *s, t_int argc, t_atom *argv);
void watom_t_set_C_b(sWatom_t *psW, t_float fCb);
void watom_t_set_C_T_c(sWatom_t *psW, t_float fFactor);
void watom_t_set_T_max(sWatom_t *psW, t_float T_max);
void watom_t_set_C_d(sWatom_t *psW, t_float fC_d);
void watom_t_set_C_q(sWatom_t *psW, t_float fFactor);
void watom_t_set_C_ab_ratio(sWatom_t *psW, t_float fRatio);
void watom_t_set_soundbuffer_length_factor(sWatom_t *psW, t_float fFactor);
void watom_t_set_C_SR(sWatom_t *psW, t_float fC_SR);
void watom_t_set_K(sWatom_t *psW, t_float fBandwidthInLobes);
void watom_t_set_compute_type(sWatom_t *psW, t_float fCutType);
void watom_t_set_thetaf0(sWatom_t *psW, t_float fF0);
void watom_t_set_thetak(sWatom_t *psW, t_float fDilation);
void watom_t_set_C_cut(sWatom_t *psW, t_float fCutRatio);

void watom_t_set_var(sWatom_t* psW, t_float f);
void watom_t_set_winlength_window(sWatom_t* psW, t_float fWinlength_window);
void watom_t_set_winlength_compute(sWatom_t* psW, t_float fWinlength_compute);
void watom_t_set_a(sWatom_t* psW, t_float fa);
void watom_t_set_b(sWatom_t* psW, t_float fb);


void watom_t_set_num_threads(sWatom_t* psW, t_float num);

void watom_t_get_first_zero_paf(sWatom_t const * const psW, t_float fAN);
void watom_t_get_window_length_paf(sWatom_t const * const psW, t_float fAN);
void watom_t_get_window_length_pac(sWatom_t const * const psW, t_float fAN);
void watom_t_print_first_and_last_value(sWatom_t const * const psW, t_float fAN);
void watom_t_print_band(sWatom_t const * const psW, t_float fAN);
void watom_t_print_windows(sWatom_t const * const psW, t_float fAN);

void watom_t_badfilter(sWatom_t *psW, t_int iBin0, t_int iBin1);
void watom_t_abs(sWatom_t *psW, t_float fAN);
void watom_t_componentabs(sWatom_t *psW, t_float fAN);
void watom_t_ln(sWatom_t *psW, t_float fAN);
void watom_t_mult(sWatom_t *psW, t_symbol *s, t_int argc, t_atom *argv);
void watom_t_cut(sWatom_t *psW, t_float fAN, t_float fCutLow, t_float fCutHigh);
void watom_t_set_nan_to_zero(sWatom_t *psW, t_float fAN);
void watom_t_set_inf_to_zero(sWatom_t *psW, t_float fAN);
void watom_t_normalize(sWatom_t *psW, t_float fAN);
void watom_t_cycle(sWatom_t *psW, t_symbol *s, t_int argc, t_atom *argv);
void watom_t_fft(sWatom_t *psW, t_float fAN);
void watom_t_floating_average(sWatom_t *psW, t_float fAN, t_float fFactor, t_float fMax);
void watom_t_differentiate(sWatom_t *psW, t_float fAN);
void watom_t_integrate(sWatom_t *psW, t_float fAN);
void watom_t_imag_plus_real(sWatom_t *psW, t_float fAN);
void watom_t_make_dc_offset(sWatom_t *psW,  t_float fAN,  t_float fChangeOffset, t_float fDCOffset_real, t_float fDCOffset_imag);
void watom_t_inner_product(sWatom_t const * const psW,  t_float fAN1,  t_float fAN2);
void watom_t_length_of_vector(sWatom_t const * const psW,  t_float fAN1);
void watom_t_prolong(sWatom_t const * const psW, t_float fAN, t_float fN, t_float fWhere, t_float fRandom);

void watom_t_array_synopsis(sWatom_t const * const psW, t_symbol *s, t_int argc, t_atom *argv);
t_int watom_t_round_up_to_multiple_of_small_primes(sWatom_t const * const psW, t_float n, t_float maxprime);




#endif //WATOM_T_H


