//
// Created by jholder on 22.10.21.
//

#ifndef MYPROJECT_COMPUTE_H
#define MYPROJECT_COMPUTE_H

#include <ostream>
#include "Data/Rod2d.hpp"
#include "Data/Simulation.h"
#include "tools/LiveAgg.hpp"

class Compute {
   public:
    enum class Type { msd, oaf, empxx, empyy, x, x_squared };
    enum class Force { zero_F, const_F, harmonic_F };

    explicit Compute(Rod2d rod, Type t_type, Force force, size_t t_every,
                     Simulation &sim);
    ~Compute() = default;

    void eval(const Rod2d &rod2D);

    [[nodiscard]] double getTarget() const;

    [[nodiscard]] const LiveAgg &getAgg() const;

    [[nodiscard]] Type getType() const;
    [[nodiscard]] std::string getType_Str() const;

    [[nodiscard]] double getTime() const;

    [[nodiscard]] double getDifference() const;

    friend std::ostream &operator<<(std::ostream &os, const Compute &compute);
    void reset(const Rod2d &rod);

   private:
    Rod2d start_rod;
    LiveAgg agg;
    size_t every;
    size_t time_step;
    Type type;
    double target;
    double time;
    std::string type_str;
    bool resetting;

    void evalX(const Rod2d &rod2D);
    void evalMSD(const Rod2d &rod2D);
    void evalOAF(const Rod2d &rod2D);
    void eval_empXX(const Rod2d &rod2D);
    void eval_empYY(const Rod2d &rod2D);
    void evalX_squared(const Rod2d &rod2D);
};

#endif  // MYPROJECT_COMPUTE_H
