#ifndef RESIDUE_IMPL_H
#define RESIDUE_IMPL_H

#ifndef RESIDUE_H
#include "Residue.h"
#endif

#ifndef RESIDUE_CLASSIFICATION_H
#include "Residue_classification.h"
#endif

#ifndef ARRAY_OF_REF_H
#include "Array_of_ref.h"
#endif

#ifndef REF_H
#include "Ref.h"
#endif

#ifndef ATOM_H
#include "Atom.h"
#endif

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

namespace MM
{
class Model;
//class Atom;
//template <class T> class Array_of;

class Residue_impl : public Residue
{
//    Model &                         model_;
    mutable Text                    local_id_;
    Array_of_ref <Atom>             atom_group_;
    Array_of_ref <Joint>            joint_group_;
    Ref <Residue_classification>    classification_;//fix

    Text                            name_;
    Text                            short_alias_;
    Text                            alias_;
    Text                            comment_line_;

public:    
    //explicit Residue_impl (Model &);
    explicit Residue_impl ();
//    Array_of<Atom> & atom();

    //Residue *       clone (Model &model) const {return new Residue_impl(model);}
    Residue *       clone () const                  {return new Residue_impl();}

    bool            has_name        () const {return !name_.        is_empty() && name_        != "-";}
    bool            has_short_alias () const {return !short_alias_. is_empty() && short_alias_ != "-";}
    bool            has_alias       () const {return !alias_.       is_empty() && alias_       != "-";}
    bool            has_comment_line() const {return !comment_line_.is_empty() && comment_line_!= "-";}

    Text const &    name         () const {return name_;}
    Text const &    short_alias  () const {return short_alias_;}
    Text const &    alias        () const {return alias_;}
    Text const &    comment_line () const {return comment_line_;}

    void            set_name         (Text const & text) {name_        = text;}
    void            set_short_alias  (Text const & text) {short_alias_ = text;}
    void            set_alias        (Text const & text) {alias_       = text;}
    void            set_comment_line (Text const & text) {comment_line_= text;}

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

    //Text const &    name () const;//fix

    int             atom_count () const     {return atom_group_.size();}
    Atom &          atom (int i)            {return atom_group_[i];}
    const Atom &    atom (int i) const      {return atom_group_[i];}
    void            add_atom (Atom & ref);
    void            remove_dead_atoms ();

//    void            add (Atom &atom)    {group_.push_back(atom);}
    //void            erase ()            {group_.clear();}

    // Joint_group interface
    int             joint_count () const     {return joint_group_.size();}
    Joint &         joint (int n)            {return joint_group_[n];}
    Joint const &   joint (int n) const      {return joint_group_[n];}
    void            add_joint (Joint &joint);
    //bool            has_left_joint      () const;
    //bool            has_right_joint     () const;
    Joint &         left_joint          ();
    Joint &         right_joint         ();
    void            remove_dead_joints  ();
};

}//MM

#endif //RESIDUE_IMPL_H
