#include "M_DynaMix_smol_file.h"

#include "Flaw.h"
#include "Model.h"
#include "Atom.h"
#include "Atom_kit.h"
#include "MOT.h"
#include "Create.h"

#include "Bond.h"

#include <iomanip>
#include <fstream>
#include <sstream>
#include <string>

namespace MM
{
//M_DynaMix_smol_file M_DynaMix_smol_file::prototype_(Prototype());
M_DynaMix_smol_file M_DynaMix_smol_file::prototype_(it_is_a_prototype);

M_DynaMix_smol_file::
M_DynaMix_smol_file ()
{
}

M_DynaMix_smol_file::
M_DynaMix_smol_file (Prototype const &)
:
    Model_file (Prototype())
{
    add_extension ("smol");
}

M_DynaMix_smol_file::
M_DynaMix_smol_file (Model & model)
:
    Model_file (model)
{
}

Model_file * M_DynaMix_smol_file::
clone (Model & model) const
{
    M_DynaMix_smol_file *result = new M_DynaMix_smol_file (model);
    
    //result->extension_ = extension_;   //fix Array += should work
    for (int i=0;  i<extension_.size();  ++i)
        result->extension_.push_back (extension_[i]);
    
    return result;
}

bool M_DynaMix_smol_file::
//next_line (std::ifstream & in, std::string & line)
next_line (std::ifstream & , std::string &)
{
    FIX;
}

void M_DynaMix_smol_file::
add (Text const & /*file_name*/)
{
    FIX;
}

void M_DynaMix_smol_file::
check_file_name ()
{
    std::string filename = name().c_str();
    if( filename.find( ".smol" ) == std::string::npos )
    //fix to end
        FLAW (Text(name()) + " is a wrong file name.\n"
              "Check file name extension.");
}

void M_DynaMix_smol_file::
save (bool)
{
    using namespace std;
    check_file_name ();
    int i=0;

    ofstream out (name().c_str());

    out << "# File created by mmMDynaMix shell." << endl;
    out << "\t" << model().atom_count() << std::endl;

    for (i=0;  i<model().atom_count();  ++i)
    {
        Atom & current_atom = model().atom(i);
        current_atom.kit().set_number (i+1);
        Text name;                                      //fix size limit
        name = Text(current_atom.element().c_str()) + (i+1);
        out << fixed << setprecision(6) << left
            << setw(7)  << name.c_str() << right                     << " "
            << setw(10) << current_atom.x()                          << " "
            << setw(10) << current_atom.y()                          << " "
            << setw(10) << current_atom.z()                          << " "
            << setw(8)  << setprecision(5) << current_atom.charge()  << " "
            << setw(4)  << ::mot().itoa (current_atom.kit().mm_type()) << endl;
    }

    out << "# Bonds" << endl;
    out << "\t" << model().bond_count() << std::endl;

    for (i=0;  i<model().bond_count();  ++i)
    {
        out << setw(6) << model().bond(i).atom (0).kit().number()  << " "
            << setw(6) << model().bond(i).atom (1).kit().number()  << endl;
    }

    #ifndef NDEBUG
    for (i=0;  i<model().atom_count();  ++i)
        model().atom(i).kit().set_number (-1);
    #endif

}

}//MM


