#include "colordialog.h"

ColorDialog::ColorDialog(QWidget *parent) : CustomDialog(parent)
{
    this->setFixedSize(300, 400);

    m_Layout = new QVBoxLayout(this);
    m_Layout->setSpacing(0);
    m_Layout->setContentsMargins(12, 12, 12, 28);

    m_frame = new QFrame(this);
    m_frame->setFixedHeight(24);

    m_hLayout1 = new QHBoxLayout(m_frame);
    m_hLayout1->setSpacing(24);
    m_hLayout1->setContentsMargins(-1, 0, 0, 0);
    m_hSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);

    closeBtn = new QPushButton(m_frame);
    closeBtn->setFixedSize(QSize(16, 16));
    closeBtn->setProperty("isWindowButton", 0x02);
    closeBtn->setProperty("useIconHighlightEffect", 0x08);
    closeBtn->setFlat(true);
    closeBtn->setIcon(QIcon::fromTheme("window-close-symbolic"));
    closeBtn->setToolTip(tr("Close"));

    m_vSpacer = new QSpacerItem(20, 12, QSizePolicy::Minimum, QSizePolicy::Fixed);

    m_frame2 = new QFrame(this);
    m_frame2->setLineWidth(0);

    m_hLayout2 = new QHBoxLayout(m_frame2);
    m_hLayout2->setSpacing(0);
    m_hLayout2->setContentsMargins(12, 0, 12, 0);

    m_hLayout3 = new QHBoxLayout();
    m_hLayout3->setSpacing(28);
    m_hLayout3->setContentsMargins(0, 0, 0, 0);

    m_vSpacer2 = new QSpacerItem(20, 16, QSizePolicy::Minimum, QSizePolicy::Fixed);

    m_frame3 = new QFrame(this);

    m_hLayout4 = new QHBoxLayout(m_frame3);
    m_hLayout4->setContentsMargins(16, 0, 23, 0);

    m_hLayout5 = new QHBoxLayout();
    m_hLayout5->setSpacing(16);
    m_hLayout5->setContentsMargins(0, -1, -1, -1);

    m_vLayout = new QVBoxLayout();
    m_vLayout->setSpacing(8);

    m_hLayout6 = new QHBoxLayout();
    m_hLayout6->setSpacing(4);

    m_label = new QLabel(m_frame3);
    m_label->setText("HEX");

    colorLineEdit = new QLineEdit(m_frame3);
    colorLineEdit->setFixedSize(QSize(188, 30));
    colorLineEdit->setFocusPolicy(Qt::StrongFocus);
    colorLineEdit->setAlignment(Qt::AlignCenter);

    m_hLayout7 = new QHBoxLayout();
    m_hLayout7->setSpacing(4);

    m_label2 = new QLabel(m_frame3);
    m_label2->setText("RGB");

    m_spinBoxR = new QSpinBox(m_frame3);
    m_spinBoxR->setFixedSize(QSize(60, 30));
    m_spinBoxR->setAlignment(Qt::AlignCenter);
    m_spinBoxR->setButtonSymbols(QAbstractSpinBox::NoButtons);

    m_spinBoxG = new QSpinBox(m_frame3);
    m_spinBoxG->setFixedSize(QSize(60, 30));
    m_spinBoxG->setAlignment(Qt::AlignCenter);
    m_spinBoxG->setButtonSymbols(QAbstractSpinBox::NoButtons);

    m_spinBoxB = new QSpinBox(m_frame3);
    m_spinBoxB->setFixedSize(QSize(60, 30));
    m_spinBoxB->setAlignment(Qt::AlignCenter);
    m_spinBoxB->setButtonSymbols(QAbstractSpinBox::NoButtons);

    this->setupInit();
    this->initLayout();
    this->signalsBind();
}

ColorDialog::~ColorDialog()
{

}

void ColorDialog::initLayout()
{
    m_hLayout1->addItem(m_hSpacer);
    m_hLayout1->addWidget(closeBtn);
    m_Layout->addWidget(m_frame);
    m_Layout->addItem(m_vSpacer);

    m_hLayout2->addLayout(m_hLayout3);
    m_Layout->addWidget(m_frame2);
    m_Layout->addItem(m_vSpacer2);

    m_hLayout6->addWidget(m_label);
    m_hLayout6->addWidget(colorLineEdit);
    m_hLayout7->addWidget(m_label2);
    m_hLayout7->addWidget(m_spinBoxR);
    m_hLayout7->addWidget(m_spinBoxG);
    m_hLayout7->addWidget(m_spinBoxB);

    m_vLayout->addLayout(m_hLayout6);
    m_vLayout->addLayout(m_hLayout7);

    m_hLayout5->addLayout(m_vLayout);
    m_hLayout4->addLayout(m_hLayout5);

    m_Layout->addWidget(m_frame3);

    this->setLayout(m_Layout);
}

void ColorDialog::setupInit()
{
    // 窗口属性
    this->setWindowFlags(Qt::FramelessWindowHint | Qt::Tool);//开启窗口无边框
    this->setAttribute(Qt::WA_DeleteOnClose);
    // 左侧颜色框
    colorSquare = new ColorSquare(this);
    QSizePolicy sizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
    colorSquare->setSizePolicy(sizePolicy);
    m_hLayout3->addWidget(colorSquare);
    // 遮罩
    MaskWidget * maskWidget = new MaskWidget(colorSquare);
    maskWidget->setGeometry(0, 0, colorSquare->width(), colorSquare->height());

    // 垂直渐变滑动条
    gradientSlider = new GradientSlider(this);
    gradientSlider->setOrientation(Qt::Vertical); //设置滑块方向
    m_hLayout3->addWidget(gradientSlider);

    // spinbox
    // α:
    spinAlpha = new QSpinBox(this);
    spinAlpha->setVisible(false);
    spinAlpha->setMaximum(100);
    sliderAlpha = new GradientSlider(this);
    sliderAlpha->setVisible(false);
    sliderAlpha->setMaximum(100);
    sliderAlpha->setOrientation(Qt::Horizontal);
    // H:
    spinHue = new QSpinBox(this);
    spinHue->setVisible(false);
    spinHue->setMaximum(359);
    sliderHue = new GradientSlider(this);
    sliderHue->setVisible(false);
    sliderHue->setMaximum(359);
    sliderHue->setOrientation(Qt::Horizontal);

    QVector<QColor> rainbow;
    for ( int i = 0; i < 360; i+= 360/6 )
        rainbow.push_back(QColor::fromHsv(i,255,255));
    rainbow.push_back(Qt::red);
    sliderHue->setColors(rainbow);
    // S:
    spinSat = new QSpinBox(this);
    spinSat->setVisible(false);
    spinSat->setMaximum(100);
    sliderSat = new GradientSlider(this);
    sliderSat->setVisible(false);
    sliderSat->setMaximum(100);
    sliderSat->setOrientation(Qt::Horizontal);
    // V:
    spinVal = new QSpinBox(this);
    spinVal->setVisible(false);
    spinVal->setMaximum(100);
    sliderVal = new GradientSlider(this);
    sliderVal->setVisible(false);
    sliderVal->setMaximum(100);
    sliderVal->setOrientation(Qt::Horizontal);
    // R:
    spinRed = m_spinBoxR;
    spinRed->setMaximum(255);
    sliderRed = new GradientSlider(this);
    sliderRed->setVisible(false);
    sliderRed->setMaximum(255);
    sliderRed->setOrientation(Qt::Horizontal);
    // G:
    spinGreen = m_spinBoxG;
    spinGreen->setMaximum(255);
    sliderGreen = new GradientSlider(this);
    sliderGreen->setVisible(false);
    sliderGreen->setMaximum(255);
    sliderGreen->setOrientation(Qt::Horizontal);
    // B:
    spinBlue = m_spinBoxB;
    spinBlue->setMaximum(255);
    sliderBlue = new GradientSlider(this);
    sliderBlue->setVisible(false);
    sliderBlue->setMaximum(255);
    sliderBlue->setOrientation(Qt::Horizontal);

    // 绘制滑动条
    drawSlider();
}

void ColorDialog::signalsBind()
{
    qDebug() << "signals bind";
    connect(closeBtn, &QPushButton::clicked, [=](bool checked){
        Q_UNUSED(checked)
        close();
    });

    connect(sliderAlpha,&GradientSlider::valueChanged,spinAlpha,&QSpinBox::setValue);
    connect(spinAlpha,static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
            sliderAlpha,&GradientSlider::setValue);
    connect(sliderHue,&GradientSlider::valueChanged,spinHue,&QSpinBox::setValue);
    connect(spinHue,static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
            sliderHue,&GradientSlider::setValue);
    connect(sliderSat,&GradientSlider::valueChanged,spinSat,&QSpinBox::setValue);
    connect(spinSat,static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
            sliderSat,&GradientSlider::setValue);
    connect(sliderVal,&GradientSlider::valueChanged,spinVal,&QSpinBox::setValue);
    connect(spinVal,static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
            sliderVal,&GradientSlider::setValue);
    connect(sliderRed,&GradientSlider::valueChanged,spinRed,&QSpinBox::setValue);
    connect(spinRed,static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
            sliderRed,&GradientSlider::setValue);
    connect(sliderGreen,&GradientSlider::valueChanged,spinGreen,&QSpinBox::setValue);
    connect(spinGreen,static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
            sliderGreen,&GradientSlider::setValue);
    connect(sliderBlue,&GradientSlider::valueChanged,spinBlue,&QSpinBox::setValue);
    connect(spinBlue,static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
            sliderBlue,&GradientSlider::setValue);

    connect(sliderHue,&GradientSlider::valueChanged,this,&ColorDialog::SetHsvSlot);
    connect(sliderSat,&GradientSlider::valueChanged,this,&ColorDialog::SetHsvSlot);
    connect(sliderVal,&GradientSlider::valueChanged,this,&ColorDialog::SetHsvSlot);
    connect(sliderRed,&GradientSlider::valueChanged,this,&ColorDialog::setRgbSlot);
    connect(sliderGreen,&GradientSlider::valueChanged,this,&ColorDialog::setRgbSlot);
    connect(sliderBlue,&GradientSlider::valueChanged,this,&ColorDialog::setRgbSlot);

    connect(sliderAlpha,&GradientSlider::valueChanged,this,&ColorDialog::updateWidgetsSlot);
    connect(colorSquare,&ColorSquare::colorSelected,this,&ColorDialog::updateWidgetsSlot);
    connect(colorSquare,&ColorSquare::colorSelected,this,&ColorDialog::colorSelectedSolt);
    connect(this,&ColorDialog::checkedChanged,colorSquare,&ColorSquare::setCheckedColorSlot);

    colorLineEdit->setText("#000000");
    connect(colorLineEdit,&QLineEdit::textChanged,this,[=](){
        QColor mcolor;
        mcolor.setNamedColor(colorLineEdit->text());
        m_spinBoxR->setValue(mcolor.red());
        m_spinBoxB->setValue(mcolor.blue());
        m_spinBoxG->setValue(mcolor.green());
    });
}

void ColorDialog::drawSlider()
{
    qDebug() << "drawSlider";
    QVector<QColor> rainbow;
    for ( int i = 0; i < 360; i+= 360/6 )
        rainbow.push_front(QColor::fromHsv(i,255,255));
    rainbow.push_front(Qt::red);
    gradientSlider->setMaximum(sliderHue->maximum());
    gradientSlider->setColors(rainbow);
    gradientSlider->setValue(sliderHue->value());
    connect(gradientSlider, &GradientSlider::valueChanged, sliderHue, &GradientSlider::setValue);
    Q_EMIT checkedChanged('H');
}

QColor ColorDialog::color() const
{
    QColor color = colorSquare->color();
    //color.setAlpha(qRound(sliderAlpha->value() * 2.55));
    return color;
}

void ColorDialog::SetColor(QColor color)
{
    qDebug() << "SetColor";
    //colorPreview->setPreviousColor(color);
    //colorSquare->setProperty("color",color);
    colorSquare->setColor(color);
    sliderAlpha->setValue(color.alpha() / 2.55);
    updateWidgetsSlot();
}


/****************Slots*********************/

void ColorDialog::colorSelectedSolt()
{
    QColor color = this->color();
    Q_EMIT colorSelected(color);
}

void ColorDialog::setRgbSlot()
{
    qDebug() << "set RGB";
    if(!signalsBlocked())
    {
        QColor color(sliderRed->value(), sliderGreen->value(), sliderBlue->value());
        if(color.saturation() == 0)
        {
            color = QColor::fromHsv(sliderHue->value(), 0, color.value());
        }
        colorSquare->setColor(color);
        updateWidgetsSlot();
    }
}

void ColorDialog::SetHsvSlot()
{
    if(!signalsBlocked())
    {
        QColor color = QColor::fromHsv(gradientSlider->value() * 360/gradientSlider->maximum(), 100, 100);
        colorSquare->setColor(color);
        updateWidgetsSlot();
    }
}

void ColorDialog::updateWidgetsSlot()
{
    blockSignals(true);
    for(QWidget* w: findChildren<QWidget*>())
        w->blockSignals(true);

    QColor col = color();

    sliderRed->setValue(col.red());
    spinRed->setValue(sliderRed->value());
    sliderRed->setFirstColor(QColor(0,col.green(),col.blue()));
    sliderRed->setLastColor(QColor(255,col.green(),col.blue()));

    sliderGreen->setValue(col.green());
    spinGreen->setValue(sliderGreen->value());
    sliderGreen->setFirstColor(QColor(col.red(),0,col.blue()));
    sliderGreen->setLastColor(QColor(col.red(),255,col.blue()));

    sliderBlue->setValue(col.blue());
    spinBlue->setValue(sliderBlue->value());
    sliderBlue->setFirstColor(QColor(col.red(),col.green(),0));
    sliderBlue->setLastColor(QColor(col.red(),col.green(),255));

    sliderHue->setValue(qRound(colorSquare->hue()*360.0));
    spinHue->setValue(sliderHue->value());

    sliderSat->setValue(qRound(colorSquare->saturation()*100.0));
    spinSat->setValue(sliderSat->value());
    sliderSat->setFirstColor(QColor::fromHsvF(colorSquare->hue(),0,colorSquare->value()));
    sliderSat->setLastColor(QColor::fromHsvF(colorSquare->hue(),1,colorSquare->value()));

    sliderVal->setValue(qRound(colorSquare->value()*100.0));
    spinVal->setValue(sliderVal->value());
    sliderVal->setFirstColor(QColor::fromHsvF(colorSquare->hue(),colorSquare->saturation(),0));
    sliderVal->setLastColor(QColor::fromHsvF(colorSquare->hue(),colorSquare->saturation(),1));

    if (!colorLineEdit->hasFocus()) {
        colorLineEdit->blockSignals(true);
        colorLineEdit->setText(col.name().toUpper());
        colorLineEdit->blockSignals(false);
    }
//    QPalette label_palette;
//    label_palette.setColor(QPalette::Background, col);
//    ui->label->setAutoFillBackground(true);
//    ui->label->setPalette(label_palette);
    SetVerticalSlider();

    blockSignals(false);
    for(QWidget* w: findChildren<QWidget*>())
        w->blockSignals(false);

    Q_EMIT colorChanged(col);
}

void ColorDialog::SetVerticalSlider()
{
    disconnect(gradientSlider, SIGNAL(valueChanged(int)), sliderHue, SLOT(setValue(int)));
    disconnect(gradientSlider, SIGNAL(valueChanged(int)), sliderSat, SLOT(setValue(int)));
    disconnect(gradientSlider, SIGNAL(valueChanged(int)), sliderVal, SLOT(setValue(int)));
    disconnect(gradientSlider, SIGNAL(valueChanged(int)), sliderRed, SLOT(setValue(int)));
    disconnect(gradientSlider, SIGNAL(valueChanged(int)), sliderGreen, SLOT(setValue(int)));
    disconnect(gradientSlider, SIGNAL(valueChanged(int)), sliderBlue, SLOT(setValue(int)));


    QVector<QColor> rainbow;
    for ( int i = 0; i < 360; i+= 360/6 )
        rainbow.push_front(QColor::fromHsv(i,255,255));
    rainbow.push_front(Qt::red);
    gradientSlider->setMaximum(sliderHue->maximum());
    gradientSlider->setColors(rainbow);
    gradientSlider->setValue(sliderHue->value());

    connect(gradientSlider, SIGNAL(valueChanged(int)), sliderHue, SLOT(setValue(int)));
    Q_EMIT checkedChanged('H');
}



