// MessageDlg.cpp : implementation file
//

#include "stdafx.h"
//#include "aplstepmgr.h"
#include "MessageDlg.h"
#include "dictionary.h"
#include "apl_api.h"
#include "icons_defines.h"
#include "SelectPecipientsDlg.h"

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


bool GetHtmlCodePage(CString &html, CString &sCodePage) // Задаем кодовую страницу на UTF-8(было 1251)
{
	sCodePage=_T("");
	CString buf,htmlLo=html; htmlLo.MakeLower();
	
	int its, ite,j,k;
	j=0;
	while(true)
	{
		its=htmlLo.Find(_T("<meta"),j);
		if(its<0) break;
		ite=htmlLo.Find(_T(">"),its);
		if(ite<0) break;
		j=ite;
		
		k=htmlLo.Find(_T("charset"),its);
		if(k>0 && k<ite)
		{
			k=htmlLo.Find(_T("="),k);
			if(k<0 || k>ite) break;

			k++;

			int k1=htmlLo.Find(_T("\""),k);
			if(k1<0 || k1>ite) break;

			buf=htmlLo.Mid(k,k1-k);
			buf.TrimLeft(); buf.TrimRight();

			if(buf!=_T("")) sCodePage=buf;

			//if(buf==_T("windows-1251")) return true;
			//if(buf==_T("utf-8")) return true;

			//Заменяем кодировку
			//html.Delete(k,k1-k);
			//html.Insert(k,_T("windows-1251"));
			//html.Insert(k,_T("utf-8"));

			return true;
		}
	}
	// Не нашлось тега с кодировкой
	// Если нет кодировки - считаем что это 1251

	bool bInsertHead=false;
	its=htmlLo.Find(_T("<head>"),0);
	if(its>0) its+=6;
	else
	{
		bInsertHead=true;
		its=htmlLo.Find(_T("<html>"),0);
		if(its<0) return false;
		its+=6;
	}
	
	buf=_T("");
	if(bInsertHead) buf+=_T("\n<head>");
	buf+=_T("\n<meta http-equiv=\"content-type\" content=\"text/html; charset=windows-1251\">");
	if(bInsertHead) buf+=_T("\n</head>");
	html.Insert(its,buf);
	return true;
}

bool InsertHtmlTag(CString &html)
{
	CString buf,htmlLo=html; htmlLo.MakeLower();
	if(htmlLo.Find(_T("<html>"))>=0 ) return true;

	int i,i_start=0,j;
	while(true)
	{
		i=htmlLo.Find(_T("<style"),i_start);
		if(i<0) break;
		j=htmlLo.Find(_T("</style>"),i+6);
		if(j<0) return false; // Это совсем кривой html

		i_start=j+8;
	}
	html.Insert(i_start,_T("<html>\n")); 
	html+=_T("\n</html>");

	return true;
}



bool InsertBodyTag(CString &html)
{
	CString buf,htmlLo=html; htmlLo.MakeLower();
	if(htmlLo.Find(_T("<body>"))>=0) return true;

	int i;
	i=htmlLo.Find(_T("</body>"));
	if(i<0) 
	{
		i=htmlLo.Find(_T("</html>"));
		if(i<0) htmlLo+=_T("</body>");
		else html.Insert(i,_T("</body>")); 
	}

	i=htmlLo.Find(_T("</head>"),0);
	if(i>0) html.Insert(i+7,_T("<body>")); 
	else
	{

		int i_start=0,j;
		// Ищем последний тег
		while(true)
		{
			j=htmlLo.Find(_T("</style>"),i_start);
			if(j<0) break;
			i_start=j+8;
		}

		if(i_start>0) html.Insert(i_start+8,_T("<body>")); 
		else 
		{
			i=htmlLo.Find(_T("<html>"));
			if(i>=0) html.Insert(i+6,_T("<body>")); 
		}
	}
	return true;
}

bool GetHtmlContent(CString &html)  // вырезаем начинку из письма
{
	if(html==_T("")) return true;
	CString buf,htmlLo=html; htmlLo.MakeLower();
	if(htmlLo.Find(_T("<html>"))<0 ) return true;

	// Ищем конец
	int i_end=htmlLo.Find(_T("</body>"));
	if(i_end<0 )
	{
		i_end=htmlLo.Find(_T("</html>"));
		if(i_end<0 ) i_end=html.GetLength();
	}

	int i_start=htmlLo.Find(_T("<body>"));
	if(i_start>=0 )i_start+=6;
	else
	{
		i_start=htmlLo.Find(_T("</head>"));
		if(i_start>=0 )i_start+=7;
		else
		{
			i_start=htmlLo.Find(_T("<html>"));
			if(i_start>=0 )i_start+=6;
			else i_start=0;
		}
	}

	int len=i_end-i_start;
	if(0==len) return true;
	if(len<0) return false;
	buf=html.Mid(i_start,len);
	html=buf;
	return true;

}

bool GetHtmlPlainText(CString &html)
{
	if(html==_T("")) return true;

	html.Replace(_T("<br>"),_T("\r\n"));
	html.Replace(_T("<BR>"),_T("\r\n"));

	int i=0;
	CString sResult;

	bool isTag=false, isStr=false;  // Если isStr=true, то  isTag жолжен быть yrue
	while(true)
	{
		TCHAR c=html[i];
		if(c==_T('\0')) break;

		if(isTag)
		{
			if(c==_T('>'))
			{
				if(!isStr) isTag=false;
			}
			else if(c==_T('"')) isStr=!isStr;

		}
		else if(c==_T('<')) isTag=true;
		
		else sResult+=c;

		i++;
	}
	html=sResult;
	return true;
}
//********************************************************************************************
//********************************************************************************************
//********************************************************************************************


// Преобразует строку UCS2 в однобайтовую где четные нули
#ifdef _UNICODE

/*void ConvertUCS2ToMsgSting(CStringW &wStr)
{
	// Тут будет строка UCS2, котороую надо будет переконвертировать в utf-8, но через байт
	int size=wStr.GetLength();
	if(size<=0) return;

	CaplStringAdapter sa(wStr);
	LPCSTR pAnsiBuf=(LPSTR)sa;

	char *wBuf=new char[2*(size+1)];
	int k1,k2;
	for(k1=0,k2=0; k1<=size; k1++, k2+=2)
	{
		wBuf[k2]=pAnsiBuf[k1];
		wBuf[k2+1]='\0';
	}
	wStr=(LPWSTR)wBuf;
	delete wBuf;
}*/

void ConvertUCS2ToMsgSting(CStringW &wStr, bool bToUtf8)
{
	// Тут будет строка UCS2, котороую надо будет переконвертировать в utf-8, но через байт
	int size=wStr.GetLength();
	if(size<=0) return;

	UINT code=1251;
	if(bToUtf8) code=CP_UTF8;

	const wchar_t *inStr=LPCWSTR(wStr);
	int iMultybyteLen=WideCharToMultiByte(code, 0, inStr, -1, 0, 0, 0, 0);

	if(0==iMultybyteLen) return;

	char *sMultybyte=new char[iMultybyteLen];
	int iMultybyteLen2=WideCharToMultiByte(code, 0, inStr, -1, sMultybyte, iMultybyteLen, 0, 0);
	if(iMultybyteLen2<=0)
	{
		delete sMultybyte; sMultybyte=0; 
		return;
	}


	char *wBuf=new char[2*iMultybyteLen2];
	int k1,k2;
	for(k1=0,k2=0; k1<iMultybyteLen2; k1++, k2+=2)
	{
		wBuf[k2]=sMultybyte[k1];
		wBuf[k2+1]='\0';
	}
	delete sMultybyte; sMultybyte=0;
	wStr=(LPWSTR)wBuf;
	delete wBuf; wBuf =0;
}


void ConvertMultiByteToMsgSting(unsigned char *pBuf, int iBufSize, CStringW &wStr)
{
	if(iBufSize<=0) return;
	char *wBuf=new char[2*(iBufSize+1)];
	int k1,k2;
	for(k1=0,k2=0; k1<=iBufSize; k1++, k2+=2)
	{
		wBuf[k2]=pBuf[k1];
		wBuf[k2+1]='\0';
	}
	wStr=(LPWSTR)wBuf;
	delete wBuf;
}

#else 

void ConvertAnsi2ToUtf8Sting(CStringA &aStr)
{
	int iLen=aStr.GetLength();
	if(iLen<=0) return;

	CStringW  wStr(aStr);
	const wchar_t *inStr=LPCWSTR(wStr);
	int iMultybyteLen=WideCharToMultiByte(CP_UTF8, 0, inStr, -1, 0, 0, 0, 0);

	if(0==iMultybyteLen) return;

	char *sMultybyte=new char[iMultybyteLen];
	int iMultybyteLen2=WideCharToMultiByte(CP_UTF8, 0, inStr, -1, sMultybyte, iMultybyteLen, 0, 0);
	if(iMultybyteLen2<=0)
	{
		delete sMultybyte; sMultybyte=0; 
		return;
	}

	aStr=sMultybyte;
	delete sMultybyte; sMultybyte=0;
}

#endif

//********************************************************************************************
//********************************************************************************************
//********************************************************************************************
/////////////////////////////////////////////////////////////////////////////
// CMessageDlg dialog


CMessageDlg::CMessageDlg(CWnd* pParent /*=NULL*/)
	: CResizableDialog(CMessageDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CMessageDlg)
	m_sSubject = _T("");
	m_iPriority = 0;
	m_iFontSize = -1;
	m_iFont = -1;
	m_sSender = _T("");
	//}}AFX_DATA_INIT

	m_appIco=0;

	m_message=0;
	m_main_message=0;
	m_recipient=0;
	m_sender=0;
	
	m_iAction= 0;
	m_sMesStatus= _T("sendet");
	m_curSelItem= NULL;
	m_possibleRecips= NULL;

	m_bInsetQuote=false;

	m_bChanged=false;
	m_bNoAction=false;
	m_bReadOnly= false;

	m_bHtmlMode=false;

	AfxInitRichEdit2();
}

void CMessageDlg::OnDestroy()
{

	if(m_sFile4Delete!=_T("")) ::DeleteFile(m_sFile4Delete);

	CResizableDialog::OnDestroy();

	if(0!=m_appIco){DestroyIcon(m_appIco); m_appIco=0;};
}

void CMessageDlg::DoDataExchange(CDataExchange* pDX)
{
	CResizableDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CMessageDlg)
	DDX_Control(pDX, IDC_FONT_JUSTIFY, m_fJustifyBtn);
	DDX_Control(pDX, IDC_TO_TEXT_STATIC, m_toTextStatic);
	DDX_Control(pDX, IDC_MES_RECIPIENTS_SEL_BUTTON, m_recSelBtn);
	DDX_Control(pDX, IDC_LOAD_FILE, m_loadFileBtn);
	DDX_Control(pDX, IDC_VIEW_FILE, m_viewFileBtn);
	DDX_Control(pDX, IDC_ADD_FILE, m_addFileBtn);
	DDX_Control(pDX, IDC_TEXT_PASTE, m_tPaste);
	DDX_Control(pDX, IDC_TEXT_CUT, m_tCut);
	DDX_Control(pDX, IDC_TEXT_COPY, m_tCopy);
	DDX_Control(pDX, IDC_FONTS_LIST, m_fontCB);
	DDX_Control(pDX, IDC_FONT_SIZE, m_fontSizeCB);
	DDX_Control(pDX, IDC_FONT_BULLETED, m_fBulletedBtn);
	DDX_Control(pDX, IDC_FONT_ORDERLIST, m_fOrderListBtn);
	DDX_Control(pDX, IDC_FONT_UNDERLINE, m_fUnderLineBtn);
	DDX_Control(pDX, IDC_FONT_STRIKE, m_fStrikeBtn);
	DDX_Control(pDX, IDC_FONT_RIGHT, m_fRightBtn);
	DDX_Control(pDX, IDC_FONT_LEFT, m_fLeftBtn);
	DDX_Control(pDX, IDC_FONT_COLOR, m_fColorBtn);
	DDX_Control(pDX, IDC_FONT_ITALIC, m_fItalicBtn);
	DDX_Control(pDX, IDC_FONT_CENTER, m_fCentefBtn);
	DDX_Control(pDX, IDC_FONT_BOLD, m_fBoldBtn);
	DDX_Control(pDX, IDC_PRIORITY_COMBO, m_priorityCB);
	DDX_Control(pDX, IDC_MESSAGE_NAME_STATIC, m_btmCtrl);
	DDX_Control(pDX, IDC_MESSAGE_ITEMS, m_itemsList);
	DDX_Control(pDX, IDC_DELETE_ITEM, m_deleteItemBtn);
	DDX_Control(pDX, IDC_ADD_ITEM, m_addItemBtn);
	DDX_Control(pDX, IDCANCEL, m_cancelBtn);
	DDX_Control(pDX, IDC_SEND_BUTTON, m_SendBtn);
	DDX_Control(pDX, IDC_DELETE_BUTTON, m_deleteBtn);
	DDX_Control(pDX, IDC_FORWARD_BUTTON, m_forwardBtn);
	DDX_Control(pDX, IDC_REPLY_BUTTON, m_replyBtn);
	DDX_Control(pDX, IDC_SAVE_BUTTON, m_draftBtn);
	DDX_Control(pDX, IDC_SUBJECT_EDIT, m_subject);
	DDX_Control(pDX, IDC_TO_STATIC, m_wndRecipient);
	DDX_Control(pDX, IDC_FROM_STATIC, m_wndSender);
	DDX_Control(pDX, IDC_MESSAGE_RICHEDIT, m_content);
	DDX_Text(pDX, IDC_SUBJECT_EDIT, m_sSubject);
	DDX_CBIndex(pDX, IDC_PRIORITY_COMBO, m_iPriority);
	DDX_CBIndex(pDX, IDC_FONT_SIZE, m_iFontSize);
	DDX_CBIndex(pDX, IDC_FONTS_LIST, m_iFont);
	DDX_Text(pDX, IDC_FROM_STATIC, m_sSender);
	//}}AFX_DATA_MAP
	DDX_Control(pDX, IDC_WORDWRAP, m_wordwrap_btn);
	DDX_Control(pDX, ID_INFO, m_info_btn);
	DDX_Control(pDX, ID_OPEN_NOMODAL, m_OpenNoModalBtn);
	DDX_Control(pDX, IDC_MES_COPY_RECIPIENTS_SEL_BUTTON, m_recCopySelBtn);
	DDX_Control(pDX, IDC_TO_COPY_STATIC, m_wndRecipientCopy);
	DDX_Control(pDX, IDC_COPY_TEXT_STATIC, m_copyTextStatic);
	DDX_Control(pDX, IDC_REPLY_ALL_BUTTON, m_replyAllBtn);
	DDX_Control(pDX, IDC_MESSAGE_ICO, m_msg_ico_ctrl);
}


BEGIN_MESSAGE_MAP(CMessageDlg, CResizableDialog)
	//{{AFX_MSG_MAP(CMessageDlg)
	ON_BN_CLICKED(IDC_DELETE_BUTTON, OnDeleteButton)
	ON_BN_CLICKED(IDC_FORWARD_BUTTON, OnForwardButton)
	ON_BN_CLICKED(IDC_REPLY_BUTTON, OnReplyButton)
	ON_BN_CLICKED(IDC_SAVE_BUTTON, OnSaveButton)
	ON_BN_CLICKED(IDC_ADD_ITEM, OnAddItem)
	ON_BN_CLICKED(IDC_DELETE_ITEM, OnDeleteItem)
	ON_NOTIFY(LVN_ITEMCHANGED, IDC_MESSAGE_ITEMS, OnItemchangedMessageItems)
	ON_BN_CLICKED(IDC_FONT_BOLD, OnFontBold)
	ON_BN_CLICKED(IDC_FONT_CENTER, OnFontCenter)
	ON_BN_CLICKED(IDC_FONT_ITALIC, OnFontItalic)
	ON_BN_CLICKED(IDC_FONT_LEFT, OnFontLeft)
	ON_BN_CLICKED(IDC_FONT_RIGHT, OnFontRight)
	ON_BN_CLICKED(IDC_FONT_UNDERLINE, OnFontUnderline)
	ON_BN_CLICKED(IDC_TEXT_PASTE, OnTextPaste)
	ON_BN_CLICKED(IDC_TEXT_CUT, OnTextCut)
	ON_BN_CLICKED(IDC_TEXT_COPY, OnTextCopy)
	ON_BN_CLICKED(IDC_FONT_BULLETED, OnFontBulleted)
	ON_CBN_CLOSEUP(IDC_FONTS_LIST, OnCloseupFontsList)
	ON_CBN_CLOSEUP(IDC_FONT_SIZE, OnCloseupFontSize)
	ON_BN_CLICKED(IDC_FONT_COLOR, OnFontColor)
	ON_NOTIFY(EN_SELCHANGE, IDC_MESSAGE_RICHEDIT, OnSelchangeMessageRichedit)
	ON_NOTIFY(EN_SETFOCUS, IDC_MESSAGE_RICHEDIT, OnSetfocusMessageRichedit)
	ON_NOTIFY(EN_KILLFOCUS, IDC_MESSAGE_RICHEDIT, OnKillfocusMessageRichedit)
	ON_BN_CLICKED(IDC_ADD_FILE, OnAddFile)
	ON_BN_CLICKED(IDC_VIEW_FILE, OnViewFile)
	ON_BN_CLICKED(IDC_LOAD_FILE, OnLoadFile)
	ON_BN_CLICKED(IDC_MES_RECIPIENTS_SEL_BUTTON, OnMesRecipientsSelButton)
	ON_BN_CLICKED(IDC_MESSAGE_NAME_STATIC, OnMessageNameStatic)
	ON_BN_CLICKED(IDC_FONT_JUSTIFY, OnFontJustify)
	ON_NOTIFY(NM_KILLFOCUS, IDC_MESSAGE_RICHEDIT, OnKillfocusMessageRichedit)
	ON_NOTIFY(NM_SETFOCUS, IDC_MESSAGE_RICHEDIT, OnSetfocusMessageRichedit)
	ON_WM_SIZE()
	//}}AFX_MSG_MAP
	ON_BN_CLICKED(IDC_WORDWRAP, &CMessageDlg::OnBnClickedWordwrap)
	ON_NOTIFY(NM_DBLCLK, IDC_MESSAGE_ITEMS, &CMessageDlg::OnNMDblclkMessageItems)
	ON_BN_CLICKED(ID_INFO, &CMessageDlg::OnBnClickedInfo)
	ON_BN_CLICKED(IDC_SEND_BUTTON, &CMessageDlg::OnBnClickedSendButton)
	ON_BN_CLICKED(ID_OPEN_NOMODAL, &CMessageDlg::OnBnClickedOpenNomodal)
	ON_BN_CLICKED(IDC_MES_COPY_RECIPIENTS_SEL_BUTTON, &CMessageDlg::OnBnClickedMesCopyRecipientsSelButton)
	ON_BN_CLICKED(IDC_REPLY_ALL_BUTTON, &CMessageDlg::OnBnClickedReplyAllButton)
	ON_WM_DESTROY()
	ON_NOTIFY(NM_RCLICK, IDC_MESSAGE_ITEMS, &CMessageDlg::OnNMRClickMessageItems)
	ON_WM_SHOWWINDOW()
	ON_BN_CLICKED(IDC_FONT_ORDERLIST, &CMessageDlg::OnBnClickedFontOrderlist)
	ON_BN_CLICKED(IDC_FONT_STRIKE, &CMessageDlg::OnBnClickedFontStrike)
END_MESSAGE_MAP()

#define TWO_THIRDS_LEFT CSize(0,65)
#define TWO_THIRDS_RIGHT CSize(100,65)


/////////////////////////////////////////////////////////////////////////////

void CMessageDlg::DisableTextEditCtrl()
{
	//return;
	m_fBoldBtn.EnableWindow(FALSE);
	m_fItalicBtn.EnableWindow(FALSE);
	m_fUnderLineBtn.EnableWindow(FALSE);
	m_fStrikeBtn.EnableWindow(FALSE);
	m_fColorBtn.EnableWindow(FALSE);
	m_fLeftBtn.EnableWindow(FALSE);
	m_fCentefBtn.EnableWindow(FALSE);
	m_fRightBtn.EnableWindow(FALSE);
	m_fJustifyBtn.EnableWindow(FALSE);
	m_tCut.EnableWindow(FALSE);
	//				m_tCopy.EnableWindow(FALSE);
	m_tPaste.EnableWindow(FALSE);
	m_fBulletedBtn.EnableWindow(FALSE);
	m_fOrderListBtn.EnableWindow(FALSE);

	m_fontCB.EnableWindow(FALSE);
	m_fontSizeCB.EnableWindow(FALSE);
}


void  CMessageDlg::InitControls()
{
	if(0==AfxGetMainWnd())
	{
		CWinApp *app=AfxGetApp(); // При вызове из ActiveX возвращает 0
		if(0!=app) m_appIco=app->LoadIcon(IDI_MAIL);
		SetIcon(m_appIco,TRUE);
	}

	ModifyStyleEx(0, WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE | WS_EX_CONTROLPARENT);   
	ModifyStyle(0, WS_MAXIMIZEBOX);   

	m_content.SetTargetDevice(NULL, 0);
	m_wordwrap_btn.SetCheck(BST_CHECKED);

	AddAnchor(IDCANCEL, BOTTOM_RIGHT);
	AddAnchor(ID_OPEN_NOMODAL, BOTTOM_RIGHT);
	AddAnchor(ID_INFO, BOTTOM_LEFT);
	AddAnchor(ID_INFO, ID_OPEN_NOMODAL);
/*	AddAnchor(IDOK, TOP_RIGHT);
	
	AddAnchor(IDC_DELETE_BUTTON, TOP_RIGHT);
	AddAnchor(IDC_FORWARD_BUTTON, TOP_RIGHT);
	AddAnchor(IDC_REPLY_BUTTON, TOP_RIGHT);
	AddAnchor(IDC_SAVE_BUTTON, TOP_RIGHT);*/

	AddAnchor(IDC_SUBJECT_EDIT, TOP_LEFT, TOP_RIGHT);
	AddAnchor(IDC_TO_COPY_STATIC,TOP_LEFT, TOP_RIGHT);
	AddAnchor(IDC_TO_STATIC,TOP_LEFT, TOP_RIGHT);
	AddAnchor(IDC_FROM_STATIC,TOP_LEFT, TOP_RIGHT);
	
	AddAnchor(IDC_MESSAGE_RICHEDIT, TOP_LEFT, TWO_THIRDS_RIGHT);
	AddAnchor(IDC_MESSAGE_ITEMS, TWO_THIRDS_LEFT, BOTTOM_RIGHT);
	
	AddAnchor(IDC_TEXT_STATIC, TWO_THIRDS_LEFT, TWO_THIRDS_RIGHT);
	AddAnchor(IDC_ADD_ITEM, TWO_THIRDS_RIGHT);
	AddAnchor(IDC_DELETE_ITEM, TWO_THIRDS_RIGHT);
	AddAnchor(IDC_ADD_FILE, TWO_THIRDS_RIGHT);
	AddAnchor(IDC_VIEW_FILE, TWO_THIRDS_RIGHT);
	AddAnchor(IDC_LOAD_FILE, TWO_THIRDS_RIGHT);
	
	AddAnchor(IDC_PRIOR_STATIC, TOP_RIGHT);
	AddAnchor(IDC_PRIORITY_COMBO, TOP_RIGHT);
	
	AddAnchor(IDC_FONTS_LIST, TOP_LEFT, TOP_RIGHT);
	AddAnchor(IDC_FONT_SIZE, TOP_RIGHT);
	
	AddAnchor(IDC_TEXT_CUT, TOP_RIGHT);
	AddAnchor(IDC_TEXT_COPY, TOP_RIGHT);
	AddAnchor(IDC_TEXT_PASTE, TOP_RIGHT);
	AddAnchor(IDC_FONT_BOLD, TOP_RIGHT);
	AddAnchor(IDC_FONT_ITALIC, TOP_RIGHT);
	AddAnchor(IDC_FONT_UNDERLINE, TOP_RIGHT);
	AddAnchor(IDC_FONT_STRIKE, TOP_RIGHT);
	AddAnchor(IDC_FONT_COLOR, TOP_RIGHT);
	AddAnchor(IDC_FONT_LEFT, TOP_RIGHT);
	AddAnchor(IDC_FONT_CENTER, TOP_RIGHT);
	AddAnchor(IDC_FONT_RIGHT, TOP_RIGHT);
	AddAnchor(IDC_FONT_JUSTIFY, TOP_RIGHT);
	AddAnchor(IDC_FONT_BULLETED, TOP_RIGHT);
	AddAnchor(IDC_FONT_ORDERLIST, TOP_RIGHT);
	AddAnchor(IDC_WORDWRAP, TOP_RIGHT);

	m_replyBtn.EnableWindow(FALSE);
	m_replyAllBtn.EnableWindow(FALSE);
	m_forwardBtn.EnableWindow(FALSE);
	m_deleteBtn.EnableWindow(FALSE);

	//Прикрепленные элементы
	//		m_imageList.Create(IDR_NAVIGATOR_ICON, 20, 11, RGB(255, 0, 255));
	m_itemsList.SetImageList(aplGetInstImageList(), LVSIL_SMALL);

	m_itemsList.SetExtendedStyle(m_itemsList.GetExtendedStyle()|LVS_EX_FULLROWSELECT|LVS_EX_SUBITEMIMAGES );
	m_itemsList.InsertColumn(0,APL_T("Элемент"), LVCFMT_LEFT, 2000);

	BOOL res= m_itemsList.SetItemState(-1, LVNI_SELECTED, LVNI_SELECTED); 
	m_deleteItemBtn.EnableWindow(FALSE);
	m_loadFileBtn.EnableWindow(FALSE);
	m_viewFileBtn.EnableWindow(FALSE);


	//Кнопки
	static CImageList imglst_tc;
	if(0==imglst_tc.m_hImageList)
	{
		imglst_tc.Create(25, 24, ILC_COLOR24|ILC_MASK, 0, 10);
		CBitmap mailBtnBitmap;
		mailBtnBitmap.LoadBitmap(IDB_TC_MAIL_BTN);
		imglst_tc.Add(&mailBtnBitmap, RGB(192,192,192));
	}
	m_SendBtn.SetIcon(imglst_tc.ExtractIcon(0));
	m_draftBtn.SetIcon(imglst_tc.ExtractIcon(1));
	m_replyBtn.SetIcon(imglst_tc.ExtractIcon(2));
	m_forwardBtn.SetIcon(imglst_tc.ExtractIcon(3));
	m_deleteBtn.SetIcon(imglst_tc.ExtractIcon(4));
	m_replyAllBtn.SetIcon(imglst_tc.ExtractIcon(5));

	m_cancelBtn.SetIcon(GetAplStdIco16(APLSTDICO_CANCEL));
	m_cancelBtn.SetFlat(FALSE);
	m_info_btn.SetIcon(GetAplStdIco16(APLSTDICO_INFO));
	m_info_btn.SetFlat(FALSE);

	m_OpenNoModalBtn.SetIcon(IDI_OPEN_IN_NEW_WND);
	//m_OpenNoModalBtn.SetIcon(AfxGetApp()->LoadIcon(IDI_OPEN_IN_NEW_WND));
	m_OpenNoModalBtn.SetFlat(FALSE);

	m_addItemBtn.SetIcon(GetAplStdIco24(2));
	m_deleteItemBtn.SetIcon(GetAplTableIco(APL_TABLE_DEL));
	m_addFileBtn.SetIcon(GetAplTableIco(APL_TABLE_NEW));
	m_viewFileBtn.SetIcon(GetAplTableIco(APL_TABLE_VIEW));
	m_loadFileBtn.SetIcon(GetAplTableIco(APL_TABLE_SAVE));

	m_recSelBtn.SetAlign(m_recSelBtn.ST_ALIGN_HORIZ_RIGHT);
	m_recSelBtn.SetIcon(GetAplTableIco(APL_TABLE_SELECT_DOWN));
	m_recCopySelBtn.SetAlign(m_recSelBtn.ST_ALIGN_HORIZ_RIGHT);
	m_recCopySelBtn.SetIcon(GetAplTableIco(APL_TABLE_SELECT_DOWN));

	if(!CaplTranslate::IsNeedTranslate())
	{
		m_fBoldBtn.SetIcon(GetAplTableIco(APL_TABLE_BOLD));
		m_fItalicBtn.SetIcon(GetAplTableIco(APL_TABLE_ITALIC));
		m_fUnderLineBtn.SetIcon(GetAplTableIco(APL_TABLE_UNDERLINE));
	}
	else
	{
		m_fBoldBtn.SetIcon(GetAplTableIco(APL_TABLE_BOLD_EN));
		m_fItalicBtn.SetIcon(GetAplTableIco(APL_TABLE_ITALIC_EN));
		m_fUnderLineBtn.SetIcon(GetAplTableIco(APL_TABLE_UNDERLINE_EN));
	}
	m_fStrikeBtn.SetIcon(GetAplTableIco(APL_TABLE_STRIKEOUT));

	m_fColorBtn.SetIcon(GetAplTableIco(9));
	m_fLeftBtn.SetIcon(GetAplTableIco(14));
	m_fCentefBtn.SetIcon(GetAplTableIco(15));
	m_fRightBtn.SetIcon(GetAplTableIco(16));
	m_fJustifyBtn.SetIcon(GetAplTableIco(17));
	m_fBulletedBtn.SetIcon(GetAplTableIco(12));
	m_fOrderListBtn.SetIcon(GetAplTableIco(13));
	m_tCut.SetIcon(GetAplTableIco(APL_TABLE_CUT));
	m_tCopy.SetIcon(GetAplTableIco(APL_TABLE_COPY));
	m_tPaste.SetIcon(GetAplTableIco(APL_TABLE_PASTE));

	m_SendBtn.SetTooltipText(APL_T("Отправить сообщение"));
	m_draftBtn.SetTooltipText(APL_T("Сохранить сообщение в черновиках"));
	m_replyBtn.SetTooltipText(APL_T("Ответить на сообщение"));
	m_replyAllBtn.SetTooltipText(APL_T("Ответить всем"));
	m_forwardBtn.SetTooltipText(APL_T("Переслать сообщение"));
	m_deleteBtn.SetTooltipText(APL_T("Удалить сообщение"));
	m_cancelBtn.SetTooltipText(APL_T("Выход"));
	m_addItemBtn.SetTooltipText(APL_T("Добавить элемент"));
	m_deleteItemBtn.SetTooltipText(APL_T("Удалить элемент"));
	m_addFileBtn.SetTooltipText(APL_T("Добавить файл"));
	m_loadFileBtn.SetTooltipText(APL_T("Скопировать на диск"));
	m_viewFileBtn.SetTooltipText(APL_T("Просмотреть файл"));
	m_fBoldBtn.SetTooltipText(APL_T("Полужирный"));
	m_fItalicBtn.SetTooltipText(APL_T("Курсив"));
	m_fUnderLineBtn.SetTooltipText(APL_T("Подчеркнутый"));
	m_fStrikeBtn.SetTooltipText(APL_T("Зачеркнутый"));
	m_fColorBtn.SetTooltipText(APL_T("Цвет"));
	m_fLeftBtn.SetTooltipText(APL_T("Выровнять по левому краю"));
	m_fCentefBtn.SetTooltipText(APL_T("Расположить по центру"));
	m_fRightBtn.SetTooltipText(APL_T("Выровнять по правому краю"));
	m_fJustifyBtn.SetTooltipText( APL_T("Выровнять по ширине"));
	m_tCut.SetTooltipText(APL_T("Вырезать"));
	m_tCopy.SetTooltipText(APL_T("Копировать"));
	m_tPaste.SetTooltipText(APL_T("Вставить"));
	m_fBulletedBtn.SetTooltipText(APL_T("Маркированный список"));
	m_fOrderListBtn.SetTooltipText(APL_T("Нумерованный список"));
   
	//m_mesName.LoadMappedBitmap(IDB_MESSAGE_NAME, 0, &cm1, 1);
	aplLoadMappedBitmap(m_mesName,IDB_MESSAGE_NAME,RGB(0,0,0),GetSysColor(COLOR_BTNFACE),50);
	HBITMAP hBmpOld=m_btmCtrl.SetBitmap(HBITMAP(m_mesName));
	::DeleteObject(hBmpOld);

	//m_mesNameCopy.LoadMappedBitmap(IDB_MESSAGE_NAME_COPY, 0, &cm1, 1);
	aplLoadMappedBitmap(m_mesNameCopy,IDB_MESSAGE_NAME_COPY,RGB(0,0,0),GetSysColor(COLOR_BTNFACE),50);

	aplLoadMappedBitmap(m_mesIcon,IDB_MESSAGE_ICO,RGB(0,0,0),GetSysColor(COLOR_BTNFACE),0);
	m_msg_ico_ctrl.SetBitmap(HBITMAP(m_mesIcon));

	// инициализация комбо-бокса приоритета
	m_priorityCB.ResetContent();
	int nStrCount = 3;
	CString strs[] = { APL_T("Высокая")
		, APL_T("Обычная")
		, APL_T("Низкая") };

	for(int i=0; i<nStrCount; ++i)
		m_priorityCB.InsertString(i, strs[i]);
}

// CMessageDlg message handlers
BOOL CMessageDlg::OnInitDialog()
{
	CResizableDialog::OnInitDialog();	
	InitControls();

	m_itemsList.m_mes_dlg=this;
	
	aplExtent ext0;
	int i;
	CString buf, buf1, sMailTemplate;
	CaplInstance *inst= NULL, *inst1= NULL, *po= NULL, *curPerson= NULL;
	CaplAggr aggr0;
	int iConLenght= m_sContent.GetLength();

	ShowItemsInList(m_items_in_list);
	
	CStringArray fonts;
	m_content.GetSystemFonts(fonts);
	for(i=0; i<fonts.GetSize(); i++)
	{
		m_fontCB.AddString(fonts[i]);
	}
	m_content.SetTextMode(TM_RICHTEXT|TM_MULTILEVELUNDO|TM_SINGLECODEPAGE);


	if(m_recipient || m_recipients.GetSize()>0) FillRecepients();
	if(m_sender) m_api->m_appr_mgr.GetPersonName(m_sender, m_sSender);

	curPerson= m_api->m_appr_mgr.GetCurrentPerson();

	//Просмотр сообщения
	if(0==m_message)
	{
		m_api->m_data.GetAttr(curPerson,m_api->m_appr_mgr.a_pers_mail_template,sMailTemplate);

		#ifdef _UNICODE

		m_bHtmlMode=true;

		#else
		int iAlwaysUseHtml;
		m_api->m_options_mgr.GetOptionValueBN(APL_NO_T("Сообщения\\Всегда создавать в формате HTML"), iAlwaysUseHtml, 0);
		if(0!=iAlwaysUseHtml) m_bHtmlMode=true;
		else
		{
			if(m_sContent==_T(""))
			{
				CString sOptions;
				m_api->m_options_mgr.LoadPersonalOptionString(sOptions);
				if(0!=m_api->m_options_mgr.GetIntPersonalOptionValueBN(sOptions, APL_NO_T("Сообщения\\Создавть в HTML"),0)) 
				{
					m_bHtmlMode=true;
				}
			}
		}
		#endif
	}
	else
	{
		apidata.GetAttr(m_message, m_api->m_message_mgr.a_message_status, m_sMesStatus);
		if(m_sMesStatus!=_T("draft"))
		{
			if(AfxGetMainWnd()!=this) // Уже открыто в отдельном окне
				m_OpenNoModalBtn.ShowWindow(SW_SHOW);
		}

		apidata.GetAttr(m_message, m_api->m_message_mgr.a_message_rec_offisial, m_recipient);
		if(!m_recipient)
			apidata.GetAttr(m_message, m_api->m_message_mgr.a_message_recipient, m_recipient);

		apidata.GetAttr(m_message, m_api->m_message_mgr.a_message_sender, m_sender);

		if(m_sender)
			m_api->m_appr_mgr.GetPersonName(m_sender, m_sSender);
		else
		{
			m_api->m_data.GetAttr(m_message, m_api->m_message_mgr.a_message_send_nick, m_sSender);
			if(m_sSender.IsEmpty()) m_sSender=  APL_T("Система");
		}

		apidata.GetAttr(m_message, m_api->m_message_mgr.a_message_date_send, buf);		
		if(buf!=_T(""))
		{
			COleDateTime odt;
			aplString2Date(buf, odt);
			buf= odt.Format();
			if(m_sMesStatus!=_T("draft")) m_sSender+=APL_T("     Отправлено  ");
			else m_sSender+=APL_T("     Сохранено в черновиках ");
			
			m_sSender+=buf;
		}

		apidata.GetAttr(m_message, m_api->m_message_mgr.a_message_copy, m_main_message);	

		if(0!=m_main_message)
		{
			bool bIsCopy=false;
			apidata.GetAttr(m_message, m_api->m_message_mgr.a_message_recipient_in_copy, bIsCopy);	
			if(bIsCopy)//m_name_copy_ctrl.ShowWindow(SW_SHOW);
			{
				HBITMAP hBmpOld=m_btmCtrl.SetBitmap(HBITMAP(m_mesNameCopy));
				::DeleteObject(hBmpOld);
			}
		}

		if(m_recipient && 0==m_main_message)
		{
			m_api->m_appr_mgr.GetPersonName(m_recipient, m_sRecipientsNick);

			apidata.GetAttr(m_message, m_api->m_message_mgr.a_message_date_received, buf1);
			if(buf1!=_T(""))
			{
				COleDateTime odt;
				aplString2Date(buf1, odt);
				buf1= odt.Format();
				m_sRecipientsNick+=  APL_T("     Получено   ");
				m_sRecipientsNick+=buf1;
			}
			else
			{
				if(m_sMesStatus!=_T("draft")) m_sRecipientsNick+=  APL_T("     (Не получено)");
			}

			m_wndRecipient.SetWindowText(m_sRecipientsNick);
		}
		else
		{
			m_recipient=0;
			// список имен получателей берем напрямую из массива копий
			aplExtent ext_copies;
			if(0==m_main_message)	apidata.GetAttr(m_message, m_api->m_message_mgr.a_message_copies, m_messageCopies);
			else
			{
				m_api->m_message_mgr.LoadMessageInfo(m_main_message);
				apidata.GetAttr(m_main_message, m_api->m_message_mgr.a_message_copies, m_messageCopies); 
			}
				
			m_api->m_message_mgr.LoadMessageInfo(m_messageCopies);
			
			for(int j= 0; j<m_messageCopies.GetSize(); j++)
			{
				apidata.GetAttr(m_messageCopies[j], m_api->m_message_mgr.a_message_rec_offisial, inst1);
				if(!inst1)//отправляли именно этому person'у
					apidata.GetAttr(m_messageCopies[j], m_api->m_message_mgr.a_message_recipient, inst1);
				if(inst1)
				{
					bool b_rec_copy;
					apidata.GetAttr(m_messageCopies[j], m_api->m_message_mgr.a_message_recipient_in_copy, b_rec_copy);
					if(b_rec_copy)  m_recipients_copy.Add(inst1);
					else  m_recipients.Add(inst1);
				}
			}
			// Зачитываем информацию о сотрудниках, если надо
			{
				if(m_recipients.GetSize()>0)
				{
					bool bNeedLoad=false;
					for(int j= 0; j<m_recipients.GetSize(); j++)
					{
						if(0==m_recipients[j]->attrs) {bNeedLoad=true; break;}
					}
					if(bNeedLoad) m_api->LoadExtentInfo(m_recipients);
				}

				if(m_recipients_copy.GetSize()>0)
				{
					bool bNeedLoad=false;
					for(int j= 0; j<m_recipients_copy.GetSize(); j++)
					{
						if(0==m_recipients_copy[j]->attrs) {bNeedLoad=true; break;}
					}
					if(bNeedLoad) m_api->LoadExtentInfo(m_recipients_copy);
				}
			}

			FillRecepients();
			if(m_messageCopies.GetSize()>0) m_info_btn.ShowWindow(SW_SHOW);
		}
		long size;
		apidata.GetAttr(m_message, m_api->m_message_mgr.a_message_content_lenght, iConLenght);

		CString sBlobId;
		apidata.GetAttr(m_message, m_api->m_message_mgr.a_message_content_source, sBlobId);

		if(sBlobId==_T(""))
		{
			apidata.GetAttr(m_message, m_api->m_message_mgr.a_message_content, m_sContent);

			#ifdef _UNICODE
			// Тут будет строка UCS2, котороую надо будет переконвертировать в 1251, но через байт
			ConvertUCS2ToMsgSting(m_sContent,false);
			#endif
		}
		else // Сообщение в BLOB-е
		{
			// теперь у нас данные могут оказаться в юникоде
			//LPTSTR szBuf= m_sContent.GetBuffer(iConLenght);
			//size=iConLenght;// приведение типов - в будущем GetAttr-ы надо тоже на long переделать
			//apidata.NET_LoadBlob2Memory(m_message, m_api->m_message_mgr.a_message_content_source,
			//	(BYTE*)szBuf, size);
			//m_sContent.ReleaseBuffer();

			unsigned char *tmpBuf=new  unsigned char[iConLenght+2];  
			size=iConLenght;// приведение типов - в будущем GetAttr-ы надо тоже на long переделать
			apidata.NET_LoadBlob2Memory(m_message, m_api->m_message_mgr.a_message_content_source, (BYTE*)tmpBuf, size);
			if(size>2) // Меньше 2х не бывае - считаем пустое
			{
				tmpBuf[size]='\0'; tmpBuf[size+1]='\0';

				#ifdef _UNICODE
					//так не работает !!! 
					//CStringW ucsStr((LPCSTR)tmpBuf);
					//m_sContent=ucsStr;
					// надо так	
					ConvertMultiByteToMsgSting(tmpBuf,size, m_sContent);
				#else
					 m_sContent=tmpBuf;
				#endif

				delete tmpBuf;

			}
		}

		apidata.GetAttr(m_message, m_api->m_message_mgr.a_message_content_format, m_sContentFormat);
		if(m_sContentFormat==_T("") && 0!=m_main_message) 
			apidata.GetAttr(m_main_message, m_api->m_message_mgr.a_message_content_format, m_sContentFormat);

		m_sContentFormat.MakeLower();

		apidata.GetAttr(m_message, m_api->m_message_mgr.a_message_subject, m_sSubject);
		apidata.GetAttr(m_message, m_api->m_message_mgr.a_message_priority, m_iPriority);
		apidata.GetAttr(m_message, m_api->m_message_mgr.a_message_status, m_sMesStatus);
		apidata.GetAttr(m_message, m_api->m_message_mgr.a_message_items, m_items);

		ShowItemsInList(m_items);

		if(m_bNoAction) m_bReadOnly=true;
		if(curPerson!=m_recipient)
		{
			CaplInstance* rec= NULL;
			apidata.GetAttr(m_message, m_api->m_message_mgr.a_message_recipient, rec);
			if(rec!=curPerson && curPerson!=m_sender)
				m_bReadOnly= true;//смотрит не понятно кто...
		}
		if(m_sMesStatus!=_T("draft") || m_bReadOnly )
		{
			m_itemsList.DragAcceptFiles(FALSE);
			m_subject.SetReadOnly();
			m_content.SetReadOnly();

			//кнопку выбора на текст
			m_toTextStatic.ModifyStyle(0, WS_VISIBLE, 0);
			m_copyTextStatic.ModifyStyle(0, WS_VISIBLE, 0);
			m_recSelBtn.ModifyStyle(WS_VISIBLE, 0, 0);
			m_recCopySelBtn.ModifyStyle(WS_VISIBLE, 0, 0);
			
			m_priorityCB.EnableWindow(FALSE);

			if(curPerson==m_sender)
			{
				m_replyBtn.EnableWindow(FALSE);
				m_replyAllBtn.EnableWindow(FALSE);
			}
			else
			{
				m_replyBtn.EnableWindow();
				m_replyAllBtn.EnableWindow();
			}
			
			if(m_sender==NULL) { m_replyBtn.EnableWindow(FALSE); m_replyAllBtn.EnableWindow(FALSE); }
			
			if(m_bReadOnly)
			{
				m_forwardBtn.EnableWindow(FALSE);
				m_deleteBtn.EnableWindow(FALSE);
				m_replyBtn.EnableWindow(FALSE);
				m_replyAllBtn.EnableWindow(FALSE);
			}
			else
			{
				m_forwardBtn.EnableWindow();
				m_deleteBtn.EnableWindow();					
			}
			m_bReadOnly=true;


			m_SendBtn.EnableWindow(FALSE);
			m_draftBtn.EnableWindow(FALSE);
			m_cancelBtn.EnableWindow(TRUE);

			m_addItemBtn.EnableWindow(FALSE);
			m_addFileBtn.EnableWindow(FALSE);

			DisableTextEditCtrl();
		}
	}
	
	if(m_sContentFormat==_T("html")) m_bHtmlMode=true;
	else if(m_sContent!=_T(""))
	{
		buf=m_sContent.Left(6); buf.MakeUpper();
		if(buf==_T("<HTML>")) m_bHtmlMode=true;
		else 
		{
			buf=m_sContent.Left(10); buf.MakeUpper();
			if(buf==_T("<!DOCTYPE ")) m_bHtmlMode=true;
		}
	}

	if(m_bHtmlMode) // Это HTML
	{
		m_sContentFormat=_T("html");
		m_wordwrap_btn.EnableWindow(FALSE);
		m_wordwrap_btn.ShowWindow(SW_HIDE);

		//m_bNoAction=true;
		m_content.ShowWindow(SW_HIDE);
		m_content.SetReadOnly(TRUE);

		m_html_ctrl.CreateFromStatic(IDC_MESSAGE_RICHEDIT,this);
		m_html_ctrl.ModifyStyle(0,WS_BORDER);
		AddAnchor(m_html_ctrl.m_hWnd, TOP_LEFT, TWO_THIRDS_RIGHT);


		CString sCodePage;

		if(m_sContent==_T(""))
		{
			if(sMailTemplate!=_T(""))
			{
				buf=sMailTemplate.Left(6); buf.MakeLower();
				if(buf==_T("<html>"))
				{ 
					m_sContent=sMailTemplate;
					sMailTemplate=_T("");
				}
			}

#ifndef _UNICODE

			if(m_sContent==_T("")) 	m_sContent=_T("<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=windows-1251\">")
					_T("<style> p{line-height: 1.2; margin-top: 0.5em; margin-bottom: 0.5em;} </style> </head><body></body></html>");
#else
			if(m_sContent==_T("")) 	m_sContent=_T("<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">")
					_T("<style> p{line-height: 1.2; margin-top: 0.5em; margin-bottom: 0.5em;} </style> </head><body></body></html>");
#endif
		}
		else
		{
			InsertHtmlTag(m_sContent);
			InsertBodyTag(m_sContent);
			GetHtmlCodePage(m_sContent,sCodePage);
		}

		// Информация при пересылке
		CString sText4Insert;
		for(i=0; i<m_sTextArray4Insert.GetSize()-1;i++)
		{
			LPCTSTR pStr=m_sTextArray4Insert[i];
			bool bBold=false;
			if(pStr[0]==_T('|')) {pStr+=1; bBold=true;}

			if(bBold)sText4Insert+=_T("<b>");
			sText4Insert+=pStr;
			if(bBold)sText4Insert+=_T("</b>");
		}

		if(sMailTemplate!=_T(""))
		{
			GetHtmlContent(sMailTemplate);
			if(sMailTemplate!=_T(""))
			{
				sMailTemplate.Replace(_T("\n"),_T("<br>"));
				sMailTemplate.Replace(_T("\r"),_T(""));
				sMailTemplate+=_T("<br><br>");
				sText4Insert.Insert(0,sMailTemplate);
			}
		}

		if(sText4Insert!=_T(""))
		{
			sText4Insert.Replace(_T("\n"),_T("<br>"));
			sText4Insert+=_T("<br><br>");

			bool bIsContentUtf8=false;
			if(m_sContent.GetLength()>6)
			{
				const unsigned char *pTmp=(const unsigned char*)(LPCTSTR(m_sContent));

				#ifdef _UNICODE
				if(pTmp[0]==0xef  && pTmp[2]==0xbb  && pTmp[4]==0xbf) bIsContentUtf8=true;
				#else
				if(pTmp[0]==0xef  && pTmp[1]==0xbb  && pTmp[2]==0xbf) bIsContentUtf8=true;
				#endif

			}

			#ifdef _UNICODE
			ConvertUCS2ToMsgSting(sText4Insert,bIsContentUtf8);
			#else
				if(bIsContentUtf8)
				{
					// Надо ansi строку преобразовать в UTF-8

					ConvertAnsi2ToUtf8Sting(sText4Insert);
				}
			#endif

			i=m_sContent.Find(_T("<body>"));
			if(i<0) i=m_sContent.Find(_T("<BODY>"));
			if(i>0) m_sContent.Insert(i+6,sText4Insert);
		}

		 CString tmp_fname;
		 if(CaplMessageManager::SaveHtmlContentToTempFile(m_sContent,tmp_fname))
		 {
			 buf=_T("file:\\")+tmp_fname; 
			 m_html_ctrl.Navigate(buf);
			 m_sFile4Delete=tmp_fname;
		 }

		m_html_ctrl.SetAlwaysUseShellExecute(true);
		if(!m_bReadOnly) m_html_ctrl.SetEditMode(true);
	}
	else //Это RTF
	{

		m_content.SetAutoURLDetect(TRUE);
		int n= m_sContent.GetLength();
		m_content.LimitText(iConLenght+1);	

		if(-1!=m_sContent.Find(_T("\\rtf1\\")))
			m_content.SetRTF(m_sContent);
		else
			m_content.SetWindowText(m_sContent);

	
		m_content.SetEventMask(m_content.GetEventMask()|
							ENM_CHANGE | ENM_UPDATE | ENM_SCROLL |
							ENM_KEYEVENTS | ENM_REQUESTRESIZE|
							ENM_DROPFILES | ENM_PROTECTED | ENM_CORRECTTEXT |
							ENM_SCROLLEVENTS | ENM_DRAGDROPDONE|
							ENM_MOUSEEVENTS | ENM_SELCHANGE);


		//здесь вставляем данные исх. сообщения
		if(m_sTextArray4Insert.GetSize()>0)
		{
			int i=0;
			//Вставка цитирования
			if(m_bInsetQuote)
			{
				while(true)
				{
					int index=m_content.LineIndex(i);
					if(index<0) break;
					m_content.SetSel(index,index);
					m_content.ReplaceSel(_T("> "));
					i++;
				}
			}

			// Очищаем параметры цвета
			m_content.SetSel(0,0);
			m_content.SetSelectionBold(false);
			m_content.SetSelectionItalic(false);
			m_content.SetSelectionUnderlined(false);
			m_content.SetSelectionStrikeouted(false);
			m_content.SetSelectionTextColor(RGB(0,0,0));

			for(i=m_sTextArray4Insert.GetSize()-1;i>=0;i--)
			{
				LPCTSTR pStr=m_sTextArray4Insert[i];
				m_content.SetSel(0,0);
				if(pStr[0]==_T('|')) {pStr+=1; m_content.SetSelectionBold(true);}
				m_content.ReplaceSel(pStr);
				m_content.SetSel(0,0);
				m_content.SetSelectionBold(false);
			}
		}

		if(sMailTemplate!=_T("")) // Шаблон письма
		{
			GetHtmlContent(sMailTemplate);
			GetHtmlPlainText(sMailTemplate);
			if(sMailTemplate!=_T(""))
			{
				sMailTemplate.Replace(_T("\r"),_T(""));
				m_content.SetSel(0,0);
				m_content.ReplaceSel(sMailTemplate);
			}
		}
	}

	if(!m_bHtmlMode)
	{
		if(m_sContent==_T(""))
		{
			m_content.SetFontName(_T("Arial"));
			m_content.SetFontSize(10);
		}
		m_iFont= m_fontCB.SelectString(-1, _T("Arial"));
		m_iFontSize= m_fontSizeCB.SelectString(-1, _T("10"));
	}

	if(0==m_message && m_sArrayFiles4NewMessage.GetSize()>0) AddFiles(m_sArrayFiles4NewMessage);

	UpdateData(FALSE);

	if(!m_bHtmlMode)
	{
		m_content.SetModify(FALSE);
		m_content.SetSel(0,0);
	}
	else
	{
		// Для HTML нужны другие размеры шрифтов
		m_fontSizeCB.ResetContent();
		for(i=1;i<8;i++)
		{
			buf.Format(_T("%i"),i);
			m_fontSizeCB.AddString(buf);
		}
	}

	if(m_bNoAction)
	{
		m_SendBtn.EnableWindow(FALSE);
		m_draftBtn.EnableWindow(FALSE);
		m_replyBtn.EnableWindow(FALSE);
		m_replyAllBtn.EnableWindow(FALSE);
		m_forwardBtn.EnableWindow(FALSE);
		m_deleteBtn.EnableWindow(FALSE);
		m_addItemBtn.EnableWindow(FALSE);
		m_deleteItemBtn.EnableWindow(FALSE);
		m_addFileBtn.EnableWindow(FALSE);
		m_OpenNoModalBtn.ShowWindow(SW_HIDE);
	}

	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

bool CMessageDlg::SaveMessage(bool bNeedFullData)
{
	if(!UpdateData()) return false;

	int i;

	if(0==m_recipient && 0==m_recipients.GetSize())
	{
		if(bNeedFullData)
		{
			MessageBox( APL_T("Получатель не указан!"),  APL_T("Ошибка"), MB_OK | MB_ICONERROR);
			return false;
		}
	}

	if(m_recipients.GetSize()>10){if(IDYES!=AfxMessageBox(APL_T("Указано более 10 получателей\n\nОтправить сообщение ?"),MB_YESNO|MB_ICONQUESTION)) return false;}
	if(m_recipients.GetSize()>100){if(IDYES!=AfxMessageBox(APL_T("Указано более 100 получателей\n\nОтправить сообщение ?"),MB_YESNO|MB_ICONEXCLAMATION)) return false;}
	if(m_recipients.GetSize()>1000){if(IDYES!=AfxMessageBox(APL_T("Указано более 1000 получателей\n\nДействительно отправить сообщение ?"),MB_YESNO|MB_ICONSTOP)) return false;}

	if(m_sSubject.IsEmpty() && bNeedFullData)
	{
		if(IDNO==MessageBox( APL_T("Отсутствует тема сообщения. Отправить сообщение?"),  APL_T("Ошибка"), MB_YESNO| MB_ICONEXCLAMATION)) return false;
	}

	CString sMesStatus= _T("draft");	

	m_items.Clear();
	for(i= 0; i<m_items_in_list.GetSize(); i++) m_items.Add(m_items_in_list[i]);
	for(i= 0; i<m_files_in_list.GetSize(); i++)
	{
		CaplInstance *inst= NULL;
		inst=m_api->m_doc_mgr.CreateFile(m_files_in_list[i], true);
		if(!inst)
		{
			CString buf; buf.Format( APL_T("Ошибка чтения файла \n\n\"%s\" "), m_files_in_list[i]);
			AfxMessageBox(buf,MB_OK|MB_ICONSTOP);
		}
		else
			m_items.Add(inst);
	}

	if(m_bHtmlMode)
	{
		// В Unicode m_html_ctrl.GetSource  возвращает юникодную строку,
		// в которой UTF8 + BOM (все нечетные символы - нули)
		m_html_ctrl.GetSource(m_sContent);

		i=m_sContent.ReverseFind(_T('>'));
		if(i>0) {CString buf=m_sContent.Left(i+1); m_sContent=buf;}  // Отрезаем непонятный мусор
	}
	else
	{
		m_sContent= m_content.GetRTF();
	}


	CString sDate;
	COleDateTime odt;
	m_api->m_data.NET_GetServerDateTime(odt);
	aplDate2String(odt, sDate);	

	CaplInstance* inst= NULL;

	if(0==m_message) m_message= m_api->m_data.CreateInstance(m_api->m_message_mgr.e_message);
	apidata.PutAttr(m_message, m_api->m_message_mgr.a_message_sender, m_sender);

	if(m_recipients_copy.GetSize()>0  && 0!=m_recipient)
	{
		m_recipients.Add(m_recipient);
		m_recipient=0;;
	}

	//оригинал из рассылки
	bool bRecipDel =false;
	CaplInstance* null= NULL;
	if(m_recipient && apidata.IsKindOf(m_recipient, m_api->m_appr_mgr.e_person))
	{
		apidata.PutAttr(m_message, m_api->m_message_mgr.a_message_recipient, m_recipient);
		apidata.PutAttr(m_message, m_api->m_message_mgr.a_message_rec_offisial, null);					
	}
	else if(m_recipient && apidata.IsKindOf(m_recipient, m_api->m_appr_mgr.e_official))
	{
		apidata.PutAttr(m_message, m_api->m_message_mgr.a_message_recipient, null);
		apidata.PutAttr(m_message, m_api->m_message_mgr.a_message_rec_offisial, m_recipient);					
	}
	else if(!m_recipient)
	{
		apidata.PutAttr(m_message, m_api->m_message_mgr.a_message_recipient, null);
		apidata.PutAttr(m_message, m_api->m_message_mgr.a_message_rec_offisial, null);

		if(m_sRecipientsCopyNick!=_T("")){m_sRecipientsNick+=APL_T(" Копия: "); m_sRecipientsNick+=m_sRecipientsCopyNick;}
		m_api->m_data.PutAttr(m_message, m_api->m_message_mgr.a_message_rec_nick, m_sRecipientsNick);
		bRecipDel= true;//это рассылка. Получатель не указан.			
	}

	long blobNum= -1;
	int contentSize= m_sContent.GetLength()+1;
	CString sBlobId= _T("");

	apidata.PutAttr(m_message, m_api->m_message_mgr.a_message_content_lenght, contentSize);
	if(contentSize<1000  && m_bHtmlMode==false) // html всегда сохраняем в blob
	{
		apidata.PutAttr(m_message, m_api->m_message_mgr.a_message_content, m_sContent);
		apidata.GetAttr(m_message, m_api->m_message_mgr.a_message_content_source, sBlobId);
		if(!sBlobId.IsEmpty())
		{
			apidata.NET_DeleteBlob(m_message, m_api->m_message_mgr.a_message_content_source);
			sBlobId= _T("");
			apidata.PutAttr(m_message, m_api->m_message_mgr.a_message_content_source, sBlobId);
		}
	}
	else
	{
		#ifdef _UNICODE // В UNICODE  не поддерживается RTF, поэтому не проверяем

			CStringA sAnsiStr(m_sContent); // В m_sContent тут UTF-8 + BOM, но в памяти как UCS2 (все нечетные - нули)
			LPCSTR szBuf= (LPCSTR)sAnsiStr;
		#else
			LPCSTR szBuf= (LPCSTR)m_sContent;
		#endif
		
		// в blob всегда сохраняем multibyte, если контрол вернул с BOM, то с BOM		
		apidata.NET_SaveFileFromMemory(m_message, m_api->m_message_mgr.a_message_content_source, 
			(BYTE*)szBuf, contentSize, blobNum,  APL_T("Сохранение тела сообщения"));

		m_sContent= _T("");
		//			sBlobId.Format(_T("%i"), blobNum);
		apidata.GetAttr(m_message, m_api->m_message_mgr.a_message_content_source, sBlobId);
		apidata.PutAttr(m_message, m_api->m_message_mgr.a_message_content, m_sContent);

		if(contentSize<=1000)
		{
			contentSize=1001; // Это обманка чтобы старые версии читали содержимое из блоба
			apidata.PutAttr(m_message, m_api->m_message_mgr.a_message_content_lenght, contentSize);
		}
	}

	apidata.PutAttr(m_message, m_api->m_message_mgr.a_message_content_format, m_sContentFormat);

	apidata.PutAttr(m_message, m_api->m_message_mgr.a_message_subject, m_sSubject);
	apidata.PutAttr(m_message, m_api->m_message_mgr.a_message_priority, m_iPriority);
	apidata.PutAttr(m_message, m_api->m_message_mgr.a_message_status, sMesStatus);
	apidata.PutAttr(m_message, m_api->m_message_mgr.a_message_recipient_kill, bRecipDel);
	apidata.PutAttr(m_message, m_api->m_message_mgr.a_message_items, m_items);
	apidata.PutAttr(m_message, m_api->m_message_mgr.a_message_date_send, sDate);
	apidata.PutAttr(m_message, m_api->m_message_mgr.a_message_copy, inst);

	// Удаляем все копии чтобы не парится
	for(i= 0; m_messageCopies.GetSize()>1 && i<m_messageCopies.GetSize(); i++)
	{
		apidata.DeleteInstance(m_messageCopies[i]);
	}
	m_messageCopies.Clear();

	int index4copy=m_recipients.GetSize();
	m_recipients.Append(m_recipients_copy);

	for(i= 0;  i<m_recipients.GetSize(); i++)
	{
		CaplInstance* mes= apidata.CreateInstance(m_api->m_message_mgr.e_message);
		apidata.PutAttr(mes, m_api->m_message_mgr.a_message_copy, m_message);

		m_messageCopies.Add(mes);

		CaplInstance *recipient=m_recipients[i];

		if(apidata.IsKindOf(recipient, m_api->m_appr_mgr.e_person))
			apidata.PutAttr(mes, m_api->m_message_mgr.a_message_recipient, recipient);
		else if(apidata.IsKindOf(recipient, m_api->m_appr_mgr.e_official))
			apidata.PutAttr(mes, m_api->m_message_mgr.a_message_rec_offisial, recipient);					

		apidata.PutAttr(mes, m_api->m_message_mgr.a_message_sender, m_sender);
		apidata.PutAttr(mes, m_api->m_message_mgr.a_message_subject, m_sSubject);
		apidata.PutAttr(mes, m_api->m_message_mgr.a_message_content_lenght, contentSize);
		apidata.PutAttr(mes, m_api->m_message_mgr.a_message_content, m_sContent);
		apidata.PutAttr(mes, m_api->m_message_mgr.a_message_content_source, sBlobId);
		apidata.PutAttr(mes, m_api->m_message_mgr.a_message_priority, m_iPriority);
		apidata.PutAttr(mes, m_api->m_message_mgr.a_message_status, sMesStatus);
		apidata.PutAttr(mes, m_api->m_message_mgr.a_message_recipient_kill, false);
		apidata.PutAttr(mes, m_api->m_message_mgr.a_message_items, m_items);
		apidata.PutAttr(mes, m_api->m_message_mgr.a_message_date_send, sDate);

		if(i>=index4copy) apidata.PutAttr(mes, m_api->m_message_mgr.a_message_recipient_in_copy, true);
	}

	apidata.PutAttr(m_message, m_api->m_message_mgr.a_message_copies, m_messageCopies);

	apidata.NET_SaveChanges();
	
	return true;
}

void CMessageDlg::OnBnClickedSendButton()
{
	if(!SaveMessage(true)) return;
	m_iAction= MESSAGE_DLG_SEND;
	EndDialog(IDOK);
}


void CMessageDlg::OnCancel() 
{
	CString subjext,rtf,buf;
	m_subject.GetWindowText(subjext);

	if(!m_bChanged)
	{
		if(m_content.GetModify()) m_bChanged =true;
	}


	if(0==m_message) //сообщение пересылается: надо удалить прикрепленные файлы.
	{
		if(subjext!=_T("") ||  m_bChanged)
		{
			int rez=AfxMessageBox(APL_T("Сохранить сообщение в черновиках ?"),MB_YESNOCANCEL|MB_ICONWARNING);
			if(IDCANCEL==rez) return;
			if(IDYES==rez) return OnSaveButton();
		}
	}
	else
	{
		if(m_sMesStatus==_T("draft"))
		{
			if(!m_bChanged)
			{
				apidata.GetAttr(m_message, m_api->m_message_mgr.a_message_subject,buf );
				if(buf!=subjext) m_bChanged =true;
			}
			if(m_bChanged)
			{
				int rez=AfxMessageBox(APL_T("Сохранить изменения ?"),MB_YESNOCANCEL|MB_ICONWARNING);
				if(IDCANCEL==rez) return;
				if(IDYES==rez) return OnSaveButton();
			}
		}
	}
	if(MESSAGE_DLG_OPEN_NOMODAL!=m_iAction) m_iAction= MESSAGE_DLG_CANCEL;
	EndDialog(IDCANCEL);
//	CDialog::OnCancel();
}

void CMessageDlg::OnDeleteButton() 
{
	m_iAction= MESSAGE_DLG_DELETE;
	EndDialog(IDOK);
}

void CMessageDlg::OnForwardButton() 
{
	m_iAction= MESSAGE_DLG_FORWARD;
	EndDialog(IDOK);
}

void CMessageDlg::OnReplyButton() 
{
	m_iAction= MESSAGE_DLG_REPLY;
	EndDialog(IDOK);
}

void CMessageDlg::OnBnClickedReplyAllButton()
{
	m_iAction= MESSAGE_DLG_REPLY_ALL;
	EndDialog(IDOK);
}


void CMessageDlg::OnSaveButton() 
{
	if(!SaveMessage(false)) return;
	m_iAction= MESSAGE_DLG_SAVE;
	EndDialog(IDOK);
}

void CMessageDlg::OnAddItem() 
{
	aplExtent res;

	m_api->m_message_mgr.SelectInstanceEx(
								APL_MODE_SELECT_PRD |
								APL_MODE_SELECT_PDF |
								APL_MODE_SELECT_DOC |
								APL_MODE_SELECT_DOC_REVISION |
								APL_MODE_SELECT_CATEG_REVISION |
								APL_MODE_SELECT_BP_REVISION |
								APL_MODE_SELECT_BPINST |
								APL_MODE_SELECT_LOT |
								APL_MODE_SELECT_PRDINST  |
								APL_MODE_SELECT_CATEGORY |
								APL_MODE_SELECT_FOLDER   |
								APL_MODE_SELECT_BP	|
								APL_MODE_SELECT_CLASSIF_SYSTEM	|
								APL_MODE_SELECT_CLASSIF_ELEMENT |
								APL_MODE_SELECT_ORDER	|
								APL_MODE_SELECT_CHANGE	|
								APL_MODE_SELECT_ORG |
								APL_MODE_SELECT_PERSON |
								APL_MODE_SELECT_MULTY|
								APL_MODE_SELECT_BP_RES	|
								APL_MODE_SELECT_PROJECT,
								res);
	CaplInstance *inst = NULL;
	for(int i=0; i<res.GetSize(); i++)
	{
		inst = res[i];
		if(inst && -1==m_items_in_list.Find(inst))
		{
			m_bChanged=true;
			CString name,buf;
			UINT ico;

			m_api->m_message_mgr.GetItemName(inst,name);
			ico = m_api->GetInstIco(inst);
			if(!name.IsEmpty())
			{
				m_items_in_list.Add(inst);
				m_items.Add(inst);
				int n= m_itemsList.GetItemCount();
				int m= m_itemsList.InsertItem(n, name, ico);
				m_itemsList.SetItemData(m, (DWORD)inst);
			}
		}
	}
}

void CMessageDlg::OnDeleteItem() 
{
	m_bChanged=true;
	if(!m_curSelItem)
	{
		CString buf= m_itemsList.GetItemText(m_index, 0);
		m_itemsList.DeleteItem(m_index);
		for(int i=0; i<m_files_in_list.GetSize(); i++)
		{
			if(buf==m_files_in_list[i])
			{
				m_files_in_list.RemoveAt(i);
				break;
			}
		}
	}
	else
	{
		if(apidata.IsKindOf(m_curSelItem, m_api->m_doc_mgr.e_apl_stored_document) ||
			apidata.IsKindOf(m_curSelItem, m_api->m_doc_mgr.e_apl_assigned_document))
		{
			bool bDel=true;
			//ЯАИ т.к. теперь при пересылке отправляется не копия файла (apl_stored_document)
			// а тот-же самый, то перед удалением проверяем есть ли он в других сообщениях
			CString sSql;
			aplExtent aeItems;
			sSql.Format(_T("SELECT Ext_1 FROM Ext_1 { apl_message.items LIKE #%d } END_SELECT"), m_curSelItem->GetId());
			m_api->m_data.NET_QueryEditParse(sSql);
			m_api->m_data.NET_QueryExecute(aeItems);

			int i,j;
			for(i=0;i<aeItems.GetSize();i++)
			{
				CaplInstance *msg=aeItems[i];
				bool bFound=false;
				for(j=0;j<m_messageCopies.GetSize();j++)
				{
					if(msg==m_messageCopies[j]){bFound=true; break;}
				}
				if(!bFound) bDel=false;
			}
			if(bDel)
			{
				if(apidata.IsKindOf(m_curSelItem, m_api->m_doc_mgr.e_apl_stored_document)) 
					apidata.NET_DeleteBlob(m_curSelItem, m_api->m_doc_mgr.a_apl_stored_document_source);
				apidata.DeleteInstance(m_curSelItem);
				apidata.NET_SaveChanges();
			}
		}
		m_items_in_list.Remove(m_items_in_list.Find(m_curSelItem));
		m_itemsList.DeleteItem(m_index);
	}
}

void CMessageDlg::OnItemchangedMessageItems(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
	*pResult = 0;

	m_deleteItemBtn.EnableWindow(FALSE);
	m_loadFileBtn.EnableWindow(FALSE);
	m_viewFileBtn.EnableWindow(FALSE);
	m_curSelItem= NULL;
	m_index=-1;

	if(m_itemsList.GetSelectedCount()<1)return;

	m_loadFileBtn.EnableWindow(TRUE);
	m_viewFileBtn.EnableWindow(TRUE);

	if(m_itemsList.GetSelectedCount()>1) return;

	// Выделен только 1

	CString buf;
	if(m_message){apidata.GetAttr(m_message, m_api->m_message_mgr.a_message_status, buf);}
	if(m_message==0 || buf==_T("draft"))m_deleteItemBtn.EnableWindow(TRUE);

	m_index= m_itemsList.GetNextItem(-1, LVNI_ALL|LVNI_SELECTED);
	m_curSelItem= (CaplInstance*)m_itemsList.GetItemData(m_index);
	return;
}

void CMessageDlg::ShowItemsInList(CaplAggr &items)
{
	m_items_in_list.Clear();
	ShowItemsInList(m_items);
}

void CMessageDlg::ShowItemsInList(aplExtent &items)
{
	m_itemsList.DeleteAllItems();
	
	m_api->m_message_mgr.LoadExtentInfo(items);

	for(int j=0; j<items.GetSize(); j++)
	{
		CaplInstance* inst0= NULL;
		CString name, buf;
		UINT ico=0;

		if(!items[j]) continue;

		CaplInstance *item=items[j];
		m_api->GetItemName(item, name);
		ico = m_api->GetInstIco(item);

		if(!name.IsEmpty())
		{
			int n= m_itemsList.GetItemCount();
			int m= m_itemsList.InsertItem(n, name, ico);
			m_itemsList.SetItemData(m, (DWORD)items[j]);
			m_items_in_list.Add(items[j]);
		}
	}
}

void CMessageDlg::OnFontBold() 
{
	if(m_bHtmlMode)
	{
		m_html_ctrl.SetSelectionBold();
		m_html_ctrl.SetFocus();
	}
	else
	{
		m_content.SetSelectionBold();
		m_content.SetFocus();
	}
	OnSelchangeMessageRichedit(0,0);
}

void CMessageDlg::OnFontItalic() 
{
	if(m_bHtmlMode)
	{
		m_html_ctrl.SetSelectionItalic();
		m_html_ctrl.SetFocus();
	}
	else
	{
		m_content.SetSelectionItalic();
		m_content.SetFocus();
	}
	OnSelchangeMessageRichedit(0,0);
}

void CMessageDlg::OnFontUnderline() 
{
	if(m_bHtmlMode)
	{
		m_html_ctrl.SetSelectionUnderlined();
		m_html_ctrl.SetFocus();
	}
	else
	{
		m_content.SetSelectionUnderlined();
		m_content.SetFocus();
	}
	OnSelchangeMessageRichedit(0,0);
}

void CMessageDlg::OnFontColor() 
{
	if(m_bHtmlMode)
	{
		m_html_ctrl.SetSelectionColor();
		m_html_ctrl.SetFocus();
	}
	else
	{
		m_content.SelectColor();
		m_content.SetFocus();
	}

	OnSelchangeMessageRichedit(0,0);
}

void CMessageDlg::OnFontLeft() 
{
	if(m_bHtmlMode)
	{
		m_html_ctrl.SetParagraphLeft();
		m_html_ctrl.SetFocus();
	}
	else
	{
		m_content.SetParagraphLeft();
		m_content.SetFocus();
	}
	OnSelchangeMessageRichedit(0,0);
}

void CMessageDlg::OnFontCenter() 
{
	if(m_bHtmlMode)
	{
		m_html_ctrl.SetParagraphCenter();
		m_html_ctrl.SetFocus();
	}
	else
	{
		m_content.SetParagraphCenter();
		m_content.SetFocus();
	}

	OnSelchangeMessageRichedit(0,0);
}

void CMessageDlg::OnFontRight() 
{
	if(m_bHtmlMode)
	{
		m_html_ctrl.SetParagraphRight();
		m_html_ctrl.SetFocus();
	}
	else
	{
		m_content.SetParagraphRight();
		m_content.SetFocus();
	}

	OnSelchangeMessageRichedit(0,0);
}

void CMessageDlg::OnFontJustify() 
{
	if(m_bHtmlMode)
	{
		m_html_ctrl.SetParagraphWidth();
		m_html_ctrl.SetFocus();
	}
	else
	{
		m_content.SetParagraphJustify();
		m_content.SetFocus();
	}
	OnSelchangeMessageRichedit(0,0);
}

void CMessageDlg::OnTextPaste() 
{
	if(m_bHtmlMode)
	{
		m_html_ctrl.Paste();
		m_html_ctrl.SetFocus();
	}
	else if(m_content.CanPaste())
	{
		m_content.Paste();
		m_content.SetSel(0, -1);
		PARAFORMAT2 pf;
		DWORD res= m_content.GetParaFormat(pf);
	}
	OnSelchangeMessageRichedit(0,0);
}

void CMessageDlg::OnTextCut()
{
	if(m_bHtmlMode)
	{
		m_html_ctrl.Cut();
		m_html_ctrl.SetFocus();
	}
	else
	{
		m_content.Cut();
		m_content.SetFocus();
	}
	OnSelchangeMessageRichedit(0,0);
}

void CMessageDlg::OnTextCopy() 
{
	if(m_bHtmlMode)
	{
		m_html_ctrl.Copy();
		m_html_ctrl.SetFocus();
	}
	else
	{
		m_content.Copy();
		m_content.SetFocus();
	}
	OnSelchangeMessageRichedit(0,0);
}

void CMessageDlg::OnFontBulleted() 
{
	if(m_bHtmlMode)
	{
		m_html_ctrl.SetUnOrderList();
		m_html_ctrl.SetFocus();
	}
	else
	{
		m_content.SetParagraphBulleted();
		m_content.SetFocus();
	}
	OnSelchangeMessageRichedit(0,0);
}

void CMessageDlg::OnBnClickedFontOrderlist()
{
	if(m_bHtmlMode)
	{
		m_html_ctrl.SetOrderList();
		m_html_ctrl.SetFocus();
	}
	else
	{
		m_content.SetParagraphOrderList();
		m_content.SetFocus();
	}
	OnSelchangeMessageRichedit(0,0);
}





void CMessageDlg::OnCloseupFontsList() 
{
	UpdateData();
	if(m_iFont==CB_ERR) return;
	
	CString sFont;
	m_fontCB.GetLBText(m_iFont, sFont);

	if(m_bHtmlMode) {m_html_ctrl.SetFontName(sFont); m_html_ctrl.SetFocus();	}
	else { m_content.SetFontName(sFont); m_content.SetFocus();	}

	OnSelchangeMessageRichedit(0,0);	
}

void CMessageDlg::OnCloseupFontSize() 
{
	UpdateData();
	if(m_iFontSize==CB_ERR) return;

	CString sFontSize;
	m_fontSizeCB.GetLBText(m_iFontSize, sFontSize);
	int size= __atol(sFontSize);

	if(m_bHtmlMode)
	{
		m_html_ctrl.SetFontSize(size);
		m_html_ctrl.SetFocus();
	}
	else
	{
		m_content.SetFontSize(size);
		m_content.SetFocus();
	}
	OnSelchangeMessageRichedit(0,0);	
}

void CMessageDlg::OnSelchangeMessageRichedit(NMHDR* pNMHDR, LRESULT* pResult) 
{
	SELCHANGE *pSelChange = reinterpret_cast<SELCHANGE *>(pNMHDR);
	// TODO: The control will not send this notification unless you override the
	// CResizableDialog::OnInitDialog() function to send the EM_SETEVENTMASK message
	// to the control with the ENM_SELCHANGE flag ORed into the lParam mask.

	CString buf, sFontName;
	int fontsize=0;
	BOOL bCanCopy=FALSE, bCanPaste=FALSE;

	if(m_bHtmlMode) 
	{
		fontsize=m_html_ctrl.GetSelectionFontSize();
		m_html_ctrl.GetSelectionFontName(sFontName);

		if(m_html_ctrl.CanPaste()) m_tPaste.EnableWindow(TRUE);
		else m_tPaste.EnableWindow(FALSE);

		bCanCopy=m_html_ctrl.CanCopy();
		bCanPaste=m_html_ctrl.CanPaste();

		m_fBoldBtn.SetState(m_html_ctrl.IsSelectionBold());
		m_fItalicBtn.SetState(m_html_ctrl.IsSelectionItalic());
		m_fUnderLineBtn.SetState(m_html_ctrl.IsSelectionUnderline());
		m_fStrikeBtn.SetState(m_html_ctrl.IsSelectionStrikeouted());

		m_fLeftBtn.SetState(m_html_ctrl.IsParagraphLeft());
		m_fCentefBtn.SetState(m_html_ctrl.IsParagraphCenter());
		m_fRightBtn.SetState(m_html_ctrl.IsParagraphRight());
		m_fJustifyBtn.SetState(m_html_ctrl.IsParagraphWidth());

		m_fOrderListBtn.SetState(m_html_ctrl.IsOrderList());
		m_fBulletedBtn.SetState(m_html_ctrl.IsUnOrderList());

		m_html_ctrl.ReleseInterfaces();

	}
	else
	{
		long nLength= m_content.GetTextLength();
		
		char * buffer = NULL;
		if (m_content.CanPaste() && OpenClipboard()) 
		{
			HANDLE hData = GetClipboardData(CF_TEXT);
			buffer = (char*)GlobalLock(hData);
			GlobalUnlock(hData);
			CloseClipboard();
		}
		
		if(buffer)
			nLength+=strlen(buffer);
		if (m_content.GetLimitText() < nLength+2)
			m_content.LimitText(nLength+2);	

		fontsize=m_content.GetSelectionFontSize();
		sFontName=m_content.GetSelectionFontName();

		m_fBoldBtn.SetState(m_content.SelectionIsBold());
		m_fItalicBtn.SetState(m_content.SelectionIsItalic());
		m_fUnderLineBtn.SetState(m_content.SelectionIsUnderlined());
		m_fStrikeBtn.SetState(m_content.SelectionIsStrikeouted());

		m_fLeftBtn.SetState(m_content.ParagraphIsLeft());
		m_fCentefBtn.SetState(m_content.ParagraphIsCentered());
		m_fRightBtn.SetState(m_content.ParagraphIsRight());
		m_fJustifyBtn.SetState(m_content.ParagraphIsJustify());

		m_fBulletedBtn.SetState(m_content.ParagraphIsBulleted());
		m_fOrderListBtn.SetState(m_content.ParagraphIsOrderList());

		bCanPaste=m_content.CanPaste();
		bCanCopy=TRUE;
	}

	buf.Format(_T("%i"), fontsize);
	int iRes= m_fontSizeCB.SelectString(-1, buf);
	iRes= m_fontCB.SelectString(-1, sFontName);
	
	m_tCut.EnableWindow(bCanCopy);
	m_tCopy.EnableWindow(bCanCopy);
	m_tPaste.EnableWindow(bCanPaste);

	if(0!=pResult) *pResult = 0;
}

void CMessageDlg::OnSetfocusMessageRichedit(NMHDR* pNMHDR, LRESULT* pResult) 
{
	// TODO: Add your control notification handler code here
//	AfxMessageBox(_T("1"));
	*pResult = 0;
}


void CMessageDlg::OnKillfocusMessageRichedit(NMHDR* pNMHDR, LRESULT* pResult) 
{
	// TODO: Add your control notification handler code here
//	AfxMessageBox(_T("2"));
	*pResult = 0;
}

void CMessageDlg::OnAddFile() 
{
	CFileDialog dlg(TRUE,0,0,OFN_FILEMUSTEXIST|OFN_HIDEREADONLY|OFN_ALLOWMULTISELECT,
		_T("All Files (*.*)|*.*||"));
	
	CString buf, sName;
	LPTSTR szFilesNames= buf.GetBuffer(2048);
	dlg.m_ofn.lpstrFile= szFilesNames;
	dlg.m_ofn.nMaxFile= 2048;

	if(dlg.DoModal()!=IDOK) return;
	
	CStringArray array_files;
	POSITION pos=dlg.GetStartPosition();
	while(pos!=0) 
	{
		sName= dlg.GetNextPathName(pos);	
		array_files.Add(sName);
	}
	m_bChanged=true;
	AddFiles(array_files);
}

void CMessageDlg::AddFiles(CStringArray &array_files)
{
	if(m_message && m_sMesStatus!=_T("draft")) return;
	m_bChanged=true;
	int i;
	CString sName;
	for(i=0;i<array_files.GetSize(); i++)
	{
		sName=array_files[i];
		LVFINDINFO info;
		info.flags= LVFI_STRING;		
		info.psz= sName;
		
		if(m_itemsList.FindItem(&info, -1)==-1)
		{

			// Проверка размера
			int iMaxFileSize=0;
			m_api->m_options_mgr.GetOptionValueBN( APL_NO_T("Настройка документов\\Максимальный допустимый размер файлов"), iMaxFileSize, (int)0);
			if(iMaxFileSize>0)
			{
				CFileStatus rStatus;
				CFile::GetStatus(sName,rStatus);
				if(rStatus.m_size>iMaxFileSize)
				{
					bool bEnableCreate=false;
					CString sRole;

					m_api->m_options_mgr.GetOptionValueBN( APL_NO_T("Настройка документов\\Роль для игнорирования ограничения размеров файлов"), sRole, _T(""));
					if(sRole!=_T("")){if(m_api->m_appr_mgr.CheckPersonRole(0,sRole)) bEnableCreate=true;}

					if(!bEnableCreate)
					{
						CString buf;
						buf.Format( APL_T("Размер указанного файла (%i) превышает разрешенный (%i)!\n\n Обратитесь к системному администратору."),
							(int)rStatus.m_size,iMaxFileSize);
						AfxMessageBox(buf,MB_OK|MB_ICONSTOP);
						return;
					}
				}
			}

			UINT ico= ICON_DOCUMENT_COPY;
			int n= m_itemsList.GetItemCount();
			int m= m_itemsList.InsertItem(n, sName, ico);
			m_itemsList.SetItemData(m, 0);
//				sName= dlg.GetPathName();
			m_files_in_list.Add(sName);			
		}
	}
}

/*void CMessageDlg::OnDeleteFile() 
{
	if(!m_curSelItem)
	{
		CString buf= m_itemsList.GetItemText(m_index, 0);
		m_itemsList.DeleteItem(m_index);
		for(int i=0; i<m_files_in_list.GetSize(); i++)
		{
			if(buf==m_files_in_list[i])
			{
				m_files_in_list.RemoveAt(i);
				break;
			}
		}
	}
	else
	{
		m_itemsList.DeleteItem(m_index);
		m_items_in_list.Remove(m_items_in_list.Find(m_curSelItem));
		apidata.DeleteInstance(m_curSelItem);
	}
}*/

void CMessageDlg::OnViewFile() 
{
	if(!m_curSelItem)
	{
		CString fpath= m_itemsList.GetItemText(m_index, 0);

		if(fpath==_T("")) return;

		HINSTANCE hInst=aplShellExecute(NULL, _T("open"), fpath, NULL, NULL, SW_SHOW);
	}
	else
		m_api->m_doc_mgr.View(m_curSelItem);
}

void CMessageDlg::OnLoadFile() 
{
	int n=m_itemsList.GetSelectedCount();
	if(n<1) return;

	if(n==1)
	{
		int nItem= m_itemsList.GetNextItem(-1 , LVNI_ALL | LVNI_SELECTED );
		CaplInstance *doc=(CaplInstance *)m_itemsList.GetItemData(nItem);
		if(0!=doc)
		{
			if(m_api->m_data.IsKindOf(doc,m_api->m_doc_mgr.e_apl_stored_document))
			{
				//это файл
				CString filename;
				m_api->m_data.GetAttr(doc,m_api->m_doc_mgr.a_apl_stored_document_file_name,filename);
				
				int i=filename.ReverseFind(_T('\\'));
				if(i>0)
				{
					CString buf=filename.Right(filename.GetLength()-(i+1));
					filename=buf;
				}

				CFileDialog dlg(FALSE,0, filename, OFN_OVERWRITEPROMPT);
				if(!dlg.DoModal()) return;
				filename=dlg.GetPathName();
				m_api->m_doc_mgr.LoadRevision(doc, filename);
			}
			else m_api->m_doc_mgr.LoadRevision(doc, _T(""));
		}
		else AfxMessageBox(APL_T("Файл еще не сохранен в БД!"));
		return;
	}
	// Выделено несколько
	static CString	sPath;

	CaplSelectFolderDialog dlg(FALSE, sPath, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, NULL, NULL);
	if(dlg.DoModal()!=IDOK) return;
	sPath = dlg.GetSelectedPath();

	int nItem=-1;
	while(true)
	{
		nItem= m_itemsList.GetNextItem(nItem , LVNI_ALL | LVNI_SELECTED );
		if(-1==nItem) break;
		CaplInstance *doc=(CaplInstance *)m_itemsList.GetItemData(nItem);
		if(0==doc) {AfxMessageBox(APL_T("Файл еще не сохранен в БД!")); continue;}
		
		m_api->m_doc_mgr.LoadRevision(doc, sPath);
	}
}

void CMessageDlg::OnMesRecipientsSelButton() 
{
	int i;
	long lMode= APL_MODE_SELECT_PERSON | APL_MODE_SELECT_OFFICIAL;
	aplExtent ext;
	if(m_recipient)	ext.Add(m_recipient);
	else {for(i= 0; i<m_recipients.GetSize(); i++) ext.Add(m_recipients[i]);}

	while(true) // Для цикла измеенния выбора
	{
		if(!m_api->m_appr_mgr.SelectPersonsOrganizations(lMode, ext, true, true, 
			 APL_T("Выбор получателей сообщения"),  APL_T("Выберите получателей сообщения"), m_possibleRecips)) return;

		if(ext.GetSize()>10)
		{
			CString buf;
			buf.Format(APL_T("Выбрано %i получателей!\n\nВы действительно хотите отправить сообщение стольким сотрудникам?"),ext.GetSize());
			if(IDYES!=AfxMessageBox(buf,MB_YESNO|MB_ICONQUESTION)) continue;
		}
		m_bChanged=true;
		m_recipients.Clear();
		m_recipient= NULL;

		if(ext.GetSize()==1) m_recipient=ext[0];
		else if(ext.GetSize()>1) m_recipients.Append(ext);
		RemoveDubliesFromRecepientsCopy();
		FillRecepients();
		break;
	}
}

void CMessageDlg::OnBnClickedMesCopyRecipientsSelButton()
{
	long lMode= APL_MODE_SELECT_PERSON | APL_MODE_SELECT_OFFICIAL;
	
	aplExtent ext;
	ext.Append(m_recipients_copy);

	while(true) // Для цикла измеенния выбора
	{
		if(!m_api->m_appr_mgr.SelectPersonsOrganizations(lMode, ext, true, true, 
			APL_T("Выбор получателей копии сообщения"),  APL_T("Выберите получателей копии сообщения"), m_possibleRecips)) return;

		if(ext.GetSize()>10)
		{
			CString buf;
			buf.Format(APL_T("Выбрано %i получателей!\n\nВы действительно хотите отправить сообщение стольким сотрудникам?"),ext.GetSize());
			if(IDYES!=AfxMessageBox(buf,MB_YESNO|MB_ICONQUESTION)) continue;
		}
		m_bChanged=true;
		m_recipients_copy.Clear();
		m_recipients_copy.Append(ext);
		RemoveDubliesFromRecepientsCopy();
		FillRecepients();
		break;
	}
}



void CMessageDlg::FillRecepients()
{
	m_sRecipientsNick= _T("");
	m_sRecipientsCopyNick= _T("");

	int i;
	CString buf;		
	if(0!=m_recipient) m_api->m_appr_mgr.GetPersonName(m_recipient, m_sRecipientsNick);
	else
	{
		for(i= 0; i<m_recipients.GetSize(); i++)
		{
			if(!m_recipients[i]) continue;
			m_api->m_appr_mgr.GetPersonName(m_recipients[i], buf);
			if(m_sRecipientsNick!=_T(""))	m_sRecipientsNick+=_T("; ");
			m_sRecipientsNick+=buf;
		}
	}
	m_wndRecipient.SetWindowText(m_sRecipientsNick);

	for(i= 0; i<m_recipients_copy.GetSize(); i++)
	{
		if(!m_recipients_copy[i]) continue;
		m_api->m_appr_mgr.GetPersonName(m_recipients_copy[i], buf);
		if(m_sRecipientsCopyNick!=_T(""))	m_sRecipientsCopyNick+=_T("; ");
		m_sRecipientsCopyNick+=buf;
	}
	m_wndRecipientCopy.SetWindowText(m_sRecipientsCopyNick);
}




void CMessageDlg::OnMessageNameStatic() 
{
	// TODO: Add your control notification handler code here
	CString text,buf;
//	if(((GetKeyState(VK_LMENU) & 0xff00)!=0)&&((GetKeyState(VK_RMENU) & 0xff00)!=0))
	if(((GetKeyState(VK_LMENU) )!=0)&&((GetKeyState(VK_RMENU) )!=0))
	{
		if(m_message!=0){buf.Format(_T("m_message->id %i;\n"),m_message->GetId());text+=buf;}else{buf.Format(_T("m_message==0;\n"));}
		if(m_sender!=0){buf.Format(_T("m_sender->id %i;\n"),m_sender->GetId());text+=buf;}else{buf.Format(_T("m_sender==0;\n"));}
		if(m_recipient!=0){buf.Format(_T("m_recipient->id %i;\n"),m_recipient->GetId());text+=buf;}else{buf.Format(_T("m_recipient==0;\n"));}
		//if(m_curSelItem!=0){buf.Format(_T("m_curSelItem->id %i;\n"),m_curSelItem->GetId());text+=buf;}else{buf.Format(_T("m_curSelItem==0;\n"));}
		AfxMessageBox(text);
	}	
	
}

void CMessageDlg::OnSize(UINT nType, int cx, int cy) 
{
	CResizableDialog::OnSize(nType, cx, cy);
	
	if(::IsWindow(m_content.m_hWnd))
		m_content.Invalidate();
}

void CMessageDlg::OnBnClickedWordwrap()
{
	if(BST_CHECKED==m_wordwrap_btn.GetCheck())
	{
		m_content.SetTargetDevice(NULL, 1);
		m_wordwrap_btn.SetCheck(BST_UNCHECKED);

	}
	else
	{
		m_content.SetTargetDevice(NULL, 0);
		m_wordwrap_btn.SetCheck(BST_CHECKED);
	}
	Invalidate();
}

void CMessageDlg::OnNMDblclkMessageItems(NMHDR *pNMHDR, LRESULT *pResult)
{
	LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
	// TODO: Add your control notification handler code here
	*pResult = 0;

	OnViewFile() ;
}

void CMessageDlg::OnBnClickedInfo()
{
	CString sInfo,buf;
	CaplInstance *inst1;
	COleDateTime odt;

	for(int j= 0; j<m_messageCopies.GetSize(); j++)
	{
		m_api->m_data.GetAttr(m_messageCopies[j], m_api->m_message_mgr.a_message_rec_offisial, inst1);
		if(0==inst1)//отправляли именно этому person'у
			m_api->m_data.GetAttr(m_messageCopies[j], m_api->m_message_mgr.a_message_recipient, inst1);
		if(inst1)
		{
			m_api->m_appr_mgr.GetPersonName(inst1, buf);

			sInfo+=buf;

			m_api->m_data.GetAttr(m_messageCopies[j], m_api->m_message_mgr.a_message_date_received, buf);
			if(buf==_T("")) buf=APL_T(" - не получено");
			else {
				aplString2Date(buf, odt);	
				buf= odt.Format(_T(" - %d.%m.%Y  %H:%M"));
			} 
			
			bool bIsCopy=false;
			m_api->m_data.GetAttr(m_messageCopies[j], m_api->m_message_mgr.a_message_recipient_in_copy, bIsCopy);
			if(bIsCopy )buf+=APL_T("   (Копия)");

			sInfo+=buf;
		}
		sInfo+=_T("\n");
	}
	aplShowBigMsg(sInfo, APL_T("Информация о получении"));
}


void CMessageDlg::OnBnClickedOpenNomodal()
{
	m_iAction=MESSAGE_DLG_OPEN_NOMODAL;
	OnCancel();
}


void CMessageDlg::RemoveDubliesFromRecepientsCopy()
{
	int i,j;
	CString buf,sList;
	for(i=0;i<m_recipients_copy.GetSize();i++)
	{
		CaplInstance *inst=m_recipients_copy[i];
		for(j=0;j<m_recipients.GetSize();j++)
		{
			if(inst!=m_recipients[j]) continue;
			m_api->m_appr_mgr.GetPersonName(inst,buf);
			if(sList!=_T(""))sList+=_T(", ");
			sList+=buf;
			m_recipients_copy.Remove(i);
			i--;
			break;
		}
	}
	if(sList!=_T(""))
	{
		buf=APL_T("Следующие сотрудники есть и в списке получателей и в списке получателй копии:\n");
		buf+=sList;
		buf+=APL_T("\n\nУказанные сотрудники исключены из списка получателей копии.");
		AfxMessageBox(buf,MB_ICONWARNING|MB_OK);
	}
}




void CMessageDlg::OnNMRClickMessageItems(NMHDR *pNMHDR, LRESULT *pResult)
{
	LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
	// TODO: Add your control notification handler code here
	*pResult = 0;

	if(0==m_message) return;
	if(0==pNMItemActivate) return;
	if(pNMItemActivate->iItem<0) return;

	CaplInstance *inst=(CaplInstance *)m_itemsList.GetItemData(pNMItemActivate->iItem);
	if(0==inst) return;
	if(inst->GetAccessmode()>aplRO) return;
	if(!m_api->m_data.IsKindOf(inst,m_api->m_doc_mgr.e_apl_stored_document)) return;

	CaplMenu menu;
	VERIFY(menu.LoadMenu(IDR_CONTEXT_MENU1));
	menu.Install(this); 
	CMenu* pPopup = menu.GetSubMenu(1);
	ASSERT(pPopup != NULL);
	if(pPopup==0) return;

	POINT point;
	GetCursorPos(&point);

	BOOL res = pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD,
		point.x, point.y, this);
	switch (res)
	{
	case ID_MESSAGEITEM_CONVERT_TO_DOC:
		{
			CString buf;
			buf.Format(_T("*%i"),inst);
			CaplInstance *doc=m_api->m_doc_mgr.CreateDocument(_T(""),_T(""),_T(""),0,buf,true);
			if(doc!=0)
			{
				// Определяем все копии
				CaplInstance *main_msg=0;
				m_api->m_data.GetAttr(m_message, m_api->m_message_mgr.a_message_copy, main_msg);
				if(0==main_msg) main_msg=m_message;
				else m_api->m_message_mgr.LoadMessageInfo(main_msg);
				aplExtent ext_copies;
				m_api->m_data.GetAttr(main_msg, m_api->m_message_mgr.a_message_copies, ext_copies);
				ext_copies.Add(main_msg);

				m_api->m_data.GetAttr(main_msg, m_api->m_message_mgr.a_message_items, m_items);
				int i;
				// Удаление файла из объектов
				for(i=0;i<m_items.GetSize();i++)
				{
					if(m_items[i]!=inst) continue;
					m_items.Remove(i);
					break;
				}
				m_items.Add(doc);


				for(i=0;i<ext_copies.GetSize();i++)
				{
					m_api->m_data.PutAttr(ext_copies[i], m_api->m_message_mgr.a_message_items, m_items);
				}
				m_api->SaveChanges();
				ShowItemsInList(m_items);
			}
		}
		break;

	}

}

void CMessageDlg::OnShowWindow(BOOL bShow, UINT nStatus)
{
	CResizableDialog::OnShowWindow(bShow, nStatus);

	// TODO: Add your message handler code here
	if(bShow)
	{
		SetForegroundWindow();
		BringWindowToTop();
	}
}


void CMessageDlg::OnBnClickedFontStrike()
{
	if(m_bHtmlMode)
	{
		m_html_ctrl.SetSelectionStrikeouted();
		m_content.SetFocus();
	}
	else 
	{
		m_content.SetSelectionStrikeouted();
		m_content.SetFocus();

	}
	OnSelchangeMessageRichedit(0,0);
}

