#include "counter.h"

// Constructor
Counter::Counter(int value, int min, int max) {
  if (min <= max && value >= min && value <= max) {
    value_ = value;
    min_ = min;
    max_ = max;
  } else {
    value_ = 0;
    min_ = 0;
    max_ = 1000;
  }
}

// Operador de asignación con int
Counter &Counter::operator=(int v) {
  if (v > max_)
    value_ = max_;
  else if (v < min_)
    value_ = min_;
  else
    value_ = v;
  return *this;
}

// Operador de asignación con Counter
Counter &Counter::operator=(const Counter &c) {
  if (this != &c) {
    value_ = c.value_;
    min_ = c.min_;
    max_ = c.max_;
  }
  return *this;
}

// Prefijo ++
Counter &Counter::operator++() {
  value_++;
  if (value_ > max_)
    value_ = max_;
  return *this;
}

// Sufijo ++
Counter Counter::operator++(int) {
  Counter temp = *this;
  ++(*this); // Llamamos al prefijo
  return temp;
}

// Prefijo --
Counter &Counter::operator--() {
  value_--;
  if (value_ < min_)
    value_ = min_;
  return *this;
}

// Sufijo --
Counter Counter::operator--(int) {
  Counter temp = *this;
  --(*this); // Llamamos al prefijo
  return temp;
}

//(Counter + int)
Counter Counter::operator+(int num) const {
  int newVal = value_ + num;
  // Ajustamos al rango
  if (newVal > max_)
    newVal = max_;
  if (newVal < min_)
    newVal = min_;
  return Counter(newVal, min_, max_);
}

//(Counter - int)
Counter Counter::operator-(int num) const {
  int newVal = value_ - num;
  // Ajustamos al rango
  if (newVal > max_)
    newVal = max_;
  if (newVal < min_)
    newVal = min_;
  return Counter(newVal, min_, max_);
}

//(int + Counter)
Counter operator+(int num, const Counter &c) {
  int newVal = num + c.value_;
  if (newVal > c.max_)
    newVal = c.max_;
  if (newVal < c.min_)
    newVal = c.min_;
  return Counter(newVal, c.min_, c.max_);
}

//(int - Counter)
Counter operator-(int num, const Counter &c) {
  int newVal = num - c.value_;
  if (newVal > c.max_)
    newVal = c.max_;
  if (newVal < c.min_)
    newVal = c.min_;
  return Counter(newVal, c.min_, c.max_);
}

// Insertador (Salida)
std::ostream &operator<<(std::ostream &os, const Counter &c) {
  os << c.value_;
  return os;
}

// Extractor (Entrada)
std::istream &operator>>(std::istream &is, Counter &c) {
  int val;
  int i = 0;
  while (i == 0) {
    if (is >> val) {
      if (val >= c.min_ && val <= c.max_) {
        c.value_ = val;
        i = 1;
      } else {
        std::cout << "Valor fuera de rango. Debe estar entre " << c.min_
                  << " y " << c.max_ << ". Introduzca de nuevo: ";
      }
    } else {
      // Error de lectura (no es un entero), salimos
      i = 1;
    }
  }
  return is;
}
