// clientView.cpp : implementation of the CClientView class
//

#include "stdafx.h"
#include "client.h"
#include "ctrlholder.h"
#include "CreateControlDlg.h"
#include "namewnd.h"
#include "clientDoc.h"
#include "clientView.h"
#include "bindcallback.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CClientView

IMPLEMENT_DYNCREATE(CClientView, CView)

BEGIN_MESSAGE_MAP(CClientView, CView)
	//{{AFX_MSG_MAP(CClientView)
	ON_COMMAND(ID_CONTROL_CREATE, OnControlCreate)
	ON_WM_CREATE()
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CClientView construction/destruction

CClientView::CClientView()
{
	m_pCtrlHolder = NULL ;
	m_pUnknown = NULL ;
	m_pBindCtx = NULL ;
	m_pCallback = NULL ;
	m_StatusText = "Nothing happening" ;
}

CClientView::~CClientView()
{
}

BOOL CClientView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CClientView drawing

void CClientView::OnDraw(CDC* pDC)
{
	CClientDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	pDC->TextOut (0, 250, m_StatusText) ;
}

/////////////////////////////////////////////////////////////////////////////
// CClientView printing

BOOL CClientView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CClientView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CClientView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CClientView diagnostics

#ifdef _DEBUG
void CClientView::AssertValid() const
{
	CView::AssertValid();
}

void CClientView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CClientDoc* CClientView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CClientDoc)));
	return (CClientDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CClientView message handlers

void CClientView::OnControlCreate() 
{

/*
Pop up dialog box asking user which control to create.
*/
	CCreateControlDlg dlg ;

	if (dlg.DoModal( ) == IDOK)
	{
		m_clsid = dlg.m_clsid ;
		m_PropName = dlg.m_PropName ;
		m_PropVal = dlg.m_PropVal ;
/*
Create a new bind status callback for asynch notifications during
the download. Create a bind context. Register the BindStatusCallback with it.
*/
		m_pCallback = new CBindStatusCallback (this) ;

		HRESULT hr = CreateBindCtx (0, &m_pBindCtx) ;
	

		IBindStatusCallback *pPrev = NULL ;

		hr = RegisterBindStatusCallback (
			m_pBindCtx,
			m_pCallback,
			&pPrev,
			NULL) ;
			
/*
Download control from net
*/
		hr = CoGetClassObjectFromURL (
			dlg.m_clsid,
			dlg.m_wUrlString,
			dlg.m_VersionMajor,
			dlg.m_VersionMinor,
			NULL,
			m_pBindCtx,				// bind context
			CLSCTX_INPROC_SERVER,	// server context
			NULL,
			IID_IUnknown,
			(LPVOID *) &m_pUnknown) ;

/*
Return code was S_OK, meaning control already existed on the user's
machine.  Create the control.
*/
		if (hr == S_OK)
		{
			ReallyCreateControl ( ) ;
			Cleanup ( ) ;
		}
/*
Return code was  XXX, meaning control must be downloaded. Show
progress control to user.
*/
		else if (hr == MK_S_ASYNCHRONOUS)
		{
			m_Progress.ShowWindow (SW_NORMAL) ;
			m_StatusText = "Control download Pending" ;
			Invalidate ( ) ;
		}
/*
Error condition.  Signal and abort.
*/
		else
		{
			AfxMessageBox ("Couldn't download control") ;
			Cleanup( ) ;
		}

	}

}

BOOL CClientView::ReallyCreateControl (void)
{
	if (m_pCtrlHolder)
	{
		delete m_pCtrlHolder ;
	}
	m_pCtrlHolder = new CCtrlHolder (m_clsid) ;

	CRect r (10, 10, 200, 200) ;

	BOOL bOK = m_pCtrlHolder->CreateControl (
		m_clsid,			//LPCTSTR lpszClass,
		"", 			//	LPCTSTR lpszWindowName,
		WS_CHILD | WS_VISIBLE | WS_BORDER, 	 // DWORD dwStyle
		r,   //const RECT& rect,
		this, 
		1, 
		NULL, 
		FALSE, 
		NULL) ;

	if (!bOK) 
	{
		AfxMessageBox ("Couldn't create") ;
	}
	else
	{
		m_pCtrlHolder->ShowWindow (SW_SHOWNORMAL) ;
		m_pCtrlHolder->BringWindowToTop( ) ;
	}
/*
Set property referred to in dialog box
*/

	m_pCtrlHolder->SetPropByName (m_PropName, m_PropVal) ;
	return bOK ;
}

int CClientView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CView::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	CRect rProg (15, 15, 150, 40) ;
	m_Progress.Create (WS_CHILD | WS_BORDER, rProg, this, 2) ;

	return 0;
}

void CClientView::Cleanup( )
{
	if (m_pUnknown)
	{
		m_pUnknown->Release ( ) ;
	}
	m_pUnknown = NULL ;

	if (m_pBindCtx)
	{
		m_pBindCtx->Release( ) ;
	}
	m_pBindCtx = NULL ;

	if (m_pCallback)
	{
		m_pCallback->Release ( ) ;
	}
	m_pCallback = NULL ;

	m_Progress.ShowWindow (SW_HIDE) ;
}
