#include "Default_bond.h"

#include "Default_id.h"
#include "Create.h"
#include "Default_bond.h"
#include "Atom.h"

#ifdef MM_WIN32
#pragma warning (disable : 4355)
#endif

namespace MM
{

Default_bond::
Default_bond (Prototype &)
    :
    id_( prototype<ID>().clone() ),
    kit_(*this)
{
}

Default_bond::
Default_bond (Atom & atom1, Atom & atom2, const Order & order )
    :
    order_( order ),
    id_( prototype<ID>().clone() ),
    kit_(*this)
{
    REQUIRE("Different atoms.", &atom1 != &atom2);
    //REQUIRE("Correct order");

    atoms_.push_back( atom1 );
    atoms_.push_back( atom2 );

    Atom_bond_manager & atom_1_protocol = atom1.interface_for (this);
    Atom_bond_manager & atom_2_protocol = atom2.interface_for (this);
    atom_1_protocol.add_bound (atom2);
    atom_1_protocol.add_bond  (*this);
    atom_2_protocol.add_bound (atom1);
    atom_2_protocol.add_bond  (*this);
}

/*Cloneable * Default_bond::
clone() const
{
    Default_bond *twin = new Default_bond ();
    return twin;
}//*/

Bond * Default_bond::
clone () const
{
    Default_bond *twin = new Default_bond (it_is_a_prototype);

    //fix to kit
    for (int i=0;  i<this->kit().visual().count();  ++i)
    {
        Visual_bond const & view = this->kit().visual().view(i);
        twin->kit().add_visual (view.clone (twin->kit()));
    }

    return twin;
}

Bond * Default_bond::
//clone (MM_atom & atom1, MM_atom & atom2, const Order & order) const
clone (Atom & atom1, Atom & atom2, const Order & order) const
{
    Default_bond *twin = new Default_bond (atom1, atom2, order);

    //fix to kit
    for (int i=0;  i<this->kit().visual().count();  ++i)
    {
        Visual_bond const & view = this->kit().visual().view(i);
        twin->kit().add_visual (view.clone (twin->kit()));
    }

    return twin;
}

Default_bond::
~Default_bond ()
{
    //fix 
    if (atoms_.size() == 2)
    {
        Atom_bond_manager & atom_1_protocol = atoms_[0].interface_for (this);
        Atom_bond_manager & atom_2_protocol = atoms_[1].interface_for (this);

        atom_1_protocol.remove_bound (atoms_[1]);
        atom_1_protocol.remove_bond  (*this);
        atom_2_protocol.remove_bound (atoms_[0]);
        atom_2_protocol.remove_bond  (*this);
    }
}

/*void Default_bond::       //fix test
release ()
{
    Atom_bond_manager & atom_1_protocol = atom_1_.interface_for (this);
    Atom_bond_manager & atom_2_protocol = atom_2_.interface_for (this);

    atom_1_protocol.remove_bound (atom_2_);
    atom_1_protocol.remove_bond  (*this);
    atom_2_protocol.remove_bound (atom_1_);
    atom_2_protocol.remove_bond (*this);
}//*/

/*
void Default_bond::set_atoms(Collection_of< Atom > &  )
{
    atoms_list_.clear();

    for( atoms.first();  atoms.is_valid();  atoms.next() )
    {
        atoms_list_.push_back( & atoms.current() );
    }
}

void Default_bond::add_atoms(Collection_of< Atom > &  )
{
    for( atoms.first();  atoms.is_valid();  atoms.next() )
    {
        atoms_list_.push_back( & atoms.current() );
    }
}

void Default_bond::add_atom( Atom & new_atom )
{
    atoms_list_.push_back( & new_atom );
}
//*/
void  Default_bond::
set_order( Order order )
{ 
    order_ = order; 
    kit().visual().renew ();
}

/*const ID & Default_bond::id() const
{ 
//    return * id_; 
    return id_(); 
}//*/

Order Default_bond::order() const
{ 
    return order_; 
}

bool Default_bond::
is_backbone () const
{
    return atoms_[0].is_backbone () && atoms_[1].is_backbone ();
}

}//MM
