#ifndef INTERACTION_H
#define INTERACTION_H

#ifndef ARRAY_OF_H
#include "Array_of.h"
#endif

#ifndef TEXT_H
#include "Text.h"
#endif

#ifndef ARRAY_H
#include "Array.h"
#endif

#ifndef ATOM_CHUNK_H
#include "Atom_chunk.h"
#endif

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

#ifdef WIN32
#pragma warning (disable : 4100)
#endif

#include <deque>

namespace MM
{

class Interaction
{
public:
    enum Task {No, Potential, Force, List};

    //virtual Interaction *  clone () const =0;
    virtual                ~Interaction () {}

    virtual double          potential () =0;
    virtual void            force ()
    {
        Lock<Interaction> lock(*this);
        zero_virial ();     
        zero_forces ();
        start       ();     
        add_force   ();     
        finish ();
    }

    virtual void            start  () {;}
    virtual void            finish () {;}

    virtual void            zero_virial () =0;
    virtual double          virial    () const =0;
    virtual double          virial    (double * x, double * y, double * z) const =0;

    virtual void            zero_forces () =0;
    virtual void            add_force () =0;

    virtual void        add_long_force  (std::deque <Atom_chunk_big> & chunk)   {;}
    virtual void        add_long_force  (double R, double Switching,
                                         Array <Atom_chunk_small> & chunk) {;} 
    //virtual void            add_long_force  (Array <Atom_chunk> & chunk) {;}
    //virtual void            add_long_force  (double R, double Switching,
    //                                         Array <Atom_chunk> & chunk) {;}

    virtual void            add_short_force () {add_force();}
    virtual void            list (double skin) {;}

    virtual void        list (std::deque <Atom_chunk_big>   &chunk, double skin) {;}
    virtual void        list (Array      <Atom_chunk_small> &chunk, double R,
                              std::deque <Atom_chunk_big>   &from)               {;}
    virtual void        list (Array      <Atom_chunk_small> &chunk, double R,
                              Array      <Atom_chunk_small> &from)               {;}
    //virtual void            list (Array <Atom_chunk> &chunk, double skin) {;}
    //virtual void            list (Array <Atom_chunk> &chunk, double R,
    //                              Array <Atom_chunk> &from) {;}

    virtual Text    title () const =0;
    virtual void    report (Text *result, Text const & hint = Text("Full")) =0;

    virtual bool        locked () const =0;
    virtual void        set_lock (bool on) =0;
};

}//MM

#endif //INTERACTION_H
