// 
// This file is part of MolMeccano, a cross-platform C++ chemical library.
//
// Copyright (C) 2001-2009 Alexey Nikitin
//

#ifndef MODEL_H
#define MODEL_H

#ifndef ATOM_GROUP_H
#include "Atom_group.h"
#endif

#ifndef BOND_GROUP_H
#include "Bond_group.h"
#endif

#ifndef MOLECULAR_GROUP_H
#include "Molecular_group.h"
#endif

#ifndef RESIDUE_GROUP_H
#include "Residue_group.h"
#endif

#ifndef JOINT_GROUP_H
#include "Joint_group.h"
#endif

namespace MM
{
class ID;//fix to hin

class Model_kit;
class Atom;
class Bond;
class Molecule;
class Vector_3D;
class Expanded_atom_group;

/**
Combine atoms, bonds, molecules, potentials, ets.
Synhronise all of this.
*/
class Model :
    public Atom_group,
    public Bond_group,
    public Molecular_group,
    public Residue_group,
    public Joint_group
{
public:    
    //virtual                     ~Model()=0;
    virtual Model *             clone () const =0;
    virtual void                copy (int n, Expanded_atom_group * result) =0;
    virtual void                erase () =0;
    virtual void                clear () =0;
    virtual void                orphan_all () =0;
    virtual void                remove_deads () =0;

    static Model &              none();

    virtual Model_kit &         kit () =0;
    virtual Model_kit const &   kit () const =0;

//    virtual Text const &        title     () const =0;
//    virtual void                set_title (Text const &) =0;

    virtual void                merge_model (Model * adoptee) =0;

    virtual void                move   (Vector_3D const& movement) =0;
    virtual void                rotate (Vector_3D const& around, double teta)=0;

    virtual Atom &              atom_prototype () =0;
    virtual void                set_atom_prototype (Atom * adoptee) =0;
    virtual int                 atom_count     () const =0;
    virtual Atom &              atom           (int i)  =0;
    virtual Atom const &        atom           (int i) const =0;
    virtual void                add_atom       (Atom * atom) =0;    //fix to adopt all?
    virtual void                erase          (Atom & atom) =0;

    virtual Atom &              atom (const ID & id) =0;        //fix to hin
    virtual Atom const &        atom (const ID & id) const =0;

    virtual Bond &              bond_prototype () =0;
    virtual void                set_bond_prototype (Bond * adoptee) =0;
    virtual int                 bond_count  () const =0;
    virtual Bond &              bond        (int i)  =0;
    virtual Bond const &        bond        (int i) const =0;
    virtual void                add_bond    (Bond * bond) =0;

    virtual void                detect_molecules() =0;      //fix 
    virtual int                 molecule_count  () const =0;
    virtual Molecule &          molecule        (int i)  =0;
    virtual Molecule const &    molecule        (int i) const =0;
    virtual void                add_molecule    (Molecule * mol) =0;
    virtual Molecule *          orphan_molecule (Molecule & mol) =0;
    virtual void                reset_molecules () =0;

    virtual int                 residue_count () const =0;
    virtual Residue &           residue (int n) =0;
    virtual Residue const &     residue (int n) const =0;
    virtual void                add_residue (Residue *res) =0;
    virtual void                reset_residues () =0;

    virtual int                 joint_count () const =0;
    virtual Joint &             joint (int n) =0;
    virtual Joint const &       joint (int n) const =0;
    virtual Joint &             joint (Text const& local_id) =0;
    virtual void                add_joint (Joint *joint) =0;

    virtual bool                save   (bool to_comment = false)=0;
    virtual bool                save_as(Text const& file_name,
                                        Text const& file_type ="auto detect",
                                        Text *      name_saved = 0,
                                        bool        to_comment = false )=0;
    virtual void                load   (Text const& file_name,
                                        Text const& file_type ="auto detect")=0;
    virtual void                add    (Text const& file_name,
                                        Text const& file_type ="auto detect")=0;
    virtual void                pull_on(Text const& file_name,
                                        Text const& file_type ="auto detect")=0;

    virtual void                clear_local_ids () =0;
};

}//MM

#endif //MODEL_H
