#ifndef __DP_ATTEN_H
#define __DP_ATTEN_H

#define DEFAULT_SITE ""

#ifdef __cplusplus
extern "C" {
#endif
#if 0
}
#endif

/* Forward declarations */
struct conf_par_entry;
struct dp_atten_data;
enum bin_type;

enum alg_type {
    ALGT_DP,     /**< Differential Pollarisation(DP) */
    ALGT_DPC,    /**< DP Constrained */
    ALGT_IDPC    /**< Iterative DP Constrained */
};

struct range {
    float val;
    float min;
    float max;
};

#define INF_RANGE(v) ((struct range){v, -INFINITY, INFINITY})

struct running_average {
    struct range dat;
    float        std_sq; /**< running average of the delta^2 */
    unsigned int gate;   /**< averaging gate */
    struct {
        unsigned int last;
        unsigned int missed;
        unsigned int total;
    } cnt;
};

struct dp_atten_params {
    /* Volaitile parameters (running averages) */
    struct running_average phidp_r0; /**< Running average of system Phi_DP */

    /* Processing parameters (read then from the config file) */
    double b_exp;              /**< Z to attenuation relationship parameter */ 
    float  sys_phi;            /**< Initial PHIdp of the system */
    enum   alg_type algorithm; /**< DP, DPC, or IDPC. IDPC is the default */
    struct range alpha_h;
    struct range alpha_v;
    struct range melting_layer; /**< Hight of the melting layer [m] */
    /* TODO: depricate remaining parameters ASAP */
    float phase_amb;
    int report_smooth_phidp;
    int debug2stderr;
};

struct pol_att_corr_dat;

/** set parameters to default values */
void dp_atten_init_config(struct dp_atten_params * params);

/** try to apply  conf. item. If failed return 1 */
int dp_atten_set_config(struct dp_atten_params * params,
                        const struct conf_par_entry * conf_item);

/** try to modify conf. item. If failed return 1 */
int dp_atten_get_config(const struct dp_atten_params * params,
                        struct conf_par_entry * conf_item);

struct dp_atten_data *  dp_atten_init(size_t bins);
void dp_atten_uninit(struct dp_atten_data * data);

void  dp_atten_run(struct dp_atten_params *param, struct dp_atten_data * data,
                   float elevation, float azimuth, float altitude, size_t bins,
                   float * phidp,
                   const int * mask, const float * zh, const float * zv,
                   const float * range, float * zhc, float * zvc,
                   enum bin_type * flags);

#if 0
{
#endif
#ifdef __cplusplus
}
#endif
#endif
