/**
 * \file
 *
 * \author Mattia Basaglia
 *
 * \copyright Copyright (C) 2013-2017 Mattia Basaglia
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */
#include "qt-color-widgets/color_list_widget.hpp"
#include "qt-color-widgets/color_selector.hpp"

namespace color_widgets {

class ColorListWidget::Private
{
public:
    QList<QColor>               colors;
    QSignalMapper               mapper;
    ColorWheel::DisplayFlags  wheel_flags;
};

ColorListWidget::ColorListWidget(QWidget *parent)
    : AbstractWidgetList(parent), p(new Private)
{
    connect(this, &AbstractWidgetList::removed, this, &ColorListWidget::handle_removed);
    connect(&p->mapper, SIGNAL(mapped(int)), SLOT(color_changed(int)));
    p->wheel_flags = ColorWheel::defaultDisplayFlags();
}

ColorListWidget::~ColorListWidget()
{
    delete p;
}

QList<QColor> ColorListWidget::colors() const
{
    return p->colors;
}

void ColorListWidget::setColors(const QList<QColor> &colors)
{
    clear();
    p->colors = colors;
    for(int i = 0;i < colors.size();i++ )
        append_widget(i);
    Q_EMIT colorsChanged(colors);
}

void ColorListWidget::swap(int a, int b)
{
    ColorSelector* sa = widget_cast<ColorSelector>(a);
    ColorSelector* sb = widget_cast<ColorSelector>(b);
    if ( sa && sb )
    {
        QColor ca = sa->color();
        sa->setColor(sb->color());
        sb->setColor(ca);
        Q_EMIT colorsChanged(p->colors);
    }
}

void ColorListWidget::append()
{
    p->colors.push_back(Qt::black);
    append_widget(p->colors.size()-1);
    Q_EMIT colorsChanged(p->colors);
    Q_EMIT color_added();
}

void ColorListWidget::emit_changed()
{
    Q_EMIT colorsChanged(p->colors);
}

void ColorListWidget::handle_removed(int i)
{
    p->colors.removeAt(i);
    Q_EMIT colorsChanged(p->colors);
}

void ColorListWidget::color_changed(int row)
{
    ColorSelector *cs = widget_cast<ColorSelector>(row);
    if ( cs )
    {
        p->colors[row] = cs->color();
        Q_EMIT colorsChanged(p->colors);
    }
}

void ColorListWidget::setColorAt(int i, QColor const& color)
{
  p->colors[i] = color;
  ColorSelector* cs = widget_cast<ColorSelector>(i);
  cs->setColor(color);
  Q_EMIT colorsChanged(p->colors);
}

void ColorListWidget::append_widget(int col)
{
    ColorSelector* cbs = new ColorSelector;
    cbs->setDisplayMode(ColorPreview::AllAlpha);
    cbs->setColor(p->colors[col]);
    //connect(cbs,SIGNAL(colorChanged(QColor)),SLOT(emit_changed()));
    p->mapper.setMapping(cbs,col);
    connect(cbs,SIGNAL(colorChanged(QColor)),&p->mapper,SLOT(map()));
    connect(this,&ColorListWidget::wheelFlagsChanged,
            cbs,&ColorSelector::setWheelFlags);
    appendWidget(cbs);
    setRowHeight(count()-1,22);
}

ColorWheel::DisplayFlags ColorListWidget::wheelFlags() const
{
    return p->wheel_flags;
}

void ColorListWidget::setWheelFlags(ColorWheel::DisplayFlags flags)
{
    if ( p->wheel_flags != flags )
    {
        p->wheel_flags = flags;
        Q_EMIT wheelFlagsChanged(flags);
    }
}

} // namespace color_widgets
