/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qtcolorline.h"
#include "qdrawutil.h"

#include <QtGui/QPainter>
#include <QtGui/QPaintEvent>
#include <QtWidgets/QStyleOption>
#include <QtGui/QRegion>

QT_BEGIN_NAMESPACE

class QtColorLinePrivate
{
    QtColorLine *q_ptr;
    Q_DECLARE_PUBLIC(QtColorLine)
public:
    QtColorLinePrivate();

    QColor color() const;
    void setColor(const QColor &color);

    QtColorLine::ColorComponent colorComponent() const;
    void setColorComponent(QtColorLine::ColorComponent component);

    void setIndicatorSize(int size);
    int indicatorSize() const;

    void setIndicatorSpace(int space);
    int indicatorSpace() const;

    void setFlip(bool flip);
    bool flip() const;

    void setBackgroundCheckered(bool checkered);
    bool isBackgroundCheckered() const;

    void setOrientation(Qt::Orientation orientation);
    Qt::Orientation orientation() const;

    void resizeEvent(QResizeEvent *event);
    void paintEvent(QPaintEvent *event);
    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);
    void mouseDoubleClickEvent(QMouseEvent *event);
private:
    void checkColor();
    bool isMainPixmapValid() const;
    void validate();
    void recreateMainPixmap();
    QSize pixmapSizeFromGeometrySize(const QSize &geometrySize) const;
    QPixmap gradientPixmap(int size, Qt::Orientation orientation, const QColor &begin, const QColor &end, bool flipped = false) const;
    QPixmap gradientPixmap(Qt::Orientation orientation, const QColor &begin, const QColor &end, bool flipped = false) const;
    QPixmap hueGradientPixmap(int size, Qt::Orientation orientation, bool flipped = false,
                int saturation = 0xFF, int value = 0xFF, int alpha = 0xFF) const;
    QPixmap hueGradientPixmap(Qt::Orientation orientation, bool flipped = false,
                int saturation = 0xFF, int value = 0xFF, int alpha = 0xFF) const;

    QVector<QRect> rects(const QPointF &point) const;

    QColor colorFromPoint(const QPointF &point) const;
    QPointF pointFromColor(const QColor &color) const;

    QColor m_color;
    QtColorLine::ColorComponent m_component;
    bool m_flipped;
    bool m_backgroundCheckered;
    Qt::Orientation m_orientation;
    bool m_dragging;
    bool m_combiningAlpha;
    int m_indicatorSize;
    int m_indicatorSpace;
    QPointF m_point;
    QPoint m_clickOffset;

    QPixmap m_mainPixmap;
    QPixmap m_alphalessPixmap;
    QPixmap m_semiAlphaPixmap;
    QSize m_pixmapSize;

    struct PixData {
        QSize size;
        QColor color;
        QtColorLine::ColorComponent component;
        bool flipped;
        Qt::Orientation orientation;
    };

    PixData m_lastValidMainPixmapData;
};

QtColorLinePrivate::QtColorLinePrivate()
    : m_color(Qt::black), m_component(QtColorLine::Value),
        m_flipped(false), m_backgroundCheckered(true), m_orientation(Qt::Horizontal), m_dragging(false), m_combiningAlpha(false)
{
    m_indicatorSize = 22;
    m_indicatorSpace = 0;
    m_pixmapSize = QSize(0, 0);
    m_point = pointFromColor(m_color);
}

void QtColorLinePrivate::setColor(const QColor &color)
{
    if (m_color == color)
        return;
    if (!color.isValid())
        return;
    if (m_dragging) // Warning perhaps here, recursive call
        return;
    m_color = color;
    checkColor();
    m_point = pointFromColor(m_color);
    q_ptr->update();
}

QColor QtColorLinePrivate::color() const
{
    return m_color;
}

void QtColorLinePrivate::setColorComponent(QtColorLine::ColorComponent component)
{
    if (m_component == component)
        return;
    if (m_dragging) // Warning perhaps here, recursive call
        return;
    m_component = component;
    checkColor();
    m_point = pointFromColor(m_color);
    q_ptr->update();
}

QtColorLine::ColorComponent QtColorLinePrivate::colorComponent() const
{
    return m_component;
}

void QtColorLinePrivate::setIndicatorSize(int size)
{
    if (size <= 0)
        return;
    if (m_dragging) // Warning perhaps here, recursive call
        return;
    if (m_indicatorSize == size)
        return;
    m_indicatorSize = size;
    m_pixmapSize = pixmapSizeFromGeometrySize(q_ptr->contentsRect().size());
    q_ptr->update();
    q_ptr->updateGeometry();
}

int QtColorLinePrivate::indicatorSize() const
{
    return m_indicatorSize;
}

void QtColorLinePrivate::setIndicatorSpace(int space)
{
    if (space < 0)
        return;
    if (m_dragging) // Warning perhaps here, recursive call
        return;
    if (m_indicatorSpace == space)
        return;
    m_indicatorSpace = space;
    m_pixmapSize = pixmapSizeFromGeometrySize(q_ptr->contentsRect().size());
    q_ptr->update();
}

int QtColorLinePrivate::indicatorSpace() const
{
    return m_indicatorSpace;
}

void QtColorLinePrivate::setFlip(bool flip)
{
    if (m_dragging) // Warning perhaps here, recursive call
        return;
    if (m_flipped == flip)
        return;
    m_flipped = flip;
    m_point = pointFromColor(m_color);
    q_ptr->update();
}

bool QtColorLinePrivate::flip() const
{
    return m_flipped;
}

void QtColorLinePrivate::setBackgroundCheckered(bool checkered)
{
    if (m_backgroundCheckered == checkered)
        return;
    m_backgroundCheckered = checkered;
    q_ptr->update();
}

bool QtColorLinePrivate::isBackgroundCheckered() const
{
    return m_backgroundCheckered;
}

void QtColorLinePrivate::setOrientation(Qt::Orientation orientation)
{
    if (m_dragging) // Warning perhaps here, recursive call
        return;
    if (m_orientation == orientation)
        return;

    m_orientation = orientation;
    if (!q_ptr->testAttribute(Qt::WA_WState_OwnSizePolicy)) {
        QSizePolicy sp = q_ptr->sizePolicy();
        sp.transpose();
        q_ptr->setSizePolicy(sp);
        q_ptr->setAttribute(Qt::WA_WState_OwnSizePolicy, false);
    }
    m_point = pointFromColor(m_color);
    q_ptr->update();
    q_ptr->updateGeometry();
}

Qt::Orientation QtColorLinePrivate::orientation() const
{
    return m_orientation;
}

void QtColorLinePrivate::checkColor()
{
    switch (m_component) {
        case QtColorLine::Red:
        case QtColorLine::Green:
        case QtColorLine::Blue:
            if (m_color.spec() != QColor::Rgb)
                m_color = m_color.toRgb();
            break;
        case QtColorLine::Hue:
        case QtColorLine::Saturation:
        case QtColorLine::Value:
            if (m_color.spec() != QColor::Hsv)
                m_color = m_color.toHsv();
            break;
        default:
            break;
    }
    if (m_color.spec() == QColor::Hsv) {
        if (m_color.hue() == 360 || m_color.hue() == -1) {
            m_color.setHsvF(0.0, m_color.saturationF(), m_color.valueF(), m_color.alphaF());
        }
    }
}

bool QtColorLinePrivate::isMainPixmapValid() const
{
    if (m_mainPixmap.isNull()) {
        if (m_pixmapSize.isEmpty())
            return true;
        else
            return false;
    }
    if (m_lastValidMainPixmapData.component != m_component)
        return false;
    if (m_lastValidMainPixmapData.size != m_pixmapSize)
        return false;
    if (m_lastValidMainPixmapData.flipped != m_flipped)
        return false;
    if (m_lastValidMainPixmapData.orientation != m_orientation)
        return false;
    if (m_lastValidMainPixmapData.color == m_color)
        return true;
    switch (m_component) {
        case QtColorLine::Red:
            if (m_color.green() == m_lastValidMainPixmapData.color.green() &&
                m_color.blue() == m_lastValidMainPixmapData.color.blue() &&
                (!m_combiningAlpha || m_color.alpha() == m_lastValidMainPixmapData.color.alpha()))
                return true;
            break;
        case QtColorLine::Green:
            if (m_color.red() == m_lastValidMainPixmapData.color.red() &&
                m_color.blue() == m_lastValidMainPixmapData.color.blue() &&
                (!m_combiningAlpha || m_color.alpha() == m_lastValidMainPixmapData.color.alpha()))
                return true;
            break;
        case QtColorLine::Blue:
            if (m_color.red() == m_lastValidMainPixmapData.color.red() &&
                m_color.green() == m_lastValidMainPixmapData.color.green() &&
                (!m_combiningAlpha || m_color.alpha() == m_lastValidMainPixmapData.color.alpha()))
                return true;
            break;
        case QtColorLine::Hue:
            if (m_color.saturation() == m_lastValidMainPixmapData.color.saturation() &&
                m_color.value() == m_lastValidMainPixmapData.color.value() &&
                (!m_combiningAlpha || m_color.alpha() == m_lastValidMainPixmapData.color.alpha()))
                return true;
            break;
        case QtColorLine::Saturation:
            if (m_color.hue() == m_lastValidMainPixmapData.color.hue() &&
                m_color.value() == m_lastValidMainPixmapData.color.value() &&
                (!m_combiningAlpha || m_color.alpha() == m_lastValidMainPixmapData.color.alpha()))
                return true;
            break;
        case QtColorLine::Value:
            if (m_color.hue() == m_lastValidMainPixmapData.color.hue() &&
                m_color.saturation() == m_lastValidMainPixmapData.color.saturation() &&
                (!m_combiningAlpha || m_color.alpha() == m_lastValidMainPixmapData.color.alpha()))
                return true;
            break;
        case QtColorLine::Alpha:
            if (m_color.hue() == m_lastValidMainPixmapData.color.hue() &&
                m_color.saturation() == m_lastValidMainPixmapData.color.saturation() &&
                m_color.value() == m_lastValidMainPixmapData.color.value())
                return true;
    }
    return false;
}

void QtColorLinePrivate::validate()
{
    if (isMainPixmapValid())
        return;

    recreateMainPixmap();
}

QPixmap QtColorLinePrivate::gradientPixmap(Qt::Orientation orientation, const QColor &begin, const QColor &end, bool flipped) const
{
    int size = m_pixmapSize.width();
    if (orientation == Qt::Vertical)
        size = m_pixmapSize.height();
    return gradientPixmap(size, orientation, begin, end, flipped);
}

QPixmap QtColorLinePrivate::gradientPixmap(int size, Qt::Orientation orientation,
            const QColor &begin, const QColor &end, bool flipped) const
{
    int gradW = size;
    int gradH = size;
    int w = size;
    int h = size;
    if (orientation == Qt::Horizontal) {
        gradH = 0;
        h = 1;
    } else {
        gradW = 0;
        w = 1;
    }
    QColor c1 = begin;
    QColor c2 = end;
    if (flipped) {
        c1 = end;
        c2 = begin;
    }
    QLinearGradient lg(0, 0, gradW, gradH);
    lg.setColorAt(0, c1);
    lg.setColorAt(1, c2);
    QImage img(w, h, QImage::Format_ARGB32);
    QPainter p(&img);
    p.setCompositionMode(QPainter::CompositionMode_Source);
    p.fillRect(QRect(0, 0, w, h), lg);
    return QPixmap::fromImage(img);
}

QPixmap QtColorLinePrivate::hueGradientPixmap(Qt::Orientation orientation, bool flipped,
                int saturation, int value, int alpha) const
{
    int size = m_pixmapSize.width();
    if (orientation == Qt::Vertical)
        size = m_pixmapSize.height();
    return hueGradientPixmap(size, orientation, flipped, saturation, value, alpha);
}

QPixmap QtColorLinePrivate::hueGradientPixmap(int size, Qt::Orientation orientation, bool flipped,
                int saturation, int value, int alpha) const
{
    int gradW = size + 1;
    int gradH = size + 1;
    int w = size;
    int h = size;
    if (orientation == Qt::Horizontal) {
        gradH = 0;
        h = 1;
    } else {
        gradW = 0;
        w = 1;
    }
    QList<QColor> colorList;
    colorList << QColor::fromHsv(0, saturation, value, alpha);
    colorList << QColor::fromHsv(60, saturation, value, alpha);
    colorList << QColor::fromHsv(120, saturation, value, alpha);
    colorList << QColor::fromHsv(180, saturation, value, alpha);
    colorList << QColor::fromHsv(240, saturation, value, alpha);
    colorList << QColor::fromHsv(300, saturation, value, alpha);
    colorList << QColor::fromHsv(0, saturation, value, alpha);
    QLinearGradient lg(0, 0, gradW, gradH);
    for (int i = 0; i <= 6; i++)
        lg.setColorAt(double(i) / 6.0, flipped ? colorList.at(6 - i) : colorList.at(i));
    QImage img(w, h, QImage::Format_ARGB32);
    QPainter p(&img);
    p.setCompositionMode(QPainter::CompositionMode_Source);
    p.fillRect(QRect(0, 0, w, h), lg);
    return QPixmap::fromImage(img);
}

void QtColorLinePrivate::recreateMainPixmap()
{
    m_lastValidMainPixmapData.size = m_pixmapSize;
    m_lastValidMainPixmapData.component = m_component;
    m_lastValidMainPixmapData.color = m_color;
    m_lastValidMainPixmapData.flipped = m_flipped;
    m_lastValidMainPixmapData.orientation = m_orientation;

    if (m_pixmapSize.isEmpty()) {
        m_mainPixmap = QPixmap();
        m_alphalessPixmap = QPixmap();
        m_semiAlphaPixmap = QPixmap();
        return;
    }

    if (m_mainPixmap.size() != m_pixmapSize) {
        m_mainPixmap = QPixmap(m_pixmapSize);
        m_alphalessPixmap = QPixmap(m_pixmapSize);
        m_semiAlphaPixmap = QPixmap(m_pixmapSize);
    }

    Qt::Orientation orient = m_orientation;
    const bool flip = m_flipped;

    const int r = m_color.red();
    const int g = m_color.green();
    const int b = m_color.blue();
    const int h = m_color.hue();
    const int s = m_color.saturation();
    const int v = m_color.value();
    const int a = m_color.alpha();
    const double coef = 0.5;
    const int semi = qRound(a * coef + 0xFF * (1.0 - coef));

    if (m_component == QtColorLine::Hue) {
        m_alphalessPixmap = hueGradientPixmap(orient, flip, s, v, 0xFF);
        if (m_combiningAlpha) {
            m_mainPixmap = hueGradientPixmap(orient, flip, s, v, a);
            m_semiAlphaPixmap = hueGradientPixmap(orient, flip, s, v, semi);
        }
    } else if (m_component == QtColorLine::Saturation) {
        m_alphalessPixmap = gradientPixmap(orient, QColor::fromHsv(h, 0, v, 0xFF), QColor::fromHsv(h, 0xFF, v, 0xFF), flip);
        if (m_combiningAlpha) {
            m_mainPixmap = gradientPixmap(orient, QColor::fromHsv(h, 0, v, a), QColor::fromHsv(h, 0xFF, v, a), flip);
            m_semiAlphaPixmap = gradientPixmap(orient, QColor::fromHsv(h, 0, v, semi), QColor::fromHsv(h, 0xFF, v, semi), flip);
        }
    } else if (m_component == QtColorLine::Value) {
        m_alphalessPixmap = gradientPixmap(orient, QColor::fromRgb(0, 0, 0, 0xFF), QColor::fromHsv(h, s, 0xFF, 0xFF), flip);
        if (m_combiningAlpha) {
            m_mainPixmap = gradientPixmap(orient, QColor::fromRgb(0, 0, 0, a), QColor::fromHsv(h, s, 0xFF, a), flip);
            m_semiAlphaPixmap = gradientPixmap(orient, QColor::fromRgb(0, 0, 0, semi), QColor::fromHsv(h, s, 0xFF, semi), flip);
        }
    } else if (m_component == QtColorLine::Red) {
        m_alphalessPixmap = gradientPixmap(orient, QColor::fromRgb(0, g, b, 0xFF), QColor::fromRgb(0xFF, g, b, 0xFF), flip);
        if (m_combiningAlpha) {
            m_mainPixmap = gradientPixmap(orient, QColor::fromRgb(0, g, b, a), QColor::fromRgb(0xFF, g, b, a), flip);
            m_semiAlphaPixmap = gradientPixmap(orient, QColor::fromRgb(0, g, b, semi), QColor::fromRgb(0xFF, g, b, semi), flip);
        }
    } else if (m_component == QtColorLine::Green) {
        m_alphalessPixmap = gradientPixmap(orient, QColor::fromRgb(r, 0, b, 0xFF), QColor::fromRgb(r, 0xFF, b, 0xFF), flip);
        if (m_combiningAlpha) {
            m_mainPixmap = gradientPixmap(orient, QColor::fromRgb(r, 0, b, a), QColor::fromRgb(r, 0xFF, b, a), flip);
            m_semiAlphaPixmap = gradientPixmap(orient, QColor::fromRgb(r, 0, b, semi), QColor::fromRgb(r, 0xFF, b, semi), flip);
        }
    } else if (m_component == QtColorLine::Blue) {
        m_alphalessPixmap = gradientPixmap(orient, QColor::fromRgb(r, g, 0, 0xFF), QColor::fromRgb(r, g, 0xFF, 0xFF), flip);
        if (m_combiningAlpha) {
            m_mainPixmap = gradientPixmap(orient, QColor::fromRgb(r, g, 0, a), QColor::fromRgb(r, g, 0xFF, a), flip);
            m_semiAlphaPixmap = gradientPixmap(orient, QColor::fromRgb(r, g, 0, semi), QColor::fromRgb(r, g, 0xFF, semi), flip);
        }
    } else if (m_component == QtColorLine::Alpha) {
        m_mainPixmap = gradientPixmap(orient, QColor::fromRgb(r, g, b, 0), QColor::fromRgb(r, g, b, 0xFF), flip);

//        m_alphalessPixmap = gradientPixmap(orient, QColor::fromRgb(r, g, b, 0xFF), QColor::fromRgb(r, g, b, 0xFF), flip);
//        m_semiAlphaPixmap = gradientPixmap(orient, QColor::fromRgb(r, g, b, semi), QColor::fromRgb(r, g, b, semi), flip);
    }
    if (!m_combiningAlpha && m_component != QtColorLine::Alpha)
        m_mainPixmap = m_alphalessPixmap;
}

QSize QtColorLinePrivate::pixmapSizeFromGeometrySize(
        const QSize &geometrySize) const
{
    QSize size(m_indicatorSize + 2 * m_indicatorSpace - 1,
                m_indicatorSize + 2 * m_indicatorSpace - 1);
    if (m_orientation == Qt::Horizontal)
        size.setHeight(0);
    else
        size.setWidth(0);
    return geometrySize - size;
}

QColor QtColorLinePrivate::colorFromPoint(const QPointF &point) const
{
    QPointF p = point;
    if (p.x() < 0)
        p.setX(0.0);
    else if (p.x() > 1)
        p.setX(1.0);
    if (p.y() < 0)
        p.setY(0.0);
    else if (p.y() > 1)
        p.setY(1.0);

    double pos = p.x();
    if (m_orientation == Qt::Vertical)
        pos = p.y();
    if (m_flipped)
        pos = 1.0 - pos;
    QColor c;
    qreal hue;
    switch (m_component) {
        case QtColorLine::Red:
            c.setRgbF(pos, m_color.greenF(), m_color.blueF(), m_color.alphaF());
            break;
        case QtColorLine::Green:
            c.setRgbF(m_color.redF(), pos, m_color.blueF(), m_color.alphaF());
            break;
        case QtColorLine::Blue:
            c.setRgbF(m_color.redF(), m_color.greenF(), pos, m_color.alphaF());
            break;
        case QtColorLine::Hue:
            hue = pos;
            hue *= 35999.0 / 36000.0;
            c.setHsvF(hue, m_color.saturationF(), m_color.valueF(), m_color.alphaF());
            break;
        case QtColorLine::Saturation:
            c.setHsvF(m_color.hueF(), pos, m_color.valueF(), m_color.alphaF());
            break;
        case QtColorLine::Value:
            c.setHsvF(m_color.hueF(), m_color.saturationF(), pos, m_color.alphaF());
            break;
        case QtColorLine::Alpha:
            c.setHsvF(m_color.hueF(), m_color.saturationF(), m_color.valueF(), pos);
            break;
    }
    return c;
}

QPointF QtColorLinePrivate::pointFromColor(const QColor &color) const
{
    qreal hue = color.hueF();
    if (color.hue() == 360)
        hue = 0.0;
    else
        hue *= 36000.0 / 35999.0;

    double pos = 0.0;
    switch (m_component) {
        case QtColorLine::Red:
            pos = color.redF();
            break;
        case QtColorLine::Green:
            pos = color.greenF();
            break;
        case QtColorLine::Blue:
            pos = color.blueF();
            break;
        case QtColorLine::Hue:
            pos = hue;
            break;
        case QtColorLine::Saturation:
            pos = color.saturationF();
            break;
        case QtColorLine::Value:
            pos = color.valueF();
            break;
        case QtColorLine::Alpha:
            pos = color.alphaF();
            break;
    }
    if (m_flipped)
        pos = 1.0 - pos;
    QPointF p(pos, pos);
    if (m_orientation == Qt::Horizontal)
        p.setY(0);
    else
        p.setX(0);
    return p;
}

QVector<QRect> QtColorLinePrivate::rects(const QPointF &point) const
{
    QRect r = q_ptr->geometry();
    r.moveTo(0, 0);

    int x1 = (int)((r.width() - m_indicatorSize - 2 * m_indicatorSpace) * point.x() + 0.5);
    int x2 = x1 + m_indicatorSize + 2 * m_indicatorSpace;
    int y1 = (int)((r.height() - m_indicatorSize - 2 * m_indicatorSpace) * point.y() + 0.5);
    int y2 = y1 + m_indicatorSize + 2 * m_indicatorSpace;

    QVector<QRect> rects;
    if (m_orientation == Qt::Horizontal) {
        // r0 r1 r2
        QRect r0(0, 0, x1, r.height());
        QRect r1(x1 + m_indicatorSpace, 0, m_indicatorSize, r.height());
        QRect r2(x2, 0, r.width() - x2, r.height());

        rects << r0 << r1 << r2;
    } else {
        // r0
        // r1
        // r2
        QRect r0(0, 0, r.width(), y1);
        QRect r1(0, y1 + m_indicatorSpace, r.width(), m_indicatorSize);
        QRect r2(0, y2, r.width(), r.height() - y2);

        rects << r0 << r1 << r2;
    }
    return rects;
}

void QtColorLinePrivate::resizeEvent(QResizeEvent *event)
{
    m_pixmapSize = pixmapSizeFromGeometrySize(event->size());
}

void QtColorLinePrivate::paintEvent(QPaintEvent *)
{
    QRect rect = q_ptr->rect();

    QVector<QRect> r = rects(m_point);

    QColor c = colorFromPoint(m_point);
    if (!m_combiningAlpha && m_component != QtColorLine::Alpha)
        c.setAlpha(0xFF);

    QPainter p(q_ptr);
    if (q_ptr->isEnabled()) {
        if (m_backgroundCheckered) {
            int pixSize = 20;
            QPixmap pm(2 * pixSize, 2 * pixSize);
            QPainter pmp(&pm);
            pmp.fillRect(0, 0, pixSize, pixSize, Qt::white);
            pmp.fillRect(pixSize, pixSize, pixSize, pixSize, Qt::white);
            pmp.fillRect(0, pixSize, pixSize, pixSize, Qt::black);
            pmp.fillRect(pixSize, 0, pixSize, pixSize, Qt::black);
            pmp.end();

            p.setBrushOrigin((rect.width() % pixSize + pixSize) / 2, (rect.height() % pixSize + pixSize) / 2);

            QRegion region(r[1].adjusted(4, 4, -4, -4));
            region += QRect(rect.topLeft(), QPoint(r[1].left() + 0, rect.bottom()));
            region += QRect(QPoint(r[1].right() - 0, rect.top()), rect.bottomRight());
            region += QRect(rect.topLeft(), QPoint(rect.right(), r[1].top() + 0));
            region += QRect(QPoint(rect.left(), r[1].bottom() - 0), rect.bottomRight());
            p.setClipRegion(region);
            p.fillRect(rect, pm);
            p.setBrushOrigin(0, 0);
            p.setClipping(false);
        }

        validate();

        QSize fieldSize = pixmapSizeFromGeometrySize(q_ptr->geometry().size());

        QPoint posOnField = r[1].topLeft() - QPoint(m_indicatorSpace, m_indicatorSpace);
        int x = posOnField.x();
        int y = posOnField.y();
        int w = fieldSize.width();
        int h = fieldSize.height();

        QRect r0, r2;
        if (m_orientation == Qt::Horizontal) {
            r0 = QRect(0, 0, x, m_pixmapSize.height());
            r2 = QRect(x + 1, 0, w - x - 1, m_pixmapSize.height());
        } else {
            r0 = QRect(0, 0, m_pixmapSize.width(), y);
            r2 = QRect(0, y + 1, m_pixmapSize.width(), h - y - 1);
        }

        p.setBrush(m_mainPixmap);
        p.setPen(Qt::NoPen);
        if (r[0].isValid()) {
            p.drawRect(r[0]);
        }
        if (r[2].isValid()) {
            p.setBrushOrigin(r[2].topLeft() - r2.topLeft());
            p.drawRect(r[2]);
        }
        if (m_indicatorSpace) {
            p.setBrush(c);
            if (m_orientation == Qt::Horizontal) {
                p.drawRect(r[1].adjusted(-m_indicatorSpace, 0, -r[1].width(), 0));
                p.drawRect(r[1].adjusted(r[1].width(), 0, m_indicatorSpace, 0));
            } else {
                p.drawRect(r[1].adjusted(0, -m_indicatorSpace, 0, -r[1].height()));
                p.drawRect(r[1].adjusted(0, r[1].height(), 0, m_indicatorSpace));
            }
        }

        QPen pen(c);
        p.setPen(pen);
        p.setBrush(Qt::NoBrush);
        if (r[1].isValid()) {
            p.drawRect(r[1].adjusted(0, 0, -1, -1));
        //    p.drawRect(r[1].adjusted(1, 1, -2, -2));
        }
        double coef = 9.0 / 10;
        p.setPen(Qt::NoPen);
        if (m_component != QtColorLine::Alpha && m_combiningAlpha) {
            p.setBrush(m_alphalessPixmap);
            if (r[0].isValid()) {
                p.setBrushOrigin(QPoint(0, 0));
                QRect thinRect1 = r[0];
                QRect thinRect2 = r[0];
                QRect thinRect = r[0];
                if (m_orientation == Qt::Horizontal) {
                    thinRect1.adjust(0, qRound(thinRect1.height() * coef), 0, 0);
                    thinRect2.adjust(0, 0, 0, -qRound(thinRect2.height() * coef));
                    thinRect.adjust(0, qRound(thinRect.height() * coef), 0, -qRound(thinRect.height() * coef));
                } else {
                    thinRect1.adjust(qRound(thinRect1.width() * coef), 0, 0, 0);
                    thinRect2.adjust(0, 0, -qRound(thinRect2.width() * coef), 0);
                    thinRect.adjust(qRound(thinRect.width() * coef), 0, -qRound(thinRect.width() * coef), 0);
                }
                p.drawRect(thinRect1);
                p.drawRect(thinRect2);
                //p.drawRect(thinRect);
            }
            if (r[2].isValid()) {
                p.setBrushOrigin(r[2].topLeft() - r2.topLeft());
                QRect thinRect1 = r[2];
                QRect thinRect2 = r[2];
                QRect thinRect = r[2];
                if (m_orientation == Qt::Horizontal) {
                    thinRect1.adjust(0, qRound(thinRect1.height() * coef), 0, 0);
                    thinRect2.adjust(0, 0, 0, -qRound(thinRect2.height() * coef));
                    thinRect.adjust(0, qRound(thinRect.height() * coef), 0, -qRound(thinRect.height() * coef));
                } else {
                    thinRect1.adjust(qRound(thinRect1.width() * coef), 0, 0, 0);
                    thinRect2.adjust(0, 0, -qRound(thinRect2.width() * coef), 0);
                    thinRect.adjust(qRound(thinRect.width() * coef), 0, -qRound(thinRect.width() * coef), 0);
                }
                p.drawRect(thinRect1);
                p.drawRect(thinRect2);
                //p.drawRect(thinRect);
            }
            /*

*/





            p.setPen(Qt::NoPen);

            p.setBrush(m_semiAlphaPixmap);
            if (r[0].isValid()) {
                p.setBrushOrigin(QPoint(0, 0));
                QRect thinRect1 = r[0];
                QRect thinRect2 = r[0];
                QRect thinRect = r[0];
                if (m_orientation == Qt::Horizontal) {
                    thinRect1.adjust(0, qRound(thinRect1.height() * coef) - 1, 0, 0);
                    thinRect1.setBottom(thinRect1.top());
                    thinRect2.adjust(0, 0, 0, -qRound(thinRect2.height() * coef) + 1);
                    thinRect2.setTop(thinRect2.bottom());
                    thinRect.adjust(0, qRound(thinRect.height() * coef), 0, -qRound(thinRect.height() * coef));
                } else {
                    thinRect1.adjust(qRound(thinRect1.width() * coef) - 1, 0, 0, 0);
                    thinRect1.setRight(thinRect1.left());
                    thinRect2.adjust(0, 0, -qRound(thinRect2.width() * coef) + 1, 0);
                    thinRect2.setLeft(thinRect2.right());
                    thinRect.adjust(qRound(thinRect.width() * coef), 0, -qRound(thinRect.width() * coef), 0);
                }
                p.drawRect(thinRect1);
                p.drawRect(thinRect2);
                //p.drawRect(thinRect);
            }
            if (r[2].isValid()) {
                p.setBrushOrigin(r[2].topLeft() - r2.topLeft());
                QRect thinRect1 = r[2];
                QRect thinRect2 = r[2];
                QRect thinRect = r[2];
                if (m_orientation == Qt::Horizontal) {
                    thinRect1.adjust(0, qRound(thinRect1.height() * coef) - 1, 0, 0);
                    thinRect1.setBottom(thinRect1.top());
                    thinRect2.adjust(0, 0, 0, -qRound(thinRect2.height() * coef) + 1);
                    thinRect2.setTop(thinRect2.bottom());
                    thinRect.adjust(0, qRound(thinRect.height() * coef), 0, -qRound(thinRect.height() * coef));
                } else {
                    thinRect1.adjust(qRound(thinRect1.width() * coef) - 1, 0, 0, 0);
                    thinRect1.setRight(thinRect1.left());
                    thinRect2.adjust(0, 0, -qRound(thinRect2.width() * coef) + 1, 0);
                    thinRect2.setLeft(thinRect2.right());
                    thinRect.adjust(qRound(thinRect.width() * coef), 0, -qRound(thinRect.width() * coef), 0);
                }
                p.drawRect(thinRect1);
                p.drawRect(thinRect2);
                //p.drawRect(thinRect);
            }
            p.setBrush(m_alphalessPixmap);
            QRegion region;
            if (m_orientation == Qt::Horizontal) {
                region += r[1].adjusted(0, qRound(r[1].height() * coef), 0, 0);
                region += r[1].adjusted(0, 0, 0, -qRound(r[1].height() * coef));
                p.setClipRegion(region);
            } else {
                region += r[1].adjusted(qRound(r[1].width() * coef), 0, 0, 0);
                region += r[1].adjusted(0, 0, -qRound(r[1].width() * coef), 0);
                p.setClipRegion(region);
            }
            p.setClipRegion(region);
            p.setBrush(Qt::NoBrush);
            p.setPen(QPen(QColor(c.rgb())));

            p.drawRect(r[1].adjusted(0, 0, -1, -1));
        //    p.drawRect(r[1].adjusted(1, 1, -2, -2));
/*
            p.setBrush(m_semiAlphaPixmap);
            if (m_orientation == Qt::Horizontal) {
                QRect top = r[1].adjusted(0, 0, 0, -qRound(r[1].height() * coef) + 1);
                top.setTop(top.bottom());
                QRect bottom = r[1].adjusted(0, qRound(r[1].height() * coef) - 1, 0, 0);
                top.setBottom(bottom.top());
                p.setClipRect(top);
                p.setClipRect(bottom, Qt::UniteClip);
            } else {

            }
            QColor semiColor(c.rgb());
            semiColor.setAlpha((c.alpha() + 0xFF) / 2);
            p.setPen(QPen(semiColor));
            p.drawRect(r[1].adjusted(0, 0, -1, -1));
        //    p.drawRect(r[1].adjusted(1, 1, -2, -2));
*/
            p.setClipping(false);
        }
    }

    p.setBrush(Qt::NoBrush);
    int lw = 4;
    //int br = 1;
    int br = 0;
    r[1].adjust(br, br, -br, -br);
    if (r[1].adjusted(lw, lw, -lw, -lw).isValid()) {
        QStyleOptionFrame opt;
        opt.init(q_ptr);
        opt.rect = r[1];
        opt.lineWidth = 2;
        opt.midLineWidth = 1;
        if (m_dragging)
            opt.state |= QStyle::State_Sunken;
        else
            opt.state |= QStyle::State_Raised;
        q_ptr->style()->drawPrimitive(QStyle::PE_Frame, &opt, &p, q_ptr);
        QRect colorRect = r[1].adjusted(lw, lw, -lw, -lw);
        if (q_ptr->isEnabled()) {
            p.fillRect(colorRect, c);
            const QColor frameColor(0, 0, 0, 38);
            p.setPen(frameColor);
            p.drawRect(colorRect.adjusted(0, 0, -1, -1));
            /*
            p.fillRect(colorRect.width() / 4 + colorRect.left(),
                       colorRect.height() / 4 + colorRect.top(),
                       colorRect.width() / 2,
                       colorRect.height() / 2,
                       QColor(c.rgb()));
            */
            /*
            if (m_component != QtColorLine::Alpha) {
                p.fillRect(colorRect.adjusted(0, colorRect.height() * 4 / 5, 0, 0), QColor(c.rgb()));
                p.fillRect(colorRect.adjusted(0, 0, 0, -colorRect.height() * 4 / 5), QColor(c.rgb()));
            }
            */
        }
    }
}

void QtColorLinePrivate::mousePressEvent(QMouseEvent *event)
{
    if (event->button() != Qt::LeftButton)
        return;

    QVector<QRect> r = rects(m_point);
    QPoint clickPos = event->pos();

    QPoint posOnField = r[1].topLeft() - QPoint(m_indicatorSpace, m_indicatorSpace);
    m_clickOffset = posOnField - clickPos;

    if (!r[1].contains(clickPos))
        return;
    m_dragging = true;
    q_ptr->update();
}

void QtColorLinePrivate::mouseMoveEvent(QMouseEvent *event)
{
    if (!m_dragging)
        return;
    QPoint newPos = event->pos();

    QSize fieldSize = q_ptr->geometry().size() -
            QSize(m_indicatorSize + 2 * m_indicatorSpace - 1, m_indicatorSize + 2 * m_indicatorSpace - 1);
    QPoint newPosOnField = newPos + m_clickOffset;
    if (newPosOnField.x() < 0)
        newPosOnField.setX(0);
    else if (newPosOnField.x() > fieldSize.width())
        newPosOnField.setX(fieldSize.width());
    if (newPosOnField.y() < 0)
        newPosOnField.setY(0);
    else if (newPosOnField.y() > fieldSize.height())
        newPosOnField.setY(fieldSize.height());

    const double x = double(newPosOnField.x()) / fieldSize.width();
    const double y = double(newPosOnField.y()) / fieldSize.height();
    m_point = QPointF(x, y);
    QColor color = colorFromPoint(m_point);
    if (m_color == color)
        return;
    m_color = color;
    emit q_ptr->colorChanged(color); // maybe before internal set, 1 line above
    q_ptr->update();
}

void QtColorLinePrivate::mouseReleaseEvent(QMouseEvent *event)
{
    if (event->button() != Qt::LeftButton)
        return;
    m_dragging = false;
    q_ptr->update();
}

void QtColorLinePrivate::mouseDoubleClickEvent(QMouseEvent *event)
{
    if (event->button() != Qt::LeftButton)
        return;

    QVector<QRect> r = rects(m_point);
    QPoint clickPos = event->pos();
    if (!r[0].contains(clickPos) && !r[2].contains(clickPos))
        return;
    QPoint newPosOnField = clickPos;
    if (r[2].contains(clickPos))
        newPosOnField -= QPoint(m_indicatorSize + 2 * m_indicatorSpace - 2, m_indicatorSize + 2 * m_indicatorSpace - 2);
    QSize fieldSize = q_ptr->geometry().size() -
            QSize(m_indicatorSize + 2 * m_indicatorSpace - 1, m_indicatorSize + 2 * m_indicatorSpace - 1);

    const double x = double(newPosOnField.x()) / fieldSize.width();
    const double y = double(newPosOnField.y()) / fieldSize.height();
    m_point = QPointF(x, y);
    QColor color = colorFromPoint(m_point);
    if (m_color == color)
        return;
    m_color = color;
    emit q_ptr->colorChanged(color); // maybe before internal set, 1 line above
    q_ptr->update();
}

////////////////////////////////////////////////////

QtColorLine::QtColorLine(QWidget *parent)
    : QWidget(parent), d_ptr(new QtColorLinePrivate)
{
    d_ptr->q_ptr = this;

    setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
}

QtColorLine::~QtColorLine()
{
}

QSize QtColorLine::minimumSizeHint() const
{
    return QSize(d_ptr->m_indicatorSize, d_ptr->m_indicatorSize);
}

QSize QtColorLine::sizeHint() const
{
    return QSize(d_ptr->m_indicatorSize, d_ptr->m_indicatorSize);
}

void QtColorLine::setColor(const QColor &color)
{
    d_ptr->setColor(color);
}

QColor QtColorLine::color() const
{
    return d_ptr->color();
}

void QtColorLine::setColorComponent(QtColorLine::ColorComponent component)
{
    d_ptr->setColorComponent(component);
}

QtColorLine::ColorComponent QtColorLine::colorComponent() const
{
    return d_ptr->colorComponent();
}

void QtColorLine::setIndicatorSize(int size)
{
    d_ptr->setIndicatorSize(size);
}

int QtColorLine::indicatorSize() const
{
    return d_ptr->indicatorSize();
}

void QtColorLine::setIndicatorSpace(int space)
{
    d_ptr->setIndicatorSpace(space);
}

int QtColorLine::indicatorSpace() const
{
    return d_ptr->indicatorSpace();
}

void QtColorLine::setFlip(bool flip)
{
    d_ptr->setFlip(flip);
}

bool QtColorLine::flip() const
{
    return d_ptr->flip();
}

void QtColorLine::setBackgroundCheckered(bool checkered)
{
    d_ptr->setBackgroundCheckered(checkered);
}

bool QtColorLine::isBackgroundCheckered() const
{
    return d_ptr->isBackgroundCheckered();
}

void QtColorLine::setOrientation(Qt::Orientation orientation)
{
    d_ptr->setOrientation(orientation);
}

Qt::Orientation QtColorLine::orientation() const
{
    return d_ptr->orientation();
}
void QtColorLine::resizeEvent(QResizeEvent *event)
{
    d_ptr->resizeEvent(event);
}

void QtColorLine::paintEvent(QPaintEvent *event)
{
    d_ptr->paintEvent(event);
}

void QtColorLine::mousePressEvent(QMouseEvent *event)
{
    d_ptr->mousePressEvent(event);
}

void QtColorLine::mouseMoveEvent(QMouseEvent *event)
{
    d_ptr->mouseMoveEvent(event);
}

void QtColorLine::mouseReleaseEvent(QMouseEvent *event)
{
    d_ptr->mouseReleaseEvent(event);
}

void QtColorLine::mouseDoubleClickEvent(QMouseEvent *event)
{
    d_ptr->mouseDoubleClickEvent(event);
}

QT_END_NAMESPACE
