#include "game/classicarrownote.h"
#include "classicmode/context.h"
#include "graphics/classicgraphicsmanager.h"

ClassicArrowNote::ClassicArrowNote(Init&& init) :
    ClassicNote(init.perfect_offset, init.id),
    _evaluator(init.intervals, init.perfect_offset),
    _context(init.context),
    _is_holding(init.is_holding)
{
   _elements.resize(init.elements.size());

   for (std::size_t i = 0; i < _elements.size(); ++i)
   {
       _elements[i].keys = init.elements[i].keys;
       _elements[i].position = init.elements[i].position;
       _elements[i].type = init.elements[i].type;
   }
}

bool ClassicArrowNote::isActive(const kku::microsec& offset) const
{
    return _evaluator.isActive(offset)
        && _state != State::DYING;
}

void ClassicArrowNote::update(const kku::microsec &music_offset)
{
    _context->update(this, music_offset);
}

void ClassicArrowNote::input(kku::GameEvent&& input)
{
    _context->input(this, std::move(input));
}

void ClassicArrowNote::draw(const std::shared_ptr<const ClassicGraphicsManager>& graphics_manager) const
{
    graphics_manager->draw(_elements);
}

bool ClassicArrowNote::isHold() const
{
    return _is_holding;
}

std::vector<ArrowElement>& ClassicArrowNote::getElements()
{
    return _elements;
}

auto ClassicArrowNote::calculatePrecision(const kku::microsec& offset) const -> Grade
{
    return _evaluator.calculatePrecision(offset);
}

bool ClassicArrowNote::isPressedAs(kku::SystemEvent::Key::Code key) const
{
    return std::any_of(_elements.begin(), _elements.end(),
           [key](const auto& element)
           {
              return key == element.pressed_as;
           });
}
