/***************************************************************************
**
**  This file is part of QGpGuiTools.
**
**  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: 2007-11-25
**  Copyright: 2007-2019
**    Marc Wathelet
**    Marc Wathelet (LGIT, Grenoble, France)
**
***************************************************************************/

#include <QtGui>

#include "XMLItem.h"

namespace QGpGuiTools {

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

  Full description of class still missing
*/

/*!
  Description of constructor still missing
*/
XMLItem::XMLItem(QObject * parent)
    : QAbstractItemModel(parent)
{
  TRACE;
}

void XMLItem::setText(QString xml)
{
  TRACE;
  XMLHeader hdr(&_rootItem);
  hdr.xml_restoreString(xml);
}

QString XMLItem::saveString()
{
  TRACE;
  XMLHeader hdr(&_rootItem);
  return hdr.xml_saveString();
}

QByteArray XMLItem::saveByteArray()
{
  TRACE;
  XMLHeader hdr(&_rootItem);
  return hdr.xml_saveByteArray();
}

void XMLItem::saveFile(QString fileName)
{
  TRACE;
  XMLHeader hdr(&_rootItem);
  hdr.xml_saveFile(fileName);
}

int XMLItem::rowCount(const QModelIndex &parent) const
{
  TRACE;
  if(!parent.isValid()) return 1;
  const XMLGenericItem * oParent=xmlItem(parent);
  return oParent->childrenCount();
}

/*!
  Currently return only 1 but may evolve in the future
*/
int XMLItem::columnCount(const QModelIndex &) const
{
  TRACE;
  return 3;
}

QVariant XMLItem::data(const QModelIndex &index, int role) const
{
  TRACE;
  if (!index.isValid()) return QVariant();
  XMLGenericItem * o=xmlItem(index);
  switch (role) {
  case Qt::DisplayRole:
    switch(index.column()) {
    case 0:
      return o->xml_tagName();
    case 1:
      return o->value();
    default:
      break;
    }
    break;
  case Qt::EditRole:
    switch(index.column()) {
    case 1:
      return o->value();
    default:
      break;
    }
    break;
  case Qt::ToolTipRole: {
      XMLSaveAttributes attributes;
      o->xml_attributes(attributes, 0);
      return attributes.toString();
    }
  case Qt::CheckStateRole:
    if(index.column()==2) {
      return o->isEnabled() ? Qt::Checked : Qt::Unchecked;
    }
    break;
  default:
    break;
  }
  return QVariant();
}

bool XMLItem::setData (const QModelIndex & index, const QVariant & value, int role)
{
  TRACE;
  if (!index.isValid()) return false;
  XMLGenericItem * o=xmlItem(index);
  switch (role) {
  case Qt::EditRole:
    if(index.column()==1) {
      o->setValue(value);
      return true;
    }
    break;
  case Qt::CheckStateRole:
    if(index.column()==2) {
      o->setEnabled(value==Qt::Checked);
      emit(includeChanged(index));
      return true;
    }
    break;
  default:
    break;
  }
  return false;
}

QVariant XMLItem::headerData(int section, Qt::Orientation orientation, int role) const
{
  TRACE;
  if(role!=Qt::DisplayRole) return QVariant();
  if(orientation==Qt::Horizontal) {
    switch(section) {
    case 0:
      return tr("Property name");
    case 1:
      return tr("Value");
    case 2:
      return tr("Included?");
    default:
      break;
    }
  }
  return QVariant();
}

QModelIndex XMLItem::parent(const QModelIndex & index) const
{
  TRACE;
  if(!index.isValid()) return QModelIndex();
  XMLGenericItem * o=xmlItem(index);
  XMLGenericItem * parent=o->parent();
  if(parent) {
    return createIndex(parent->containerIndex(), 0, parent);
  } else
    return QModelIndex();
}

QModelIndex XMLItem::index(int row, int column, const QModelIndex & parent) const
{
  TRACE;
  if( !parent.isValid()) return createIndex(row, column, (void *)&_rootItem);
  XMLGenericItem * o=xmlItem(parent);
  XMLGenericItem * oi=static_cast<XMLGenericItem *>(o->containerAt(row));
  if(oi)
    return createIndex(row, column, oi);
  else
    return QModelIndex();
}

XMLGenericItem * XMLItem::xmlItem(const QModelIndex& index) const
{
  TRACE;
  return static_cast<XMLGenericItem *>(index.internalPointer());
}

QModelIndex XMLItem::index(XMLGenericItem * o)
{
  TRACE;
  if(o) {
    if(o->parent()) {
      return createIndex(o->parent()->rank(o) , 0, o);
    } else {
      return createIndex(0 , 0, o);
    }
  } else {
    return QModelIndex();
  }
}

Qt::ItemFlags XMLItem::flags(const QModelIndex & index) const
{
  Qt::ItemFlags f=Qt::ItemIsSelectable;
  // Editable or not?
  XMLGenericItem * o=xmlItem(index);
  switch(index.column()) {
  case 1:
    if(o->childrenCount()==0) {
      f|=Qt::ItemIsEditable;
    }
    break;
  case 2:
    if(index.parent().isValid()) {
      f|=Qt::ItemIsUserCheckable;
    }
    break;
  default:
    break;
  }
  // Enabled or not
  // 20130904: fixed that item are disabled when not included.
  //           it was impossible to include them again
  if(o->isParentEnabled()) {
    f|=Qt::ItemIsEnabled;
  }
  return f;
}

QList<XMLGenericItem *> XMLItem::getSelection(const QItemSelectionModel& sm)
{
  TRACE;
  QModelIndexList l=sm.selectedIndexes();
  QList<XMLGenericItem *> sel;
  for(QModelIndexList::iterator it=l.begin(); it!=l.end(); it++) {
    sel.append(xmlItem(*it));
  }
  std::sort(sel.begin(), sel.end());
  unique(sel);
  return sel;
}

} // namespace QGpGuiTools
