#ifndef __PM_PARAMS_H__
#define __PM_PARAMS_H__
#include "pm_config.h"
#include <math.h>
#include <stdio.h>
/**
 * @brief Measurement mode enumeration for polarimeter
 */
typedef enum
{
    PM_MEAS_MODE_OPTICAL_ROTATION,  // Optical rotation mode
    PM_MEAS_MODE_SPECIFIC_ROTATION, // Specific rotation mode
    PM_MEAS_MODE_CONCENTRATION,     // Concentration mode
    PM_MEAS_MODE_SUGAR_SCALE        // International sugar scale mode
} PM_MeasMode_t;

/**
 * @brief Measurement parameters for polarimeter
 */
/* Break the parameters into three logical groups to make ownership and usage clearer.
 * This is a destructive refactor: code that previously accessed params-><field>
 * should be updated to use the relevant subgroup (config, measured, computed).
 */

typedef struct
{
    /* Settings provided by user or configuration */
    float         tube_length; /* dm */
    float         wavelength;  /* nm */
    PM_MeasMode_t mode;        /* default measurement mode */
} pm_config_t;

typedef struct
{
    /* Values read from sensors / user input */
    float zero_point;        /* ° */
    float measured_value;    /* ° */
    float temperature;       /* °C */
    float concentration;     /* g/100ml - used when known */
    float specific_rotation; /* ° - used when known */
} pm_measured_t;

typedef struct
{
    float actual_rotation;   /* ° */
    float specific_rotation; /* ° - computed or copied from measured */
    float concentration;     /* g/100ml - computed or copied */
    float sugar_scale;       /* °Z */
} pm_computed_t;

typedef struct
{
    pm_config_t   config;
    pm_measured_t measured;
    pm_computed_t computed;
} pm_params_t;

/* Function prototypes with pm_ prefix */
/**
 * @brief Compute actual rotation: measured_value - zero_point
 * @param params Pointer to measurement parameters
 * @return Actual rotation in degrees (°)
 */
/* Recompute all derived fields from the current config + measured values */
void pm_params_recompute(pm_params_t *params);

/* Backwards-compatible helpers (wrap computed/measured access) */
float pm_calculate_actual_rotation(pm_params_t *params);

/**
 * @brief Compute specific rotation [α]
 * @param params Pointer to measurement parameters
 * @return Specific rotation ([α], °) or NAN on error
 */
float pm_calculate_specific_rotation(pm_params_t *params);

/**
 * @brief Compute concentration from rotation and specific rotation
 * @param params Pointer to measurement parameters
 * @return Concentration in g/100mL or NAN on error
 */
float pm_calculate_concentration(pm_params_t *params);

/**
 * @brief Compute international sugar scale (°Z) from rotation
 * @param params Pointer to measurement parameters
 * @return Sugar scale value (°Z)
 */
float pm_calculate_sugar_scale(pm_params_t *params);

/**
 * @brief Calculate result based on selected measurement mode
 * @param params Pointer to measurement parameters
 * @return Computed result based on mode, or NAN on error
 */
float pm_calculate_measurement(pm_params_t *params);

/**
 * @brief Get human-readable mode name
 * @param mode Measurement mode
 * @return Null-terminated string with mode name
 */
const char *pm_get_mode_name(PM_MeasMode_t mode);

/**
 * @brief Print formatted measurement result to log/console
 * @param params Pointer to measurement parameters
 * @param result Computed result to print
 */
void pm_print_measurement_result(pm_params_t *params, float result);


void pm_params_reset(pm_params_t *params);
pm_params_t *pm_params_get_instance(void);

void pm_params_init(pm_params_t *params);

#endif // __PM_PARAMS_H__
