#ifndef JOINT_H
#define JOINT_H

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

#ifndef EXPANDED_ATOM_GROUP_H
#include "Expanded_atom_group.h"
#endif

#ifndef LIVING_FRAME_H
#include "Living_frame.h"
#endif

namespace MM
{
class Point_3D;
class Atom;
class Prototype;
class Residue;

class Joint : public Living_frame
{
    mutable Text        local_id_;
    Text                comment_;

    Own <Atom_group>    atoms_;

    Point_3D const *    first_point_;
    Point_3D const *    second_point_;
    Point_3D const *    third_point_;

    Atom *              stub_atom_;
    Atom *              terminal_atom_;
    Atom *              directional_atom_;

    Residue *           in_residue_;

public:
    Joint (Prototype &);

    Joint (Point_3D const & first_point,
           Point_3D const & second_point,
           Point_3D const & third_point,
           Atom           & stub_atom,
           Atom           & terminal_atom,
           Atom           & directional_atom,
           Atom_group *adoptee);

    Joint (Atom & stub_atom, Atom & terminal_atom, Atom & directional_atom);

    Joint *             clone (Atom & stub_atom,
                               Atom & terminal_atom,
                               Atom & directional_atom) const      
    {return new Joint (stub_atom, terminal_atom, directional_atom);}

    Text const &        local_id     () const                {return local_id_;}
    void                set_local_id (Text const & id) const {local_id_ = id;}

    Text const &        comment_line () const               {return comment_;}
    void                set_comment_line (Text const& v)    {comment_=v;}

    Point_3D const &    first_point  ()             {return *first_point_;}
    Point_3D const &    second_point ()             {return *second_point_;}
    Point_3D const &    third_point  ()             {return *third_point_;}

    Atom &              stub_atom        ()         {return *stub_atom_;}
    Atom &              terminal_atom    ()         {return *terminal_atom_;}
    Atom &              directional_atom ()         {return *directional_atom_;}
    Atom const &        stub_atom        () const   {return *stub_atom_;}
    Atom const &        terminal_atom    () const   {return *terminal_atom_;}
    Atom const &        directional_atom () const   {return *directional_atom_;}

    void                set_stub_atom        (Atom & stub_atom);
    void                set_directional_atom (Atom & directional_atom);

    //Atom_group &        atom_group ();
    void                get_atom_group (Expanded_atom_group &);

    Residue &           in_residue ()               {return *in_residue_;}
    Residue const &     in_residue () const         {return *in_residue_;}
    void                set_residue (Residue &res)  {in_residue_ = &res;}


    void                chain   (Joint & second_joint, double distance);
    void                overlay (Joint & second_joint);
    //void                move    () {}
    //void                rotate () {}
    //void                translate () {}
};

}//MM

#endif //JOINT_H
