/*
 * File Name: listeners_unittest.cpp
 */

/*
 * This file is part of uds-plugin-comics.
 *
 * uds-plugin-images is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * uds-plugin-images is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * Copyright (C) 2008 iRex Technologies B.V.
 * All rights reserved.
 */

#include <cassert>
#include <algorithm>
#include <tut.h>
#include <tut_reporter.h>
#include "listeners.h"
#include "plugin_inc.h"
#include "log.h"

namespace
{

    typedef std::vector<unsigned long> id_vector;
    typedef std::vector<unsigned long>::iterator id_vector_iter;

class A
{
public:
    A(){}
    ~A(){}

public:
    static void callback( IPluginUnknown          *thiz_sender,
                          unsigned long           handler_id,
                          const PluginEvent       plugin_event,
                          void                    *user_data,
                          const PluginEventAttrs  *plugin_data )
    {
        LOGPRINTF("Callback of A instance %p type %d", 
                  user_data, plugin_event); 
    }
    
    void add_id(const unsigned long id)
    {
        ids.push_back(id);
    }

    void remove_id(const unsigned long id)
    {
        id_vector_iter it = std::find(ids.begin(), ids.end(), id);
        if (it != ids.end())
        {
            ids.erase(it);
        }
    }

    unsigned long front()
    {
        return ids.front();
    }

private:
    id_vector ids;  
};

class B
{
public:
    B(){}
    ~B(){}

public:
    static void callback( IPluginUnknown          *thiz_sender,
                          unsigned long           handler_id,
                          const PluginEvent       plugin_event,
                          void                    *user_data,
                          const PluginEventAttrs  *plugin_data )
    {
        LOGPRINTF("Callback of B instance %p  type %d",
                   user_data, plugin_event);
    }
};


};  // anonymous namespace

namespace tut
{
    struct empty
    { 
    };

    typedef test_group<empty> tf;
    typedef tf::object object;
    tf listeners_group("listeners test");

    // Test 1: Basic test.
    template<>
    template<>
    void object::test<1>()
    {
        using namespace utils;
        Listeners container;
        A a;            
        B b;
        unsigned long id;

        id = container.add_listener(EVENT_PAGINATE_START, A::callback, &a);
        a.add_id(id);
        id = container.add_listener(EVENT_PAGINATE_END, A::callback, &a);
        a.add_id(id);        

        id =  container.add_listener(EVENT_PAGINATE_START, B::callback, &b);

        for(int e = EVENT_PAGINATE_START;
            e != EVENT_MARKER_OUT_OF_DATE;
            ++e)
        {
            container.broadcast(0, static_cast<PluginEvent>(e), 0);
        }
    
        container.remove_listener(id);
        container.remove_listener(a.front());

        container.broadcast(0, EVENT_PAGINATE_START, 0);
    }

};


using std::exception;
using std::cerr;
using std::endl;

namespace tut
{
    test_runner_singleton runner;
}

int main()
{
    tut::reporter reporter;
    tut::runner.get().set_callback(&reporter);

    try
    {
        tut::runner.get().run_tests();
    }
    catch (const std::exception& ex)
    {
        cerr << "tut raised ex: " << ex.what() << endl;
        return 1;
    }

    while(1);
    return 0;
}



