#include "stretchtoolbar.h"
#include <QVBoxLayout>
#include <QDebug>
#include <QToolButton>
#include <QSettings>
#include <QStyle>
#include "imageringlist.h"

StretchToolbar::StretchToolbar(QWidget *parent) : QToolBar(tr("Stretch toolbar"), parent)
{
    setObjectName("stretchtoolbar");
    QWidget *lum = new QWidget(this);
    QVBoxLayout *vbox1 = new QVBoxLayout(lum);
    m_stfSlider = new STFSlider(Qt::white, this);
    vbox1->addWidget(m_stfSlider);
    connect(this, &StretchToolbar::orientationChanged, m_stfSlider, &STFSlider::orientationChanged);

    m_stfSliderR = new STFSlider(Qt::red, this);
    m_stfSliderG = new STFSlider(Qt::green, this);
    m_stfSliderB = new STFSlider(Qt::blue, this);
    QWidget *rgb = new QWidget(this);
    QBoxLayout *box2 = new QBoxLayout(orientation() == Qt::Horizontal ? QBoxLayout::TopToBottom : QBoxLayout::LeftToRight, rgb);
    box2->setSpacing(0);
    box2->addWidget(m_stfSliderR);
    box2->addWidget(m_stfSliderG);
    box2->addWidget(m_stfSliderB);
    connect(this, &StretchToolbar::orientationChanged, m_stfSliderR, &STFSlider::orientationChanged);
    connect(this, &StretchToolbar::orientationChanged, m_stfSliderG, &STFSlider::orientationChanged);
    connect(this, &StretchToolbar::orientationChanged, m_stfSliderB, &STFSlider::orientationChanged);
    connect(this, &StretchToolbar::orientationChanged, [box2](Qt::Orientations orientation){
        box2->setDirection(orientation == Qt::Horizontal ? QBoxLayout::TopToBottom : QBoxLayout::LeftToRight);
    });

    m_stack = new QStackedWidget(this);
    m_stack->addWidget(lum);
    m_stack->addWidget(rgb);
    m_stack->setCurrentIndex(0);
    addWidget(m_stack);

    connect(m_stfSlider, &STFSlider::paramChanged, [this](float blackPoint, float midPoint, float whitePoint){
        m_mtfParam.blackPoint[0] = m_mtfParam.blackPoint[1] = m_mtfParam.blackPoint[2] = blackPoint;
        m_mtfParam.midPoint[0] = m_mtfParam.midPoint[1] = m_mtfParam.midPoint[2] = midPoint;
        m_mtfParam.whitePoint[0] = m_mtfParam.whitePoint[1] = m_mtfParam.whitePoint[2] = whitePoint;
        emit paramChanged(m_mtfParam);
    });
    connect(m_stfSliderR, &STFSlider::paramChanged, [this](float blackPoint, float midPoint, float whitePoint){
        m_mtfParam.blackPoint[0] = blackPoint;
        m_mtfParam.midPoint[0] = midPoint;
        m_mtfParam.whitePoint[0] = whitePoint;
        emit paramChanged(m_mtfParam);
    });
    connect(m_stfSliderG, &STFSlider::paramChanged, [this](float blackPoint, float midPoint, float whitePoint){
        m_mtfParam.blackPoint[1] = blackPoint;
        m_mtfParam.midPoint[1] = midPoint;
        m_mtfParam.whitePoint[1] = whitePoint;
        emit paramChanged(m_mtfParam);
    });
    connect(m_stfSliderB, &STFSlider::paramChanged, [this](float blackPoint, float midPoint, float whitePoint){
        m_mtfParam.blackPoint[2] = blackPoint;
        m_mtfParam.midPoint[2] = midPoint;
        m_mtfParam.whitePoint[2] = whitePoint;
        emit paramChanged(m_mtfParam);
    });

    QAction *rgbStretch = addAction(QIcon(":/link.png"), tr("Linked channels"));
    rgbStretch->setCheckable(true);
    rgbStretch->setChecked(true);
    connect(rgbStretch, &QAction::toggled, this, &StretchToolbar::unlinkStretch);

    QAction *autoStretchButton = addAction(QIcon(":/nuke.png"), tr("Auto Stretch F12"));
    autoStretchButton->setShortcut(Qt::Key_F12);
    connect(autoStretchButton, &QAction::triggered, this, &StretchToolbar::autoStretch);

    QAction *resetButton = addAction(style()->standardIcon(QStyle::SP_DialogResetButton), tr("Reset Screen Transfer Function F11"));
    resetButton->setShortcut(Qt::Key_F11);
    connect(resetButton, &QAction::triggered, this, &StretchToolbar::resetMTF);

    QAction *invertButton = addAction(QIcon(":/invert.png"), tr("Invert colors"));
    invertButton->setCheckable(true);
    connect(invertButton, &QAction::toggled, this, &StretchToolbar::invert);

    QAction *falseColorButton = addAction(QIcon(":/falsecolor.png"), tr("False colors"));
    falseColorButton->setCheckable(true);
    connect(falseColorButton, &QAction::toggled, this, &StretchToolbar::falseColor);

    m_debayer = addAction(QIcon(":/bayer.png"), tr("Debayer CFA"));
    m_debayer->setCheckable(true);
    connect(m_debayer, &QAction::toggled, this, &StretchToolbar::superPixel);

    m_autoStretchOnLoad = addAction(QIcon(":/nuke_a.png"), tr("Apply auto stretch on load"));
    m_autoStretchOnLoad->setCheckable(true);

    QAction *showGridButton = addAction(QIcon(":/grid.svg"), tr("Draw equatorial grid"));
    showGridButton->setCheckable(true);
    connect(showGridButton, &QAction::toggled, this, &StretchToolbar::drawGrid);

    QSettings settings;
    m_autoStretchOnLoad->setChecked(settings.value("stretchtoolbar/autostretch", false).toBool());
}

StretchToolbar::~StretchToolbar()
{
    QSettings settings;
    settings.setValue("stretchtoolbar/autostretch", m_autoStretchOnLoad->isChecked());
}

const MTFParam &StretchToolbar::params() const
{
    return m_mtfParam;
}

void StretchToolbar::stretchImage(Image *img)
{
    if(img && img->rawImage())
    {
        m_mtfParam = img->rawImage()->calcMTFParams(m_stack->currentIndex() == 0,
                                                    m_stack->currentIndex() == 1 && img->rawImage()->channels() == 1 && m_debayer->isChecked());

        if(m_stack->currentIndex() == 0)
        {
            m_stfSlider->setMTFParams(m_mtfParam.blackPoint[0], m_mtfParam.midPoint[0], m_mtfParam.whitePoint[0]);
        }
        else
        {
            m_stfSliderR->setMTFParams(m_mtfParam.blackPoint[0], m_mtfParam.midPoint[0], m_mtfParam.whitePoint[0]);
            m_stfSliderG->setMTFParams(m_mtfParam.blackPoint[1], m_mtfParam.midPoint[1], m_mtfParam.whitePoint[1]);
            m_stfSliderB->setMTFParams(m_mtfParam.blackPoint[2], m_mtfParam.midPoint[2], m_mtfParam.whitePoint[2]);
        }
        emit paramChanged(m_mtfParam);
    }
}

void StretchToolbar::resetMTF()
{
    MTFParam params;
    m_mtfParam = params;
    if(m_stack->currentIndex() == 0)
    {
        m_stfSlider->setMTFParams(0, 0.5, 1);
    }
    else
    {
        m_stfSliderR->setMTFParams(0, 0.5, 1);
        m_stfSliderG->setMTFParams(0, 0.5, 1);
        m_stfSliderB->setMTFParams(0, 0.5, 1);
    }
    emit paramChanged(params);
}

void StretchToolbar::imageLoaded(Image *img)
{
    if(m_autoStretchOnLoad->isChecked())
        stretchImage(img);
}

void StretchToolbar::unlinkStretch(bool enable)
{
    if(!enable)
    {
        m_stack->setCurrentIndex(1);
        m_mtfParam.blackPoint[0] = m_stfSliderR->blackPoint(); m_mtfParam.midPoint[0] = m_stfSliderR->midPoint(); m_mtfParam.whitePoint[0] = m_stfSliderR->whitePoint();
        m_mtfParam.blackPoint[1] = m_stfSliderG->blackPoint(); m_mtfParam.midPoint[1] = m_stfSliderG->midPoint(); m_mtfParam.whitePoint[1] = m_stfSliderG->whitePoint();
        m_mtfParam.blackPoint[2] = m_stfSliderB->blackPoint(); m_mtfParam.midPoint[2] = m_stfSliderB->midPoint(); m_mtfParam.whitePoint[2] = m_stfSliderB->whitePoint();
    }
    else
    {
        m_stack->setCurrentIndex(0);
        m_mtfParam.blackPoint[0] = m_mtfParam.blackPoint[1] = m_mtfParam.blackPoint[2] = m_stfSlider->blackPoint();
        m_mtfParam.midPoint[0] = m_mtfParam.midPoint[1] = m_mtfParam.midPoint[2] = m_stfSlider->midPoint();
        m_mtfParam.whitePoint[0] = m_mtfParam.whitePoint[1] = m_mtfParam.whitePoint[2] = m_mtfParam.whitePoint[2] = m_stfSlider->whitePoint();
    }
    emit paramChanged(m_mtfParam);
}
