// XDrawChem
// Copyright (C) 2004-2005  Bryan Herger <bherger@users.sourceforge.net>
// Copyright (C) 2020  Yaman Qalieh <ybq987@gmail.com>

// 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 3 of the License, or
// (at your option) any later version.

// This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.

#include <cerrno>
#include <cstdio>
#include <cstdlib>

#include <QBitmap>
#include <QtGlobal>

#include "application.h"
#include "chemdata.h"
#include "defs.h"
#include "prefs.h"
#include "render2d.h"

extern Preferences preferences;

// canned structure images
#include "aa_xpm.h"
#include "na_xpm.h"
#include "ring_xpm.h"
#include "sugar_xpm.h"

QMenu *ApplicationWindow::BuildNewRingMenu() {
    QMenu *ringSub = new QMenu(this);
    qInfo() << "BuildNewRingMenu";
    // make ring list
    QMenu *genericSub = new QMenu(tr("Rings"), ringSub);
    ring3Action = genericSub->addAction(QIcon(QPixmap(r_cyclopropane)), tr("[*] Cyclopropane"));
    ring3Action->setData(QString(":/ring_cml/cyclopropane.cml"));

    ring4Action = genericSub->addAction(QIcon(QPixmap(r_cyclobutane)), tr("[*] Cyclobutane"));
    ring4Action->setData(QString(":/ring_cml/cyclobutane.cml"));

    ring5Action = genericSub->addAction(QIcon(QPixmap(r_cyclopentane)), tr("[*] Cyclopentane"));
    ring5Action->setData(QString(":/ring_cml/cyclopentane.cml"));

    ringImidazoleAction = genericSub->addAction(QIcon(QPixmap(r_imidazole)), tr("Imidazole"));
    ringImidazoleAction->setData(QString(":/ring_cml/imidazole.cml"));

    ringCyclopentadieneAction =
        genericSub->addAction(QIcon(QPixmap(r_cyclopentadiene)), tr("[*] Cyclopentadiene"));
    ringCyclopentadieneAction->setData(QString(":/ring_cml/cyclopentadiene.cml"));

    ring6Action = genericSub->addAction(QIcon(QPixmap(r_6flat)), tr("[*] Cyclohexane (flat)"));
    ring6Action->setData(QString(":/ring_cml/cyclohexane.cml"));

    ring6BoatAction = genericSub->addAction(QIcon(QPixmap(r_6boat)), tr("Cyclohexane (boat)"));
    ring6BoatAction->setData(QString(":/ring_cml/6ring_boat.cml"));

    ring6ChairAction = genericSub->addAction(QIcon(QPixmap(r_6chair)), tr("Cyclohexane (chair)"));
    ring6ChairAction->setData(QString(":/ring_cml/6ring_chair.cml"));

    ringBenzeneAction = genericSub->addAction(QIcon(QPixmap(r_benzene)), tr("[*] Benzene"));
    ringBenzeneAction->setData(QString(":/ring_cml/benzene.cml"));

    ringPyrimidineAction = genericSub->addAction(QIcon(QPixmap(r_pyrimidine)), tr("Pyrimidine"));
    ringPyrimidineAction->setData(QString(":/ring_cml/pyrimidine.cml"));

    ring7Action = genericSub->addAction(QIcon(QPixmap(ring7)), tr("[*] Cycloheptane"));
    ring7Action->setData(QString(":/ring_cml/cycloheptane.cml"));

    ring8Action = genericSub->addAction(QIcon(QPixmap(ring8)), tr("[*] Cyclooctane"));
    ring8Action->setData(QString(":/ring_cml/cyclooctane.cml"));

    ringIndoleAction = genericSub->addAction(QIcon(QPixmap(r_indole)), tr("Indole"));
    ringIndoleAction->setData(QString(":/ring_cml/indole.cml"));

    ringPurineAction = genericSub->addAction(QIcon(QPixmap(r_purine)), tr("Purine"));
    ringPurineAction->setData(QString(":/ring_cml/purine.cml"));

    ringNaphAction = genericSub->addAction(QIcon(QPixmap(naphthalene_xpm)), tr("Naphthalene"));
    ringNaphAction->setData(QString(":/ring_cml/naphthalene.cml"));

    ringBiphenylAction = genericSub->addAction(QIcon(QPixmap(biphenyl_xpm)), tr("Biphenyl"));
    ringBiphenylAction->setData(QString(":/ring_cml/biphenyl.cml"));

    ringAnthraAction = genericSub->addAction(QIcon(QPixmap(anthracene_xpm)), tr("Anthracene"));
    ringAnthraAction->setData(QString(":/ring_cml/anthracene.cml"));

    ringSteroidAction =
        genericSub->addAction(QIcon(QPixmap(r_steroid)), tr("Steroid (fused ring template)"));
    ringSteroidAction->setData(QString(":/ring_cml/steroid.cml"));

    ringSub->addMenu(genericSub);

    // make amino acid list
    QAction *aaAction;
    QMenu *aaSub = new QMenu(tr("Amino acids"), this);
    aaAction = aaSub->addAction(QIcon(QPixmap(aa_ala)), tr("Alanine"));
    aaAction->setData(":/ring_cml/alanine.cml");
    aaAction = aaSub->addAction(QIcon(QPixmap(aa_arg)), tr("Arginine"));
    aaAction->setData(":/ring_cml/arginine.cml");
    aaAction = aaSub->addAction(QIcon(QPixmap(aa_asn)), tr("Asparagine"));
    aaAction->setData(":/ring_cml/asparagine.cml");
    aaAction = aaSub->addAction(QIcon(QPixmap(aa_asp)), tr("Aspartic acid"));
    aaAction->setData(":/ring_cml/aspartic_acid.cml");
    aaAction = aaSub->addAction(QIcon(QPixmap(aa_cys)), tr("Cysteine"));
    aaAction->setData(":/ring_cml/cysteine.cml");
    aaAction = aaSub->addAction(QIcon(QPixmap(aa_glu)), tr("Glutamic acid"));
    aaAction->setData(":/ring_cml/glutamic_acid.cml");
    aaAction = aaSub->addAction(QIcon(QPixmap(aa_gln)), tr("Glutamine"));
    aaAction->setData(":/ring_cml/glutamine.cml");
    aaAction = aaSub->addAction(QIcon(QPixmap(aa_gly)), tr("Glycine"));
    aaAction->setData(":/ring_cml/glycine.cml");
    aaAction = aaSub->addAction(QIcon(QPixmap(aa_his)), tr("Histidine"));
    aaAction->setData(":/ring_cml/histidine.cml");
    aaAction = aaSub->addAction(QIcon(QPixmap(aa_ile)), tr("Isoleucine"));
    aaAction->setData(":/ring_cml/isoleucine.cml");
    aaAction = aaSub->addAction(QIcon(QPixmap(aa_leu)), tr("Leucine"));
    aaAction->setData(":/ring_cml/leucine.cml");
    aaAction = aaSub->addAction(QIcon(QPixmap(aa_lys)), tr("Lysine"));
    aaAction->setData(":/ring_cml/lysine.cml");
    aaAction = aaSub->addAction(QIcon(QPixmap(aa_met)), tr("Methionine"));
    aaAction->setData(":/ring_cml/methionine.cml");
    aaAction = aaSub->addAction(QIcon(QPixmap(aa_nph)), tr("Nitrophenylalanine"));
    aaAction->setData(":/ring_cml/nitrophenylalanine.cml");
    aaAction = aaSub->addAction(QIcon(QPixmap(aa_phe)), tr("Phenylalanine"));
    aaAction->setData(":/ring_cml/phenylalanine.cml");
    aaAction = aaSub->addAction(QIcon(QPixmap(aa_pro)), tr("Proline"));
    aaAction->setData(":/ring_cml/proline.cml");
    aaAction = aaSub->addAction(QIcon(QPixmap(aa_ser)), tr("Serine"));
    aaAction->setData(":/ring_cml/serine.cml");
    aaAction = aaSub->addAction(QIcon(QPixmap(aa_statine)), tr("Statine"));
    aaAction->setData(":/ring_cml/statine.cml");
    aaAction = aaSub->addAction(QIcon(QPixmap(aa_thr)), tr("Threonine"));
    aaAction->setData(":/ring_cml/threonine.cml");
    aaAction = aaSub->addAction(QIcon(QPixmap(aa_trp)), tr("Tryptophan"));
    aaAction->setData(":/ring_cml/tryptophan.cml");
    aaAction = aaSub->addAction(QIcon(QPixmap(aa_tyr)), tr("Tyrosine"));
    aaAction->setData(":/ring_cml/tyrosine.cml");
    aaAction = aaSub->addAction(QIcon(QPixmap(aa_val)), tr("Valine"));
    aaAction->setData(":/ring_cml/valine.cml");

    ringSub->addMenu(aaSub);

    // make nucleic acid list
    QMenu *naSub = new QMenu(tr("Nucleic acids"), this);
    naAdenineAction = naSub->addAction(QIcon(QPixmap(na_adenine)), tr("Adenine"));
    naAdenineAction->setData(":/ring_cml/adenine.cml");
    naCytosineAction = naSub->addAction(QIcon(QPixmap(na_cytosine)), tr("Cytosine"));
    naCytosineAction->setData(":/ring_cml/cytosine.cml");
    naGuanineAction = naSub->addAction(QIcon(QPixmap(na_guanine)), tr("Guanine"));
    naGuanineAction->setData(":/ring_cml/guanine.cml");
    naThymineAction = naSub->addAction(QIcon(QPixmap(na_thymine)), tr("Thymine"));
    naThymineAction->setData(":/ring_cml/thymine.cml");
    naUracilAction = naSub->addAction(QIcon(QPixmap(na_uracil)), tr("Uracil"));
    naUracilAction->setData(":/ring_cml/uracil.cml");

    ringSub->addMenu(naSub);

    // make sugar list
    QMenu *sugarSub = new QMenu(tr("Sugars"), this);
    srAction = sugarSub->addAction(QIcon(QPixmap(s_ribose)), tr("Ribose"));
    srAction->setData(":/ring_cml/ribose.cml");
    sdAction = sugarSub->addAction(QIcon(QPixmap(s_deoxyribose)), tr("Deoxyribose"));
    sdAction->setData(":/ring_cml/deoxyribose.cml");
    sfAction = sugarSub->addAction(QIcon(QPixmap(s_d_fructose)), tr("D-fructose"));
    sfAction->setData(":/ring_cml/d-fructose.cml");
    sgAction = sugarSub->addAction(QIcon(QPixmap(s_d_glucose)), tr("D-glucose"));
    sgAction->setData(":/ring_cml/d-glucose.cml");

    ringSub->addMenu(sugarSub);

    // make function group list
    QMenu *fgSub = new QMenu(tr("Useful groups"), this);
    fgSub->addAction(tr("[*] FMOC"))->setData(":/ring_cml/fmoc.cml");
    fgSub->addAction(tr("[*] BOC"))->setData(":/ring_cml/boc.cml");
    fgSub->addAction(tr("[*] DABCYL"))->setData(":/ring_cml/dabcyl.cml");
    fgSub->addAction(tr("[*] DABSYL"))->setData(":/ring_cml/dabsyl.cml");
    fgSub->addAction(tr("[*] DANSYL"))->setData(":/ring_cml/dansyl.cml");
    fgSub->addAction(tr("[*] EDANS"))->setData(":/ring_cml/edans.cml");
    fgSub->addAction(tr("[*] Biotin"))->setData(":/ring_cml/biotin.cml");

    ringSub->addMenu(fgSub);

    // make user-defined list
    QMenu *customMenu = BuildCustomRingMenu();
    ringSub->addMenu(customMenu);
    customRingMenuAction = customMenu->menuAction();

    return ringSub;
}

QMenu *ApplicationWindow::BuildCustomRingMenu() {
    QMenu *userDefSub = new QMenu(tr("User-defined"), this);
    QDir d(preferences.getCustomRingDir(), "*.png");

    ringlist = d.entryList();
    QAction *customAction;
    for (int cc = 0; cc < ringlist.count(); cc++) {
        QPixmap px1(QString(preferences.getCustomRingDir() + ringlist[cc]));
        QBitmap mask1(px1.width(), px1.height());

        mask1.fill(Qt::color1);
        px1.setMask(mask1);
        /*userDefSub->addAction( QPixmap( QString(RingDir + ringlist[cc]) ),
           ringlist[cc],
           this, FromRingMenu(int)), 0, cc ); */
        QString name = ringlist[cc].left(ringlist[cc].length() - 4);
        customAction = userDefSub->addAction(QIcon(px1), name);
        customAction->setData(preferences.getCustomRingDir() + name + ".cml");
    }
    userDefSub->addAction(tr("Add new..."), this, SLOT(saveCustomRing()));

    return userDefSub;
}

void ApplicationWindow::setRingAction(QAction *action) {
    qInfo() << "setRingAction() invoked with data " << action->data();
    if (action->data().isNull())
        return;
    drawRingButton->setDefaultAction(action);
    m_renderer->setMode_DrawRing(action->data().toString(), action->iconText(), 1);
}
