#include <QDebug>
#include <QMouseEvent>
#include <QPainter>
#include <QScrollBar>

#include <cmath>

#include "glyphsview.h"

static const int COLUMNS_COUNT = 100;

GlyphsView::GlyphsView(QWidget *parent) : QAbstractScrollArea(parent)
{
    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
    setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
}

void GlyphsView::setFontInfo(const FontInfo &fi)
{
    m_fontInfo = fi;
    m_glyphs.resize(fi.numberOfGlyphs);
#ifdef WITH_FREETYPE
    m_ftGlyphs.resize(fi.numberOfGlyphs);
#endif
#ifdef WITH_HARFBUZZ
    m_hbGlyphs.resize(fi.numberOfGlyphs);
#endif

    m_indexes.clear();
    for (int i = 0; i < fi.numberOfGlyphs; ++i) {
        QStaticText text(QString::number(i));
        text.prepare();
        m_indexes << text;
    }

    updateScrollBars();
    horizontalScrollBar()->setValue(0);
    verticalScrollBar()->setValue(0);
}

void GlyphsView::setGlyph(int idx, const Glyph &glyph)
{
    m_glyphs.replace(idx, glyph);
}

#ifdef WITH_FREETYPE
void GlyphsView::setFTGlyph(int idx, const Glyph &glyph)
{
    m_ftGlyphs.replace(idx, glyph);
}
#endif

#ifdef WITH_HARFBUZZ
void GlyphsView::setHBGlyph(int idx, const Glyph &glyph)
{
    m_hbGlyphs.replace(idx, glyph);
}
#endif

void GlyphsView::setDrawBboxes(const bool flag)
{
    m_drawBboxes = flag;
    viewport()->update();
}

void GlyphsView::setDrawGlyphs(const bool flag)
{
    m_drawGlyphs = flag;
    viewport()->update();
}

void GlyphsView::setDrawFTGlyphs(const bool flag)
{
    m_drawFTGlyphs = flag;
    viewport()->update();
}

void GlyphsView::setDrawHBGlyphs(const bool flag)
{
    m_drawHBGlyphs = flag;
    viewport()->update();
}

void GlyphsView::paintEvent(QPaintEvent *)
{
    QPainter p(viewport());
    p.translate(-horizontalScrollBar()->value(), -verticalScrollBar()->value());

    const double cellHeight = m_fontInfo.height * m_scale;
    drawGrid(p, cellHeight);

    p.setRenderHint(QPainter::Antialiasing);

    {
        auto font = p.font();
        font.setPointSize(10);
        p.setFont(font);
    }

    int x = 0;
    int y = m_fontInfo.ascender;
    int num_y = m_fontInfo.height;
    for (int i = 0; i < m_glyphs.size(); ++i) {
        // Text rendering is the slowest part, so we are using preprocessed text.
        p.setPen(palette().color(QPalette::Text));
        p.drawStaticText(
            qRound(x * m_scale + 1),
            qRound(num_y * m_scale - p.fontMetrics().ascent() - 2),
            m_indexes.at(i)
        );

        if (m_drawGlyphs) {
            p.save();

            const int dx = qRound((m_fontInfo.height - m_glyphs.at(i).bbox.width()) / 2.0)
                - m_glyphs.at(i).bbox.x();

            p.scale(m_scale, m_scale);
            p.translate(x + dx, y);

            if (m_drawBboxes) {
                p.setPen(QPen(Qt::darkGreen, 0.5 / m_scale));
                p.setBrush(Qt::NoBrush);
                p.drawRect(m_glyphs.at(i).bbox);
            }

            p.setPen(Qt::NoPen);
            p.setPen(Qt::NoPen);
            if (m_drawFTGlyphs || m_drawHBGlyphs) {
                p.setBrush(Qt::red);
            } else {
                p.setBrush(palette().color(QPalette::Text));
            }

            p.drawPath(m_glyphs.at(i).outline);

            p.restore();
        }

#ifdef WITH_HARFBUZZ
        if (m_drawHBGlyphs) {
            p.save();

            const int dx = qRound((m_fontInfo.height - m_hbGlyphs.at(i).bbox.width()) / 2.0)
                - m_hbGlyphs.at(i).bbox.x();

            p.scale(m_scale, m_scale);
            p.translate(x + dx, y);

            if (m_drawBboxes) {
                p.setPen(QPen(Qt::darkGreen, 0.5 / m_scale));
                p.setBrush(Qt::NoBrush);
                p.drawRect(m_hbGlyphs.at(i).bbox);
            }

            p.setPen(Qt::NoPen);
            if (m_drawFTGlyphs) {
                p.setBrush(Qt::blue);
            } else {
                p.setBrush(palette().color(QPalette::Text));
            }

            p.drawPath(m_hbGlyphs.at(i).outline);

            p.restore();
        }
#endif

#ifdef WITH_FREETYPE
        if (m_drawFTGlyphs) {
            p.save();

            const int dx = qRound((m_fontInfo.height - m_ftGlyphs.at(i).bbox.width()) / 2.0)
                - m_ftGlyphs.at(i).bbox.x();

            p.scale(m_scale, m_scale);
            p.translate(x + dx, y);

            if (m_drawBboxes) {
                p.setPen(QPen(Qt::darkGreen, 0.5 / m_scale));
                p.setBrush(Qt::NoBrush);
                p.drawRect(m_ftGlyphs.at(i).bbox);
            }

            p.setPen(Qt::NoPen);
            p.setBrush(palette().color(QPalette::Text));

            if (m_drawGlyphs || m_drawHBGlyphs) {
                p.setBrush(palette().color(QPalette::Base));
            }

            p.drawPath(m_ftGlyphs.at(i).outline);

            p.restore();
        }
#endif

        x += m_fontInfo.height;
        if (i > 0 && (i + 1) % COLUMNS_COUNT == 0) {
            x = 0;
            y += m_fontInfo.height;
            num_y += m_fontInfo.height;
        }
    }
}

void GlyphsView::drawGrid(QPainter &p, const double cellHeight)
{
    p.setRenderHint(QPainter::Antialiasing, false);
    p.setPen(QPen(palette().color(QPalette::Text), 0.25));
    p.setBrush(Qt::NoBrush);

    const int rows = qRound(floor(m_glyphs.size() / COLUMNS_COUNT)) + 1;
    const auto maxH = qMin(rows * cellHeight, (double)horizontalScrollBar()->maximum());

    double x = cellHeight;
    for (int c = 1; c < COLUMNS_COUNT; ++c) {
        p.drawLine(QLineF(x, 0, x, maxH));
        x += cellHeight;
    }

    double y = cellHeight;
    for (int r = 1; r <= rows; ++r) {
        p.drawLine(QLineF(0, y, horizontalScrollBar()->maximum() + viewport()->width(), y));
        y += cellHeight;
    }
}

void GlyphsView::mousePressEvent(QMouseEvent *e)
{
    if (e->button() & Qt::LeftButton) {
        m_mousePressPos = e->pos();
        m_origOffset = QPoint(horizontalScrollBar()->value(), verticalScrollBar()->value());
    }
}

void GlyphsView::mouseMoveEvent(QMouseEvent *e)
{
    if (m_mousePressPos.isNull()) {
        return;
    }

    const auto diff = m_mousePressPos - e->pos();
    horizontalScrollBar()->setValue(m_origOffset.x() + diff.x());
    verticalScrollBar()->setValue(m_origOffset.y() + diff.y());
}

void GlyphsView::mouseReleaseEvent(QMouseEvent *)
{
    m_mousePressPos = QPoint();
    m_origOffset = QPoint();
}

void GlyphsView::wheelEvent(QWheelEvent *e)
{
    e->accept();

    if (e->delta() > 0) {
        m_scale += 0.01;
    } else {
        m_scale -= 0.01;
    }

    m_scale = qBound(0.03, m_scale, 1.0);

    updateScrollBars();
    viewport()->update();
}

void GlyphsView::resizeEvent(QResizeEvent *e)
{
    QAbstractScrollArea::resizeEvent(e);
    updateScrollBars();
}

void GlyphsView::updateScrollBars()
{
    const double cellHeight = m_fontInfo.height * m_scale;
    const int rows = qRound(floor(m_glyphs.size() / COLUMNS_COUNT)) + 1;
    const auto w = COLUMNS_COUNT * cellHeight - viewport()->width();
    const auto h = rows * cellHeight - viewport()->height();
    horizontalScrollBar()->setMinimum(0);
    verticalScrollBar()->setMinimum(0);
    horizontalScrollBar()->setMaximum(qMax(0, qRound(w)));
    verticalScrollBar()->setMaximum(qMax(0, qRound(h)));
}
