// Copyright (C) 2001-2003
// William E. Kempf
//
//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#include <boost/thread/mutex.hpp>
#include <boost/thread/condition.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/xtime.hpp>
#include <iostream>

#if defined(BOOST_HAS_WINTHREADS)
#   include <windows.h>
#   include <process.h>
#endif

enum game_state
{
    START,
    PLAYER_A,
    PLAYER_B,
    GAME_OVER,
    ONE_PLAYER_GONE,
    BOTH_PLAYERS_GONE
};

int state;
boost::mutex mutex;
boost::condition cond;

char* player_name(int state)
{
    if (state == PLAYER_A)
        return "PLAYER-A";
    if (state == PLAYER_B)
        return "PLAYER-B";
    throw "bad player";
    return 0;
}

void player(void* param)
{
    boost::mutex::scoped_lock lock(mutex);

    int active = (int)param;
    int other = active == PLAYER_A ? PLAYER_B : PLAYER_A;

    while (state < GAME_OVER)
    {
        std::cout << player_name(active) << ": Play." << std::endl;
        state = other;
        cond.notify_all();
        do
        {
            cond.wait(lock);
            if (state == other)
            {
                std::cout << "---" << player_name(active)
                          << ": Spurious wakeup!" << std::endl;
            }
        } while (state == other);
    }

    ++state;
    std::cout << player_name(active) << ": Gone." << std::endl;
    cond.notify_all();
}

struct thread_adapt
{
    thread_adapt(void (*func)(void*), void* param)
        : _func(func), _param(param)
    {
    }
    int operator()() const
    {
        _func(_param);
        return 0;
    }

    void (*_func)(void*);
    void* _param;
};

class thread_adapter
{
public:
    thread_adapter(void (*func)(void*), void* param)
        : _func(func), _param(param)
    {
    }
    void operator()() const { _func(_param); }
private:
    void (*_func)(void*);
    void* _param;
};

int main(int argc, char* argv[])
{
    state = START;

    boost::thread thrda(thread_adapter(&player, (void*)PLAYER_A));
    boost::thread thrdb(thread_adapter(&player, (void*)PLAYER_B));

    boost::xtime xt;
    boost::xtime_get(&xt, boost::TIME_UTC);
    xt.sec += 1;
    boost::thread::sleep(xt);
    {
        boost::mutex::scoped_lock lock(mutex);
        std::cout << "---Noise ON..." << std::endl;
    }

    for (int i = 0; i < 1000000000; ++i)
        cond.notify_all();

    {
        boost::mutex::scoped_lock lock(mutex);
        std::cout << "---Noise OFF..." << std::endl;
        state = GAME_OVER;
        cond.notify_all();
        do
        {
            cond.wait(lock);
        } while (state != BOTH_PLAYERS_GONE);
    }

    std::cout << "GAME OVER" << std::endl;

    thrda.join();
    thrdb.join();

    return 0;
}
