#include "exportccdlg.h"

ExportCCDlg::ExportCCDlg(QString _dirName, Molecule *_mole, QString fn){
    mole=_mole;
    dirName=_dirName;
    V3 Vo=V3(0,0,0);
    //double a0= 1.0 / 0.5291772109;
    f.setFileName(fn);
    QFileInfo fileInfo(f.fileName());
    filenameQM = fileInfo.baseName();

    //QDialog *dlg = new QDialog();
    setWindowTitle(QString("Export coordinates for Gaussian"));
    glt = new QGridLayout(this);
    titlE = new QLineEdit(QString("from:%1").arg(dirName),this);
    pe = new QPlainTextEdit(this);
    QFont font;
    font.setFamily(FONTFAM);
    font.setFixedPitch(true);
    font.setPointSize(11);
    pe->setFont(font);
    calcbox = new QComboBox(this);
    nproc = new QSpinBox(this);
    mem = new QSpinBox(this);
    charge = new QSpinBox(this);
    multipl = new QSpinBox(this);
    membx = new QComboBox(this);
    theorbox = new QComboBox(this);
    basisbox = new QComboBox(this);
    outputLevel = new QComboBox(this);
    sve = new QCheckBox("save scratch files",this);
    chk = new QCheckBox("Checkpoint:",this);
    spec = new QCheckBox("Special opt:",this);
    bb = new QDialogButtonBox( QDialogButtonBox::Save | QDialogButtonBox::Cancel);

    if (fn.isEmpty()) {
        emit rejected();
        done(QDialog::Rejected);
        close();
    }

    calcbox->addItems(QStringList()<<"Single Point Energy"<<"Geometry Optimization"<<"Frequencies");
    calcbox->setCurrentIndex(2);
    nproc->setMaximum(99);
    nproc->setMinimum(1);
    nproc->setValue(4);
    mem->setMaximum(1024);
    mem->setMinimum(1);
    mem->setValue(800);
    charge->setMinimum(-99);
    charge->setMaximum(99);
    charge->setValue(0);
    multipl->setMinimum(1);
    multipl->setMaximum(99);
    multipl->setValue(1);
    membx->addItems(QStringList()<<"KB"<<"MB"<<"GB"<<"TB"<<"KW"<<"MW"<<"GW"<<"TW");
    membx->setCurrentIndex(1);
    pe->setWordWrapMode(QTextOption::NoWrap);
    theorbox->addItems(QStringList()<<"AM1"<<"PM3"<<"RHF"<<"B3LYP"<<"MP2"<<"CCSD");
    theorbox->setCurrentIndex(3);
    basisbox->addItems(QStringList()<<"3-21G+"<<"6-21G**"<<"4-31G**"<<"6-31G3pd++"<<"6-311G3pd++"<<"D953pd++"<<"D95V(d,p)++"<<"SHC*"<<"CEP-4G*"<<"CEP-31G*"<<"CEP-121G*"<<"LanL2MB"<<
                       "LanL2DZ"<<"SDD"<<"SDDAll"<<"cc-pVDZ"<<"cc-pVTZ"<<"cc-pVQZ"<<"cc-pV5Z"<<"cc-pV6Z"<<"SV"<<"SVP"<<"TZV"<<"TZVP"<<"QZVP"<<
                     "Def2SV"<<"Def2SVP"<<"Def2SVPP"<<"Def2TZV"<<"Def2TZVP"<<"Def2TZVPP"<<"Def2QZV"<<"Def2QZVP"<<"Def2QZVPP"<<
                     "MidiX"<<"EPR-II"<<"EPR-III"<<
                     "UGBS2++"<<"MTSmall"<<"DGDZVP"<<"DGDZVP2"<<"DGTZVP"<<"CBSB7++");
    basisbox->setCurrentIndex(32);
    outputLevel->addItems(QStringList()<<"Normal print level"<<"Additional output"<<"Terse output");
    sve->setCheckable(true);
    sve->setChecked(true);
    chk->setCheckable(true);
    chk->setChecked(true);
    spec->setCheckable(true);
    spec->setChecked(true);
    //toggled ( bool checked )

    glt->addWidget(new QLabel("Title"),0,0,1,1);
    glt->addWidget(titlE              ,0,1,1,10);
    glt->addWidget(new QLabel("Calculation:"),1,0,1,1);
    glt->addWidget(calcbox,1,1,1,1);
    glt->addWidget(new QLabel("Processors:"),1,2,1,1);
    glt->addWidget(nproc,1,3,1,1);
    glt->addWidget(new QLabel("Memory:"),1,4,1,1);
    glt->addWidget(mem,1,5,1,1);
    glt->addWidget(membx,1,6,1,1);
    glt->addWidget(new QLabel("Theory:"),2,0,1,1);
    glt->addWidget(theorbox,2,1,1,1);
    glt->addWidget(new QLabel("Basis:"),2,2,1,1);
    glt->addWidget(basisbox,2,3,1,1);
    glt->addWidget(sve,2,4,1,1);
    glt->addWidget(chk,2,5,1,1);
    glt->addWidget(new QLabel("Charge:"),3,0,1,1);
    glt->addWidget(charge,3,1,1,1);
    glt->addWidget(new QLabel("Multiplicity:"),3,2,1,1);
    glt->addWidget(multipl,3,3,1,1);
    glt->addWidget(outputLevel,3,4,1,1);
    glt->addWidget(spec,3,5,1,1);
    glt->addWidget(pe,15,0,1,10);
    connect(bb, SIGNAL(accepted()), this, SLOT(accept()));
    connect(bb, SIGNAL(rejected()), this, SLOT(reject()));
    glt->addWidget(bb,16,0,1,10);

    // center of molecule
    int visCount=0;
    for (int i=0; i<mole->showatoms.size();i++) {
       if (mole->showatoms.at(i).an<0) continue;   //ignore none atoms
       if ((mole->nopm1)&&(mole->showatoms.at(i).symmGroup)&&(mole->showatoms.at(i).part<-0)) continue; // ignore hidden parts (-1)
       if (mole->showatoms.at(i).hidden) continue;
       visCount++;
       Vo+=mole->showatoms.at(i).pos;
    }
    Vo*=1.0/visCount;


    // atoms themselves
    for (int i=0; i< mole->showatoms.size(); i++){
        if (mole->showatoms.at(i).an<0) continue;   //ignore none atoms
        if ((mole->nopm1)&&(mole->showatoms.at(i).symmGroup)&&(mole->showatoms.at(i).part<-0)) continue; // ignore hidden parts (-1)
        if (mole->showatoms.at(i).hidden) continue;
          bodyQM.append(QString("%1 %2 %3 %4 \n")
                      .arg(mole->pse(mole->showatoms.at(i).an),-2)
                      .arg(mole->showatoms.at(i).pos.x-Vo.x,13,'f',10)
                      .arg(mole->showatoms.at(i).pos.y-Vo.y,13,'f',10)
                      .arg(mole->showatoms.at(i).pos.z-Vo.z,13,'f',10) );

         }


        footerQM.append(QString("\n\n"));

        makeHeader();

    connect(sve,SIGNAL(toggled(bool)),this,SLOT(makeHeader()));
    connect(chk,SIGNAL(toggled(bool)),this,SLOT(makeHeader()));
    connect(spec,SIGNAL(toggled(bool)),this,SLOT(makeHeader()));
    connect(charge,SIGNAL(valueChanged(int)),this,SLOT(makeHeader()));
    connect(multipl,SIGNAL(valueChanged(int)),this,SLOT(makeHeader()));
    connect(mem,SIGNAL(valueChanged(int)),this,SLOT(makeHeader()));
    connect(nproc,SIGNAL(valueChanged(int)),this,SLOT(makeHeader()));
    connect(calcbox,SIGNAL(currentIndexChanged(int)),this,SLOT(makeHeader()));
    connect(membx,SIGNAL(currentIndexChanged(int)),this,SLOT(makeHeader()));
    connect(theorbox,SIGNAL(currentIndexChanged(int)),this,SLOT(makeHeader()));
    connect(basisbox,SIGNAL(currentIndexChanged(int)),this,SLOT(makeHeader()));
    connect(outputLevel,SIGNAL(currentIndexChanged(int)),this,SLOT(makeHeader()));
    connect(titlE,SIGNAL(editingFinished()),this,SLOT(makeHeader()));



}
void ExportCCDlg::accept(){
    bool success = f.open(QIODevice::WriteOnly|QIODevice::Text);
     if (success){
         if (pe->toPlainText().isEmpty()) pe->setPlainText(QString("%1%2%3").arg(headerQM).arg(bodyQM).arg(footerQM));
       f.write(pe->toPlainText().toLatin1());
       f.close();
     }
    done(QDialog::Accepted);
}
void ExportCCDlg::makeHeader(){
    headerQM.clear();
    QString outlev="N";
    if (outputLevel->currentIndex()==1) outlev="P";
    if (outputLevel->currentIndex()==2) outlev="T";
    QString calct = "SP";
    if (calcbox->currentIndex()==1) calct = "Opt";
    if (calcbox->currentIndex()==2) calct = "Opt Freq";
    QString gfout;
    QString gfin;
    if (nproc->value()>1) headerQM.append(QString("%NProcShared=%1\n").arg(nproc->value()));
    if (sve->isChecked()) headerQM.append(QString("%SAVE\n"));
    if (chk->isChecked()) headerQM.append(QString("%CHK=%1.chk\n").arg(filenameQM));
    headerQM.append(QString("%MEM=%1%2\n").arg(mem->value()).arg(membx->currentText()));
    headerQM.append(QString("#%1 %2 %3 %4\n").arg(outlev).arg(calct).arg(gfout).arg(gfin));
    if (spec->isChecked())headerQM.append(QString("# INT=(GRID=99590) SCF=(MAXCYCLE=250,TIGHT)\n"));
    headerQM.append(QString("# %1/%2\n\n").arg(theorbox->currentText()).arg(basisbox->currentText()));
    headerQM.append(QString("%1\n\n").arg(titlE->text()));
    headerQM.append(QString("%1  %21\n").arg(charge->value()).arg(multipl->value()));
    pe->setPlainText(QString("%1%2%3").arg(headerQM).arg(bodyQM).arg(footerQM));
}
