#include "Panel_sequence_editor.h"

#include "Panel_sequence.h"

#include "Path.h"
#include "Torsion_list.h"
#include "Defs.h"

#include <QToolButton>
#include <QHeaderView>

namespace MM
{

Panel_sequence_editor::
Panel_sequence_editor ()
:
    Panel ("Chain", "middle"),
    current_dir_(Path::repository()),
    conformational_file_(conformational_model_)
{
    setupUi (this);

    tableWidget_Conformation->setColumnCount (2);
    tableWidget_Conformation->verticalHeader  ()->hide();
    tableWidget_Conformation->horizontalHeader()->hide();


    connect(listWidget_Chain_type, 
            SIGNAL(itemDoubleClicked (QListWidgetItem *)),
            this,   SLOT  (change_repository (QListWidgetItem *)));

    connect(listWidget_Chain_type, 
            SIGNAL (itemClicked (QListWidgetItem *)),
            this,   SLOT   (renew_residues ()));

    connect (listWidget_Conformational_type,    
             SIGNAL (currentItemChanged (QListWidgetItem*, QListWidgetItem*)),
             this,  SLOT   (renew_conformation_N ()));

    connect (spinBox_Conformation_N,    SIGNAL (valueChanged(int)),
             this,                      SLOT   (renew_conformation ()));

    renew_chain_type ();
}

QDir Panel_sequence_editor::
repository ()
{
    QString dir_name (".");

    QListWidgetItem * item = listWidget_Chain_type->currentItem();

    if (item != 0)
        dir_name = item->text();

    QDir result (current_dir_);
    result.cd (dir_name);
    return result;
}

void Panel_sequence_editor::
change_repository (QListWidgetItem * item)
{
    current_dir_.cd (item->text());
    renew_chain_type ();
}

void Panel_sequence_editor::
renew_chain_type ()
{
    listWidget_Chain_type->clear ();
    listWidget_Chain_type->addItems 
        (current_dir_.entryList (QDir::AllDirs, QDir::Name));
    renew_residues ();
}

void Panel_sequence_editor::
renew_residues ()
{
    delete widget_Residues;
    widget_Residues = new QWidget;
    frame_Residues->layout()->addWidget (widget_Residues);

//    QGridLayout * layout = new QGridLayout (1, 4);
    QGridLayout * layout = new QGridLayout;

    layout->setMargin  (0);
    layout->setSpacing (5);
    widget_Residues->setLayout (layout);

    QStringList filters;
    filters << "*.mlm";

    QFileInfoList file = repository().
        entryInfoList (filters, QDir::Files, QDir::Name);

    for (int i=0;  i<file.size();  ++i)
    {
        QFileInfo const & info = file.at(i);

        QToolButton *button = new QToolButton;
        button->setSizePolicy 
            (QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);

        QAction * action = new QAction (info.baseName(), button);
        button->setDefaultAction (action);
        connect (button,    SIGNAL (triggered   (QAction*)),
                 this,      SLOT   (add_residue (QAction*)));

        layout->addWidget (button, i/4, i%4);
    }

    renew_conformational_type ();
}

void Panel_sequence_editor::
renew_conformational_type ()
{
    QStringList filters;
    filters << "*.conf";

    QFileInfoList file = repository().
        entryInfoList (filters, QDir::Files, QDir::Name);

    //listWidget_Conformational_type->blockSignals(true);//fix
    listWidget_Conformational_type->clear ();

    for (int i=0;  i<file.size();  ++i)
    {
        QFileInfo const & info = file.at(i);
        listWidget_Conformational_type->addItem (info.baseName());
    }
    //listWidget_Conformational_type->blockSignals(false);

    renew_conformation_N ();
}

void Panel_sequence_editor::
no_conformation ()
{
    spinBox_Conformation_N->setValue (0);
    spinBox_Conformation_N->setEnabled (false);
    label_Conformations_range->setText("");
    label_Conformations_range->setEnabled (false);
    tableWidget_Conformation->setRowCount (0);
    tableWidget_Conformation->setEnabled (false);
}

void Panel_sequence_editor::
renew_conformation_N ()
{
    spinBox_Conformation_N->setValue (0);
    spinBox_Conformation_N   ->setEnabled (true);
    label_Conformations_range->setEnabled (true);
    tableWidget_Conformation ->setEnabled (true);

    QListWidgetItem * item = listWidget_Conformational_type->currentItem();

    //tableWidget_Conformation-> blockSignals(true);//fix

    QString file_name = "- default -.conf";

    if (item)
    {
        file_name = item->text();
        file_name += ".conf";
    }

    QDir dir = repository ();
    QFileInfo info;
    info.setFile (dir, file_name);

    if (info.exists ())
    {
        conformational_file_.add (info.absoluteFilePath());

        Torsion_list & list = conformational_file_.torsion_list ();
        int items = list.residue_count();

        if (items == 0)
            no_conformation ();
        else
        {
            spinBox_Conformation_N->setMaximum (items - 1);
            label_Conformations_range->setText (tr("of %1").arg(items));
            renew_conformation ();
        }
    }
    else
        //tableWidget_Conformation->setRowCount (0);
        no_conformation ();
}

void Panel_sequence_editor::
renew_conformation ()
{
    //tableWidget_Conformation->blockSignals(true);//fix
    tableWidget_Conformation->setRowCount (0);

    Torsion_list & list = conformational_file_.torsion_list ();

    int i, n = spinBox_Conformation_N->value();

    for (i=0, list.first_torsion (n);
         list.is_valid_torsion ();
         list.next_torsion (), ++i)
    {
        Text   torsion_type;
        double value;
        list.current_torsion (torsion_type, value);

        QTableWidgetItem *torsion_type_item = 
            new QTableWidgetItem (torsion_type);

        QTableWidgetItem *value_item = 
            new QTableWidgetItem (QString("%1").arg (180. * value / __Pi__));

        tableWidget_Conformation->insertRow (i);
        tableWidget_Conformation->setItem (i, 0, torsion_type_item);
        tableWidget_Conformation->setItem (i, 1, value_item);
    }

    tableWidget_Conformation->resizeColumnsToContents();

    //tableWidget_Geometry_parameters->blockSignals(false);//fix
}

void Panel_sequence_editor::
add_residue (QAction * action)
{
    Panel_sequence::singleton()->add_residue (action->text());
}

}//MM
