#ifndef MTS_VV_H
#define MTS_VV_H

#ifndef MTS_H
#include "MTS.h"
#endif

#ifndef MD_H
#include "MD.h"
#endif

#ifndef LOCK_H
#include "Lock.h"
#endif

#include "Timer.h"
#define TIME(ref) ;

namespace MM
{

class MTS_VV : public MTS
{
    //int     update_list_;
    //double  R_;
    //double  skin_;

public:
    explicit MTS_VV (Prototype const &) {adopt_prototype (this);}
    explicit MTS_VV ()
    //:   update_list_(4), R_(6), skin_(.5) /*skin_(2*0.04)*/
    {inner_steps_ = 10;}

//    explicit MTS_MD (MD_subject & subject) : MD_method (subject) { }

    virtual void adopt_inner_step (){}

protected:
    /*virtual Text const& method () const
    {
        static const Text name = MD::method() 
            + ": Multiple time step";
        return name;
    }//*/

    char const*     class_name () const {return "MTS_VV";}
    char const*     title      () const {return "Multiple time step V.V.";}
    char const*     alias      () const {return "MTS VV";}

    MD_method *     clone () const      {return new MTS_VV;}

    virtual void start ()
    {
        Lock<MD> lock(simulation());
        MD_method::start ();
        step_N_ = 0;

        list (MD_subject::Long, skin_); 
        list (MD_subject::Short, R_, skin_);

        //clear_moment (MD_subject::Long1);

        F (MD_subject::Long);
        F (MD_subject::Long1,  R_, S_);
        F (MD_subject::Short);
    }

    virtual void step ()
    {
        TIME (" { ### ");
        Lock<MD> lock(simulation());

        int last_step = inner_steps_-1;

        kick (.5, MD_subject::Long);
        //kick (inner_steps_, .5, MD_subject::Long);
        //clear_moment (MD_subject::Long1);

        simulation_->algorithm().description ("{");

        for (int i=0;  i<inner_steps_;  ++i)
        {
            kick  (.5 / inner_steps_, MD_subject::Long1);
            kick  (.5 / inner_steps_, MD_subject::Short);
            //kick  (0., .5 / inner_steps_, MD_subject::Long1);
            //kick  (0., .5 / inner_steps_, MD_subject::Short);
            drift (1. / inner_steps_);

            //if (i == 0)
            //if (i == last_step)
            //if (i == inner_steps_/2)
            //if (i == 4)
            //    clear_moment (MD_subject::Long1);

            if (i == last_step)
            {
                if (step_N_ % update_list_ == 0)
                {
                    TIME ("list{ ");
                    list (MD_subject::Long,  skin_);
                    list (MD_subject::Short, R_, skin_); 
                    TIME ("list} ");
                }

                zero_virial();

                TIME ("F-W-{ ");
                F (MD_subject::Long );
                TIME ("F-W-} ");
            }
            TIME ("F-S-{ ");
            F (MD_subject::Long1, R_, S_);
            F (MD_subject::Short); 
            TIME ("F-S-} ");

            kick  (.5 / inner_steps_, MD_subject::Long1);
            kick  (.5 / inner_steps_, MD_subject::Short);
            //kick  (0., .5 / inner_steps_, MD_subject::Long1);
            //kick  (0., .5 / inner_steps_, MD_subject::Short);

            if (i<last_step)
                simulation_->algorithm().description ("");
        }

        simulation_->algorithm().description ("}");

        kick (.5, MD_subject::Long);
        //kick (inner_steps_, .5, MD_subject::Long);

        ++step_N_;
        TIME (" } ### ");
    }

    //virtual void step ()
    //{
    //    int last_step = inner_steps_-1;

    //    //outer_half_step ();
    //    kick (.5, MD_subject::Long);
    //    //F (MD_subject::Short);   //fix

    //    simulation_->algorithm().description ("{");

    //    for (int i=0;  i<inner_steps_;  ++i)
    //    {
    //        //inner_step ();

    //        kick  (.5 / inner_steps_, MD_subject::Short);
    //        drift (1. / inner_steps_);

    //        if (i == last_step)
    //            F (MD_subject::Whole);
    //        else
    //            F (MD_subject::Short);

    //        kick  (.5 / inner_steps_, MD_subject::Short);

    //        if (i<last_step)
    //            simulation_->algorithm().description ("");
    //    }

    //    simulation_->algorithm().description ("}");

    //    //outer_half_step ();
    //    //F (MD_subject::Long);
    //    //F (MD_subject::Whole);
    //    kick (.5, MD_subject::Long);
    //}
};

}//MM

#endif //MTS_VV_H
