/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

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

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

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();
    QColor c = colorFromPoint(m_point);
    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 cBack = q_ptr->palette().color(QPalette::Active, QPalette::Window);
    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);
            p.setClipRect(r[1].adjusted(4, 4, -4, -4));
            p.setClipRect(QRect(rect.topLeft(), QPoint(r[1].left() + 0, rect.bottom())), Qt::UniteClip);
            p.setClipRect(QRect(QPoint(r[1].right() - 0, rect.top()), rect.bottomRight()), Qt::UniteClip);
            p.setClipRect(QRect(rect.topLeft(), QPoint(rect.right(), r[1].top() + 0)), Qt::UniteClip);
            p.setClipRect(QRect(QPoint(rect.left(), r[1].bottom() - 0), rect.bottomRight()), Qt::UniteClip);
            /*
            p.setClipRect(r[1].adjusted(3, 3, -3, -3));
            p.setClipRect(QRect(rect.topLeft(), QPoint(r[1].left() + 1, rect.bottom())), Qt::UniteClip);
            p.setClipRect(QRect(QPoint(r[1].right() - 1, rect.top()), rect.bottomRight()), Qt::UniteClip);
            p.setClipRect(QRect(rect.topLeft(), QPoint(rect.right(), r[1].top() + 1)), Qt::UniteClip);
            p.setClipRect(QRect(QPoint(rect.left(), r[1].bottom() - 1), rect.bottomRight()), Qt::UniteClip);
            */
            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);
            if (m_orientation == Qt::Horizontal) {
                p.setClipRect(r[1].adjusted(0, qRound(r[1].height() * coef), 0, 0));
                p.setClipRect(r[1].adjusted(0, 0, 0, -qRound(r[1].height() * coef)), Qt::UniteClip);
            } else {
                p.setClipRect(r[1].adjusted(qRound(r[1].width() * coef), 0, 0, 0));
                p.setClipRect(r[1].adjusted(0, 0, -qRound(r[1].width() * coef), 0), Qt::UniteClip);
            }
            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();

    QSize fieldSize = q_ptr->geometry().size() -
            QSize(m_indicatorSize + 2 * m_indicatorSpace - 1, m_indicatorSize + 2 * m_indicatorSpace - 1);
    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());

    double x = (double)newPosOnField.x() / fieldSize.width();
    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);

    double x = (double)newPosOnField.x() / fieldSize.width();
    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
