#include <QWidget>
#include <QPainter>
#include <QSignalMapper>
#include <QMouseEvent>
#include "ColorWheel.h"


// Values from this come up the same as doing:   QColor::fromHsvF(hue, sat, 1.0).rgba()
extern uint32_t rgbFromHsvF(qreal h1, qreal s, qreal v, qreal /*a*/);
extern bool m_wheelCached;
extern QImage colorWheelCache;
extern void makeColorWheel(int siz, unsigned bgColor);


static const int siz = 250;
static const int cen = (siz / 2);
static const int rad = (siz / 2) - 20;

static const int dotSiz = 18;// 16;
static const int dotAlpha = 96;// 64;

static const float twoPi = 2 * acos(-1);

// static const int wheelWidth = siz * 2;// 600;


// Properties of a scheme:
//   mode (3-bits), primary hue (8-bits), angle / hue-delta (8-bits)
//   saturation (8-bits), stretch (5-bits)
ColorWheel::ColorWheel(QWidget* parent) : QWidget(parent)
{
    m_palette.m_mode = 0;
    m_palette.m_primaryHue = 0;
    m_palette.m_secondaryHueDelta = 10;
    m_palette.m_saturation = 0;
    m_palette.m_stretch = 0;
    m_hueMovingIdx = -1;
}


void ColorWheel::setMode(int a_mode)
{
    m_palette.m_mode = a_mode;
    update();
}


void ColorWheel::mousePressEvent(QMouseEvent* me)
{
    int closestIdx = -1;
    int closestDist = 1000000;
    //for (int h = m_palette.hueCount() - 1; h >= 0; h--)
    for (int h = 0; h < m_palette.hueCount(); h++)
    {
        int x = cen + (rad - dotSiz - 5) * ::cos(m_palette.hue(h) * twoPi);
        int y = cen + (rad - dotSiz - 5) * ::sin(m_palette.hue(h) * twoPi);

        int dx = me->pos().x() - x;
        int dy = me->pos().y() - y;

        int distSqr = dx*dx + dy*dy;
        if (distSqr < closestDist)
        {
          closestDist = distSqr;
          closestIdx = h;
        }
    }

    m_hueMovingIdx = closestIdx;

    if (m_hueMovingIdx != -1)
    {
        int x = me->pos().x() - (cen);
        int y = me->pos().y() - (cen);
        m_palette.setHue(m_hueMovingIdx, ::atan2(y, x) / twoPi);
        paletteChanged();
        update();
    }
}


void ColorWheel::mouseReleaseEvent(QMouseEvent*)
{
    m_hueMovingIdx = -1;
}


void ColorWheel::mouseMoveEvent(QMouseEvent* me)
{
    if (m_hueMovingIdx != -1)
    {
        int x = me->pos().x() - (cen);
        int y = me->pos().y() - (cen);
        m_palette.setHue(m_hueMovingIdx, ::atan2(y, x) / twoPi);
        paletteChanged();
        update();
    }
}


void ColorWheel::paintEvent(QPaintEvent*)
{
    QPainter p(this);

    if (!m_wheelCached)
        makeColorWheel(siz, 0);

    p.drawImage(0, 0, colorWheelCache);

    for (int h = 0; h < m_palette.hueCount(); h++)
    {
        int x = cen + (rad /*- dotSiz */ - 15 - 5) * ::cos(m_palette.hue(h) * twoPi);
        int y = cen + (rad /*- dotSiz */ - 15 - 5) * ::sin(m_palette.hue(h) * twoPi);
        if (h == 0) {
            p.setPen(QPen(QColor(255, 255, 255, dotAlpha + 20), 2));
            p.setBrush(QColor(192, 192, 192, dotAlpha + 20));
        }
        else {
            p.setPen(QPen(QColor(0, 0, 0, dotAlpha - 10), 2));
            p.setBrush(QColor(0, 0, 0, dotAlpha - 10));
        }
        p.drawEllipse(x - dotSiz / 2, y - dotSiz / 2, dotSiz, dotSiz);
    }
}


