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

#include <GeopsyCore.h>
#include <GeopsyGui.h>

#include "Engine.h"
#include "GroupProperties.h"

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

  Full description of class still missing
*/

/*!
  Description of constructor still missing
*/
GroupProperties::GroupProperties(QWidget * parent)
    : PropertyWidget(parent)
{
  TRACE;
  setupUi(this);

  SignalGroupItem * gi=new SignalGroupItem(this);
  folderTree->setModel(gi);
  folderTree->header()->hide();
  folderTree->setSelectionBehavior(QAbstractItemView::SelectRows);
  folderTree->setSelectionMode(QAbstractItemView::SingleSelection);
  folderTree->setEditTriggers(QAbstractItemView::NoEditTriggers);
  folderTree->expandAll();
  // Populate key list
  multiGroupKey->addItems(MetaDataFactory::instance()->registeredNames());

  nameEdit->completer()->setCaseSensitivity(Qt::CaseSensitive);
  nameEdit->addItems(Settings::getHistory("GroupNames"));

  // Create properties
  addProperty(Name, nameEdit->lineEdit(), nameLabel);
  addProperty(Comments, commentsEdit, commentsLabel);
  addProperty(Folder, nullptr, folderLabel);
}

void GroupProperties::setDatabase(SignalDatabase * db)
{
  TRACE;
  static_cast<SignalGroupItem *>(folderTree->model())->setDatabase(db);
}

void GroupProperties::removeMultiGroup()
{
  TRACE;
  delete multiGroupBox;
  multiGroupBox=nullptr;
}

void GroupProperties::on_multiGroupBox_toggled(bool on)
{
  TRACE;
  if(on && nameEdit->currentText().isEmpty()) {
    nameEdit->setEditText(tr("group {Return=justify(GroupIndex,4,\"0\");}"));
  }
}

void GroupProperties::on_multiGroupKey_currentIndexChanged(int)
{
  TRACE;
  MetaDataIndex index=MetaDataFactory::instance()->index(multiGroupKey->currentText());
  multiGroupKeyIndex->setEnabled(MetaDataFactory::instance()->count(index) & multiGroupBox->isChecked());
}

void GroupProperties::on_multiGroupKeyButton_toggled(bool checked)
{
  TRACE;
  checked&=multiGroupBox->isChecked();
  multiGroupKey->setEnabled(checked);
  multiGroupKeyIndex->setEnabled(checked);
}

bool GroupProperties::isMultiGroupKey()
{
  TRACE;
  return multiGroupBox && multiGroupBox->isChecked() && multiGroupKeyButton->isChecked();
}

bool GroupProperties::isMultiGroupArray()
{
  TRACE;
  return multiGroupBox && multiGroupBox->isChecked() && multiGroupArrayButton->isChecked();
}

MetaDataIndex GroupProperties::splitKey()
{
  TRACE;
  MetaDataIndex index=MetaDataFactory::instance()->index(multiGroupKey->currentText());
  index.setIndex(multiGroupKeyIndex->text());
  return index;
}

void GroupProperties::setValues(QList<AbstractSignalGroup *> gList)
{
  TRACE;
  QList< AbstractSignalGroup*>::iterator it;
  for(it=gList.begin(); it!=gList.end(); it++) {
    checkValues(*it);
  }
  setWidgets();
  if(gList.count()==1) {
    AbstractSignalGroup * g=gList.first();
    infoLabel->setText(tr("Group containing %1 signals and %2 child(ren)").arg(g->signalCount()).arg(g->childrenCount()));
    SubSignalPool s=g->subPool();
    bool f=App::freeze(true); // Avoid message complaining about 3 components
    if(!s.associate3Components() && multiGroupBox) {
      multiGroupArrayButton->setEnabled(false);
      multiGroupKeyButton->setChecked(true);
    }
    App::freeze(f);
  } else if(gList.count()>1) {
    infoLabel->setText(tr("Several groups selected"));
    if(multiGroupBox) {
      multiGroupBox->setEnabled(false);
    }
  }
  if(gList.count()>0) {
    AbstractSignalGroup * g=gList.first();
    if(g->parent()) {
      SignalGroupItem * gi=static_cast<SignalGroupItem *>(folderTree->model());
      folderTree->setCurrentIndex(gi->index(g->parent()));
    }
  }
}

/*!
  Set current name from history if history contains items and if current name is empty.
*/
void GroupProperties::setNameFromHistory()
{
  TRACE;
  if(nameEdit->currentText().isEmpty() && nameEdit->count()>0) {
    nameEdit->setEditText(nameEdit->itemText(0));
  }
}

void GroupProperties::checkValues(AbstractSignalGroup * g)
{
  TRACE;
  if(!g) return ;
  // Bug found at least on one dirty Linux environment: automatic naming of group
  // resulted in a very long name, not properly handled by the underlying X11 system.
  if(g->name().count()>200) {
    setValue(Name, g->name().left(200)+"...");
  } else {
    setValue(Name, g->name());
  }
  setValue(Comments, g->comments());
#if QT_POINTER_SIZE==8
  setValue(Folder, (qint64)g->parent());
#else
  setValue(Folder, (qint32)g->parent());
#endif
}

void GroupProperties::setProperties(AbstractSignalGroup * g)
{
  TRACE;
  if(propertyValue(Name)->isTouched()) {
    g->setName(nameEdit->currentText());
  }
  if(propertyValue(Comments)->isTouched()) {
    g->setComments(commentsEdit->toPlainText());
  }
}

AbstractSignalGroup * GroupProperties::folder()
{
  TRACE;
  QModelIndex i=folderTree->currentIndex();
  if(i.isValid()) {
    return SignalGroupItem::group(i);
  } else {
    return Engine::instance()->database(this)->masterGroup();
  }
}

void GroupProperties::on_folderTree_clicked(const QModelIndex & index)
{
  TRACE;
  propertyValue(Folder)->setTouched();
  // Make sure it is the current index
  folderTree->setCurrentIndex(index);
}

