#include "Collect_phase_trajectory.h"

#include "Atom.h"
#include "Atom_group.h"
#include "Atom_kit.h"
#include "Point_3D.h"
#include "Text.h"
#include "Path.h"
#include "Arbitrary_atom_group.h"
#include "File_text_output.h"

#include "Create.h"

#include <iomanip>
#include <string>
#include <sstream>
class Monitor;

namespace MM
{

Collect_phase_trajectory::
Collect_phase_trajectory (Atom_group & group,
                          Text const & filename,
                          int precision,
                          Text in)
:
    Monitor_frame (in),
    group_(group), 
    //out_(new File_text_output (filename.c_str())), 
    out_(filename.c_str()), 
    //counter_(0), 
    precision_(precision)
{
    //std::string space;
    //for (int i=0;  i<precision_;  ++i)
    //    space += " ";

    ////out_().text ("step \t");
    ////out_().text ("x ");
    ////out_().text (space.c_str());
    ////out_().text ("\t");
    ////out_().text ("y ");
    ////out_().text (space.c_str());
    ////out_().text ("\t");
    ////out_().text ("z ");
    ////out_().text (space.c_str());
    ////out_().text ("\t");
    ////out_().text ("vx ");
    ////out_().text (space.c_str());
    ////out_().text ("\t");
    ////out_().text ("vy ");
    ////out_().text (space.c_str());
    ////out_().text ("\t");
    ////out_().text ("vz ");
    ////out_().text (space.c_str());
    ////out_().line ("");

    //out_<< "step " << " " 
    //    << "x " <<space<< " " << "y " <<space<< " " << "z " <<space<< " "
    //    << "vx" <<space<< " " << "vy" <<space<< " " << "vz" <<space<< "\n";//*/
}

/*namespace 
{
    static Arbitrary_atom_group     no_model;
}///*/

Collect_phase_trajectory * prototype_of_collect_phase_trajectory
    = new Collect_phase_trajectory (Prototype());

Collect_phase_trajectory::
Collect_phase_trajectory (Prototype const &)
:
    Monitor_frame ("Prototype"),
    group_(nil<Atom_group>())
{
    adopt_prototype (this);
}//*/

Text Collect_phase_trajectory::
class_name () const
{
    return "Collect_phase_trajectory";
}

Monitor * Collect_phase_trajectory::
clone (Atom_group & atom_group, Text const & args, Text in) const
{
    Text filename  = Path::report() + "phase_trajectory.xls";
    int  precision = 4;                                     //fix

    std::string new_filename;
    int         new_precision = -1;                         //fix
    std::istringstream input (args.c_str());
    input >> new_filename >> new_filename >> new_precision;
    if (new_filename.size() > 0)
        filename = new_filename.c_str();
    if (new_precision != -1)
        new_precision = new_precision;                      //fix

    return new Collect_phase_trajectory (atom_group, filename, precision, in);
}

void Collect_phase_trajectory::
handle_execute ()
{
    //++counter_;

    //out_().line (group_.atom_count());

    //out_().text ("step ");                            //fix
    //out_().line (counter_ * observation_period());    //fix

    //for (int i=0;  i<group_.atom_count();  ++i)
    //{
    //    Atom      const & atom =group_.atom(i);
    //    Point_3D  const & position = atom.position();
    //    Vector_3D const & velocity = atom.kit().velocity();

    //    out_().text (atom.element().c_str());   out_().text ("\t");

    //    out_().text (position.x());             out_().text ("\t");
    //    out_().text (position.y());             out_().text ("\t");
    //    out_().text (position.x());             out_().text ("\t");

    //    out_().text (velocity.x());             out_().text ("\t");
    //    out_().text (velocity.y());             out_().text ("\t");
    //    out_().line (velocity.x());
    //}

    //out_().flush();

    using namespace std;
    int width = precision_+4;

    out_ << group_.atom_count() << endl;                       
    out_ << " after         " 
         //<< counter_ * observation_period() 
         << count() 
         << " steps "
         << endl; //fix

    for (int i=0;  i<group_.atom_count();  ++i)
    {
        Atom      const & atom =group_.atom(i);
        Point_3D  const & position = atom.position();
        Vector_3D const & velocity = atom.kit().velocity();

        out_ 
            << fixed << setprecision(precision_)
            << setw(5)  << atom.element().c_str() << " "
            << setw(width) << position.x()        << " "
            << setw(width) << position.y()        << " "
            << setw(width) << position.z()        << " "

            << setw(width) << velocity.x()        << " "
            << setw(width) << velocity.y()        << " "
            << setw(width) << velocity.z()        << " "

            << endl;
    }
}

Monitor_presentation * Collect_phase_trajectory::
create_file_presentation (Text const& )
{
    FIX;
    return 0;
}

Monitor_presentation * Collect_phase_trajectory::
create_graph_presentation (Text const& )
{
    FIX;
    return 0;
}

}//MM
