// ReportElement.cpp: implementation of the CReportElement class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "resource.h"
#include "ReportDict.h"
#include "PropertyDlg.h"
#include "SelectTableDlg.h"
#include <math.h>
#include "Functions.h"

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

//#define GRPZ

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CRectReportElement::CRectReportElement(CaplReportMgr *ReportMgr):CReportElement(ReportMgr, E_RECT),m_Flags(0)
{
	m_name = APL_T("Прямоугольник с текстом");
	
	m_dsfrow = -1;
	m_dsfcol = -1;
}

CRectReportElement::~CRectReportElement()
{
}

bool CRectReportElement::IsWin7OrLater() 
{
	DWORD version = GetVersion();
	DWORD major = (DWORD) (LOBYTE(LOWORD(version)));
	DWORD minor = (DWORD) (HIBYTE(LOWORD(version)));

	return (major > 6) || ((major == 6) && (minor >= 1));
}

// отрисовка текста в ячейке
void CRectReportElement::DrawText(CDC * pDC, double scale, int mode)
{
	if(m_value.GetType() == NONE_VAL) return;
	bool bDraw = true;

	CRect rect;
	GetRect(rect, scale, pDC->IsPrinting());
	CFont font, *old;
	UINT format = 0;

	format = m_value.m_align;
	CString text=_T("");
	
	COLORREF oldTextColor = pDC->SetTextColor(m_value.m_color);

	if(m_value.GetType()==INST_VAL)
	{
		CReportParam* par = m_value.GetParam();
		int ParType = -1;
		if(par)
			ParType = par->GetType();

		if(par==NULL)
		{
			m_value.SetText(_T(""));
		}
		else if(ParType==PAGE_PARAM || ParType==STATIC_PAGE_NUM)
		{
			if(ParType==STATIC_PAGE_NUM)
			{
				CaplInstance *textValue = 0;
				m_ReportMgr->m_data->GetAttr(m_owner_sheet->m_inst, m_ReportMgr->a_elem_text_val, textValue);				

				if(0 != textValue)
				{
					m_ReportMgr->m_data->GetAttr(textValue, m_ReportMgr->a_val_text, text);
				}
			}
			
			if(text.IsEmpty() == true)
				text = m_owner_sheet->m_name;				

			text.TrimLeft(APL_T("Лист"));
			if(m_value.m_text_params&APL_TP_HIDE_FOR_ONE_PAGE && mode!=0 && m_ReportMgr->m_sheets.GetSize()==1)
				text = _T("");
		}
		else if(ParType==PAGE_COUNT || ParType==STATIC_PAGE_COUNT)
		{
			if(ParType==STATIC_PAGE_COUNT)
				text = m_value.m_text;
			
			if(text.IsEmpty() == true)
				text.Format(_T("%d"),m_owner_sheet->m_ReportMgr->m_sheets.GetSize());			
			
			if(m_value.m_text_params&APL_TP_HIDE_FOR_ONE_PAGE && mode!=0 && m_ReportMgr->m_sheets.GetSize()==1)
				text = _T("");
		}
		else if(ParType==CURRENT_DATE || ParType==STATIC_CUR_DATE)
		{
			COleDateTime time = COleDateTime::GetCurrentTime();
			aplGetFormatedDate(time, text);
		}
		else if(mode!=0)
		{
			text = par->GetText();
		}
		else if(mode==0)
		{
			text = par->m_name;
			pDC->SetTextColor(::GetSysColor(COLOR_GRAYTEXT));
		}
	}
	else 
		text = m_value.GetText();
	if(text.IsEmpty()) return;
	LOGFONT lf;
	lf = m_value.m_font;
	if(m_value.m_direction==HORIZ_TEXT)
		lf.lfEscapement = 0;
	else if(m_value.m_direction==VERT_TEXT)
		lf.lfEscapement = -900;
	else if(m_value.m_direction==RHORZ_TEXT)
		lf.lfEscapement = 1800;
	else if(m_value.m_direction==RVERT_TEXT)
		lf.lfEscapement = 900;
	
	int FontHeight = 0;
	lf.lfQuality = DEFAULT_QUALITY;
	double dTemp = (double)(lf.lfHeight)*scale;
	lf.lfHeight = (int)(dTemp);

	// ААА. при экспорте страниц масштаб увеличивается и шрифты выше чем в WinXp получаются бОльшими, чем нужно
	if(scale > 1 && IsWin7OrLater())
		lf.lfHeight = (int)(lf.lfHeight * 0.75); 

	if (0 == font.CreatePointFontIndirect(&lf, pDC))
		TRACE_TO_FILE(APL_T("Ошибка CreatePointFontIndirect"));
	old = pDC->SelectObject(&font);
	rect.NormalizeRect();
	if (format & AT_TOP)
		rect.top -= (int)(m_line_width*2*scale);
	rect.bottom += (int)(m_line_width*2*scale);
	if (format & AT_LEFT)
		rect.left += (int)(5.0+m_line_width*2*scale);
	rect.right -= (int)(m_line_width*2*scale);	

	if(m_value.m_text_params&APL_TP_FITTORECT)
	{
		int cx = rect.Width(), cy = abs(rect.Height());
		bool ok = false;
		int step = lf.lfHeight;
		do
		{
			CSize size = pDC->GetTextExtent(text);
			if(m_value.m_direction==VERT_TEXT || m_value.m_direction==RVERT_TEXT)//Vert
			{
				if(size.cx<=cy && size.cy<=cx)
					ok = true;
			}
			else
			{
				if(size.cx<=cx && size.cy<=cy)
					ok = true;
			}
			lf.lfHeight--;
			font.DeleteObject();
			font.CreatePointFontIndirect(&lf,pDC);
			pDC->SelectObject(&font);
			if(lf.lfHeight<=0)
			{
				bDraw = false;
				break;
			}
		}
		while(!ok);
		
	}
	if(lf.lfHeight>-1 && lf.lfHeight<1) 
		bDraw=false;
	if(bDraw)
		ReportDrawText(pDC,rect,text,format, scale);
	pDC->SelectObject(old);
	pDC->SetTextColor(oldTextColor);
	font.DeleteObject();
}

BOOL CRectReportElement::Draw(CDC *pDC, double scale, int draw_mode, UINT flag)
{
	if(pDC==NULL) return FALSE;
	if(scale==0) return FALSE;
	CRect rect; 
	GetRect(rect, scale, pDC->IsPrinting()); // получаем координаты прямоугольника 
	CPen m_obj_pen;
	CBrush m_bg_brush;
	m_obj_pen.CreatePen(PS_SOLID | PS_GEOMETRIC, (int)((double)m_line_width*scale), OBJ_COLOR);
	m_bg_brush.CreateSolidBrush(BG_COLOR);
	
	CPen *old = pDC->SelectObject(&m_obj_pen);
	COLORREF otc;
	otc = pDC->SetTextColor(m_value.m_color);
	if(m_bNeedFillBackground)
		pDC->FillSolidRect(rect, m_background_color);
	if(flag&DRAW_TEXT)
		DrawText(pDC, scale, draw_mode); // отрисовка текста
	if(m_line_width>0 && m_value.m_border_visible)	
		DrawRect(pDC,rect);
	else if(draw_mode==0)
	{
		m_obj_pen.DeleteObject();
		m_obj_pen.CreatePen(PS_SOLID|PS_GEOMETRIC,1,::GetSysColor(COLOR_GRAYTEXT));
		pDC->SelectObject(&m_obj_pen);
		DrawRect(pDC,rect);
	}
	if(m_select && !pDC->IsPrinting() && flag&DRAW_SEL) 
		DrawSelPoints(pDC, scale); // отрисовка рамки выделения
	
	if(m_Flags&&APL_RRE_SHOW_TOP_LINE)
	{
		m_obj_pen.DeleteObject();
		m_obj_pen.CreatePen(PS_SOLID|PS_GEOMETRIC|PS_JOIN_BEVEL|PS_ENDCAP_FLAT, 10, m_value.m_color);
		pDC->SelectObject(&m_obj_pen);
		rect.NormalizeRect();
		pDC->MoveTo(rect.left+5, rect.bottom-5);
		pDC->LineTo(rect.right-5, rect.bottom-5);
	}

	pDC->SetTextColor(otc);
	pDC->SelectObject(old);
	m_obj_pen.DeleteObject();
	m_bg_brush.DeleteObject();
	
	return true;
}

int CRectReportElement::ShowContextMenu(CPoint pt, CWnd * wnd, int mode)
{
	if(wnd == NULL) return false;
	
	HINSTANCE hInst = AfxGetResourceHandle();
	AfxSetResourceHandle(dllInst);
	wnd->ClientToScreen(&pt);

	CMenu menu;
	CMenu *pPopup;
	menu.LoadMenu(IDR_CONTEXT_MENU);
	pPopup = menu.GetSubMenu(1);

	if(mode>0)
	{
		pPopup->EnableMenuItem(ID_FIXED,MF_BYCOMMAND|MF_GRAYED);
		pPopup->EnableMenuItem(ID_ALIGN, MF_BYCOMMAND|MF_GRAYED);
		pPopup->EnableMenuItem(ID_DELETE,MF_BYCOMMAND|MF_GRAYED);
		pPopup->EnableMenuItem(ID_EDIT_PASTE,MF_BYCOMMAND|MF_GRAYED);
		pPopup->EnableMenuItem(ID_PROPERTY,MF_BYCOMMAND|MF_GRAYED);
		pPopup->EnableMenuItem(ID_REPORTELEM_BACK,MF_BYCOMMAND|MF_GRAYED);
		pPopup->EnableMenuItem(ID_REPORTELEM_FRONT,MF_BYCOMMAND|MF_GRAYED);
	}
	else if(m_fixed)
		pPopup->ModifyMenu(ID_FIXED,MF_BYCOMMAND|MF_STRING, ID_FIXED,APL_T("Раcфиксировать"));


	BOOL res = pPopup->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON|TPM_RETURNCMD,pt.x, pt.y, wnd);

	AfxSetResourceHandle(hInst);
	if(res == 0) return false;

	switch(res)
	{
		case ID_FIXED :
			if(m_fixed>0) m_fixed = 0;
			else m_fixed = 1;
			break;
		case ID_ALIGN :
			Align();
			break;
		case ID_SHOW_PAGE_NUM :
			{
				CReportParam* par = 0;
				int ind = m_owner_sheet->m_ReportMgr->m_data_source.m_params.Find(PAGE_PARAM);
				if(ind<0)
				{
					par = new CReportParam(m_ReportMgr);
					par->SetType(PAGE_PARAM);
					par->m_name = APL_T("Номер страницы");
				}
				else 
					par = m_owner_sheet->m_ReportMgr->m_data_source.m_params.GetAt(ind);
				m_value.SetText(par);
			}break;
		case ID_SHOW_PAGE_COUNT :
			{
				CReportParam* par = 0;
				int ind = m_owner_sheet->m_ReportMgr->m_data_source.m_params.Find(PAGE_COUNT);
				if(ind<0)
				{
					par = new CReportParam(m_ReportMgr);
					par->SetType(PAGE_COUNT);
					par->m_name = APL_T("Количество страниц");
				}
				else 
					par = m_owner_sheet->m_ReportMgr->m_data_source.m_params.GetAt(ind);
				m_value.SetText(par);
			}break;
		case ID_SHOW_CURRENT_DATE :
			{
				CReportParam* par = 0;
				int ind = m_owner_sheet->m_ReportMgr->m_data_source.m_params.Find(CURRENT_DATE);
				if(ind<0)
				{
					par = new CReportParam(m_ReportMgr);
					par->SetType(CURRENT_DATE);
					par->m_name = APL_T("Текущая дата");
				}
				else 
					par = m_owner_sheet->m_ReportMgr->m_data_source.m_params.GetAt(ind);
				m_value.SetText(par);
			}break;
		case ID_REPORTELEM_STATIC_DATE :
			{
				CReportParam* par = 0;
				int ind = m_owner_sheet->m_ReportMgr->m_data_source.m_params.Find(STATIC_CUR_DATE);
				if(ind<0)
				{
					par = new CReportParam(m_ReportMgr);
					par->SetType(STATIC_CUR_DATE);
					par->m_name = APL_T("Дата формирования отчета");
				}
				else 
					par = m_owner_sheet->m_ReportMgr->m_data_source.m_params.GetAt(ind);
				m_value.SetText(par);
			}break;
		case ID_REPORTELEM_STATIC_PAGE_COUNT:
			{
				CReportParam* par = 0;
				int ind = m_owner_sheet->m_ReportMgr->m_data_source.m_params.Find(STATIC_PAGE_COUNT);
				if(ind<0)
				{
					par = new CReportParam(m_ReportMgr);
					par->SetType(STATIC_PAGE_COUNT);
					par->m_name = APL_T("Локальное количество страниц");
				}
				else 
					par = m_owner_sheet->m_ReportMgr->m_data_source.m_params.GetAt(ind);
				m_value.SetText(par);
			}break;
		case ID_REPORTELEM_STATIC_PAGE_NUM:
			{
				CReportParam* par = 0;
				int ind = m_owner_sheet->m_ReportMgr->m_data_source.m_params.Find(STATIC_PAGE_NUM);
				if(ind<0)
				{
					par = new CReportParam(m_ReportMgr);
					par->SetType(STATIC_PAGE_NUM);
					par->m_name = APL_T("Локальный номер страницы");
				}
				else 
					par = m_owner_sheet->m_ReportMgr->m_data_source.m_params.GetAt(ind);
				m_value.SetText(par);
			}break;
		default : 
			return ExecuteCmd(res);
	}
	return 0;
}

void CRectReportElement::ReportDrawText(CDC *pDC, CRect r, CString str, DWORD flags, double scale)
{
	if(pDC==NULL) return;
	int bkMode = pDC->SetBkMode(TRANSPARENT);
	CSize sz;
	CSize size;
	r.NormalizeRect();

	str.Replace(_T("\r"), _T(""));
	CRect TmpRect = r;
	TmpRect.DeflateRect(CSize((int)((-2.0)*scale),(int)((-2.0)*scale)));
	CRgn rgn1, rgn2;
	HRGN OldRgn = NULL;
	CRect RgnRect;
	GetRect(RgnRect, scale, pDC->IsPrinting());
	ConvertLOMETRICtoTEXT(pDC, RgnRect);
	OldRgn = ::CreateRectRgnIndirect(&RgnRect);
	int res = GetClipRgn(pDC->m_hDC, OldRgn);
	RgnRect.NormalizeRect();
	rgn1.CreateRectRgnIndirect(&RgnRect);
	if(res==1)
	{
		CRect old_rgn_rect;
		int tmp_res;
		rgn2.Attach(OldRgn);
		rgn2.GetRgnBox(&old_rgn_rect);
		tmp_res = rgn1.CombineRgn(&rgn1, &rgn2, RGN_AND);
		if(tmp_res==NULLREGION)
		{
		}
		rgn2.Detach();
	}
	int Result = pDC->SelectClipRgn(&rgn1);
	if(Result==ERROR)
	{
		TRACE(_T("SelectClipRgn Error"));
	}
	
	// 	if(m_owner_sheet->m_index%2)
	// 		format = AT_RIGHT;
	// 	else
	// 		format = AT_LEFT;



	if ((flags&010000)!=0)
	{
		CString text = m_owner_sheet->m_name;
		text.TrimLeft(APL_T("Лист"));
		if(_atoi(text)%2)
			flags>>=6;
	}	

	CPoint pt = CPoint(r.left,r.bottom);//Спецефика LOMETRIC;
	if(m_value.m_direction==HORIZ_TEXT)//Horz Text;
	{
		CStringArray strs;
		int cnt = 1;
		if(!(m_value.m_text_params&APL_TP_NOTBREAKSTRING) && !(m_value.m_text_params&APL_TP_FITTORECT))
			cnt = m_value.BreakString(&strs, r.Width(), pDC, str);
		else strs.Add(str);
		if(cnt>-1)
		{
			TEXTMETRIC tm;
			pDC->GetTextMetrics(&tm);
			size = pDC->GetTextExtent(strs.GetAt(0));
			int h = (tm.tmAscent)*cnt+tm.tmExternalLeading*(cnt-1);
			if(m_value.m_space_para==aplSpacePara15)
				h = (tm.tmAscent)*cnt+(tm.tmDescent+tm.tmExternalLeading)*(cnt-1);
			else if(m_value.m_space_para==aplSpacePara2)
				h = (tm.tmAscent)*cnt+(tm.tmDescent+tm.tmExternalLeading)*2*(cnt-1);
			
			int cx, cy = pDC->GetTextExtent(_T("Ag")).cy;
			if(flags&AT_TOP)
				pt.y = r.bottom-(tm.tmDescent+tm.tmExternalLeading);
			else if(flags&AT_BOTTOM)
				pt.y = r.top+h+(tm.tmDescent+tm.tmExternalLeading);
			else if(flags&AT_VCENTER)
				pt.y = (r.bottom + r.top)/2+h/2;
			for(int i=0; i<cnt;i++)
			{
				cx = pDC->GetTextExtent(strs.GetAt(i)).cx;
				if(flags&AT_RIGHT)
					pt.x = r.right - cx;
				else if(flags&AT_LEFT)
					pt.x = r.left;
				else if(flags&AT_CENTER)
					pt.x = r.Width()/2 - cx/2+r.left;
				CString tstr = strs.GetAt(i);
				pDC->TextOut(pt.x, pt.y, tstr);
				pt.y=pt.y-tm.tmAscent;
				if(m_value.m_space_para==aplSpacePara15)
					pt.y-=tm.tmDescent+tm.tmExternalLeading;
				else if(m_value.m_space_para==aplSpacePara2)
					pt.y-=(tm.tmDescent+tm.tmExternalLeading)*2;
			}
		}
	}
	else if(m_value.m_direction==VERT_TEXT)//Vert Text;
	{
		CStringArray strs;
		int cnt = 1;
		if(!(m_value.m_text_params&APL_TP_NOTBREAKSTRING) && !(m_value.m_text_params&APL_TP_FITTORECT))
			cnt = m_value.BreakString(&strs,r.Height(),pDC,&str);
		else strs.Add(str);
		if(cnt>-1)
		{
			TEXTMETRIC tm;
			pDC->GetTextMetrics(&tm);
			size = pDC->GetTextExtent(strs.GetAt(0));
			int h = (tm.tmAscent)*cnt;
			if(m_value.m_space_para==aplSpacePara15)
				h = (tm.tmAscent)*cnt+(tm.tmExternalLeading+tm.tmDescent)*(cnt-1);
			else if(m_value.m_space_para==aplSpacePara2)
				h = (tm.tmAscent)*cnt+(tm.tmExternalLeading+tm.tmDescent)*2*(cnt-1);
			if(flags&AT_RIGHT)
				pt.x = r.right - h - (tm.tmExternalLeading+tm.tmDescent);
			else if(flags&AT_LEFT)
				pt.x = r.left;
			else if(flags&AT_CENTER)
				pt.x = (r.left+r.right)/2 - (h/2);
			int cx, cy = pDC->GetTextExtent(_T("Ag")).cy;
			for(int i=0; i<cnt;i++)
			{
				cx = pDC->GetTextExtent(strs.GetAt(i)).cx;
				if(flags&AT_TOP)
					pt.y = r.bottom-cx-1;
				else if(flags&AT_BOTTOM)
					pt.y = r.top + 1;
				else if(flags&AT_VCENTER)
					pt.y = r.Height()/2 - cx/2+r.top;
				//Определяем помещается ли наш текст в прямоугольник
				pDC->TextOut(pt.x, pt.y, strs.GetAt(i));
				pt.x=pt.x+tm.tmAscent;
				if(m_value.m_space_para==aplSpacePara15)
					pt.x+=tm.tmExternalLeading+tm.tmDescent;
				else if(m_value.m_space_para==aplSpacePara2)
					pt.x+=(tm.tmExternalLeading+tm.tmDescent)*2;
			}
		}
	}
	else if(m_value.m_direction==RHORZ_TEXT)//Vert Text;
	{
		CStringArray strs;
		int cnt = 1;
		if(!(m_value.m_text_params&APL_TP_NOTBREAKSTRING) && !(m_value.m_text_params&APL_TP_FITTORECT))
			cnt = m_value.BreakString(&strs,r.Width(),pDC,str);
		else strs.Add(str);
		if(cnt>-1)
		{
			TEXTMETRIC tm;
			pDC->GetTextMetrics(&tm);
			size = pDC->GetTextExtent(strs.GetAt(0));
			int h = (tm.tmAscent)*cnt+tm.tmExternalLeading*(cnt-1);
			if(m_value.m_space_para==aplSpacePara15)
			{
				h = (tm.tmAscent)*cnt+(tm.tmDescent+tm.tmExternalLeading)*(cnt-1);
			}
			else if(m_value.m_space_para==aplSpacePara2)
			{
				h = (tm.tmAscent)*cnt+(tm.tmDescent+tm.tmExternalLeading)*2*(cnt-1);
			}
			
			int cx, cy = pDC->GetTextExtent(_T("Ag")).cy;
			if(flags&AT_TOP)
				pt.y = r.bottom-h-(tm.tmDescent+tm.tmExternalLeading);
			else if(flags&AT_BOTTOM)
				pt.y = r.top;
			else if(flags&AT_VCENTER)
				pt.y = (r.bottom + r.top)/2-h/2;
			for(int i=0; i<cnt;i++)
			{
				cx = pDC->GetTextExtent(strs.GetAt(i)).cx;
				if(flags&AT_RIGHT)
					pt.x = r.right;
				else if(flags&AT_LEFT)
					pt.x = r.left + cx;
				else if(flags&AT_CENTER)
					pt.x = r.Width()/2 + cx/2+r.left;
				CString tstr = strs.GetAt(i);
				pDC->TextOut(pt.x, pt.y, tstr);
				pt.y=pt.y+tm.tmAscent;
				if(m_value.m_space_para==aplSpacePara15)
					pt.y+=tm.tmDescent+tm.tmExternalLeading;
				else if(m_value.m_space_para==aplSpacePara2)
					pt.y+=(tm.tmDescent+tm.tmExternalLeading)*2;
				else
					pt.y+=tm.tmExternalLeading;
			}
		}
	}
	else if(m_value.m_direction==RVERT_TEXT)//Vert Text;
	{
		CStringArray strs;
		int cnt = 1;
		if(!(m_value.m_text_params&APL_TP_NOTBREAKSTRING) && !(m_value.m_text_params&APL_TP_FITTORECT))
			cnt = m_value.BreakString(&strs,r.Height(),pDC,&str);
		else strs.Add(str);
		if(cnt>-1)
		{
			TEXTMETRIC tm;
			pDC->GetTextMetrics(&tm);
			size = pDC->GetTextExtent(strs.GetAt(0));
			int h = (tm.tmAscent)*cnt;
			if(m_value.m_space_para==aplSpacePara15)
				h = (tm.tmAscent)*cnt+(tm.tmExternalLeading+tm.tmDescent)*(cnt-1);
			else if(m_value.m_space_para==aplSpacePara2)
				h = (tm.tmAscent)*cnt+(tm.tmExternalLeading+tm.tmDescent)*2*(cnt-1);
			if(flags&AT_RIGHT)
				pt.x = r.right;
			else if(flags&AT_LEFT)
				pt.x = r.left+h+(tm.tmDescent+tm.tmExternalLeading);
			else if(flags&AT_CENTER)
				pt.x = (r.left+r.right)/2 + (h/2);
			int cx, cy = pDC->GetTextExtent(_T("Ag")).cy;
			for(int i=0; i<cnt;i++)
			{
				cx = pDC->GetTextExtent(strs.GetAt(i)).cx;
				if(flags&AT_TOP)
					pt.y = r.bottom;
				else if(flags&AT_BOTTOM)
					pt.y = r.top+cx;
				else if(flags&AT_VCENTER)
					pt.y = r.Height()/2 + cx/2+r.top;
				pDC->TextOut(pt.x, pt.y, strs.GetAt(i));
				pt.x=pt.x-tm.tmAscent;
				if(m_value.m_space_para==aplSpacePara15)
					pt.x-=tm.tmExternalLeading+tm.tmDescent;
				else if(m_value.m_space_para==aplSpacePara2)
					pt.x-=(tm.tmExternalLeading+tm.tmDescent)*2;
				else
					pt.x-=tm.tmExternalLeading;
			}
		}
	}
	rgn1.DeleteObject();
	rgn1.Attach(OldRgn);
	if(res==1)
		pDC->SelectClipRgn(&rgn1);
	else
		pDC->SelectClipRgn(NULL);
	rgn1.DeleteObject();
	pDC->SetBkMode(bkMode);
}

void CRectReportElement::Update(bool set)
{
	if(set)		
	{
		if(m_inst==0)
		{
			CaplEntity* ent = 0;
			if(m_type==E_RECT) ent = m_ReportMgr->e_report_rect;
			else ent = m_ReportMgr->e_report_line;
			m_inst = m_ReportMgr->m_data->CreateInstance(ent);
		}
		m_value.UpdateData(m_ReportMgr);
		m_ReportMgr->m_data->PutAttr(m_inst, m_ReportMgr->a_elem_text_val,m_value.m_inst);
		m_ReportMgr->m_data->PutAttr(m_inst, m_ReportMgr->a_elem_name,m_name);
		m_ReportMgr->m_data->PutAttr(m_inst, m_ReportMgr->a_elem_line_width,m_line_width);
		m_ReportMgr->m_data->PutAttr(m_inst, m_ReportMgr->a_elem_fixed,m_fixed);
		m_ReportMgr->m_data->PutAttr(m_inst, m_ReportMgr->a_elem_create_tc,m_bCreateTableContent);
		
		m_ReportMgr->m_data->PutAttr(m_inst, m_ReportMgr->a_elem_dsfrow, m_dsfrow);
		m_ReportMgr->m_data->PutAttr(m_inst, m_ReportMgr->a_elem_dsfcol, m_dsfcol);
		
		m_ReportMgr->m_data->PutAttr(m_inst, m_ReportMgr->a_elem_textcolor, (int)m_color);

		int flags = 0;
		if(m_bNeedFillBackground)
			flags|=APL_RE_FILL_BACKGROUND;
		if ((m_value.GetParam() != NULL))
		{
			CRParamsArray& RParams = m_owner_sheet->m_ReportMgr->m_data_source.m_RParams;
			for (int i = 0; i < RParams.GetSize(); ++i)
			{
				if (RParams[i]->m_name == m_value.GetParam()->m_name)
				{
					if (RParams[i]->m_color!=0)
					{
						flags |= APL_RE_FILL_BACKGROUND;
						m_background_color = RParams[i]->m_color;
					}
					break;
				}
			}
		}
		m_ReportMgr->m_data->PutAttr(m_inst, m_ReportMgr->a_elem_backgroundcolor, (int)m_background_color);
		m_ReportMgr->m_data->PutAttr(m_inst, m_ReportMgr->a_elem_flags, flags);
		
		m_ReportMgr->PutPoint(m_inst,m_ReportMgr->a_elem_org_pt,m_org_pt);
		m_ReportMgr->PutPoint(m_inst,m_ReportMgr->a_elem_size,m_size);

		m_ReportMgr->m_data->PutAttr(m_inst, m_ReportMgr->a_rect_elem_flags, (int)m_Flags);
	}
	else
	{
		if(m_inst==0) return;
		m_ReportMgr->m_data->GetAttr(m_inst,m_ReportMgr->a_elem_name,m_name);
		m_ReportMgr->m_data->GetAttr(m_inst,m_ReportMgr->a_elem_text_val,m_value.m_inst);
		m_ReportMgr->m_data->GetAttr(m_inst,m_ReportMgr->a_elem_line_width,m_line_width);
		m_ReportMgr->m_data->GetAttr(m_inst,m_ReportMgr->a_elem_fixed,m_fixed);
		m_ReportMgr->m_data->GetAttr(m_inst, m_ReportMgr->a_elem_create_tc, m_bCreateTableContent);
		
		CaplValue aplVal;
		m_ReportMgr->m_data->GetAttr(m_inst,m_ReportMgr->a_elem_dsfrow,aplVal);
		if(aplVal.type==aplINTEGER) aplVal.Get(m_dsfrow); else m_dsfrow=-1;
		m_ReportMgr->m_data->GetAttr(m_inst,m_ReportMgr->a_elem_dsfcol,aplVal);
		if(aplVal.type==aplINTEGER) aplVal.Get(m_dsfcol); else m_dsfcol=-1;
		
		int tmp;
		m_ReportMgr->m_data->GetAttr(m_inst, m_ReportMgr->a_elem_textcolor, tmp);
		m_color = (COLORREF)tmp;
		m_ReportMgr->m_data->GetAttr(m_inst, m_ReportMgr->a_elem_backgroundcolor, tmp);
		m_background_color= (COLORREF)tmp;
		
		int flags = 0;
		m_ReportMgr->m_data->GetAttr(m_inst, m_ReportMgr->a_elem_flags, flags);
		m_bNeedFillBackground = (flags & APL_RE_FILL_BACKGROUND) !=0 ? true : false;
		m_value.CreateFromInst(m_value.m_inst,m_ReportMgr);
		m_ReportMgr->GetPoint(m_inst,m_ReportMgr->a_elem_org_pt,m_org_pt);
		m_ReportMgr->GetPoint(m_inst,m_ReportMgr->a_elem_size,m_size);

		m_ReportMgr->m_data->GetAttr(m_inst, m_ReportMgr->a_rect_elem_flags, flags);
		m_Flags = flags;
	}
}

int CRectReportElement::GetMemSize()
{
	int int_size = sizeof(int);
	int dw_size = sizeof(DWORD);
	int size = 4*int_size;//размер элемента;
	size+=sizeof(TReportElementType);//тип элемента;
	size+=int_size;//толщина линии;
	size+=int_size;//наименование;
	size+=sizeof(COLORREF);//line_color;
	size+=sizeof(UINT);//флаги;
	size+=m_name.GetLength()*sizeof(TCHAR);
	size+=m_value.GetMemSize();
	return size;
}	

void CRectReportElement::CopyToMem(BYTE *pByte, int &ind)
{
	int* pInt = NULL;
	int int_size = sizeof(int);
	TCHAR* pCh = NULL;
	
	pInt = (int*)&pByte[ind];
	*pInt = m_type;//записал тип элемента;
	ind+=sizeof(TReportElementType);
	
	pInt = (int*)&pByte[ind];
	*pInt = m_org_pt.x;//записал x;
	ind+=int_size;
	
	pInt = (int*)&pByte[ind];
	*pInt = m_org_pt.y;//записал y;
	ind+=int_size;
	
	pInt = (int*)&pByte[ind];
	*pInt = m_size.cx;//записал cx;
	ind+=int_size;
	
	pInt = (int*)&pByte[ind];
	*pInt = m_size.cy;//записал cy;
	ind+=int_size;
	
	pInt = (int*)&pByte[ind];
	*pInt = m_line_width;//записал толщину линии;
	ind+=int_size;
	
	COLORREF *pCR = (COLORREF*)&pByte[ind];
	*pCR = m_color;//записал цвет линии;
	ind+=sizeof(COLORREF);

	UINT *pUINT = (UINT*)&pByte[ind];
	*pUINT = m_Flags;//записал флаги;
	ind+=sizeof(UINT);

	pInt = (int*)&pByte[ind];
	*pInt = m_name.GetLength();
	ind+=int_size;
	for(int i=0; i<m_name.GetLength();i++)
	{
		pCh = (TCHAR*)&pByte[ind];
		*pCh = m_name[i];
		ind+=sizeof(TCHAR);
	}

	m_value.CopyToMem(pByte,ind);
}

bool CRectReportElement::LoadDataFromMem(BYTE *pByte, int &ind)
{
	int* pInt = NULL;
	int int_size = sizeof(int);
	TCHAR* pCh = NULL;
	
	pInt = (int*)&pByte[ind];
	m_org_pt.x = *pInt;
	ind+=int_size;
	
	pInt = (int*)&pByte[ind];
	m_org_pt.y = *pInt;
	ind+=int_size;
	
	pInt = (int*)&pByte[ind];
	m_size.cx = *pInt;//записал cx;
	ind+=int_size;
	
	pInt = (int*)&pByte[ind];
	m_size.cy = *pInt;//записал cy;
	ind+=int_size;
	
	pInt = (int*)&pByte[ind];
	m_line_width = *pInt;//записал толщину линии;
	ind+=int_size;
	
	COLORREF *pCR = (COLORREF*)&pByte[ind];
	m_color = *pCR;//записал цвет линии;
	ind+=sizeof(COLORREF);

	UINT *pUINT = (UINT*)&pByte[ind];
	m_Flags = *pUINT;//записал флаги;
	ind+=sizeof(UINT);

	pInt = (int*)&pByte[ind];
	int cnt = *pInt;
	ind+=int_size;
	m_name.Empty();
	for(int i=0; i<cnt;i++)
	{
		pCh = (TCHAR*)&pByte[ind];
		m_name+=*pCh;
		ind+=sizeof(TCHAR);
	}

	if(cnt>0)
		m_value.LoadDataFromMem(pByte,ind);
	
	return true;
}

void CRectReportElement::Delete()
{
	if(m_inst==0) return;
	
	CaplInstance* inst;
	//Удаление точек
	m_ReportMgr->m_data->GetAttr(m_inst, m_ReportMgr->a_elem_org_pt, inst);
	if(inst)
		m_ReportMgr->m_data->DeleteInstance(inst);
	m_ReportMgr->m_data->GetAttr(m_inst, m_ReportMgr->a_elem_size, inst);
	if(inst)
		m_ReportMgr->m_data->DeleteInstance(inst);
	
	//Удаление текста
	//ReportParam
	if(m_value.m_inst)
	{
		m_ReportMgr->m_data->GetAttr(m_value.m_inst, m_ReportMgr->a_val_font, inst);
		if(inst)
			m_ReportMgr->m_data->DeleteInstance(inst);
		m_ReportMgr->m_data->DeleteInstance(m_value.m_inst);
	}
}

CReportElement* CRectReportElement::CreateClon()
{
	CRectReportElement* elem = new CRectReportElement(m_ReportMgr);
	elem->m_org_pt = m_org_pt;
	elem->m_name = m_name;
	elem->m_size = m_size;
	elem->m_type = m_type;
	elem->m_fixed = m_fixed;
	elem->m_line_width = m_line_width;
	elem->m_value = m_value;
	elem->m_color = m_color;
	return elem;
}

bool CRectReportElement::GetElemDSRowCol(int &row, int &col)
{
	if(m_type!=E_RECT) return false;
	
	row = m_dsfrow;
	col = m_dsfcol;
	return (row>-1 && col>-1);
}