/******************************************************************************
 * Copyright (c) 2000-2025 Ericsson Telecom AB
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
 *
 * Contributors:
 *   Balasko, Jeno
 *   Raduly, Csaba
 *   Szabados, Kristof
 *   Szabo, Bence Janos
 *
 ******************************************************************************/
#ifndef ENUM_HH_
#define ENUM_HH_

#include "Setting.hh"
#include "Identifier.hh"
#include "Int.hh"
#include "datatypes.h"

namespace Common {

class int_val_t;
class SubTypeParse;
class Value;

class EnumItemIntValues {
private:
  size_t nof_values;
  int* values;
  boolean* intervals;

  EnumItemIntValues operator=(const EnumItemIntValues&);
  bool chk_this_value_internal(Value* p_val, const char* p_val_descr) const;
public:
  EnumItemIntValues(size_t p_nof_values);
  EnumItemIntValues(const EnumItemIntValues& p_other);
  ~EnumItemIntValues();
  void set_value(size_t p_idx, int p_value, bool starts_interval);
  bool has_value(int p_value) const;
  bool intersects(const EnumItemIntValues& p_other) const;
  bool contains(const EnumItemIntValues& p_other) const;
  bool next_unused(Int& p_value) const;
  size_t get_nof_values() const { return nof_values; }
  int* get_values() const { return values; }
  boolean* get_intervals() const { return intervals; }
  void finalize();
  bool chk_this_value(Value* p_val, const string& p_ei_name) const;
  bool chk_this_value_range(Value* p_min, Value* p_max,
    const string& p_ei_name, Location* p_loc) const;
};
  
/**
 * Class to represent an Enumeration item. Is like a NamedValue, but
 * the value can be NULL, and a(n integer) value can be assigned
 * later.
 */
class EnumItem : public Node, public Location {
private:
  Identifier *name;
  vector<SubTypeParse>* values;
  Value *value;
  string text; ///< for TEXT encoding instruction
  string descaped_text; ///< made from text variable but replaces all the escaped values
  Int *int_single_value;
  EnumItemIntValues* int_values;
  bool ext_add; ///< indicates whether this is an extension addition or part of the root
  bool int_value_calculated;
  /** Copy constructor not implemented */
  EnumItem(const EnumItem&);
  /** Assignment disabled */
  EnumItem& operator=(const EnumItem&);

  bool calculate_int_value_internal(Value* p_value, bool p_is_range_limit, Int& p_int_res);
public:
  EnumItem(Identifier *p_name, Value *p_value);
  EnumItem(Identifier *p_name, vector<SubTypeParse>* p_values);
  virtual ~EnumItem();
  virtual EnumItem *clone() const;
  virtual void set_fullname(const string& p_fullname);
  const Identifier& get_name() const { return *name; }
  Value *get_single_value() const { return value; }
  void set_single_value(Value *p_value);
  vector<SubTypeParse>* get_values() const { return values; }
  const string& get_text() const { return text; }
  const string& get_descaped_text() const { return descaped_text; }
  void set_text(const string& p_text);
  virtual void set_my_scope(Scope *p_scope);
  bool calculate_int_value();
  Int* get_int_val() const { return int_single_value; }
  EnumItemIntValues* get_int_values() const { return int_values; }
  void set_ext_add() { ext_add = true; }
  bool is_ext_add() const { return ext_add; }
  virtual void dump(unsigned level) const;
};

/**
 * Class to represent a collection of enumerated items.
 */
class EnumItems : public Node {
private:
  Scope *my_scope;
  vector<EnumItem> eis_v;
  /** Stores the first occurrence of EnumItem with id. The string key
   * refers to the id of the ei, the value is the ei itself. */
  map<string, EnumItem> eis_m;
  /** Copy constructor not implemented */
  EnumItems(const EnumItems& p);
  /** Assignment disabled */
  EnumItems& operator=(const EnumItems& p);
public:
  EnumItems() : Node(), my_scope(0), eis_v(), eis_m() { }
  virtual ~EnumItems();
  /** Clears the vector and the map, but does not delete the items */
  void release_eis();
  virtual EnumItems *clone() const;
  virtual void set_fullname(const string& p_fullname);
  void set_my_scope(Scope *p_scope);
  void add_ei(EnumItem *p_nv);
  size_t get_nof_eis() const { return eis_v.size(); }
  EnumItem* get_ei_byIndex(const size_t p_i) { return eis_v[p_i]; }
  bool has_ei_withName(const Identifier& p_name) const
    { return eis_m.has_key(p_name.get_name()); }
  EnumItem* get_ei_byName(const Identifier& p_name) const
    { return eis_m[p_name.get_name()]; }
  bool has_ei_with_multiple_values() const;
  virtual void dump(unsigned level) const;
};

}

#endif /* ENUM_HH_ */
