/******************************************************************************

  This source file is part of the Avogadro project.

  Copyright 2016 Barry E Moore II

  This source code is released under the New BSD License, (the "License").

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

******************************************************************************/

#include "3dmoldialog.h"
#include "ui_3dmoldialog.h"

#include <avogadro/core/elements.h>
#include <avogadro/qtgui/molecule.h>

#include <avogadro/io/fileformatmanager.h>

#include <string>

#include <QtGui/QClipboard>

using Avogadro::QtGui::Molecule;

namespace Avogadro {
namespace QtPlugins {

ThreeDMolDialog::ThreeDMolDialog(QtGui::Molecule* mol, QWidget* parent_)
  : QDialog(parent_), m_molecule(nullptr), m_ui(new Ui::ThreeDMolDialog)
{
  m_ui->setupUi(this);
  setMolecule(mol);
}

ThreeDMolDialog::~ThreeDMolDialog()
{
  delete m_ui;
}

void ThreeDMolDialog::setMolecule(QtGui::Molecule* mol)
{
  if (mol == m_molecule)
    return;

  if (m_molecule)
    m_molecule->disconnect(this);

  m_molecule = mol;

  if (!m_molecule)
    return;

  connect(m_molecule, SIGNAL(changed(unsigned int)), SLOT(updateLabels()));
  connect(m_molecule, SIGNAL(destroyed()), SLOT(moleculeDestroyed()));
  connect(m_ui->exitButton, SIGNAL(clicked()), SLOT(close()));
  connect(m_ui->copyButton, SIGNAL(clicked()), SLOT(copyToClipboard()));

  updateLabels();
}

void ThreeDMolDialog::updateLabels()
{
  if (m_molecule) {
    updateTextBrowser();
  } else {
    m_ui->plainTextEdit->clear();
  }
}

void ThreeDMolDialog::updateTextBrowser()
{
  QString text =
    "<script src='http://3Dmol.csb.pitt.edu/build/3Dmol-min.js'></script>\n";
  // MDL representation
  std::string mol;
  bool writeSDF =
    Io::FileFormatManager::instance().writeString(*m_molecule, mol, "sdf");
  text.append("<div style='height: 400px; width: 400px; position: relative;' "
              "class='viewer_3Dmoljs' data-element='molecule'");
  if (writeSDF)
    text.append(" data-type='sdf' data-backgroundcolor='0xffffff' "
                "data-style='stick'></div>\n");
  else
    text.append(" data-type='xyz' data-backgroundcolor='0xffffff' "
                "data-style='stick'></div>\n");

  text.append("<textarea id='molecule' style='display: none;'>");
  if (writeSDF) {
    text.append(mol.c_str());
  } else {
    // couldn't write MDL for some reason, write XYZ
    size_t numAtoms = m_molecule->atomCount();
    text.append(QString::number(numAtoms) + "\n");
    text.append("Generated by Avogadro.\n");

    for (size_t i = 0; i < numAtoms; ++i) {
      Core::Atom atom = m_molecule->atom(i);
      QString line("%1 %2 %3 %4\n");
      text.append(line.arg(Core::Elements::symbol(atom.atomicNumber()))
                    .arg(atom.position3d().x())
                    .arg(atom.position3d().y())
                    .arg(atom.position3d().z()));
    } // end for(atoms)
  }

  text.append("</textarea>");
  m_ui->plainTextEdit->setPlainText(text);
}

void ThreeDMolDialog::moleculeDestroyed()
{
  m_molecule = nullptr;
  updateLabels();
}

void ThreeDMolDialog::copyToClipboard()
{
  QApplication::clipboard()->setText(m_ui->plainTextEdit->toPlainText());
}

} // namespace QtPlugins
} // namespace Avogadro
