/***************************************************************************
 *  Copyright (C) 2006 by Carsten Niehaus <cniehaus@kde.org>
 *  Copyright (C) 2007-2008 by Marcus D. Hanwell <marcus@cryos.org>
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program 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.                                   *
 *                                                                         *
 ***************************************************************************/
#include "kalziumglwidget.h"

#include <QSettings>

#include <avogadro/primitive.h>
#include <avogadro/pluginmanager.h>
#include <avogadro/toolgroup.h>
#include <avogadro/engine.h>

#include "openbabel2wrapper.h"

#include <config-kalzium.h>

KalziumGLWidget::KalziumGLWidget(QWidget *parent) : Avogadro::GLWidget(parent),
  m_lastEngine1(0), m_lastEngine2(0)
{
    // work around a bug in OpenBabel: the chemical data files parsing
    // is dependent on the LC_NUMERIC locale.
    m_lc_numeric = QByteArray(setlocale(LC_NUMERIC, 0));
    setlocale(LC_NUMERIC, "C");

    // Prevent What's this from intercepting right mouse clicks
    setContextMenuPolicy(Qt::PreventContextMenu);
    // Load the tools and set navigate as the default
    // first set the Avogadro plugin directory,
    // avoiding overwriting an already set envvar
    static bool s_pluginDirSet = false;
    if (!s_pluginDirSet)
    {
        if (qgetenv("AVOGADRO_PLUGINS").isEmpty())
        {
            qputenv("AVOGADRO_PLUGINS", AVOGADRO_PLUGIN_DIR);
        }
        s_pluginDirSet = true;
    }
    Avogadro::PluginManager *manager = Avogadro::PluginManager::instance();
    manager->loadFactories();
    Avogadro::ToolGroup* tools = new Avogadro::ToolGroup(this);
    tools->append(manager->tools(this));
    tools->setActiveTool("Navigate");
    setToolGroup(tools);
    // Set the default engine to be active
    loadDefaultEngines();

    // Set the default quality level to high
    setQuality(2);

    setMolecule(new Avogadro::Molecule(this));
    update();
}

KalziumGLWidget::~KalziumGLWidget()
{
    //restore the LC_NUMERIC locale.
    setlocale(LC_NUMERIC, m_lc_numeric.constData());
}

bool KalziumGLWidget::openFile(const QString &file)
{
    Avogadro::Molecule* mol = OpenBabel2Wrapper::readMolecule( file );
    if (!mol)
        return false;
    Avogadro::Molecule* oldmol = molecule();
    if (oldmol)
        oldmol->deleteLater();
    setMolecule( mol );
    update();
    return true;
}

void KalziumGLWidget::setStyle( int style )
{
    foreach(Avogadro::Engine *engine, engines())
    {
        if((m_lastEngine1 == 0 && engine->identifier() == "Ball and Stick")
           || (m_lastEngine1 == 1 && engine->identifier() == "Stick")
           || (m_lastEngine1 == 2 && engine->identifier() == "Van der Waals Spheres")
           || (m_lastEngine1 == 3 && engine->identifier() == "Wireframe"))
        {
            engine->setEnabled(false);
        }
        if((style == 0 && engine->identifier() == "Ball and Stick")
           || (style == 1 && engine->identifier() == "Stick")
           || (style == 2 && engine->identifier() == "Van der Waals Spheres")
           || (style == 3 && engine->identifier() == "Wireframe"))
        {
            engine->setEnabled(true);
        }
    }
    m_lastEngine1 = style;
    update();
}

void KalziumGLWidget::setStyle2( int style )
{
    foreach(Avogadro::Engine *engine, engines())
    {
        if((m_lastEngine2 == 1 && engine->identifier() == "Ribbon")
           || (m_lastEngine2 == 2 && engine->identifier() == "Ring")
           || (m_lastEngine2 == 3 && engine->identifier() == "Orbitals"))
        {
            engine->setEnabled(false);
        }
        if((style == 1 && engine->identifier() == "Ribbon")
           || (style == 2 && engine->identifier() == "Ring")
           || (style == 3 && engine->identifier() == "Orbitals"))
        {
            engine->setEnabled(true);
        }
    }
    m_lastEngine2 = style;
    update();
}

void KalziumGLWidget::setLabels(int style)
{
  // Use the QSettings framework to configure the label engine
  foreach(Avogadro::Engine *engine, engines())
  {
    if(engine->name() == "Label")
    {
      QSettings settings;
      int atomType = 0;
      int bondType = 0;
      bool enabled = false;
      // We need to use 
      switch(style)
      {
        case 0: // Display no labels
          enabled = false;
          break;
        case 1: // Display the atom index
          enabled = true;
          atomType = 1;
          break;
        case 2: // Display the atom symbol
          enabled = true;
          atomType = 3;
          break;
        case 3: // Display the atom name
          enabled = true;
          atomType = 2;
          break;
        default:
          engine->setEnabled(false);
      }
      settings.setValue("atomLabel", atomType);
      settings.setValue("bondLabel", bondType);
      settings.setValue("enabled", enabled);
      engine->readSettings(settings);
    }
  }
}

void KalziumGLWidget::setQuality(int quality)
{
    // Set the global quality of the GLWidget, 0=min, 2=mid, 4=max
    int q = 0;
    if(quality == 1) q = 2;
    else if(quality == 2) q = 4;
    GLWidget::setQuality(q);
    invalidateDLs();
    GLWidget::update();
}

#include "kalziumglwidget.moc"
