/***************************************************************************
**
**  This file is part of QGpGuiWave.
**
**  QGpGuiWave is free software: you can redistribute it and/or modify
**  it under the terms of the GNU General Public License as published by
**  the Free Software Foundation, either version 3 of the License, or
**  (at your option) any later version.
**
**  QGpGuiWave 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.
**
**  You should have received a copy of the GNU General Public License
**  along with Foobar.  If not, see <http://www.gnu.org/licenses/>
**
**  See http://www.geopsy.org for more information.
**
**  Created: 2007-02-08
**  Copyright: 2007-2019
**    Marc Wathelet
**    Marc Wathelet (LGIT, Grenoble, France)
**
***************************************************************************/

#include <QGpCoreWave.h>

#include "ModeItem.h"

namespace QGpGuiWave {

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

    Full description of class still missing
  */

  /*!
    Description of constructor still missing
  */
  ModeItem::ModeItem(QObject * parent)
    : QAbstractTableModel(parent)
  {
    _proxy=nullptr;
    _type=Mode::Dispersion;
  }

  /*!
    \fn ModeItem::~ModeItem()
    Description of destructor still missing
  */

  void ModeItem::setProxy(ModalProxy * p)
  {
    TRACE;
    beginResetModel();
    _proxy=p;
    endResetModel();
  }

  void ModeItem::setType(Mode::Type t)
  {
    TRACE;
    beginResetModel();
    _type=t;
    endResetModel();
  }

  void ModeItem::beginModeChange()
  {
    TRACE;
    beginResetModel();
  }

  void ModeItem::endModeChange()
  {
    TRACE;
    endResetModel();
  }

  int ModeItem::rowCount(const QModelIndex &) const
  {
    TRACE;
    if(!_proxy) return 0;
    return _proxy->modes().count();
  }

  int ModeItem::columnCount(const QModelIndex &) const
  {
    switch(_type) {
    case Mode::Dispersion:
      break;
    case Mode::Autocorr:
    case Mode::Ellipticity:
      return 2;
    }
    return 3;
  }

  QVariant ModeItem::data(const QModelIndex &index, int role) const
  {
    TRACE;
    const Mode& m=_proxy->modes().at(index.row());
    switch (role) {
    case Qt::DisplayRole:
      switch(_type) {
      case Mode::Dispersion:
        switch(index.column()) {
        case 0: return Mode::userSlowness(m.slowness());
        case 1: return Mode::userPolarization(m.polarization());
        case 2: return m.index();
        default: break;
        }
        break;
      case Mode::Autocorr:
        switch(index.column()) {
        case 0: return Mode::userPolarization(m.polarization());
        case 1: return m.index();
        default: break;
        }
        break;
      case Mode::Ellipticity:
        switch(index.column()) {
        case 0: return Mode::userValue(m.value());
        case 1: return m.index();
        default: break;
        }
        break;
      }
      break;
    default:
      break;
    }
    return QVariant();
  }

  bool ModeItem::setData (const QModelIndex & index, const QVariant & value, int role)
  {
    TRACE;
    Mode& m=_proxy->modes()[index.row()];
    switch (role) {
    case Qt::EditRole:
      switch(_type) {
      case Mode::Dispersion:
        switch(index.column()) {
        case 0: m.setSlowness(Mode::userSlowness(value.toString())); break;
        case 1: m.setPolarization(Mode::userPolarization(value.toString())); break;
        case 2: m.setIndex(value.toInt()); break;
        default: break;
        }
        break;
      case Mode::Autocorr:
        switch(index.column()) {
        case 0: m.setPolarization(Mode::userPolarization(value.toString())); break;
        case 1: m.setIndex(value.toInt()); break;
        default: break;
        }
        break;
      case Mode::Ellipticity:
        switch(index.column()) {
        case 0: m.setValue(Mode::userValue(value.toString())); break;
        case 1: m.setIndex(value.toInt()); break;
        default: break;
        }
        break;
      }
      return true;
    default:
      return false;
    }
  }

  QVariant ModeItem::headerData(int section, Qt::Orientation orientation, int role) const
  {
    TRACE;
    switch (role) {
    case Qt::DisplayRole:
      if(orientation==Qt::Horizontal) {
        switch(_type) {
        case Mode::Dispersion:
          switch (section) {
          case 0: return tr("Slowness");
          case 1: return tr("Polarization");
          case 2: return tr("Mode index");
          default: return 0;
          }
        case Mode::Autocorr:
          switch (section) {
          case 0: return tr("Polarization");
          case 1: return tr("Mode index");
          default: return 0;
          }
        case Mode::Ellipticity:
          switch (section) {
          case 0: return tr("Value");
          case 1: return tr("Mode index");
          default: return 0;
          }
        }
      } else {
        return section + 1;
      }
    default:
      return QVariant();
    }
  }

  void ModeItem::add(const Mode& m)
  {
    TRACE;
    int i=_proxy->modes().count();
    beginInsertRows(QModelIndex(), i,i);
    _proxy->addMode(m);
    endInsertRows();
  }

  void ModeItem::remove(const QItemSelectionModel * selModel)
  {
    TRACE;
    // Remove first layer only if count>1
    if(_proxy->modes().count()>1) {
      for(int i=_proxy->modes().count()-1; i>=0; i--) {
        if(selModel->rowIntersectsSelection(i, QModelIndex())) {
          beginRemoveRows(QModelIndex(), i, i);
          _proxy->removeMode(i);
          endRemoveRows();
        }
      }
    }
  }

} // namespace QGpGuiWave
