/***************************************************************************
**
**  This file is part of SciFigs.
**
**  This library 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 2.1 of the License, or (at your option) any later version.
**
**  This file 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 library; if not, write to the Free Software
**  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
**
**  See http://www.geopsy.org for more information.
**
**  Created: 2002-05-27
**  Copyright: 2002-2019
**    Marc Wathelet
**    Marc Wathelet (ULg, Liège, Belgium)
**    Marc Wathelet (LGIT, Grenoble, France)
**
***************************************************************************/

#include "LegendTable.h"
#include "Symbol.h"
#include "LegendTableItem.h"
#include "LegendTableDelegate.h"

namespace SciFigs {

/*!
  \class LegendTable LegendTable.h
  \brief GUI table for Legend

*/

LegendTable::LegendTable(QWidget * parent)
   : QTableView(parent)
{
  TRACE;
  LegendTableItem * model=new LegendTableItem(this);
  connect(model, SIGNAL(dataChanged (const QModelIndex &, const QModelIndex &)),
          this, SIGNAL(changed()));
  setModel(model);
  LegendTableDelegate * delegate=new LegendTableDelegate(this);
  setItemDelegate(delegate);
  connect(delegate, SIGNAL(dataChanged()), this, SLOT(applyAllSelected()));
  setSelectionBehavior(QAbstractItemView::SelectRows);
  setSelectionMode(QAbstractItemView::ExtendedSelection);
  setEditTriggers(QAbstractItemView::AllEditTriggers);
  horizontalHeader()->setStretchLastSection(true);
  horizontalHeader()->hide();
  verticalHeader()->hide();
  connect(this, SIGNAL(clicked(const QModelIndex&)), delegate, SLOT(colorClicked(QModelIndex)));
}

void LegendTable::setPropertySections(PropertySections s)
{
  TRACE;
  int columnIndex =0;
  _columnIndexes.clear();
  if(s & Pen) {
    setSpan(0, columnIndex, 1, 3);
    _columnIndexes.insert(columnIndex++, ColumnPenColor);
    _columnIndexes.insert(columnIndex++, ColumnPenWidth);
    _columnIndexes.insert(columnIndex++, ColumnPenStyle);
  }
  if(s & SymbolType) {
    setSpan(0, columnIndex, 1, 2);
    _columnIndexes.insert(columnIndex++, ColumnSymbolType);
    _columnIndexes.insert(columnIndex++, ColumnSymbolSize);
  }
  if(s & SymbolPen) {
    setSpan(0, columnIndex, 1, 3);
    _columnIndexes.insert(columnIndex++, ColumnSymbolPenColor);
    _columnIndexes.insert(columnIndex++, ColumnSymbolPenWidth);
    _columnIndexes.insert(columnIndex++, ColumnSymbolPenStyle);
  }
  if(s & SymbolBrush) {
    setSpan(0, columnIndex, 1, 2);
    _columnIndexes.insert(columnIndex++, ColumnSymbolBrushColor);
    _columnIndexes.insert(columnIndex++, ColumnSymbolBrushStyle);
  }
  if(s & Text) {
    if(s & TextColor) {
      setSpan(0, columnIndex, 1, 2);
      _columnIndexes.insert(columnIndex++, ColumnTextColor);
      _columnIndexes.insert(columnIndex++, ColumnText);
    } else {
      setSpan(0, columnIndex, 2, 1);
      _columnIndexes.insert(columnIndex++, ColumnText);
    }
  } else if(s & TextColor) {
    setSpan(0, columnIndex, 2, 1);
    _columnIndexes.insert(columnIndex++, ColumnTextColor);
  }
  static_cast<LegendTableItem *>(model())->setColumnIndexes(&_columnIndexes);
  static_cast<LegendTableDelegate *>(itemDelegate())->setColumnIndexes(&_columnIndexes);
}

/*!
  Linked to properties: if \a c is true, the legend is the same for all
  legend widgets controled by this table. This is just a visual effect.

  TODO: find a good way to mark it on the screen
*/
void LegendTable::setConstant(bool c)
{
  QPalette palette=QWidget::palette();
  palette.setColor(QPalette::Text, c ? palette.color(QPalette::Text) : QColor(164,112,128));
  viewport()->setPalette(palette);
}

void LegendTable::setLegend(Legend * legend)
{
  static_cast<LegendTableItem *>(model())->setLegend(legend);
  resizeColumnsToContents();
  emit changed();
}

void LegendTable::setOneColor(bool oc)
{
  static_cast<LegendTableItem *>(model())->setOneColor(oc);
}

bool LegendTable::oneColor() const
{
  return static_cast<LegendTableItem *>(model())->oneColor();
}

void LegendTable::setReadOnlyText(bool ro)
{
  static_cast<LegendTableItem *>(model())->setReadOnlyText(ro);
}

bool LegendTable::readOnlyText() const
{
  return static_cast<LegendTableItem *>(model())->readOnlyText();
}

QPixmap LegendTable::penStylePixmap(Qt::PenStyle s)
{
  TRACE;
  QPixmap pm(32, 16);
  QPainter p;
  p.begin(&pm);
  p.fillRect(0, 0, 32, 16, Qt::white);
  p.setPen(QPen(Qt::black, 0, s));
  p.drawLine(0, 8, 32, 8);
  p.end();
  return pm;
}

void LegendTable::initPenStyles(QComboBox * w)
{
  w->setIconSize (QSize(32, 16));
  w->addItem(penStylePixmap(Qt::NoPen), "");
  w->addItem(penStylePixmap(Qt::SolidLine), "");
  w->addItem(penStylePixmap(Qt::DashLine), "");
  w->addItem(penStylePixmap(Qt::DotLine), "");
  w->addItem(penStylePixmap(Qt::DashDotLine), "");
  w->addItem(penStylePixmap(Qt::DashDotDotLine), "");
}

Qt::PenStyle LegendTable::penStyle(int index)
{
  switch (index) {
  default: return Qt::NoPen;
  case 1: return Qt::SolidLine;
  case 2: return Qt::DashLine;
  case 3: return Qt::DotLine;
  case 4: return Qt::DashDotLine;
  case 5: return Qt::DashDotDotLine;
  }
}

int LegendTable::penItem(Qt::PenStyle p)
{
  switch (p) {
  case Qt::CustomDashLine:
  case Qt::MPenStyle:
  case Qt::NoPen:
    break;
  case Qt::SolidLine: return 1;
  case Qt::DashLine: return 2;
  case Qt::DotLine: return 3;
  case Qt::DashDotLine: return 4;
  case Qt::DashDotDotLine: return 5;
  }
  return 0;
}

QPixmap LegendTable::symbolTypePixmap(Symbol::Type t)
{
  TRACE;
  QPixmap pm(16, 16);
  QPainter p;
  p.begin(&pm);
  p.fillRect(0, 0, 16, 16, Qt::white);
  Symbol s(t, 3.5);
  s.paint(p, QPointF(7, 7));
  p.end();
  return pm;
}

void LegendTable::initSymbolTypes(QComboBox * w)
{
  w->setIconSize(QSize(16, 16));
  w->addItem(symbolTypePixmap(Symbol::NoSymbol), "");
  w->addItem(symbolTypePixmap(Symbol::Cross), "");
  w->addItem(symbolTypePixmap(Symbol::Square), "");
  w->addItem(symbolTypePixmap(Symbol::Circle), "");
  w->addItem(symbolTypePixmap(Symbol::TriangleUp), "");
  w->addItem(symbolTypePixmap(Symbol::TriangleDown), "");
  w->addItem(symbolTypePixmap(Symbol::Losange), "");
  w->addItem(symbolTypePixmap(Symbol::Star), "");
}

Symbol::Type LegendTable::symbolType(int index)
{
  switch (index) {
  default: return Symbol::NoSymbol;
  case 1: return Symbol::Cross;
  case 2: return Symbol::Square;
  case 3: return Symbol::Circle;
  case 4: return Symbol::TriangleUp;
  case 5: return Symbol::TriangleDown;
  case 6: return Symbol::Losange;
  case 7: return Symbol::Star;
  }
}

int LegendTable::symbolItem(Symbol::Type t)
{
  switch (t) {
  case Symbol::NoSymbol: break;
  case Symbol::Cross: return 1;
  case Symbol::Square: return 2;
  case Symbol::Circle: return 3;
  case Symbol::TriangleUp: return 4;
  case Symbol::TriangleDown: return 5;
  case Symbol::Losange: return 6;
  case Symbol::Star: return 7;
  }
  return 0;
}

QPixmap LegendTable::brushStylePixmap(Qt::BrushStyle s)
{
  TRACE;
  QPixmap pm(16, 16);
  QPainter p;
  p.begin(&pm);
  p.fillRect(0, 0, 16, 16, Qt::white);
  p.setPen(QPen(Qt::NoPen));
  p.setBrush(QBrush(Qt::black, s));
  p.drawRect(0, 0, 16, 16);
  p.end();
  return pm;
}

void LegendTable::initBrushStyles(QComboBox * w)
{
  w->setIconSize (QSize(16, 16));
  w->addItem(brushStylePixmap(Qt::NoBrush), "");
  w->addItem(brushStylePixmap(Qt::SolidPattern), "");
  w->addItem(brushStylePixmap(Qt::Dense1Pattern), "");
  w->addItem(brushStylePixmap(Qt::Dense2Pattern), "");
  w->addItem(brushStylePixmap(Qt::Dense3Pattern), "");
  w->addItem(brushStylePixmap(Qt::Dense4Pattern), "");
  w->addItem(brushStylePixmap(Qt::Dense5Pattern), "");
  w->addItem(brushStylePixmap(Qt::Dense6Pattern), "");
  w->addItem(brushStylePixmap(Qt::Dense7Pattern), "");
  w->addItem(brushStylePixmap(Qt::HorPattern), "");
  w->addItem(brushStylePixmap(Qt::VerPattern), "");
  w->addItem(brushStylePixmap(Qt::CrossPattern), "");
  w->addItem(brushStylePixmap(Qt::BDiagPattern), "");
  w->addItem(brushStylePixmap(Qt::FDiagPattern), "");
  w->addItem(brushStylePixmap(Qt::DiagCrossPattern), "");
}

Qt::BrushStyle LegendTable::brushStyle(int index)
{
  switch (index) {
  default: return Qt::NoBrush;
  case 1: return Qt::SolidPattern;
  case 2: return Qt::Dense1Pattern;
  case 3: return Qt::Dense2Pattern;
  case 4: return Qt::Dense3Pattern;
  case 5: return Qt::Dense4Pattern;
  case 6: return Qt::Dense5Pattern;
  case 7: return Qt::Dense6Pattern;
  case 8: return Qt::Dense7Pattern;
  case 9: return Qt::HorPattern;
  case 10: return Qt::VerPattern;
  case 11: return Qt::CrossPattern;
  case 12: return Qt::BDiagPattern;
  case 13: return Qt::FDiagPattern;
  case 14: return Qt::DiagCrossPattern;
  }
}

int LegendTable::brushItem(Qt::BrushStyle b)
{
  switch (b) {
  case Qt::LinearGradientPattern:
  case Qt::RadialGradientPattern:
  case Qt::ConicalGradientPattern:
  case Qt::TexturePattern:
  case Qt::NoBrush:
    break;
  case Qt::SolidPattern: return 1;
  case Qt::Dense1Pattern: return 2;
  case Qt::Dense2Pattern: return 3;
  case Qt::Dense3Pattern: return 4;
  case Qt::Dense4Pattern: return 5;
  case Qt::Dense5Pattern: return 6;
  case Qt::Dense6Pattern: return 7;
  case Qt::Dense7Pattern: return 8;
  case Qt::HorPattern: return 9;
  case Qt::VerPattern: return 10;
  case Qt::CrossPattern: return 11;
  case Qt::BDiagPattern: return 12;
  case Qt::FDiagPattern: return 13;
  case Qt::DiagCrossPattern: return 14;
  }
  return 0;
}

void LegendTable::applyAllSelected()
{
  TRACE;
  QModelIndexList l=selectionModel()->selectedRows();
  if(l.count()>1) {
    QVariant val=model()->data(currentIndex());
    QModelIndex index;
    foreach(index, l) {
      model()->setData(model()->index(index.row(), currentIndex().column()), val);
    }
  }
}

} // namespace SciFigs
