#include "Panel_build_crystal.h"

//#include "Main_window.h"
#include "Selected_atoms.h"
#include "Project.h"
#include "Selector.h"
#include "Model.h"
#include "Model_kit.h"
#include "Atom_kit.h"
#include "Mach_eps.h"
#include "Text.h"

#include "Crystal_builder.h"
//#include "Crystal_builder_impl.h"

#include <QFileInfo>

#include <math.h>

namespace MM
{

Panel_build_crystal::
Panel_build_crystal ()
:
    Panel ("Crystal", "right"),
    silent_flag_(false)
        
        /*,
    timer_(this)*/
{
    setupUi (this);

    checkBox_Show_border->hide();
    comboBox_border_style->hide();

    checkBox_FCC->hide();


    //connect(&timer_,          SIGNAL(timeout()),
    //        this,             SLOT(update_panel()));
    //timer_.start(200);

    connect (pushButton_From_Fractional_to_Cartesian, SIGNAL(clicked()), 
            this, SLOT(from_fractional_to_cartesian()));

    connect(comboBox_Crystal_system, SIGNAL(currentIndexChanged (const QString &)),
            this,             SLOT(update_panel ()));

    connect(comboBox_Type,    SIGNAL(currentIndexChanged (const QString &)),
            this,             SLOT(set_FCC_Type (const QString &)));

    connect(checkBox_Use_PBC, SIGNAL(stateChanged(int)),
            this,             SLOT(set_use_PBC(int)));

    connect (lineEdit_mod_a,  SIGNAL(editingFinished()), 
            this, SLOT(accept_lattice_paramiters()));
    connect (lineEdit_mod_b,  SIGNAL(editingFinished()), 
            this, SLOT(accept_lattice_paramiters()));
    connect (lineEdit_mod_c,  SIGNAL(editingFinished()), 
            this, SLOT(accept_lattice_paramiters()));
    connect (lineEdit_alpha,  SIGNAL(editingFinished()), 
            this, SLOT(accept_lattice_paramiters()));
    connect (lineEdit_beta,   SIGNAL(editingFinished()), 
            this, SLOT(accept_lattice_paramiters()));
    connect (lineEdit_gamma,  SIGNAL(editingFinished()), 
            this, SLOT(accept_lattice_paramiters()));

    connect (lineEdit_ax,  SIGNAL(textChanged(const QString&)), 
            this, SLOT(accept_lattice_vectors(const QString&)));
    connect (lineEdit_ay,  SIGNAL(textChanged(const QString&)), 
            this, SLOT(accept_lattice_vectors(const QString&)));
    connect (lineEdit_az,  SIGNAL(textChanged(const QString&)), 
            this, SLOT(accept_lattice_vectors(const QString&)));
    connect (lineEdit_bx,  SIGNAL(textChanged(const QString&)), 
            this, SLOT(accept_lattice_vectors(const QString&)));
    connect (lineEdit_by,  SIGNAL(textChanged(const QString&)), 
            this, SLOT(accept_lattice_vectors(const QString&)));
    connect (lineEdit_bz,  SIGNAL(textChanged(const QString&)), 
            this, SLOT(accept_lattice_vectors(const QString&)));
    connect (lineEdit_cx,  SIGNAL(textChanged(const QString&)), 
            this, SLOT(accept_lattice_vectors(const QString&)));
    connect (lineEdit_cy,  SIGNAL(textChanged(const QString&)), 
            this, SLOT(accept_lattice_vectors(const QString&)));
    connect (lineEdit_cz,  SIGNAL(textChanged(const QString&)), 
            this, SLOT(accept_lattice_vectors(const QString&)));

    connect (lineEdit_c_copies, SIGNAL(editingFinished()), 
            this, SLOT(accept_number_of_copies()));
    connect (lineEdit_a_copies, SIGNAL(editingFinished()), 
            this, SLOT(accept_number_of_copies()));
    connect (lineEdit_b_copies, SIGNAL(editingFinished()), 
            this, SLOT(accept_number_of_copies()));

    //connect (checkBox_Preview,  SIGNAL(stateChanged(int)), 
    //        this,               SLOT(preview(int)));

    connect (pushButton_Apply, SIGNAL(clicked ()), this, SLOT(apply ()));
    connect (pushButton_Select,SIGNAL(clicked ()), this, SLOT(select()));

    //connect (lineEdit_alpha,   SIGNAL(lostFocus()),       this, SLOT(check_validity()));
    //connect (lineEdit_gamma,   SIGNAL(lostFocus()),       this, SLOT(check_validity()));
    //connect (lineEdit_beta,    SIGNAL(lostFocus()),       this, SLOT(check_validity()));
    //connect (lineEdit_mod_a,   SIGNAL(lostFocus()),       this, SLOT(check_validity()));
    //connect (lineEdit_mod_b,   SIGNAL(lostFocus()),       this, SLOT(check_validity()));
    //connect (lineEdit_mod_c,   SIGNAL(lostFocus()),       this, SLOT(check_validity()));
    //connect (lineEdit_az,      SIGNAL(lostFocus()),       this, SLOT(check_validity()));
    //connect (lineEdit_bz,      SIGNAL(lostFocus()),       this, SLOT(check_validity()));
    //connect (lineEdit_cz,      SIGNAL(lostFocus()),       this, SLOT(check_validity()));
    //connect (lineEdit_ay,      SIGNAL(lostFocus()),       this, SLOT(check_validity()));
    //connect (lineEdit_by,      SIGNAL(lostFocus()),       this, SLOT(check_validity()));
    //connect (lineEdit_cy,      SIGNAL(lostFocus()),       this, SLOT(check_validity()));
    //connect (lineEdit_ax,      SIGNAL(lostFocus()),       this, SLOT(check_validity()));
    //connect (lineEdit_bx,      SIGNAL(lostFocus()),       this, SLOT(check_validity()));
    //connect (lineEdit_cx,      SIGNAL(lostFocus()),       this, SLOT(check_validity()));


    connect(checkBox_same_abc,      SIGNAL(stateChanged  (int)),
            this,                   SLOT(update_panel()));

    connect(checkBox_FCC,           SIGNAL(stateChanged  (int)),
            this,                   SLOT(set_close_packed(int)));

    connect(checkBox_Elaborated,    SIGNAL(stateChanged  (int)),
            this,                   SLOT(set_full_control(int)));



    //class Angles_validator : public QDoubleValidator
    //{
    //    QLineEdit       *alpha_, *beta_, *gamma_;

    //public:
    //    explicit Angles_validator (QLineEdit *alpha, 
    //                               QLineEdit *beta, 
    //                               QLineEdit *gamma, QObject * parent)
    //    :   
    //        QDoubleValidator (-180, 180, 15, parent), 
    //        alpha_(alpha), beta_(beta), gamma_(gamma) { }

    //    virtual State validate (QString & input, int & pos) const
    //    {
    //        State result = QDoubleValidator::validate (input, pos);
    //        
    //        if (result != QValidator::Invalid)
    //        {
    //            double alpha = alpha_->text().toDouble();
    //            double beta  = beta_ ->text().toDouble();
    //            double gamma = gamma_->text().toDouble();

    //            if (alpha + beta  < gamma || 
    //                beta  + gamma < alpha ||
    //                alpha + gamma < beta  ||
    //                input.toDouble() < ::d_mach_eps_2
    //                )
    //            {
    //                to_user().info("!");
    //                return QValidator::Intermediate;
    //                //return QValidator::Invalid;
    //            }
    //        }
    //        return result;
    //    }
    //    
    //    virtual void fixup (QString & input) const
    //    {
    //        input = "80";
    //    }
    //};

    lineEdit_mod_a->setValidator (new QDoubleValidator (0, 1000, 15, this));    
    lineEdit_mod_b->setValidator (new QDoubleValidator (0, 1000, 15, this));     
    lineEdit_mod_c->setValidator (new QDoubleValidator (0, 1000, 15, this)); 

    lineEdit_alpha->setValidator (new QDoubleValidator (-180, 180, 15, this));    
    lineEdit_beta ->setValidator (new QDoubleValidator (-180, 180, 15, this));     
    lineEdit_gamma->setValidator (new QDoubleValidator (-180, 180, 15, this));  

    //lineEdit_alpha->setValidator (new Angles_validator
    //    (lineEdit_alpha, lineEdit_beta, lineEdit_gamma, this));     
    //lineEdit_beta ->setValidator (new Angles_validator
    //    (lineEdit_alpha, lineEdit_beta, lineEdit_gamma, this));     
    //lineEdit_gamma->setValidator (new Angles_validator
    //    (lineEdit_alpha, lineEdit_beta, lineEdit_gamma, this));     

    lineEdit_ax->setValidator (new QDoubleValidator (this));     
    lineEdit_ay->setValidator (new QDoubleValidator (this)); 
    lineEdit_az->setValidator (new QDoubleValidator (this)); 
    lineEdit_bx->setValidator (new QDoubleValidator (this)); 
    lineEdit_by->setValidator (new QDoubleValidator (this)); 
    lineEdit_bz->setValidator (new QDoubleValidator (this)); 
    lineEdit_cx->setValidator (new QDoubleValidator (this)); 
    lineEdit_cy->setValidator (new QDoubleValidator (this)); 
    lineEdit_cz->setValidator (new QDoubleValidator (this)); 
    
    lineEdit_a_copies->setValidator (new QIntValidator (1, 100, this));
    lineEdit_b_copies->setValidator (new QIntValidator (1, 100, this));
    lineEdit_c_copies->setValidator (new QIntValidator (1, 100, this));

    update_panel ();
}

void Panel_build_crystal::
showEvent (QShowEvent * event)
{
    QWidget::showEvent(event);

    if (Project::singleton().model_count() == 0)
        renew_current_model (Model::none());
    else
        renew_current_model (Project::singleton().current_model());
}

void Panel_build_crystal::
renew_current_model (Model & model) 
{
    if (&model == &Model::none())
    {
        setEnabled (false);
    }
    else
    {
        setEnabled (true);
        update_panel ();
    }
}

void Panel_build_crystal::
renew (Model_event::Hint hint)
{
    if((hint == Model_event::Structure_changed && !silent_flag_) ||
        hint == Model_event::Conformation_changed)
    {
        update_panel ();
    }
}

void Panel_build_crystal::
update_panel ()
{
    static bool entrance = false;
    //REQUIRE ("No reentrance", !entrance);
    if (entrance)                   //fix remove
        return;
    entrance = true;

    int i=0;
    lineEdit_mod_a->blockSignals (true);
    lineEdit_mod_b->blockSignals (true);
    lineEdit_mod_c->blockSignals (true);
    lineEdit_alpha->blockSignals (true);
    lineEdit_beta ->blockSignals (true);
    lineEdit_gamma->blockSignals (true);
    lineEdit_ax->blockSignals (true);
    lineEdit_ay->blockSignals (true);
    lineEdit_az->blockSignals (true);
    lineEdit_bx->blockSignals (true);
    lineEdit_by->blockSignals (true);
    lineEdit_bz->blockSignals (true);
    lineEdit_cx->blockSignals (true);
    lineEdit_cy->blockSignals (true);
    lineEdit_cz->blockSignals (true);
    lineEdit_a_copies->blockSignals (true);
    lineEdit_b_copies->blockSignals (true);
    lineEdit_c_copies->blockSignals (true);
    checkBox_Use_PBC    ->blockSignals (true);
    checkBox_Show_border->blockSignals (true);
    //checkBox_Preview    ->blockSignals (true);

    update_controls ();
    update_lattice_paramiters ();
    update_lattice_vectors ();

    if (checkBox_Elaborated->isChecked())
    {
        pushButton_From_Fractional_to_Cartesian ->show();
        groupBox_Lattice_vectors                ->show();
    }
    else 
    {
        pushButton_From_Fractional_to_Cartesian ->hide();
        groupBox_Lattice_vectors                ->hide();
    }

    if (checkBox_FCC->isChecked())
        frame_FCC->show();
    else
        frame_FCC->hide();

    //if (checkBox_Use_PBC->isChecked())
    //    frame_Lattice->setEnabled(false);
    //else
    //    frame_Lattice->setEnabled(true);

    if (comboBox_Crystal_system->currentText() == "Cubic")
    {
        lineEdit_mod_b->setText (lineEdit_mod_a->text());
        lineEdit_mod_c->setText (lineEdit_mod_a->text());
        lineEdit_alpha->setText ("90");
        lineEdit_beta ->setText ("90");
        lineEdit_gamma->setText ("90");

        lineEdit_mod_b->setEnabled(false);
        lineEdit_mod_c->setEnabled(false);
        lineEdit_alpha->setEnabled(false);
        lineEdit_beta ->setEnabled(false);
        lineEdit_gamma->setEnabled(false);
    }
    else if (comboBox_Crystal_system->currentText() == "Tetragonal")
    {
        lineEdit_mod_b->setText (lineEdit_mod_a->text());
        lineEdit_alpha->setText ("90");
        lineEdit_beta ->setText ("90");
        lineEdit_gamma->setText ("90");

        lineEdit_mod_b->setEnabled(false);
        lineEdit_mod_c->setEnabled(true);
        lineEdit_alpha->setEnabled(false);
        lineEdit_beta ->setEnabled(false);
        lineEdit_gamma->setEnabled(false);
    }
    else if (comboBox_Crystal_system->currentText() == "Rhombohedral")
    {
        lineEdit_mod_b->setText (lineEdit_mod_a->text());
        lineEdit_mod_c->setText (lineEdit_mod_a->text());

        lineEdit_mod_b->setEnabled(false);
        lineEdit_mod_c->setEnabled(false);
        lineEdit_alpha->setEnabled(true);
        lineEdit_beta ->setEnabled(true);
        lineEdit_gamma->setEnabled(true);
    }
    else if (comboBox_Crystal_system->currentText() == "Orthorhombic")
    {
        lineEdit_alpha->setText ("90");
        lineEdit_beta ->setText ("90");
        lineEdit_gamma->setText ("90");

        lineEdit_mod_b->setEnabled(true);
        lineEdit_mod_c->setEnabled(true);
        lineEdit_alpha->setEnabled(false);
        lineEdit_beta ->setEnabled(false);
        lineEdit_gamma->setEnabled(false);
    }
    else if (comboBox_Crystal_system->currentText() == "Monoclinic")
    {
        lineEdit_beta ->setText ("90");
        lineEdit_gamma->setText ("90");

        lineEdit_mod_b->setEnabled(true);
        lineEdit_mod_c->setEnabled(true);
        lineEdit_alpha->setEnabled(true);
        lineEdit_beta ->setEnabled(false);
        lineEdit_gamma->setEnabled(false);
    }
    else
    {
        lineEdit_mod_b->setEnabled(true);
        lineEdit_mod_c->setEnabled(true);
        lineEdit_alpha->setEnabled(true);
        lineEdit_beta ->setEnabled(true);
        lineEdit_gamma->setEnabled(true);
    }


    if (checkBox_same_abc->isChecked())
    {
        lineEdit_b_copies->setText (lineEdit_a_copies->text());
        lineEdit_c_copies->setText (lineEdit_a_copies->text());

        lineEdit_b_copies->setEnabled(false);
        lineEdit_c_copies->setEnabled(false);
    }
    else
    {
        lineEdit_b_copies->setEnabled(true);
        lineEdit_c_copies->setEnabled(true);
    }


    if (comboBox_Octahedral_holes ->currentText() == "Empty" &&
        comboBox_Tetrahedral_holes->currentText() == "Empty")
    {
        comboBox_Type->setCurrentIndex
            (comboBox_Type->findText("Face-centered cubic"));
    }
    else if(comboBox_Octahedral_holes ->currentText() == "Filled" &&
            comboBox_Tetrahedral_holes->currentText() == "Empty")
    {
        comboBox_Type->setCurrentIndex
            (comboBox_Type->findText("NaCl"));
    }
    else if(comboBox_Octahedral_holes ->currentText() == "Empty" &&
            comboBox_Tetrahedral_holes->currentText() == "Filled")
    {
        comboBox_Type->setCurrentIndex
            (comboBox_Type->findText("CaF2"));
    }
    else if(comboBox_Octahedral_holes ->currentText() == "Empty" &&
            comboBox_Tetrahedral_holes->currentText() == "1/2 Filled")
    {
        comboBox_Type->setCurrentIndex
            (comboBox_Type->findText("ZnS"));
    }
    else if(comboBox_Octahedral_holes ->currentText() == "Empty" &&
            comboBox_Tetrahedral_holes->currentText() == "1/4 Filled")
    {
        comboBox_Type->setCurrentIndex
            (comboBox_Type->findText("Cu2O"));
    }
    else if(comboBox_Octahedral_holes ->currentText() == "Filled" &&
            comboBox_Tetrahedral_holes->currentText() == "Filled")
    {
        comboBox_Type->setCurrentIndex
            (comboBox_Type->findText("BiF3"));
    }
    else
    {
        //comboBox_Octahedral_holes->setCurrentItem
        //    (comboBox_Octahedral_holes->findText ("Empty"));
        //comboBox_Tetrahedral_holes->setCurrentItem
        //    (comboBox_Tetrahedral_holes->findText ("Empty"));
        //to_user().fatal_error ("Unknown crystall type.");

        comboBox_Type->setCurrentIndex
            (comboBox_Type->findText("?"));
    }


    bool change = false;
    int model_count = Project::singleton().model_count();
    if (model_count == comboBox_Octahedral_from->count())
        for (i=0;  i<model_count;  ++i)
        {
            Model & model = Project::singleton().model(i);
            Text file_name = model.kit().file_name();
            QFileInfo file (file_name);
            
            if (comboBox_Octahedral_from->findText (file.baseName()) == -1)
                change = true;
        }
    else
        change = true;
    
    if (change)
    {
        comboBox_Octahedral_from ->clear ();
        comboBox_Tetrahedral_from->clear ();

        for (i=0;  i<model_count;  ++i)
        {
            Model & model = Project::singleton().model(i);
            Text file_name = model.kit().file_name();
            QFileInfo file (file_name);
            comboBox_Octahedral_from ->addItem (file.baseName());
            comboBox_Tetrahedral_from->addItem (file.baseName());
        }

        QFileInfo sel = QString (Project::singleton().current_model().kit().file_name());
        comboBox_Octahedral_from ->setCurrentIndex 
            (comboBox_Octahedral_from ->findText (sel.baseName()));
        comboBox_Tetrahedral_from ->setCurrentIndex 
            (comboBox_Tetrahedral_from->findText (sel.baseName()));
    }

    accept_lattice_paramiters ("silent");
    update_lattice_paramiters ();

    //accept_lattice_vectors    ("silent");
    update_lattice_vectors    ();

//    accept_number_of_copies   ("silent");
    update_copies             ();

    lineEdit_mod_a->blockSignals (false);
    lineEdit_mod_b->blockSignals (false);
    lineEdit_mod_c->blockSignals (false);
    lineEdit_alpha->blockSignals (false);
    lineEdit_beta ->blockSignals (false);
    lineEdit_gamma->blockSignals (false);
    lineEdit_ax->blockSignals (false);
    lineEdit_ay->blockSignals (false);
    lineEdit_az->blockSignals (false);
    lineEdit_bx->blockSignals (false);
    lineEdit_by->blockSignals (false);
    lineEdit_bz->blockSignals (false);
    lineEdit_cx->blockSignals (false);
    lineEdit_cy->blockSignals (false);
    lineEdit_cz->blockSignals (false);
    lineEdit_a_copies->blockSignals (false);
    lineEdit_b_copies->blockSignals (false);
    lineEdit_c_copies->blockSignals (false);
    checkBox_Use_PBC    ->blockSignals (false);
    checkBox_Show_border->blockSignals (false);
    //checkBox_Preview    ->blockSignals (false);

    //update ();
    entrance = false;               //fix
}

void Panel_build_crystal::
from_fractional_to_cartesian()
{
    builder().convert_from_fractional_to_cartesian();
}

void Panel_build_crystal::
set_FCC_Type (const QString & name)
{
    if (name == "Face-centered cubic")
    {
        comboBox_Octahedral_holes->setCurrentIndex
            (comboBox_Octahedral_holes ->findText ("Empty"));
        comboBox_Tetrahedral_holes->setCurrentIndex
            (comboBox_Tetrahedral_holes->findText ("Empty"));
    }
    else if (name == "NaCl")
    {
        comboBox_Octahedral_holes->setCurrentIndex
            (comboBox_Octahedral_holes ->findText ("Filled"));
        comboBox_Tetrahedral_holes->setCurrentIndex
            (comboBox_Tetrahedral_holes->findText ("Empty"));
    }
    else if (name == "CaF2")
    {
        comboBox_Octahedral_holes->setCurrentIndex
            (comboBox_Octahedral_holes ->findText ("Empty"));
        comboBox_Tetrahedral_holes->setCurrentIndex
            (comboBox_Tetrahedral_holes->findText ("Filled"));
    }
    else if (name == "ZnS")
    {
        comboBox_Octahedral_holes->setCurrentIndex
            (comboBox_Octahedral_holes ->findText ("Empty"));
        comboBox_Tetrahedral_holes->setCurrentIndex
            (comboBox_Tetrahedral_holes->findText ("1/2 Filled"));
    }
    else if (name == "Cu2O")
    {
        comboBox_Octahedral_holes->setCurrentIndex
            (comboBox_Octahedral_holes ->findText ("Empty"));
        comboBox_Tetrahedral_holes->setCurrentIndex
            (comboBox_Tetrahedral_holes->findText ("1/4 Filled"));
    }
    else if (name == "BiF3")
    {
        comboBox_Octahedral_holes->setCurrentIndex
            (comboBox_Octahedral_holes ->findText ("Filled"));
        comboBox_Tetrahedral_holes->setCurrentIndex
            (comboBox_Tetrahedral_holes->findText ("Filled"));
    }

    //update_panel ();
}

void Panel_build_crystal::
apply ()
{
    builder().expand_model ();
    //builder().model().kit().visual().fit_to_screen();
    Project::singleton().current_model().kit().selector().clear();
    update_panel ();
}

void Panel_build_crystal::
select ()
{
    Atom_group & group = builder().cell_copy ();
    Model & model = Project::singleton().current_model();
    CHECK ("", &model != &Model::none());

    Selector & selector = model.kit().selector ();
    selector.clear();
    for (int i=0;  i<group.atom_count();  ++i)
        selector.select(group.atom(i), true);

    //builder().select_preview ();
}



void Panel_build_crystal::
update_controls ()
{
    checkBox_Use_PBC    -> setChecked (builder().use_PBC     ());
    checkBox_Show_border-> setChecked (builder().show_border ());
    //checkBox_Preview    -> setChecked (builder().show_images ());
}

void Panel_build_crystal::
update_lattice_paramiters ()
{
    lineEdit_mod_a-> setText (QString::number (builder().a_mod()));
    lineEdit_mod_b-> setText (QString::number (builder().b_mod()));
    lineEdit_mod_c-> setText (QString::number (builder().c_mod()));
    lineEdit_alpha-> setText (QString::number (builder().alpha()));
    lineEdit_beta -> setText (QString::number (builder().beta ()));
    lineEdit_gamma-> setText (QString::number (builder().gamma()));
}

void Panel_build_crystal::
update_lattice_vectors ()
{
    Vector_3D const & a = builder().a ();
    Vector_3D const & b = builder().b ();
    Vector_3D const & c = builder().c ();

    const double zero = ::d_mach_eps_2;
    lineEdit_ax-> setText (a.x() > zero || a.x() < -zero ? QString::number (a.x()) : "0");
    lineEdit_ay-> setText (a.y() > zero || a.y() < -zero ? QString::number (a.y()) : "0");
    lineEdit_az-> setText (a.z() > zero || a.z() < -zero ? QString::number (a.z()) : "0");
    lineEdit_bx-> setText (b.x() > zero || b.x() < -zero ? QString::number (b.x()) : "0");
    lineEdit_by-> setText (b.y() > zero || b.y() < -zero ? QString::number (b.y()) : "0");
    lineEdit_bz-> setText (b.z() > zero || b.z() < -zero ? QString::number (b.z()) : "0");
    lineEdit_cx-> setText (c.x() > zero || c.x() < -zero ? QString::number (c.x()) : "0");
    lineEdit_cy-> setText (c.y() > zero || c.y() < -zero ? QString::number (c.y()) : "0");
    lineEdit_cz-> setText (c.z() > zero || c.z() < -zero ? QString::number (c.z()) : "0");
}

void Panel_build_crystal::
update_copies ()
{
    lineEdit_a_copies->setText (QString::number (builder().a_copies()));
    lineEdit_b_copies->setText (QString::number (builder().b_copies()));
    lineEdit_c_copies->setText (QString::number (builder().c_copies()));
}

Crystal_builder & Panel_build_crystal::
builder ()
{
    Model & model = Project::singleton().current_model();
    CHECK ("", &model != &Model::none());
    return  model.kit().crystal_builder();
}

Model & Panel_build_crystal::
model ()
{
    Model & model = Project::singleton().current_model();
    CHECK ("", &model != &Model::none());
    return  model;
}

void Panel_build_crystal::
set_use_PBC (int use)
{
    builder().set_use_PBC (use);
    update_panel ();
}

void Panel_build_crystal::
accept_lattice_paramiters ()
{
    static const QString hint = "";
    accept_lattice_paramiters (hint);
}

void Panel_build_crystal::
accept_lattice_paramiters (const QString & hint)
{
    const double zero = ::d_mach_eps_2;

    double mod_a = lineEdit_mod_a->text().toDouble();
    double mod_b = lineEdit_mod_b->text().toDouble();
    double mod_c = lineEdit_mod_c->text().toDouble();
    double alpha = lineEdit_alpha->text().toDouble();
    double beta  = lineEdit_beta ->text().toDouble();
    double gamma = lineEdit_gamma->text().toDouble();

    if (fabs(mod_a) < zero)
        mod_a = 10;
    if (fabs(mod_b) < zero)
        mod_b = 10;
    if (fabs(mod_c) < zero)
        mod_c = 10;
       
    //if (!(
    //    //lineEdit_mod_a->hasAcceptableInput () &&
    //    //lineEdit_mod_b->hasAcceptableInput () &&
    //    //lineEdit_mod_c->hasAcceptableInput () &&
    //    lineEdit_alpha->hasAcceptableInput () &&
    //    lineEdit_beta ->hasAcceptableInput () &&
    //    lineEdit_gamma->hasAcceptableInput ()
    //   ))
    //{
    //    to_user().error 
    //        ("Alpha, beta and gamma should be less than sum of two others.");
    //    alpha = beta = gamma = 90;
    //}

    if (alpha + beta  < gamma || beta  + gamma < alpha || alpha + gamma < beta ||
        fabs (alpha)  < zero  || fabs (beta)   < zero  || fabs (gamma)  < zero)
    {
        to_user().error 
            ("Alpha, beta and gamma should be less than sum of two others "
             "and greater then 0.");
        alpha = beta = gamma = 90;
    }
        
    builder().set (mod_a, mod_b, mod_c, alpha, beta, gamma);

    if (hint != "silent")
        update_panel ();
}

void Panel_build_crystal::
accept_lattice_vectors    (const QString & hint)
{
    const double zero = ::d_mach_eps_2;

    double ax = lineEdit_ax->text().toDouble();
    double ay = lineEdit_ay->text().toDouble();
    double az = lineEdit_az->text().toDouble();
    double bx = lineEdit_bx->text().toDouble();
    double by = lineEdit_by->text().toDouble();
    double bz = lineEdit_bz->text().toDouble();
    double cx = lineEdit_cx->text().toDouble();
    double cy = lineEdit_cy->text().toDouble();
    double cz = lineEdit_cz->text().toDouble();

    if (fabs(ax) < zero || fabs(by) < zero || fabs(cz) < zero)
        return;

    builder().set (Vector_3D_impl (ax, ay, az),
                   Vector_3D_impl (bx, by, bz),
                   Vector_3D_impl (cx, cy, cz));

    if (hint != "silent")
        update_panel ();
}

void Panel_build_crystal::
accept_number_of_copies   ()
{
    silent_flag_ = true;

    Crystal_builder & bl = builder ();

    int a = lineEdit_a_copies->text().toInt();
    int b = lineEdit_b_copies->text().toInt();
    int c = lineEdit_c_copies->text().toInt();

    if (bl.a_copies() != a || bl.b_copies() != b || bl.c_copies() != c)
    {
        if (checkBox_same_abc->isChecked())
            bl.set_number_of_copies (a, a, a);
        else
            bl.set_number_of_copies (a, b, c);
    }

    select ();
    update_panel ();
    silent_flag_ = false;
}

}//MM
