/***************************************************************************
 *   Copyright (C) 2007 by Anistratov Oleg                                 *
 *   ower86@gmail.com                                                      *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License version 2        *
 *   as published by the Free Software Foundation;                         *
 *                                                                         *
 *   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 General Public License for more details.                          *
 *                                                                         *
 ***************************************************************************/
#include "colorchooser.h"

#include <QColorDialog>

#include "colorlabel.h"

ColorPicker::ColorPicker(QWidget *parent)
 : QFrame(parent),
   m_colorsNum(16),
   m_maxColors(16)
{
  grid = new QGridLayout(this);
  m_button = new QToolButton(this);

  m_baseColors.append(Qt::white);
  m_baseColors.append(Qt::black);
  m_baseColors.append(Qt::red);
  m_baseColors.append(Qt::green);
  m_baseColors.append(Qt::blue);
  m_baseColors.append(Qt::cyan);
  m_baseColors.append(Qt::magenta);
  m_baseColors.append(Qt::yellow);
  m_baseColors.append(Qt::gray);
  m_baseColors.append(Qt::darkGray);
  m_baseColors.append(Qt::darkRed);
  m_baseColors.append(Qt::darkYellow);
  m_baseColors.append(Qt::darkMagenta);
  m_baseColors.append(Qt::darkCyan);
  m_baseColors.append(Qt::darkBlue);
  m_baseColors.append(Qt::darkGreen);

  grid->setMargin(0);
  grid->setSpacing(0);

  for(int i = 0; i < m_colorsNum; i++)
  {
    ColorLabel* lab = new ColorLabel(this);

    lab->setFrameStyle(QFrame::StyledPanel);
//     lab->setFrameStyle(QFrame::Box);
    lab->setMinimumHeight(20);
    lab->setMinimumWidth (20);
    lab->setMaximumHeight(20);
    lab->setMaximumWidth (20);

    connect(lab, SIGNAL(clicked()), this, SLOT(colorClicked()));

    m_colorLabels.append(lab);
  }

//   for(int i = 0; i < 2; i++)
//     for(int j = 0; j < (m_colorsNum / 2); j++)

  for(int i = 0; i < m_colorsNum; i++)
    grid->addWidget(m_colorLabels[i], i % 2, i / 2);

  grid->addWidget(m_button, 0, (m_colorsNum / 2), 2, 1);

  connect(m_button, SIGNAL(clicked()), this, SLOT(selectColorDialog()));

  setFrameStyle(QFrame::StyledPanel);
  setLineWidth(1);

  redrawLabels();
}

void ColorPicker::selectColorDialog()
{
  QColor color = QColorDialog::getColor(m_color, this);
  if(color.isValid())
    emit colorChanged(m_color = color);

  redrawLabels();
  setButtonColor();
}

void ColorPicker::redrawLabels()
{
  int i;

  if(!m_colorsNum)
    return;

  m_colors.clear();

  for(i = 0; i < m_colorsNum && i < QColorDialog::customCount (); i++)
    if(!m_colors.contains(QColorDialog::customColor(i)))
      m_colors.append(QColor(QColorDialog::customColor(i)));

  i = m_colors.size();
  foreach(QColor color, m_baseColors)
  {
     if(!m_colors.contains(color))
     {
       m_colors.append(color);
       i++;
     }

     if(i >= m_colorsNum)
       break;
  }

  if(!m_colors.contains(m_color))
    m_colors.replace(m_colorsNum - 1, m_color);

  for(int i = 0; i < m_colors.size() && i < m_colorLabels.size(); i++)
    m_colorLabels[i]->setColor(m_colors[i]);
}

void ColorPicker::colorClicked()
{
  ColorLabel* lab = qobject_cast<ColorLabel*>(sender());

  m_color = lab->color();

  emit colorChanged(m_color);

  setButtonColor();
}

void ColorPicker::setButtonColor()
{
  QPixmap pix(m_button->width(), m_button->height());

  pix.fill(m_color);

  m_button->setIcon(QIcon(pix));
}

void ColorPicker::setColor(QColor color)
{
  m_color = color;
  setButtonColor();
}

void ColorPicker::setColorsNum(int num)
{
  m_colorsNum = (num > m_maxColors ? m_maxColors : (num < 0 ? 0 : num));

  int i = 0;

//   if((m_colorsNum == (m_maxColors / 2) && (m_colorsNum - old) ==  1) ||
//      (m_colorsNum == (m_maxColors / 2) && (m_colorsNum - old) == -1))
//     changeRows();

  foreach(ColorLabel* cl, m_colorLabels)
  {
    bool hid = (i++ >= m_colorsNum);
    cl->setHidden(hid);
  }
}

void ColorPicker::wheelEvent(QWheelEvent* ev)
{
  if(ev->delta() > 0 && m_colorsNum < m_maxColors)
    setColorsNum(m_colorsNum + 1);
  else if(ev->delta() < 0 && m_colorsNum > 0)
    setColorsNum(m_colorsNum - 1);
}

void ColorPicker::changeRows()
{
  foreach(ColorLabel* cl, m_colorLabels)
    grid->removeWidget(cl);

  if(m_colorsNum > (m_maxColors / 2))
  {
    for(int i = 0; i < m_maxColors; i++)
      grid->addWidget(m_colorLabels[i], i % 2, i / 2);
  }
  else
  {
    for(int i = 0; i < m_maxColors; i++)
      grid->addWidget(m_colorLabels[i], 0, i);
  }
}
