#include "stdafx.h"
#include "resource.h"
#include "ctrlholder.h"
#include "clientdoc.h"
#include "namewnd.h"
#include "clientview.h"
#include "bindcallback.h"

/*
Constructor 
*/

CBindStatusCallback::CBindStatusCallback (CClientView *pView)
{
    m_RefCount = 1;
	m_pView = pView ;
	m_LastSize = 0 ;
	m_pBinding = NULL ;
	m_BeganDownload = FALSE ;
}

/*
Destructor
*/

CBindStatusCallback::~CBindStatusCallback()
{
	GlobalFree (m_pBuf) ;

	if (m_pBinding)
	{
		m_pBinding->Release( ) ;
	}
} 


STDMETHODIMP CBindStatusCallback::OnStartBinding(DWORD grfBSCOption, IBinding* pbinding)
{

/*
Addref the binding for later use.
*/
	m_pBinding = pbinding ;
		
	m_pBinding->AddRef ( )  ;

/*
Show status to user.
*/

	m_pView->m_StatusText = "Starting to bind ..." ;
	m_pView->Invalidate( ) ;

	return S_OK;
}  

STDMETHODIMP CBindStatusCallback::OnProgress(ULONG ulProgress, ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
{
/*
Find character string that corresponds to status flag.  Place in
edit control for user to look at.
*/

	char *cp ;
	switch (ulStatusCode)
	{
		case BINDSTATUS_FINDINGRESOURCE: cp = "Finding resource..."; break ;
		case BINDSTATUS_CONNECTING: cp = "Connecting"; break ;
		case BINDSTATUS_REDIRECTING: cp = "Redirecting"; break ;
		case BINDSTATUS_BEGINDOWNLOADDATA: cp = "Beginning download"; break ;
		case BINDSTATUS_DOWNLOADINGDATA: cp = "Downloading"; break ;
		case BINDSTATUS_ENDDOWNLOADDATA: cp = "Download completed"; break ;
		case BINDSTATUS_BEGINDOWNLOADCOMPONENTS: "Component download beginning"; break ;
		case BINDSTATUS_INSTALLINGCOMPONENTS: cp = "Installing components"; break ;
		case BINDSTATUS_ENDDOWNLOADCOMPONENTS: cp = "Component download finished"; break ;
		case BINDSTATUS_USINGCACHEDCOPY: cp = "Using cached copy"; break ;
		case BINDSTATUS_SENDINGREQUEST: cp = "Sending request"; break ;
		case BINDSTATUS_CLASSIDAVAILABLE: cp = "Class ID Available"; break ;
//		case BINDSTATUS_MIMETYPEAVAILABLE: cp = "Mime type available"; break ;
//		case BINDSTATUS_CACHEFILENAMEAVAILABLE: cp = "Cache file name available"; break ;
		default: cp = "Unknown progress flag" ;
	}
 	m_pView->m_StatusText = cp  ;
	m_pView->Invalidate ( ) ;

/*
Set state of progress indicator bar
*/
	m_pView->m_Progress.SetRange (0, ulProgressMax/1000) ;
	m_pView->m_Progress.SetPos (ulProgress/1000) ;

    return(NOERROR);
}  

STDMETHODIMP CBindStatusCallback::OnStopBinding(HRESULT hrStatus, LPCWSTR pszError) 
{
    if (hrStatus == S_OK)
	{
		m_pView->m_StatusText = "Completed" ;
	}
	else
	{
		char out [236] ;
		wsprintf (out, "download error, code == 0x%x", hrStatus) ;
		m_pView->m_StatusText = out ;
	}

	m_pView->Invalidate ( ) ;
    return S_OK;
}  


/*
Moniker is asking us to fill in a BINDINFO structure decribing the binding
operation that is about to occur.
*/

STDMETHODIMP CBindStatusCallback::GetBindInfo(DWORD* pgrfBINDF, BINDINFO* pbindInfo)
{

/*
Fill out flags 
*/

    *pgrfBINDF = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA ;

/*
Fill out structure
*/
    pbindInfo->cbSize = sizeof(BINDINFO);		// size
    pbindInfo->szExtraInfo = L""; //NULL;

    memset(&pbindInfo->stgmedData, 0, sizeof(STGMEDIUM));
    pbindInfo->grfBindInfoF = 0;
    pbindInfo->dwBindVerb = BINDVERB_GET;
    pbindInfo->szCustomVerb = NULL;
	pbindInfo->cbstgmedData	= 0 ;

    return S_OK;
} 

/*
Data Available
*/

STDMETHODIMP CBindStatusCallback::OnDataAvailable(DWORD grfBSCF, DWORD dwSize, FORMATETC* pfmtetc, STGMEDIUM* pstgmed) 
{
    return S_OK;
}  

 
STDMETHODIMP CBindStatusCallback::OnObjectAvailable(REFIID riid, IUnknown* punk) 
{
	m_pView->ReallyCreateControl( ) ;

	m_pView->Cleanup ( ) ;

    return S_OK;
}  

/*
Stubbed-out methods

*/
STDMETHODIMP CBindStatusCallback::GetPriority(LONG* pnPriority) 
{
    return S_OK;
}  

STDMETHODIMP CBindStatusCallback::OnLowResource(DWORD dwReserved)
{
    return S_OK;
}  

/*
ICodeInstall methods
*/

STDMETHODIMP CBindStatusCallback::GetWindow (REFGUID rguid, HWND *phWnd)
{
	if (phWnd)
	{
		*phWnd = m_pView->m_hWnd ;
	}
    return S_OK;
}  

STDMETHODIMP CBindStatusCallback::OnCodeInstallProblem (ULONG uiStatus, 
	LPCWSTR pExistFile, LPCWSTR pSource, DWORD dwReserved)
{
	USES_CONVERSION

	MessageBox (NULL, W2A(pSource), W2A(pExistFile), 0) ;
    return E_FAIL ;
}  




/*
IUnknown methods
*/

STDMETHODIMP CBindStatusCallback::QueryInterface(REFIID riid, void** ppv)
{ 
	if (riid==IID_IUnknown || riid==IID_IBindStatusCallback)
	{
        *ppv = (IBindStatusCallback *) this;
        AddRef();
        return S_OK;
    }
	else if (riid == IID_ICodeInstall)
	{
		*ppv = (ICodeInstall *) this ;
        AddRef();
        return S_OK;
	}
	else
	{
		*ppv = NULL ;
		return E_NOINTERFACE;
	}
}

STDMETHODIMP_(ULONG) CBindStatusCallback::AddRef()    
{ 
	return m_RefCount ++; 
}

STDMETHODIMP_(ULONG)  CBindStatusCallback::Release()
{ 
	if (--m_RefCount == 0) 
	{ 
		delete this ; 
		return 0; 
	} 
	else
	{
		return m_RefCount ; 
	}
}



