#include "Test.h"

#include "Molecular_depth_iterator.h"
#include "Molecular_width_iterator.h"
//#include "Bond_width_iterator.h"
//#include "Molecular_bond_iterator.h"
#include "Atom_impl.h"
#include "Element.h"
#include "Default_bond.h"
#include "Create.h"
//#include "Log.h"

namespace MM
{

class Molecular_iterator_test : public Test
{
    Molecular_iterator *link;
public:
    Molecular_iterator_test (const Text& suite_name) : Test (suite_name) { }

    void run()
    {
        test_tree();   count_tests();
        test_ring();   count_tests();
    }

    void test_tree()
    {
        Atom_impl a1 ("C"); a1.set_charge (1);  //      1        //
        Atom_impl a2 ("C"); a2.set_charge (2);  //      |        //
        Atom_impl a3 ("C"); a3.set_charge (3);  //      2        // 
        Atom_impl a4 ("C"); a4.set_charge (4);  //     / \       //
        Atom_impl a5 ("C"); a5.set_charge (5);  //    3   4      //
        Atom_impl a6 ("C"); a6.set_charge (6);  //       / \     //
                                                //      5   6    //
        Default_bond b12  (a1, a2);
        Default_bond b23  (a2, a3);
        Default_bond b24  (a2, a4);
        Default_bond b45  (a4, a5);
        Default_bond b46  (a4, a6);

        Molecular_depth_iterator it (a1); 
        TEST ("", &it.current() == &a1);    TEST ("", it.is_valid());
        it.next ();
        TEST ("", &it.current() == &a2);    TEST ("", it.is_valid());
        it.next ();
        TEST ("", &it.current() == &a4);    TEST ("", it.is_valid());
        it.next ();
        TEST ("", &it.current() == &a6);    TEST ("", it.is_valid());
        it.next ();
        TEST ("", &it.current() == &a5);    TEST ("", it.is_valid());
        it.next ();
        TEST ("", &it.current() == &a3);    TEST ("", it.is_valid());
        it.next ();
        TEST ("", !it.is_valid());

        a1.kit().flag().clear (Atom_kit::molecular_mark);
        a2.kit().flag().clear (Atom_kit::molecular_mark);
        a3.kit().flag().clear (Atom_kit::molecular_mark);
        a4.kit().flag().clear (Atom_kit::molecular_mark);
        a5.kit().flag().clear (Atom_kit::molecular_mark);
        a6.kit().flag().clear (Atom_kit::molecular_mark);

        Molecular_depth_iterator it2 (a4); 
        TEST ("", &it2.current() == &a4);    TEST ("", it2.is_valid());
        it2.next ();
        TEST ("", &it2.current() == &a6);    TEST ("", it2.is_valid());
        it2.next ();
        TEST ("", &it2.current() == &a5);    TEST ("", it2.is_valid());
        it2.next ();
        TEST ("", &it2.current() == &a2);    TEST ("", it2.is_valid());
        it2.next ();
        TEST ("", &it2.current() == &a3);    TEST ("", it2.is_valid());
        it2.next ();
        TEST ("", &it2.current() == &a1);    TEST ("", it2.is_valid());
        it2.next ();
        TEST ("", !it2.is_valid());
//        log() << it2.current().charge () << "\n";

        a1.kit().flag().clear (Atom_kit::molecular_mark);
        a2.kit().flag().clear (Atom_kit::molecular_mark);
        a3.kit().flag().clear (Atom_kit::molecular_mark);
        a4.kit().flag().clear (Atom_kit::molecular_mark);
        a5.kit().flag().clear (Atom_kit::molecular_mark);
        a6.kit().flag().clear (Atom_kit::molecular_mark);

        Molecular_width_iterator it3 (a1);
        TEST ("", &it3.current() == &a1);    TEST ("", it3.is_valid());
        it3.next ();
        TEST ("", &it3.current() == &a2);    TEST ("", it3.is_valid());
        it3.next ();
        TEST ("", &it3.current() == &a3);    TEST ("", it3.is_valid());
        it3.next ();
        TEST ("", &it3.current() == &a4);    TEST ("", it3.is_valid());
        it3.next ();
        TEST ("", &it3.current() == &a5);    TEST ("", it3.is_valid());
        it3.next ();
        TEST ("", &it3.current() == &a6);    TEST ("", it3.is_valid());
        it3.next ();
        TEST ("", !it3.is_valid());

        a1.kit().flag().clear (Atom_kit::molecular_mark);
        a2.kit().flag().clear (Atom_kit::molecular_mark);
        a3.kit().flag().clear (Atom_kit::molecular_mark);
        a4.kit().flag().clear (Atom_kit::molecular_mark);
        a5.kit().flag().clear (Atom_kit::molecular_mark);
        a6.kit().flag().clear (Atom_kit::molecular_mark);

        Molecular_width_iterator it4 (a4);
        TEST ("", &it4.current() == &a4);    TEST ("", it4.is_valid());
        it4.next ();
        TEST ("", &it4.current() == &a2);    TEST ("", it4.is_valid());
        it4.next ();
        TEST ("", &it4.current() == &a5);    TEST ("", it4.is_valid());
        it4.next ();
        TEST ("", &it4.current() == &a6);    TEST ("", it4.is_valid());
        it4.next ();
        TEST ("", &it4.current() == &a1);    TEST ("", it4.is_valid());
        it4.next ();
        TEST ("", &it4.current() == &a3);    TEST ("", it4.is_valid());
        it4.next ();
        TEST ("", !it4.is_valid());
    }

    void test_ring()
    {
        Atom_impl a1 ("C"); a1.set_charge (1);  //      1      //
        Atom_impl a2 ("C"); a2.set_charge (2);  //     / \     //
        Atom_impl a3 ("C"); a3.set_charge (3);  //    2   3    //
        Atom_impl a4 ("C"); a4.set_charge (4);  //    |   |    //
        Atom_impl a5 ("C"); a5.set_charge (5);  //    4---5    //

        Default_bond b12  (a1, a2);
        Default_bond b13  (a1, a3);
        Default_bond b24  (a2, a4);
        Default_bond b35  (a3, a5);
        Default_bond b45  (a4, a5);

        Molecular_depth_iterator it (a1); 
        TEST ("", &it.current() == &a1);    TEST ("", it.is_valid());
        it.next ();
        TEST ("", &it.current() == &a3);    TEST ("", it.is_valid());
        it.next ();
        TEST ("", &it.current() == &a5);    TEST ("", it.is_valid());
        it.next ();
        TEST ("", &it.current() == &a4);    TEST ("", it.is_valid());
        it.next ();
        TEST ("", &it.current() == &a2);    TEST ("", it.is_valid());
        it.next ();
        TEST ("", !it.is_valid());

        a1.kit().flag().clear (Atom_kit::molecular_mark);
        a2.kit().flag().clear (Atom_kit::molecular_mark);
        a3.kit().flag().clear (Atom_kit::molecular_mark);
        a4.kit().flag().clear (Atom_kit::molecular_mark);
        a5.kit().flag().clear (Atom_kit::molecular_mark);

        Molecular_width_iterator it2 (a1); 
        TEST ("", &it2.current() == &a1);    TEST ("", it2.is_valid());
        it2.next ();
        TEST ("", &it2.current() == &a2);    TEST ("", it2.is_valid());
        it2.next ();
        TEST ("", &it2.current() == &a3);    TEST ("", it2.is_valid());
        it2.next ();
        TEST ("", &it2.current() == &a4);    TEST ("", it2.is_valid());
        it2.next ();
        TEST ("", &it2.current() == &a5);    TEST ("", it2.is_valid());
        it2.next ();
        TEST ("", !it2.is_valid());

        a1.kit().flag().clear (Atom_kit::molecular_mark);
        a2.kit().flag().clear (Atom_kit::molecular_mark);
        a3.kit().flag().clear (Atom_kit::molecular_mark);
        a4.kit().flag().clear (Atom_kit::molecular_mark);
        a5.kit().flag().clear (Atom_kit::molecular_mark);

        /*Bond_width_iterator bond_it (a1);
        TEST ("", &bond_it.current() == &b12);    TEST ("", bond_it.is_valid());
        bond_it.next ();
        TEST ("", &bond_it.current() == &b13);    TEST ("", bond_it.is_valid());
        bond_it.next ();
        TEST ("", &bond_it.current() == &b24);    TEST ("", bond_it.is_valid());
        bond_it.next ();
        TEST ("", &bond_it.current() == &b35);    TEST ("", bond_it.is_valid());
        bond_it.next ();
        TEST ("", &bond_it.current() == &b45);    TEST ("", bond_it.is_valid());
	//bond_it.next ();
        //TEST ("", !bond_it.is_valid());//*/

        /*Molecular_bond_iterator bond_it (a1);
        TEST ("", &bond_it.current() == &b12);    TEST ("", bond_it.is_valid());
        bond_it.next ();
        TEST ("", &bond_it.current() == &b13);    TEST ("", bond_it.is_valid());
        bond_it.next ();
        TEST ("", &bond_it.current() == &b24);    TEST ("", bond_it.is_valid());
        bond_it.next ();
        TEST ("", &bond_it.current() == &b35);    TEST ("", bond_it.is_valid());
        bond_it.next ();
        TEST ("", &bond_it.current() == &b45);    TEST ("", bond_it.is_valid());
        //bond_it.next ();
        //TEST ("", !bond_it.is_valid());//*/
    }
};

Molecular_iterator_test test_molecular_iterator ("correctness");

}//MM
