#ifndef _SCALAR_FW_ACTIVE_SET_H_
#define _SCALAR_FW_ACTIVE_SET_H_

#include <tuple>
#include <vector>

#include "types.h"

template <typename ix_t, typename val_t>
class ActiveSet
{
public:
   // entry = (weight, vector)
   using entry_t = std::pair<val_t, vec_t<val_t>>;

   ActiveSet(const ix_t dim);
   ActiveSet(ActiveSet<ix_t, val_t> && other);
   ~ActiveSet();

   ix_t size() const;
   bool validate() const;
   val_t weight_from_atom(const vec_t<val_t>& vector) const;
   const vec_t<val_t>& x() const;

   std::pair<entry_t, entry_t> argminmax(const vec_t<val_t> & direction) const;

   void initialize(const vec_t<val_t> & v);
   void push(const entry_t & entry);
   void remove(const ix_t ix);
   entry_t & operator[](const ix_t ix);
   void update(const entry_t & entry, bool renorm = true);
   void cleanup(const val_t weight_purge_threshold = 1e-12);
   void renormalize();
   void update_x();

   ActiveSet copy();

   void print();

 protected:
   ix_t find_atom(const vec_t<val_t>& vector);

   ix_t                 m_dim;
   std::vector<entry_t> m_as;
   vec_t<val_t>         m_x;
};

#endif // _SCALAR_FW_ACTIVE_SET_H_
