/*
  This file is part of CDO. CDO is a collection of Operators to
  manipulate and analyse Climate model Data.

  Copyright (C) 2006 Brockmann Consult
  See COPYING file for copying and redistribution conditions.

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; version 2 of the License.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
*/

#ifndef PERCENTILES_HIST_H_
#define PERCENTILES_HIST_H_

#include <cassert>

#include "field.h"

struct Histogram
{
  double min = 0;
  double max = 0;
  double step = 0;
  int nbins = 0;
  int nsamp = 0;
  void *ptr = nullptr;
};

class // HistogramSet
#ifdef __GNUG__
[[gnu::warn_unused]]
#endif
HistogramSet
{
private:
  int nvars = 0;
  std::vector<int> var_nlevels;
  std::vector<size_t> var_nhists;
  std::vector<std::vector<std::vector<Histogram>>> histograms;

  void
  init()
  {
    var_nlevels.resize(nvars, 0);
    var_nhists.resize(nvars, 0);
    histograms.resize(nvars);
  }

public:
  HistogramSet() {}

  HistogramSet(int _nvars) : nvars(_nvars)
  {
    assert(nvars > 0);
    init();
  }

  void
  create(const int _nvars)
  {
    nvars = _nvars;
    assert(nvars > 0);
    init();
  }

  ~HistogramSet()
  {
    for (auto varID = nvars; varID-- > 0;)
      {
        const auto nhists = this->var_nhists[varID];
        for (auto levelID = this->var_nlevels[varID]; levelID-- > 0;)
          {
            for (auto histID = nhists; histID-- > 0;) free(this->histograms[varID][levelID][histID].ptr);
          }
      }
  }

  void createVarLevels(int varID, int nlevels, size_t nhists);
  void defVarLevelBounds(int varID, int levelID, const Field &field1, const Field &field2);
  void defVarLevelBoundsF(int varID, int levelID, const Field &field1, const Field &field2);
  int addSubVarLevelValues(int varID, int levelID, const Field &field, int operation, int ptype);
  void getVarLevelPercentiles(Field &field, int varID, int levelID, double p, int ptype);
  // void reset(int varID, int levelID, int ptype); // unused
};

#endif /* PERCENTILES_HIST_H_ */
