#ifndef REPLICA_EXCHANGE_H
#define REPLICA_EXCHANGE_H

#ifndef SIMULATION_H
#include "Simulation.h"
#endif

#ifndef PROJECT_H
#include "Project.h"
#endif

#ifndef MD_SIMULATOR_H
#include "MD_simulator.h"
#endif

#ifndef MODEL_KIT_H
#include "Model_kit.h"
#endif

#ifndef MD_METHOD_H
#include "MD_method.h"
#endif

#ifndef MD_SUBJECT_H
#include "MD_subject.h"
#endif

#ifndef THERMOSTAT_H
#include "Thermostat.h"
#endif

#ifndef BAROSTAT_H
#include "Barostat.h"
#endif

#ifdef WIN32
#pragma warning(disable : 4800)
#pragma warning(disable : 4996)
#endif
#include "MersenneTwister.h"

namespace MM
{

class Replica_exchange : public Simulation
{
    int                         exchange_per_step_;
    int                         attempts_;
    int                         accept_count_, reject_count_;

    MTRand                      generator_;
    bool                        stop_flag_;
    Array_of_own <MD_subject>   subject_;

public:
    Replica_exchange () 
    :   exchange_per_step_(1), attempts_(1), 
        accept_count_(0), reject_count_(0), 
        stop_flag_(true)
        {}

    static Replica_exchange  & singleton ();

    bool                    potential_is_different 
                                               (Common_interactions const & i,
                                                Common_interactions const & j) const;

    void                    exchange_potential (Common_interactions & i,
                                                Common_interactions & j);

    int                     exchange_per_step () const      {return exchange_per_step_;}
    void                    set_exchange_per_step (int v)   {exchange_per_step_ = v;}

    int                     attempts () const               {return attempts_;}
    void                    set_attempts (int v)            {attempts_ = v;}

    void                    stop () {stop_flag_ = true;}

    virtual char const *    class_name () const {return "Replica_exchange";}
    virtual Text            title      () const {return "Replica exchange";}

protected:
    virtual void            cycle      ();
    //virtual void            step       () =0;
    virtual int             iterations () const {return steps ();}//fix
    virtual void            start      ();
    virtual void            finish     ();

    virtual void            exchange_replica ();
};

}//MM

#endif //REPLICA_EXCHANGE_H
