/**
 *
 * @file src/trace/Variable.cpp
 *
 * @copyright 2008-2024 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
 *                      Univ. Bordeaux. All rights reserved.
 *
 * @author Camille Ordronneau
 * @author Johnny Jazeix
 * @author Mathieu Faverge
 * @author Olivier Lagrasse
 * @author Augustin Degomme
 * @author Clement Vuchener
 *
 * @date 2024-07-17
 */

#include <string>
#include <iostream>
#include <sstream>
#include <fstream>
#include <map>
#include <list>
#include <vector>
#include <stack>
/* -- */
#include "trace/values/Values.hpp"
#include "trace/EntityTypes.hpp"
#include "trace/Entitys.hpp"
/* -- */
using namespace std;

Variable::Variable(Container *container, VariableType *type) :
    Entity(container, map<std::string, Value *>()), _min(0.0), _max(0.0), _type(type) {
}

Variable::~Variable() {
    _values.clear();
    _type = nullptr;
}

void Variable::add_value(Date time, Double value) {
    if (_values.empty())
        _min = _max = value;
    else if (value > _max)
        _max = value;
    else if (value < _min)
        _min = value;
    _values.emplace_back(time, value);
}

Double Variable::get_last_value() const {
    return _values.back().second;
}

const list<pair<Date, Double>> *Variable::get_values() const {
    return &_values;
}

double Variable::get_value_at(const Times &d) const {
    list<pair<Date, Double>>::const_iterator it = _values.begin();
    const list<pair<Date, Double>>::const_iterator it_end = _values.end();
    if (it == it_end)
        return 0.0;
    const Double *val = &((*it).second);
    ++it;
    while ((it != it_end)) {
        if (((*it).first.get_value()) > d)
            break;
        val = &((*it).second);
        ++it;
    }
    return val->get_value();
}

Double Variable::get_min() const {
    return _min;
}

Double Variable::get_max() const {
    return _max;
}

VariableType *Variable::get_type() const {
    return _type;
}
