int* CHTMLViewerDoc::SizeText(CDC* pDC, char* pText, int nLen, int& nHeight)
{
	int i; char c;
	int* pWidths = new int[nLen];
	
	CSize sz = pDC->GetTextExtent(pText, 1);
	*pWidths = sz.cx;
	nHeight = sz.cy;
	
	// i = 0 is already done
	for (i = 1; i < 256; i++, c++)	
		pWidths[i] = pDC->GetTextExtent(pText+i, 1).cx;

	// Caller must delete the array pointed by pWidths
}

CView* CHTMLViewerDoc::GetTextView()
{
	POSITION pos = GetFirstViewPosition();

	ASSERT(pos);

	CView* pView = GetNextView(pos);

	ASSERT_KINDOF(CHTMLViewerView, pView);

	return pView;
}

CHTMLViewerView::CHTMLViewerView() : m_rcMargins(20, 20, 20, 20)
{
	m_pFontWidthMap = NULL;
}

CHTMLViewerView::~CHTMLViewerView()
{
	if (m_pFontWidthMap) delete[] m_pFontWidthMap;
}

void CHTMLViewerView::CalcFontSize(CDC* pDC, int* pFontWidthMap)
{
	ASSERT(pFontWidthMap);
	
	int i; char c;

	for (i = 0, c = 0; i < 256; i++, c++)
		pFontWidthMap[i] = pDC->GetTextExtent(&c, 1).cx;
}

int CHTMLViewerView::CalcLine(LPCTSTR pText, int nLen, STYLE style, int cx, int& x)
{
	ASSERT(pText && nLen > 0 && cx >= 0);
	int i = 0, dx;
	x = 0;

	do {
		dx = m_pFontWidthMap[(unsigned char)pText[i]];
		if (x + dx <= cx) {
			x += dx;
			i++;
		}
		else return i;
	} while(i < nLen);
	
	return nLen;
}

void CHTMLViewerView::PrepareText()
{
	/*CRect cr;

	GetClientRect(cr);
	cr.right -= m_rcMargins.right;

	POSITION pos = GetTokens().GetHeadPosition();
	CDC* pDC = GetDC();
	LOGFONT lf;
	FONTINFO fi;
	CFont* pCurrFont;
	CFont font;

	while(pos)
	{
		fi = GetTokens().GetNext(pos);
		pCurrFont = pDC->GetCurrentFont();
		pCurrFont->GetLogFont(&lf);

		lf.lfWeight = fi.lfWeight;
		lf.lfItalic = fi.lfItalic;

		font.CreateFontIndirect(&lf);
		pDC->SelectObject(&font);

		CArray<int, int> aDx;

		aDx.

		::GetTextExtPointEx(pDC->GetSafeHdc(), fi.sText, fi.nTextLen, cr.right,
	}
	
	pDC->SelectObject(pCurrFont);
	ReleaseDC(pDC);*/
}

void CHTMLViewerView::OnDraw(CDC* pDC)
{
	CHTMLViewerDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	TOKENLIST& list = pDoc->m_tokens;
	POSITION pos = list.GetHeadPosition();
	FONTINFO fi;
	LOGFONT lf;
	CFont *pCurrFont, font;
	CRect rect;
	GetClientRect(rect);
	rect.DeflateRect(m_rcMargins);

	int x = rect.left, y = rect.top;
	int nCharCount, dx;
	

	while (pos) 
	{
		fi = list.GetNext(pos);

		pCurrFont = pDC->GetCurrentFont();
		pCurrFont->GetLogFont(&lf);

		lf.lfWeight = (fi.m_bBold) ? 700:400;
		lf.lfItalic = (fi.m_bItalic) ? TRUE:FALSE;

		if (font.GetSafeHandle()) font.DeleteObject();
		font.CreateFontIndirect(&lf);
		pDC->SelectObject(&font);

		while (fi.m_nLen > 0)
		{
			nCharCount = CalcLine(fi.m_pText, fi.m_nLen, TEXT, rect.right - x, dx);
			if (nCharCount == 0)
			{
				y += 20;
				x = rect.left;
			}
			else if (nCharCount < fi.m_nLen) 
			{
				pDC->TextOut(x, y, fi.m_pText, nCharCount);
				fi.m_pText += nCharCount;
				fi.m_nLen -= nCharCount;
				y += 20;
				x = rect.left;
			}
			else
			{
				pDC->TextOut(x, y, fi.m_pText, nCharCount);
				x += dx;
				fi.m_nLen = 0;
				break;
			}
		}
	}
}

void CHTMLViewerView::OnInitialUpdate()
{
	CScrollView::OnInitialUpdate();
	CSize sizeTotal;
	sizeTotal.cx = sizeTotal.cy = 100;
	SetScrollSizes(MM_TEXT, sizeTotal);

	/*m_pFontWidthMap = new int[256];
	CDC* pDC = GetDC();
	ASSERT(pDC);
	CalcFontSize(pDC, m_pFontWidthMap);
	ReleaseDC(pDC);*/
}

void CHTMLViewerView::OnDraw(CDC* pDC)
{
	CHTMLViewerDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	TOKENLIST& list = pDoc->m_tokens;
	POSITION pos = list.GetHeadPosition();
	CTokenInfo ti;
	CFont *pOldFont, font;
	CRect rect;
	GetClientRect(rect);
	rect.DeflateRect(m_rcMargins);

	int x = rect.left, y = rect.top;
	int nCharCount, dx;
	
	pOldFont = pDC->GetCurrentFont();

	while (pos) 
	{
		ti = list.GetNext(pos);

		PrepareFont(&font, ti.m_nStyle);
		pDC->SelectObject(&font);

		while (ti.m_nLen > 0)
		{
			nCharCount = CalcLine(ti.m_pWidths, ti.m_nLen, rect.right - x, dx);
			if (nCharCount == 0)
			{
				y += 20;
				x = rect.left;
			}
			else if (nCharCount < ti.m_nLen) 
			{
				pDC->TextOut(x, y, ti.m_pText, nCharCount);
				ti.m_pText += nCharCount;
				ti.m_nLen -= nCharCount;
				y += 20;
				x = rect.left;
			}
			else
			{
				pDC->TextOut(x, y, ti.m_pText, nCharCount);
				x += dx;
				ti.m_nLen = 0;
				break;
			}
		}
		font.DeleteObject();
	}
	pDC->SelectObject(pOldFont);
}