//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//

#include "av_upnp.h"

using namespace av_upnp;
using namespace av_upnp::details;


/////////////////////////////////////////////////////////////////////////////
// IUPnPEventSinkSupport

IUPnPEventSinkSupport::IUPnPEventSinkSupport()
    : m_punkSubscriber(NULL)
{
}


IUPnPEventSinkSupport::~IUPnPEventSinkSupport()
{
    assert(m_punkSubscriber == NULL);
}



/////////////////////////////////////////////////////////////////////////////
// IEventSinkSupport

// OnStateChanged
DWORD IEventSinkSupport::OnStateChanged(
                            /*[in]*/ LPCWSTR pszStateVariableName,
                            /*[in*/  LPCWSTR)
{
    if(!pszStateVariableName) // don't check for NULL pszValue, not sued; see ignore comment below
        return ERROR_AV_POINTER;

    ce::gate<ce::critical_section> csPunkSubscriberLock(m_csPunkSubscriber);
    
    if(m_punkSubscriber)
    {
        // We ignore the new value, pszValue, for ConnectionManager and ContentDirectory (upnp will retrieve the value through get_)

        ce::gate<ce::critical_section> csMapDISPIDsLock(m_csMapDISPIDs);
        
        const DISPIDMap::const_iterator it = m_mapDISPIDs.find(pszStateVariableName);
        
        if(it == m_mapDISPIDs.end())
            return ERROR_AV_INVALID_STATEVAR;
            
        DISPID dispid = it->second;

        HRESULT hr = m_punkSubscriber->OnStateChanged(1, &dispid);
        
        if(FAILED(hr))
            return ERROR_AV_UPNP_ACTION_FAILED; // return general error, specifics not known
    }

    return SUCCESS_AV;
}
    

// OnStateChanged
DWORD IEventSinkSupport::OnStateChanged(
                            /*[in]*/ LPCWSTR pszStateVariableName,
                            /*[in*/  long)
{
    // We ignore the new value, nValue, for ConnectionManager and ContentDirectory (upnp will retrieve the value through get_)
    return OnStateChanged(pszStateVariableName, (LPCWSTR)NULL);
}


// OnStateChanged
DWORD IEventSinkSupport::OnStateChanged(
        /*[in]*/  LPCWSTR pszStateVariableName,
        /*[in]*/  LPCWSTR pszChannel,
        /*[in]*/  long nValue)
{
    // This overload of OnStateChanged is only for RenderingControl use,
    // therefore we error (override this method to change this behavior)
    assert(false);
    
    return ERROR_AV_UPNP_ACTION_FAILED;
}
