#ifndef TEST_SUITE_H
#define TEST_SUITE_H

#ifndef TEST_H
#include "Test.h"
#endif

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

#ifndef ARRAY_H
#include "Array.h"
#endif

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

#ifndef TEXT_OUTPUT_H
#include "Text_output.h"
#endif

#ifndef USER_H
#include "User.h"
#endif

namespace MM
{
class Text_output;

class Test_suite : protected DbC
{
    Text_output                            *out_;
    Text                                    name_;
    Array <Test*>                           tests_;

    static Array <Own <Test_suite> > &      suites();
    static Text_output *&   default_output_ptr ();

public:
    explicit                Test_suite (const Text& name);
                            Test_suite (const Text& name, Text_output& output);
    virtual                ~Test_suite ()   {out_=0;}

    static void             run_all ();
    static Test_suite &     singleton      (const Text& suite_name);
    static void             register_suite (const Text& suite_name);
    static bool             exist_suite    (const Text& suite_name);

    static void             register_default_output (Text_output& output);
    static Text_output &    default_output ();

    void                    set_output (Text_output& output) {out_= &output;}

    int                     passed () const;
    int                     failed () const;

    void                    add_test  (Test&);
    void                    add_suite (Test_suite &);
    void                    run  ();
    
    void                    sort ();
    void                    mix  ();     

private:
    Test_suite(const Test_suite&);
    Test_suite& operator=(const Test_suite&);

    class Default_output : public Text_output
    {
        Text_output & text (const Text& text) 
        { 
            to_user().info (text); 
            return *this;
        }
        
        Text_output & line (const Text & text) 
        {
            to_user().info (text+"\n");
            return *this;
        }
    };
};

}//MM

#endif //TEST_SUITE_H

