// MailRTFView.cpp : implementation file
//

#include "stdafx.h"
#include "psm.h"
#include "PSMDoc.h"
#include "MailRTFView.h"

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

/////////////////////////////////////////////////////////////////////////////
// CMailRTFView

IMPLEMENT_DYNCREATE(CMailRTFView, CRichEditView)

CMailRTFView::CMailRTFView()
{
	m_cur_mes= NULL;
	m_iStartViewTick=-1;
}

CMailRTFView::~CMailRTFView()
{
}


BEGIN_MESSAGE_MAP(CMailRTFView, CRichEditView)
	//{{AFX_MSG_MAP(CMailRTFView)
		// NOTE - the ClassWizard will add and remove mapping macros here.
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMailRTFView drawing

void CMailRTFView::OnDraw(CDC* pDC)
{
	CPSMDoc* pDoc = GetDocument();
	// TODO: add draw code here
}

/////////////////////////////////////////////////////////////////////////////
// CMailRTFView diagnostics

#ifdef _DEBUG
void CMailRTFView::AssertValid() const
{
	CRichEditView::AssertValid();
}

void CMailRTFView::Dump(CDumpContext& dc) const
{
	CRichEditView::Dump(dc);
}

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

/////////////////////////////////////////////////////////////////////////////
// CMailRTFView message handlers

void CMailRTFView::OnInitialUpdate() 
{
	CRichEditView::OnInitialUpdate();
	
	GetRichEditCtrl().SetReadOnly();
	SetMargins(CRect(720, 720, 720, 720));
}

void CMailRTFView::EndRead()
{
//	TRACE(_T("End\n"));
//	m_iStartViewTick= -1;
//	return;

	CPSMDoc* doc= GetDocument();
	if(!doc) return;
	long iEndViewTick= GetTickCount();

	if((iEndViewTick-m_iStartViewTick)>=3000 && m_cur_mes)
	{
		CaplInstance* inst;
		CString buf;

		doc->m_api.m_data.GetAttr(m_cur_mes, doc->m_api.m_message_mgr.a_message_status, buf);
		doc->m_api.m_data.GetAttr(m_cur_mes, doc->m_api.m_message_mgr.a_message_recipient, inst);

		if(buf==_T("sendet") && doc->m_api.m_appr_mgr.GetCurrentPerson()==inst)
		{
			doc->m_api.m_data.PutAttr(m_cur_mes, doc->m_api.m_message_mgr.a_message_status, _T("readed"));
			doc->m_api.SaveChanges();
		}
	}
	
	m_iStartViewTick= -1;
}

void CMailRTFView::UpdateBody(CaplInstance *message)
{
	if(0==message) return;
	CRichEditCtrl* rtfCtrl= &GetRichEditCtrl();
	if(!rtfCtrl) return;

	CPSMDoc* doc= GetDocument();
	if(!doc) return;

	int iConLenght;
	long size;

	if(!doc->m_api.m_message_mgr.IsUserSenderOrRecipient(message))
	{
		rtfCtrl->SetWindowText(APL_T("Вы не являетесь не отправителем, ни получателем.\nПросмотр невозможен."));
		m_cur_mes=0;
		return;
	}	

	m_cur_mes= message;
	if(m_iStartViewTick!=-1) EndRead();
	m_iStartViewTick= GetTickCount();
	TRACE(_T("Start\n"));


	CString sBody;
	if(m_cur_mes)
	{
		doc->m_api.m_data.GetAttr(m_cur_mes, doc->m_api.m_message_mgr.a_message_content_lenght, iConLenght);
		CString sBlobId;
		doc->m_api.m_data.GetAttr(m_cur_mes, doc->m_api.m_message_mgr.a_message_content_source, sBlobId);
		//if(iConLenght<1000)
		if(sBlobId==_T(""))		
		{
			doc->m_api.m_data.GetAttr(m_cur_mes, doc->m_api.m_message_mgr.a_message_content, sBody);
		}
		else//зафигачили недетское сообщение...
		{
			LPTSTR szBuf= sBody.GetBuffer(iConLenght);
			size=iConLenght;
			doc->m_api.m_data.NET_LoadBlob2Memory(m_cur_mes, doc->m_api.m_message_mgr.a_message_content_source, (BYTE*)szBuf, size);
			sBody.ReleaseBuffer();
		}
		
		int n= sBody.GetLength();

		rtfCtrl->LimitText(iConLenght+1);	

		if(-1==sBody.Find(_T("\\rtf1\\")))
		{
			rtfCtrl->SetWindowText(sBody);	
			return;
		}
	}
	
	EDITSTREAM es;
	es.dwError = 0;
	es.pfnCallback = CBStreamIn;
	es.dwCookie = (DWORD) &sBody;
	rtfCtrl->StreamIn(SF_RTF, es);
	
//	rtfCtrl.SetRTF(sBody);
}

DWORD CALLBACK CMailRTFView::CBStreamIn(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
	CString *pstr = (CString *) dwCookie;

	if (pstr->GetLength() < (int) (cb/sizeof(TCHAR)))
	{
		*pcb = pstr->GetLength()*sizeof(TCHAR);
		memcpy(pbBuff, (LPCTSTR) *pstr, *pcb);
		pstr->Empty();
	}
	else
	{
		*pcb = cb;
		memcpy(pbBuff, (LPCTSTR) *pstr, *pcb);
		*pstr = pstr->Right(pstr->GetLength() - (cb/sizeof(TCHAR)));
	}

	return 0;
}

DWORD CALLBACK CMailRTFView::CBStreamOut(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
	CString *psEntry = (CString*) dwCookie;
	
	CString tmpEntry = _T("");
	tmpEntry = (CString) pbBuff;

	*psEntry += tmpEntry.Left(cb/sizeof(TCHAR));

	return 0;
}

void CMailRTFView::OnPrintBody()
{	
	CRichEditView::OnFilePrint();
}

void CMailRTFView::OnPrint(CDC* pDC, CPrintInfo* pInfo) 
{
	CPSMDoc* doc= GetDocument();
	if(!doc) return;

	ASSERT_VALID(this);
	ASSERT_VALID(pDC);
	ASSERT(pInfo != NULL);
	ASSERT(pInfo->m_bContinuePrinting);	

	UINT nPage = pInfo->m_nCurPage;
	ASSERT(nPage <= (UINT)m_aPageStart.GetSize());
	long nIndex = (long) m_aPageStart[nPage-1];
	
	int cy_top= 0; 
	int cy_bottom= 0;
	
	CGdiObject *oldObj = pDC->SelectStockObject(ANSI_VAR_FONT);
	CRect pSize= GetPrintRect();
	
	int oldMode= pDC->GetMapMode();
	pDC->SetMapMode(MM_TWIPS);
	CString buf, buf1, buf2;
	buf.Format( APL_T("Страница %i   "), pInfo->m_nCurPage);
	CSize tSize= pDC->GetOutputTextExtent(buf);
	cy_top= tSize.cy;
	pDC->TextOut(pSize.right-tSize.cx, -cy_top, buf);

	if(pInfo->m_nCurPage==1)
	{
		COleDateTime time = COleDateTime::GetCurrentTime();
		buf1 = time.Format(_T("%d.%m.%Y %H:%M"));
		CaplInstance* person= doc->m_api.m_appr_mgr.GetCurrentPerson();
		if(person)doc->m_api.m_appr_mgr.GetPersonName(person, buf2, false);
		if(buf2.IsEmpty()) buf2=  APL_T("[Анонимный пользователь]");
		buf.Format( APL_T("Распечатал: %s, %s"), buf2, buf1);

		tSize= pDC->GetOutputTextExtent(buf);	
		pDC->TextOut(pSize.left, -cy_top, buf);
		cy_top+=tSize.cy;

		CPen pen;
		pen.CreatePen(PS_SOLID|PS_COSMETIC, 1, RGB(0,0,0));
		CPen *oldPen = pDC->SelectObject(&pen);
		
		pDC->MoveTo(pSize.left, -cy_top);
		pDC->LineTo(pSize.right, -cy_top);
		
		pDC->SelectObject(oldPen);
		pen.DeleteObject();
		
		cy_top+=tSize.cy;
		
		doc->m_api.m_data.GetAttr(m_cur_mes, doc->m_api.m_message_mgr.a_message_sender, person);
		if(!person)
		{
			doc->m_api.m_data.GetAttr(m_cur_mes, doc->m_api.m_message_mgr.a_message_send_nick, buf);
			if(!buf1.IsEmpty()) buf.Format(_T("e-mail \"%s\""), buf1);
			if(buf.IsEmpty()) buf=  APL_T("[Системное сообщение]");
		}
		//else doc->m_api.m_appr_mgr.GetPersonName(person, buf);
		else doc->m_api.GetItemName(person,buf);
		
		pDC->TextOut(pSize.left, -cy_top,  APL_T("От:"), 3);
		tSize= pDC->GetOutputTextExtent(buf);	
		pDC->TextOut(pSize.left+720, -cy_top, buf);
		cy_top+=tSize.cy;
		
		doc->m_api.m_data.GetAttr(m_cur_mes, doc->m_api.m_message_mgr.a_message_rec_offisial, person);
		if(!person) doc->m_api.m_data.GetAttr(m_cur_mes, doc->m_api.m_message_mgr.a_message_recipient, person);
		if(!person)
		{
			doc->m_api.m_data.GetAttr(m_cur_mes, doc->m_api.m_message_mgr.a_message_rec_nick, buf1);
			if(!buf1.IsEmpty()) buf.Format(_T("e-mail \"%s\""), buf1);
		}
		//else doc->m_api.m_appr_mgr.GetPersonName(person, buf);
		else doc->m_api.GetItemName(person,buf1);

		pDC->TextOut(pSize.left, -cy_top,  APL_T("Кому:"), 5);
		tSize= pDC->GetOutputTextExtent(buf);
		pDC->TextOut(pSize.left+720, -cy_top, buf);
		cy_top+=tSize.cy;

		doc->m_api.m_data.GetAttr(m_cur_mes, doc->m_api.m_message_mgr.a_message_date_send, buf);
		if(!buf.IsEmpty())
		{
			aplString2Date(buf, time);	
			buf= time.Format(_T("%d.%m.%Y  %H:%M"));
		}
		pDC->TextOut(pSize.left, -cy_top,  APL_T("Дата:"), 5);
		tSize= pDC->GetOutputTextExtent(buf);
		pDC->TextOut(pSize.left+720, -cy_top, buf);
		cy_top+=tSize.cy;

		doc->m_api.m_data.GetAttr(m_cur_mes, doc->m_api.m_message_mgr.a_message_subject, buf);
		pDC->TextOut(pSize.left, -cy_top,  APL_T("Тема:"), 5);
		tSize= pDC->GetOutputTextExtent(buf);
		pDC->TextOut(pSize.left+720, -cy_top, buf);
		cy_top+=tSize.cy;
	}

	pDC->SelectObject(oldObj);
	pDC->SetMapMode(oldMode);

	FORMATRANGE fr;

	// offset by printing offset
	pDC->SetViewportOrg(-pDC->GetDeviceCaps(PHYSICALOFFSETX),
		-pDC->GetDeviceCaps(PHYSICALOFFSETY));
	
	// adjust DC because richedit doesn't do things like MFC
	if (::GetDeviceCaps(pDC->m_hDC, TECHNOLOGY) != DT_METAFILE && pDC->m_hAttribDC != NULL)
	{
		::ScaleWindowExtEx(pDC->m_hDC,
			::GetDeviceCaps(pDC->m_hDC, LOGPIXELSX),
			::GetDeviceCaps(pDC->m_hAttribDC, LOGPIXELSX),
			::GetDeviceCaps(pDC->m_hDC, LOGPIXELSY),
			::GetDeviceCaps(pDC->m_hAttribDC, LOGPIXELSY), NULL);
	}

	fr.hdcTarget = pDC->m_hAttribDC;
	fr.hdc = pDC->m_hDC;
	fr.rcPage = GetPageRect();
	fr.rc = GetPrintRect();
	
	int cy= 360, i=1;
	while (true)
	{		
		if(cy_top<cy*i)
		{
			cy_top=cy*i;
			break;
		}
		i++;
	}

	fr.rc.top+=cy_top;
//	fr.rc.top+=cy_top;
//	fr.rc.bottom-=cy_bottom;

	fr.chrg.cpMin = nIndex;
	fr.chrg.cpMax = 0xFFFFFFFF;
	nIndex = GetRichEditCtrl().FormatRange(&fr, TRUE);

	if (nIndex >= GetTextLength())
	{
		TRACE0("End of Document\n");
		pInfo->SetMaxPage(nPage);
	}

	// update pagination information for page just printed
	if (nPage == (UINT)m_aPageStart.GetSize())
	{
		if (nIndex < GetTextLength())
			m_aPageStart.Add(nIndex);
	}
	else
	{
		ASSERT(nPage+1 <= (UINT)m_aPageStart.GetSize());
		ASSERT(nIndex == (long)m_aPageStart[nPage+1-1]);
 	}
}

BOOL CMailRTFView::OnPreparePrinting(CPrintInfo* pInfo) 
{
	return DoPreparePrinting(pInfo);	
}
