#include "nodeuiscene.h"
using Xybrid::UI::NodeUIScene;

#include "data/project.h"
#include "data/node.h"
using namespace Xybrid::Data;

#include "audio/audioengine.h"
using namespace Xybrid::Audio;

#include "util/keys.h"

#include "config/colorscheme.h"

#include <QDebug>

#include <QTimer>
#include <QPainter>
#include <QKeyEvent>
#include <QScrollBar>

NodeUIScene::NodeUIScene(QGraphicsView* v, const std::shared_ptr<Xybrid::Data::Node>& node) : GadgetScene(v), node(node) {
    setSceneRect(QRectF(QPointF(-9999,-9999), QPointF(9999, 9999))); // keep view anchored
    node->initUI(this);
    view->centerOn(itemsBoundingRect().center());

    connect(view->horizontalScrollBar(), &QScrollBar::valueChanged, this, &NodeUIScene::queueResize);
    connect(view->verticalScrollBar(), &QScrollBar::valueChanged, this, &NodeUIScene::queueResize);
    connect(view->horizontalScrollBar(), &QScrollBar::rangeChanged, this, &NodeUIScene::queueResize);
    connect(view->verticalScrollBar(), &QScrollBar::rangeChanged, this, &NodeUIScene::queueResize);

    autoResize();
}

NodeUIScene::~NodeUIScene() {
    //
}

void NodeUIScene::queueResize() {
    if (!resizeQueued) {
        resizeQueued = true;
        QTimer::singleShot(1, this, &NodeUIScene::autoResize);
    }
}

void NodeUIScene::autoResize() {
    resizeQueued = false;
    if (!view) return;
    if (!autoCenter) return;
    auto vrect = view->mapToScene(view->viewport()->visibleRegion().boundingRect()).boundingRect();
    auto brect = itemsBoundingRect();
    vrect.moveCenter(brect.center());
    setSceneRect(vrect);
}

void NodeUIScene::drawBackground(QPainter* p, const QRectF& rect) {
    p->fillRect(rect, Config::colorScheme.patternBg);
}

void NodeUIScene::keyPressEvent(QKeyEvent* e) {
    QGraphicsScene::keyPressEvent(e);
    if (!e->isAccepted() && !e->isAutoRepeat()) {
        auto note = Util::keyToNote(e->key());
        if (note >= 0) {
            if (e->modifiers() & Qt::Modifier::SHIFT) note += 24;
            startPreview(Util::unshiftedKey(e->key()), note);
        }
    }
}

void NodeUIScene::keyReleaseEvent(QKeyEvent* e) {
    QGraphicsScene::keyReleaseEvent(e);
    if (!e->isAccepted() && !e->isAutoRepeat()) stopPreview(Util::unshiftedKey(e->key()));
}

void NodeUIScene::startPreview(int key, int16_t note) {
    stopPreview(key); // end current preview first, if applicable
    auto p = node->project->shared_from_this();
    previewKey[key] = {audioEngine->previewPort(), audioEngine->preview(p, 0, note, 0, node.get())};

    emit notePreview(note);
}

void NodeUIScene::stopPreview(int key) {
    if (auto k = previewKey.find(key); k != previewKey.end()) {
        auto p = node->project->shared_from_this();
        //audioEngine->preview(p, k->second[0], k->second[1], false);
        audioEngine->preview(p, k->second.first, -2, k->second.second, node.get());
        previewKey.erase(k);
    }
}
