//===-- SBBroadcaster.cpp ---------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/Core/Broadcaster.h"
#include "lldb/Core/Log.h"
#include "lldb/lldb-forward-rtti.h"

#include "lldb/API/SBBroadcaster.h"
#include "lldb/API/SBListener.h"
#include "lldb/API/SBEvent.h"

using namespace lldb;
using namespace lldb_private;


SBBroadcaster::SBBroadcaster () :
    m_opaque_sp (),
    m_opaque_ptr (NULL)
{
}

SBBroadcaster::SBBroadcaster (const char *name) :
    m_opaque_sp (new Broadcaster (name)),
    m_opaque_ptr (NULL)
{
    m_opaque_ptr = m_opaque_sp.get();
    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API | LIBLLDB_LOG_VERBOSE));

    if (log)
        log->Printf ("SBBroadcaster::SBBroadcaster (name=\"%s\") => SBBroadcaster(%p)",
                     name, m_opaque_ptr);
}

SBBroadcaster::SBBroadcaster (lldb_private::Broadcaster *broadcaster, bool owns) :
    m_opaque_sp (owns ? broadcaster : NULL),
    m_opaque_ptr (broadcaster)
{
    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API | LIBLLDB_LOG_VERBOSE));

    if (log)
        log->Printf ("SBBroadcaster::SBBroadcaster (broadcaster=%p, bool owns=%i) => SBBroadcaster(%p)", 
                     broadcaster, owns, m_opaque_ptr);
}

SBBroadcaster::SBBroadcaster (const SBBroadcaster &rhs) :
    m_opaque_sp (rhs.m_opaque_sp),
    m_opaque_ptr (rhs.m_opaque_ptr) 
{
}

const SBBroadcaster &
SBBroadcaster::operator = (const SBBroadcaster &rhs)
{
    if (this != &rhs)
    {
        m_opaque_sp = rhs.m_opaque_sp;
        m_opaque_ptr = rhs.m_opaque_ptr;
    }
    return *this;
}

SBBroadcaster::~SBBroadcaster()
{
    reset (NULL, false);
}

void
SBBroadcaster::BroadcastEventByType (uint32_t event_type, bool unique)
{
    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    if (log)
        log->Printf ("SBBroadcaster(%p)::BroadcastEventByType (event_type=0x%8.8x, unique=%i)", m_opaque_ptr, event_type, unique);

    if (m_opaque_ptr == NULL)
        return;

    if (unique)
        m_opaque_ptr->BroadcastEventIfUnique (event_type);
    else
        m_opaque_ptr->BroadcastEvent (event_type);
}

void
SBBroadcaster::BroadcastEvent (const SBEvent &event, bool unique)
{
    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    if (log)
        log->Printf ("SBBroadcaster(%p)::BroadcastEventByType (SBEvent(%p), unique=%i)", m_opaque_ptr, event.get(), unique);

    if (m_opaque_ptr == NULL)
        return;

    EventSP event_sp = event.GetSP ();
    if (unique)
        m_opaque_ptr->BroadcastEventIfUnique (event_sp);
    else
        m_opaque_ptr->BroadcastEvent (event_sp);
}

void
SBBroadcaster::AddInitialEventsToListener (const SBListener &listener, uint32_t requested_events)
{
    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBBroadcaster(%p)::AddInitialEventsToListener (SBListener(%p), event_mask=0x%8.8x)", m_opaque_ptr, listener.get(), requested_events);
    if (m_opaque_ptr)
        m_opaque_ptr->AddInitialEventsToListener (listener.get(), requested_events);
}

uint32_t
SBBroadcaster::AddListener (const SBListener &listener, uint32_t event_mask)
{
    if (m_opaque_ptr)
        return m_opaque_ptr->AddListener (listener.get(), event_mask);
    return 0;
}

const char *
SBBroadcaster::GetName () const
{
    if (m_opaque_ptr)
        return m_opaque_ptr->GetBroadcasterName().GetCString();
    return NULL;
}

bool
SBBroadcaster::EventTypeHasListeners (uint32_t event_type)
{
    if (m_opaque_ptr)
        return m_opaque_ptr->EventTypeHasListeners (event_type);
    return false;
}

bool
SBBroadcaster::RemoveListener (const SBListener &listener, uint32_t event_mask)
{
    if (m_opaque_ptr)
        return m_opaque_ptr->RemoveListener (listener.get(), event_mask);
    return false;
}

Broadcaster *
SBBroadcaster::get () const
{
    return m_opaque_ptr;
}

void
SBBroadcaster::reset (Broadcaster *broadcaster, bool owns)
{
    if (owns)
        m_opaque_sp.reset (broadcaster);
    else
        m_opaque_sp.reset ();
    m_opaque_ptr = broadcaster;
}


bool
SBBroadcaster::IsValid () const
{
    return m_opaque_ptr != NULL;
}

void
SBBroadcaster::Clear ()
{
    m_opaque_sp.reset();
    m_opaque_ptr = NULL;
}

bool
SBBroadcaster::operator == (const SBBroadcaster &rhs) const
{
    return m_opaque_ptr == rhs.m_opaque_ptr;
    
}

bool
SBBroadcaster::operator != (const SBBroadcaster &rhs) const
{
    return m_opaque_ptr != rhs.m_opaque_ptr;
}

bool
SBBroadcaster::operator < (const SBBroadcaster &rhs) const
{
    return m_opaque_ptr < rhs.m_opaque_ptr;
}
