#include "histogram.h"
#include <cmath>
#include <algorithm>
#include <QPainter>
#include <QDebug>
#include <QStyleOption>

Histogram::Histogram(QWidget *parent) : QWidget(parent)
{
    setStyleSheet("QWidget { background: white; color: black; } ");
}

void Histogram::imageLoaded(Image *img)
{
    if(img && img->rawImage())
    {
        m_histogram = img->rawImage()->imageStats().m_histogram;
        m_points.clear();
        update();
    }
}

void Histogram::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.fillRect(rect(), Qt::black);

    uint h = height();
    uint w = width();

    if(m_histogram.size())
    {
        if(m_points.size() != w)
        {
            m_points.clear();
            for(uint64_t i = 0; i < w; i++)
            {
                uint32_t sum = 0;
                uint64_t start = i * m_histogram.size() / w;
                uint64_t end =(i+1) * m_histogram.size() / w;
                for(uint64_t o = start; o < end; o++)
                    sum += m_histogram[o];
                if(start != end)
                    m_points.push_back(sum);
            }
            float scale = *std::max_element(m_points.begin(), m_points.end());
            if(m_log)
            {
                scale = std::log(scale);
                std::for_each(m_points.begin(), m_points.end(), [scale](float &x){ x = (x > 0 ? std::log(x) : 0.0f) / scale; });
            }
            else
            {
                std::for_each(m_points.begin(), m_points.end(), [scale](float &x){ x /= scale; });
            }
        }
        std::vector<QPointF> points;
        points.push_back(QPointF(0, h));
        for(size_t i = 0; i < m_points.size(); i++)
        {
            points.push_back(QPointF((float)i * w / m_points.size(), h - m_points[i] * h));
        }
        points.push_back(QPoint(w, h));
        painter.setBrush(Qt::gray);
        painter.setPen(Qt::white);

        painter.drawPolygon(&points[0], points.size());
    }

    QStyleOptionButton button;
    button.initFrom(this);
    button.state = m_log ? QStyle::State_On : QStyle::State_Off;
    button.text = tr("Logarithmic scale");
    button.rect = style()->subElementRect(QStyle::SE_CheckBoxClickRect, &button, this);
    button.rect.moveTop(0);
    button.rect.moveRight(w);
    style()->drawControl(QStyle::CE_CheckBox, &button, &painter, this);
}

void Histogram::mouseReleaseEvent(QMouseEvent *)
{
    m_log = !m_log;
    m_points.clear();
    update();
}
