/***************************************************************************
**
**  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: 2009-03-19
**  Copyright: 2009-2019
**    Marc Wathelet
**    Marc Wathelet (LGIT, Grenoble, France)
**
***************************************************************************/

#include <QGpGuiTools.h>
#include "LegendTableDelegate.h"
#include "LegendTable.h"

namespace SciFigs {

/*!
  \class LegendTableDelegate LegendTableDelegate.h
  \brief Brief description of class still missing

  Full description of class still missing
*/


void LegendTableDelegate::setColumnIndexes(const QHash<int,LegendTable::Column> * columnIndexes)
{
  TRACE;
  _columnIndexes=columnIndexes;
}

inline LegendTable::Column LegendTableDelegate::column(int index) const
{
  QHash<int,LegendTable::Column>::const_iterator it=_columnIndexes->find(index);
  if(it!=_columnIndexes->end()) {
    return it.value();
  } else {
    return LegendTable::ColumnNull;
  }
}

QWidget * LegendTableDelegate::createEditor(QWidget * parent, const QStyleOptionViewItem & option,
                                            const QModelIndex & index) const
{
  TRACE;
  switch (column( index.column()) ) {
  case LegendTable::ColumnNull: return nullptr;
  case LegendTable::ColumnText: {
      QLineEdit * w=new QLineEdit(parent);
      return w;
    }
  case LegendTable::ColumnPenColor:
  case LegendTable::ColumnSymbolPenColor:
  case LegendTable::ColumnSymbolBrushColor:
  case LegendTable::ColumnTextColor:
    return QItemDelegate::createEditor(parent, option, index);
  case LegendTable::ColumnPenWidth:
  case LegendTable::ColumnSymbolSize:
  case LegendTable::ColumnSymbolPenWidth: {
      DoubleSpinBox * w=new DoubleSpinBox(parent);
      w->setSingleStep(0.1);
      w->setMinimum(0.0);
      w->setMaximum(100.0);
      connect(w, SIGNAL(valueChanged(double)), this, SLOT(commitWidget()) );
      return w;
    }
  case LegendTable::ColumnPenStyle:
  case LegendTable::ColumnSymbolPenStyle: {
      QComboBox * w=new QComboBox(parent);
      connect(w, SIGNAL(activated(int)), this, SLOT(commitWidget()) );
      LegendTable::initPenStyles(w);
      return w;
    }
  case LegendTable::ColumnSymbolType: {
      QComboBox * w=new QComboBox(parent);
      connect(w, SIGNAL(activated(int)), this, SLOT(commitWidget()) );
      LegendTable::initSymbolTypes(w);
      return w;
    }
  case LegendTable::ColumnSymbolBrushStyle: {
      QComboBox * w=new QComboBox(parent);
      connect(w, SIGNAL(activated(int)), this, SLOT(commitWidget()) );
      LegendTable::initBrushStyles(w);
      return w;
    }
  }
  return nullptr;
}

void LegendTableDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
  TRACE;
  switch (column( index.column()) ) {
  case LegendTable::ColumnNull: break;
  case LegendTable::ColumnText: {
      QLineEdit * w=qobject_cast<QLineEdit *>(editor);
      ASSERT(w);
      w->setText(index.model() ->data(index).toString());
      w->selectAll();
    }
    break;
  case LegendTable::ColumnPenColor:
  case LegendTable::ColumnSymbolPenColor:
  case LegendTable::ColumnSymbolBrushColor:
  case LegendTable::ColumnTextColor:
    QItemDelegate::setEditorData(editor, index);
    break;
  case LegendTable::ColumnPenWidth:
  case LegendTable::ColumnSymbolSize:
  case LegendTable::ColumnSymbolPenWidth: {
      DoubleSpinBox * w=qobject_cast<DoubleSpinBox *>(editor);
      ASSERT(w);
      w->setValue(index.model() ->data(index).toDouble());
      break;
    }
  case LegendTable::ColumnPenStyle:
  case LegendTable::ColumnSymbolPenStyle:
  case LegendTable::ColumnSymbolType:
  case LegendTable::ColumnSymbolBrushStyle: {
      QComboBox * w=qobject_cast<QComboBox *>(editor);
      ASSERT(w);
      w->setCurrentIndex(index.model()->data(index).toInt());
      break;
    }
  }
}

void LegendTableDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
                                           const QModelIndex &index) const
{
  TRACE;
  switch (column( index.column()) ) {
  case LegendTable::ColumnNull: break;
  case LegendTable::ColumnText: {
      QLineEdit * w=qobject_cast<QLineEdit *>(editor);
      ASSERT(w);
      if(w->isModified() && model->data(index)!=w->text()) {
        model->setData(index, w->text());
        emit dataChanged();
      }
    }
    break;
  case LegendTable::ColumnPenColor:
  case LegendTable::ColumnSymbolPenColor:
  case LegendTable::ColumnTextColor:
  case LegendTable::ColumnSymbolBrushColor:
    break;
  case LegendTable::ColumnPenWidth:
  case LegendTable::ColumnSymbolSize:
  case LegendTable::ColumnSymbolPenWidth: {
      DoubleSpinBox * w=qobject_cast<DoubleSpinBox *>(editor);
      ASSERT(w);
      QVariant oldValue=model->data(index);
      if(oldValue!=w->value()) {
        model->setData(index, w->value());
        emit dataChanged();
      }
      break;
    }
  case LegendTable::ColumnPenStyle:
  case LegendTable::ColumnSymbolPenStyle:
  case LegendTable::ColumnSymbolType:
  case LegendTable::ColumnSymbolBrushStyle: {
      QComboBox * w=qobject_cast<QComboBox *>(editor);
      ASSERT(w);
      QVariant oldValue=model->data(index);
      if(oldValue!=w->currentIndex()) {
        model->setData(index, w->currentIndex());
        emit dataChanged();
      }
      break;
    }
  }
}

QSize LegendTableDelegate::sizeHint (const QStyleOptionViewItem & option, const QModelIndex & index) const
{
  TRACE;
  if(index.row()<2) {
    return QItemDelegate::sizeHint(option, index);
  } else {
    switch (column( index.column()) ) {
    case LegendTable::ColumnNull:
    case LegendTable::ColumnText:
      break;
    case LegendTable::ColumnPenWidth:
    case LegendTable::ColumnSymbolSize:
    case LegendTable::ColumnSymbolPenWidth:
      return QSize(70, 0);
    case LegendTable::ColumnPenColor:
    case LegendTable::ColumnSymbolPenColor:
    case LegendTable::ColumnSymbolBrushColor:
    case LegendTable::ColumnTextColor:
      return QSize(30, 0);
    case LegendTable::ColumnPenStyle:
    case LegendTable::ColumnSymbolPenStyle:
      return QSize(30, 0);
    case LegendTable::ColumnSymbolType:
    case LegendTable::ColumnSymbolBrushStyle:
      return QSize(30, 0);
    }
    return QItemDelegate::sizeHint(option, index);
  }
}

void LegendTableDelegate::paint (QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const
{
  TRACE;
  if(index.row()<2) {
    QItemDelegate::paint(painter, option, index);
  } else {
    QPoint p=option.rect.center();
    switch (column( index.column()) ) {
    case LegendTable::ColumnNull:
    case LegendTable::ColumnText:
    case LegendTable::ColumnPenWidth:
    case LegendTable::ColumnSymbolSize:
    case LegendTable::ColumnSymbolPenWidth:
      QItemDelegate::paint(painter, option, index);
      break;
    case LegendTable::ColumnPenColor:
    case LegendTable::ColumnSymbolPenColor:
    case LegendTable::ColumnSymbolBrushColor:
    case LegendTable::ColumnTextColor: {
        drawBackground(painter, option, index);
        QColor c=index.model() ->data(index).value<QColor>();
        painter->fillRect(p.x()-8, p.y()-8, 16, 16 , c);
      }
      break;
    case LegendTable::ColumnPenStyle:
    case LegendTable::ColumnSymbolPenStyle: {
        drawBackground(painter, option, index);
        Qt::PenStyle s=(Qt::PenStyle) index.model() ->data(index).toInt();
        painter->fillRect(p.x()-16, p.y()-8, 32, 16, Qt::white);
        painter->setPen(QPen( Qt::black, 0, s) );
        painter->drawLine(p.x()-16, p.y(), p.x()+16, p.y());
      }
      break;
    case LegendTable::ColumnSymbolType: {
        drawBackground(painter, option, index);
        Symbol::Type t=(Symbol::Type) index.model() ->data(index).toInt();
        painter->fillRect(p.x()-8, p.y()-8, 16, 16, Qt::white);
        Symbol s(t, 3.5);
        s.paint( *painter, QPointF(p.x()-1, p.y()-1));
      }
      break;
    case LegendTable::ColumnSymbolBrushStyle: {
        drawBackground(painter, option, index);
        Qt::BrushStyle s=(Qt::BrushStyle) index.model() ->data(index).toInt();
        painter->fillRect(p.x()-8, p.y()-8, 16, 16, Qt::white);
        painter->setPen(QPen( Qt::NoPen) );
        painter->setBrush(QBrush( Qt::black, s) );
        painter->drawRect(p.x()-8, p.y()-8, 16, 16);
      }
      break;
    }
  }
}

void LegendTableDelegate::colorClicked(const QModelIndex& index)
{
  TRACE;
  switch (column(index.column())) {
  case LegendTable::ColumnNull:
  case LegendTable::ColumnText:
  case LegendTable::ColumnPenWidth:
  case LegendTable::ColumnSymbolSize:
  case LegendTable::ColumnSymbolPenWidth:
  case LegendTable::ColumnPenStyle:
  case LegendTable::ColumnSymbolPenStyle:
  case LegendTable::ColumnSymbolType:
  case LegendTable::ColumnSymbolBrushStyle:
    break;
  case LegendTable::ColumnPenColor:
  case LegendTable::ColumnSymbolPenColor:
  case LegendTable::ColumnSymbolBrushColor:
  case LegendTable::ColumnTextColor: {
      QColor c=index.model()->data(index).value<QColor>();
      c=QColorDialog::getColor(c, Application::activeWindow());
      if(c.isValid()) {
        const_cast<QAbstractItemModel *>(index.model())->setData(index, c);
        emit dataChanged();
      }
    }
    break;
  }
}

void LegendTableDelegate::commitWidget(QWidget * w)
{
  TRACE;
  if(! w) {
    w=qobject_cast<QWidget *>(sender());
    ASSERT(w);
  }
  emit commitData(w);
}

} // namespace SciFigs
