#ifndef COMPOSITE_INTERACTION_H
#define COMPOSITE_INTERACTION_H

#ifndef INTERACTION_H
#include "Interaction.h"
#endif

#ifndef COMMON_INTERACTIONS_H
#include "Common_interactions.h"
#endif

#ifndef ARRAY_OF_OWN_H
#include "Array_of_own.h"
#endif

#ifndef OWN_H
#include "Own.h"
#endif

//#include <deque>

namespace MM
{

class Composite_interaction : public Interaction
{
    Array_of_own <Interaction>      interaction_;
    Own <Common_interactions>       common_;

    bool                            common_on_;
    bool                            addition_on_;

public:
    Composite_interaction () : common_on_(true), addition_on_(true) { }

    Interaction * clone () const {return new Composite_interaction;}
    double      potential ();

    void        start  () ;
    void        finish () ;

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

    void        zero_forces ();
    void        add_force ();

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

    //void        add_long_force  (double R, double skin,
    //                             Array <Atom_chunk> & chunk);

    void        add_short_force ();
    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);
    //void        list (Array <Atom_chunk> &chunk, double skin);
    //void        list (Array <Atom_chunk> &chunk, double R,
    //                  Array <Atom_chunk> &from);

    void        report (Text *result, Text const & hint);

    Text        title () const {return "Composite_interaction";}
    void        adopt (Interaction *adoptee);
    void        clear ();

    Common_interactions &      common () {return common_();}
    Common_interactions const& common () const {return common_();}
    void adopt_common (Common_interactions *adoptee) {common_.adopt(adoptee);}

    virtual bool        locked () const ;
    virtual void        set_lock (bool) ;

    void                set_common_on  (bool on) {common_on_ = on;}
    void                setaddition_on (bool on) {addition_on_ = on;}
};

}//MM

#endif //COMPOSITE_INTERACTION_H
