#include "fvec.hpp"
#include <math.h>
#include <algorithm>
#include <hack/math/math.hpp>
#include <hack/logger/logger.hpp>

namespace hr
{
  // Конструктор: создает вектор заданного размера, заполненный значением v
  fvec_t::fvec_t(std::size_t size, base_t v) : m_data(size, v)
  {
  }

  // Возвращает текущий размер вектора
  std::size_t fvec_t::size() const
  {
    return m_data.size();
  }
  
  // Проверяет, пуст ли вектор
  bool fvec_t::empty() const
  {
    return m_data.empty();
  }

  // Добавляет элемент в конец вектора
  void fvec_t::push_back(const base_t& v)
  {
    m_data.push_back(v);
  }

  // Изменяет размер вектора, новые элементы заполняются значением el
  void fvec_t::resize(std::size_t new_size, base_t el)
  {
    m_data.resize(new_size, el);
  }

  // Резервирует необходимое пространство
  void fvec_t::reserve(std::size_t size)
  {
    m_data.reserve(size);
  }

  // Циклический сдвиг вектора: первая половина меняется местами со второй
  // Пример: [1,2,3,4,5,6] -> [4,5,6,1,2,3]
  // Для нечетных размеров: [1,2,3,4,5,6,7] -> [5,6,7,1,2,3,4]
  // Алгоритм:
  // 1. Основной сдвиг: меняем местами первую и вторую половины
  // 2. Для нечетных размеров: корректируем средний элемент
  void fvec_t::shift()
  {
    std::size_t half = size() / 2;
    std::size_t start = half;

    // Для нечетных размеров start будет на 1 больше half
    if (2 * half < size()) ++start;

    // Основной сдвиг: меняем первую половину со второй
    for (size_t i = 0; i < half; ++i) std::swap(m_data[i], m_data[i + start]);

    // Корректировка для нечетных размеров: сдвигаем средний элемент
    if (half != start) 
      for (std::size_t i = 0; i < half; ++i) 
        std::swap(m_data[i + start - 1], m_data[i + start]);
  }
}
