// Copyright (c) Softanics

#pragma once

#include "stdafx.h"
#include "BxProgressEventsImpl.h"
#include "Utils.h"

CBxProgressEventsImpl::CBxProgressEventsImpl() :
    m_hrResult(E_FAIL)
{
    m_hEventFinished = CreateEventW(NULL, FALSE, FALSE, NULL);
}

CBxProgressEventsImpl::~CBxProgressEventsImpl()
{
    CloseHandle(m_hEventFinished);
}

CComPtr<CBxProgressEventsImpl> CBxProgressEventsImpl::Create()
{
    return new CBxProgressEventsImpl();
}

BOOL CBxProgressEventsImpl::WaitForFinish()
{
    DWORD res = WaitForSingleObject(m_hEventFinished, INFINITE);

    if (WAIT_OBJECT_0 == res)
        return S_OK;
    else if (WAIT_FAILED == res)
        return HRESULT_FROM_WIN32(GetLastError());
    else
        return E_UNEXPECTED;
}

HRESULT CBxProgressEventsImpl::GetResult()
{
    return m_hrResult;
}

HRESULT STDMETHODCALLTYPE CBxProgressEventsImpl::QueryInterface(REFIID riid, void** ppvObject)
{
    return CFreeThreadedObject::QueryInterface(riid, ppvObject);
}

HRESULT STDMETHODCALLTYPE CBxProgressEventsImpl::InternalQueryInterface(REFIID riid, void** ppvObject)
{
    DEF_BEGIN_INTERFACE_MAP()
        DEF_DECLARE_INTERFACE(IBxProgressEvents)
    DEF_END_INTERFACE_MAP()
}

ULONG STDMETHODCALLTYPE CBxProgressEventsImpl::AddRef()
{
    return CObjectWithCounter::AddRef();
}

ULONG STDMETHODCALLTYPE CBxProgressEventsImpl::Release()
{
    return CObjectWithCounter::Release();
}

HRESULT STDMETHODCALLTYPE CBxProgressEventsImpl::OnProgress(int nPercent)
{
    return S_OK;
}

HRESULT STDMETHODCALLTYPE CBxProgressEventsImpl::OnMessage(BxEnumLogLevel level, BSTR strText)
{
    if (BxEnumLogLevel_Info == level)
        printf("INFO: ");
    else if (BxEnumLogLevel_Warning == level)
        printf("WARNING: ");
    else if (BxEnumLogLevel_Error == level)
        printf("ERROR: ");

    _tprintf(L"%s\r\n", strText);

    return S_OK;
}

HRESULT STDMETHODCALLTYPE CBxProgressEventsImpl::OnFinished(HRESULT hr)
{
    if (S_OK == hr)
        printf("Finished successfully\r\n");
    else
        printf("Finished with error, hr = 0x%.8x\r\n", hr);

    m_hrResult = hr;
    SetEvent(m_hEventFinished);

    return S_OK;
}
