/*
 * Project: MoleCuilder
 * Description: creates and alters molecular systems
 * Copyright (C)  2017 Frederik Heber. All rights reserved.
 *
 *
 *   This file is part of MoleCuilder.
 *
 *    MoleCuilder 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 2 of the License, or
 *    (at your option) any later version.
 *
 *    MoleCuilder 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 MoleCuilder.  If not, see .
 */
/*
 * QtGeometryList.cpp
 *
 *  Created on: Mar 25, 2017
 *      Author: heber
 */
// include config.h
#ifdef HAVE_CONFIG_H
#include 
#endif
#include "Views/Qt4/QtGeometryList.hpp"
#include 
//#include "CodePatterns/MemDebug.hpp"
#include "CodePatterns/Observer/Notification.hpp"
#include "CodePatterns/toString.hpp"
#include "Geometry/GeometryRegistry.hpp"
#include 
#include 
using namespace std;
const int QtGeometryList::COLUMNCOUNT = COLUMNTYPES_MAX;
const char *QtGeometryList::COLUMNNAMES[QtGeometryList::COLUMNCOUNT]={"Name","Vector"};
QtGeometryList::QtGeometryList(QWidget * _parent) :
    QTreeWidget (_parent),
    Observer("QtGeometryList"),
    geometryregistry_enabled(false)
{
  setColumnCount(COLUMNCOUNT);
  setSelectionMode(QAbstractItemView::SingleSelection);
  setSortingEnabled(true);
  QStringList header;
	for(int i=0; iinstallEventFilter(this);
}
QtGeometryList::~QtGeometryList()
{
  if (geometryregistry_enabled) {
    GeometryRegistry::getInstance().signOff(this);
    GeometryRegistry::getInstance().signOff(this, GeometryRegistry::GeometryInserted);
    GeometryRegistry::getInstance().signOff(this, GeometryRegistry::GeometryRemoved);
  }
}
void QtGeometryList::subjectKilled(Observable *publisher)
{
  // as a new instance should always already be present ... just sign on
  if (static_cast(publisher) == GeometryRegistry::getPointer()) {
    geometryregistry_enabled = false;
  }
}
void QtGeometryList::update(Observable *publisher) {}
void QtGeometryList::recieveNotification(Observable *publisher, Notification_ptr notification)
{
  if (static_cast(publisher) == GeometryRegistry::getPointer()) {
    switch (notification->getChannelNo()) {
      case GeometryRegistry::GeometryInserted:
      {
        refill(NULL);
        break;
      }
      case GeometryRegistry::GeometryRemoved:
      {
        refill(GeometryRegistry::getInstance().lastChanged());
        break;
      }
      default:
        ASSERT(0, "QtGeometryList::recieveNotification() - we cannot get here.");
        break;
    }
  }
}
void QtGeometryList::refill(::GeometryObject *ignore)
{
  boost::recursive_mutex::scoped_lock lock(refill_mutex);
  clear();
  GeometryRegistry ® = GeometryRegistry::getInstance();
  GeometryRegistry::const_iterator iter;
  for (iter = reg.getBeginIter(); iter != reg.getEndIter(); iter ++){
    ::GeometryObject *v = iter->second;
    if (v == ignore)
      continue;
    QTreeWidgetItem *treeItem = new QTreeWidgetItem(this);
    treeItem->setText(NAME, QString(v->getName().c_str()));
    treeItem->setText(VECTOR, QString(toString(v->getVector()).c_str()));
  }
}
void QtGeometryList::paintEvent(QPaintEvent * event)
{
  boost::recursive_mutex::scoped_lock lock(refill_mutex);
  /*if (dirty)
    refill(NULL);*/
  QTreeWidget::paintEvent(event);
}
bool QtGeometryList::eventFilter(QObject* object, QEvent* event)
{
    if(event->type() == QEvent::MouseMove)
    {
         mouseMoveFunction(static_cast(event));
    }
    // Repeat for other mouse events
   // returning true blocks event returning false doesnt so if you want to block all mouse events except what your handling then return true inside each of your ifs
   return false;
}
void QtGeometryList::mouseMoveFunction(QMouseEvent * event)
{
  boost::recursive_mutex::scoped_lock lock(refill_mutex);
  if (event->type() == QEvent::MouseMove) {
    QTreeWidgetItem* current = itemAt(event->pos());
    if (current == NULL)
      return;
    // reset all tooltips
    bool NoneSelected = true;
    for (int i=0;isetToolTip(NAME, tr(""));
      item->setToolTip(VECTOR, tr(""));
      NoneSelected &= !item->isSelected();
    }
    const std::string name = current->text(NAME).toStdString();
    GeometryObject *v = GeometryRegistry::getInstance().getByName(name);
    const Vector currentVec = v->getVector();
    if ((NoneSelected) || (current->isSelected())) {
      // show norm
      std::string tooltiptext("Length:");
      tooltiptext += toString(currentVec.Norm());
      tooltiptext += std::string(" Angström");
      current->setToolTip(NAME, trUtf8(tooltiptext.c_str()));
      current->setToolTip(VECTOR, trUtf8(tooltiptext.c_str()));
    } else {
      for (int i=0;iisSelected()) {
          // show angle
          const std::string othername = item->text(NAME).toStdString();
          GeometryObject *otherv = GeometryRegistry::getInstance().getByName(othername);
          const Vector otherVec = otherv->getVector();
          std::string tooltiptext("Angle:");
          tooltiptext += toString(currentVec.Angle(otherVec)*180/M_PI);
          tooltiptext += std::string(" deg");
          current->setToolTip(NAME, trUtf8(tooltiptext.c_str()));
          current->setToolTip(VECTOR, trUtf8(tooltiptext.c_str()));
          break;
        }
      }
    }
  }
}