#include "stdafx.h"
#include "aplPdf_aux.h"
#include "hlprDll.h"
#include <apl_image.h>
#include <ReportDict.h>
#include <strsafe.h>

std::wstring apl::reportCtr::aux::S2W( const CString& src )
{
	std::wstring dest;
	{ 
		const int size = src.GetLength();
		dest.resize(size); 
		for (std::string::size_type i = 0; i < size; i++) 
		{
			dest[i] = static_cast<unsigned char>(src[i]); 
		}
	}
	return dest;
}

bool apl::reportCtr::aux::GetExePath( CString &buf )
{
	buf.Empty();
	char *tBuf = new char[1024];
	GetModuleFileName(GetModuleHandle(NULL), tBuf, 1024);
	buf+=tBuf;
	delete []tBuf;
	if(buf.Find("\\")>-1)
	{
		buf = buf.Left(buf.ReverseFind('\\')+1);
	}
	else
	{
		buf.Empty();
	}
	//
	return true;
}

CString apl::reportCtr::aux::getExePath()
{
	CString out;
	{
		aux::GetExePath(out);
	}
	return out;
}

void apl::reportCtr::aux::ShowPageSizeParams( const char* prefix, const QPageSize* ps, void(*extractor)(const QPageSize* ps, double& w, double& h) )
{
	double w(-1),h(-1);
	extractor(ps, w, h);
	//
	CString sw,sh;
	sw.Format("%g",w);
	sh.Format("%g",h);
	AfxMessageBox(CString(prefix)+CString("Page(MM): w=")+sw+CString(", h=")+sh);
}

void apl::reportCtr::aux::ShowPageSizePoint( const char* prefix, const QPageSize* ps, void(*extractor)(const QPageSize* ps, int& w, int& h) )
{
	int w(-1),h(-1);
	extractor(ps, w, h);
	//
	CString sw,sh;
	sw.Format("%d",w);
	sh.Format("%d",h);
	//AfxMessageBox(CString("Page(MM): w=")+sw+CString(", h=")+sh);
	AfxMessageBox(CString(prefix)+CString("Page(points): w=")+sw+CString(", h=")+sh);
}

template <typename T, typename U>
void apl::reportCtr::aux::ShowPageSize( const char* prefix, T* t, void(*extractor)(T* t, U& w, U& h) )
{
	U w(-1),h(-1);
	extractor(t, w, h);
	//
	CString sw,sh;
	sw.Format("%f",w);
	sh.Format("%f",h);
	AfxMessageBox(CString(prefix)+CString("w=")+sw+CString(", h=")+sh);
}

CString apl::reportCtr::aux::intToStr( const int& i )
{
	CString out;
	{
		out.Format("%d", i);
	}
	return out;
}

CString apl::reportCtr::aux::DigitToStr( const double& i )
{
	CString out;
	{
		out.Format("%g", i);
	}
	return out;
}

void apl::reportCtr::aux::ShowMargins( const CReportSheet& sheet )
{
	//margin
	const CRect& print_offset = sheet.m_print_offset_rect;
	CString sT =  intToStr(print_offset.top);
	CString sB =  intToStr(print_offset.bottom);
	CString sL =  intToStr(print_offset.left);
	CString sR =  intToStr(print_offset.right);
	AfxMessageBox(CString("offset: top=")+sT+" B="+sB+" L="+sL+" R="+sR);
}

void apl::reportCtr::aux::ShowOptPt( const CReportSheet& sheet )
{
	const CPoint pO = sheet.GetOrgPt();
	CString sX = intToStr(pO.x);
	CString sY = intToStr(pO.y);
	AfxMessageBox(CString("pO: x=")+sX+" y="+sY);
}

void apl::reportCtr::aux::ShowSize( const CReportSheet& sheet )
{
	const CSize& cs = sheet.m_size;
	CString cX = intToStr(cs.cx);
	CString cY = intToStr(cs.cy);
	AfxMessageBox(CString("Size: cX=")+cX+" cY="+cY);
}

void apl::reportCtr::aux::ShowLogFont( const tagLOGFONTA& lgf )
{
	CString out("LogFont=");
	{
		out += "H=";
		out += DigitToStr(lgf.lfHeight);
	}
	{
		out += " lfEscapement=";
		out += intToStr(lgf.lfEscapement);
	}
	{
		out += " lfOrientation=";
		out += intToStr(lgf.lfOrientation);
	}
	AfxMessageBox(out);
	/*
	typedef struct tagLOGFONTA
	{
	LONG      lfHeight;
	LONG      lfWidth;
	LONG      lfEscapement;
	LONG      lfOrientation;
	LONG      lfWeight;
	BYTE      lfItalic;
	BYTE      lfUnderline;
	BYTE      lfStrikeOut;
	BYTE      lfCharSet;
	BYTE      lfOutPrecision;
	BYTE      lfClipPrecision;
	BYTE      lfQuality;
	BYTE      lfPitchAndFamily;
	CHAR      lfFaceName[LF_FACESIZE];
	} LOGFONTA, *PLOGFONTA, NEAR *NPLOGFONTA, FAR *LPLOGFONTA;
	*/
}

void apl::reportCtr::aux::hlpr::drawLine2( const CReportElement& elem, decl::pf_DrawLine F, QPainter * dc )
{
	hlpr::Rect rect = hlpr::calcFromRC(elem.m_org_pt.x, elem.m_org_pt.y,elem.m_size.cx, elem.m_size.cy);
	F(rect.x_,rect.y_,rect.x_+rect.w_,rect.y_+rect.h_, dc);
}

double apl::reportCtr::aux::hlpr::extractTextOrientation( const CTextValue& txt_value )
{
	double degree = 0.0;
	//
	const DWORD& direction = txt_value.m_direction;
	//
	switch (direction)
	{
	case HORIZ_TEXT :
		degree = 0.0;
		break;
	case VERT_TEXT :
		degree = -90;
		break;
	case RHORZ_TEXT :
		degree = 180.0;
		break;
	case RVERT_TEXT :
		degree = 90;
		break;
	}
	return degree;
}

CString apl::reportCtr::aux::hlpr::extractShowableText( const CTextValue& txt_value, const CReportSheet& sheet )
{
	CString text;
	{
		int ParType = -1;
		const CReportParam* par = txt_value.GetParam();
		if(par)
		{
			ParType = par->GetType();
		}
		//
		switch (ParType)
		{
		case NOTYPE_PARAM:
			//text = "NOTYPE_PARAM";
			text = txt_value.GetText();
			break;
		case STRING_PARAM:
			//text = "STRING_PARAM";
			text = txt_value.GetText();
			break;
		case INT_PARAM:
			text = "INT_PARAM";
			break;
		case DATE_PARAM:
			text = "DATE_PARAM";
			break;
		case OBJ_PARAM:
			text = "OBJ_PARAM";
			break;
		case PAGE_PARAM:
			//text = "PAGE_PARAM";
			text = sheet.m_name;
			text.TrimLeft("Лист");
			//text = txt_value.GetText();-empty
			break;
		case PAGE_COUNT:
			text = "PAGE_COUNT";
			text = intToStr(sheet.m_ReportMgr->m_sheets.GetSize());
			break;
		case CURRENT_DATE:
			text = "CURRENT_DATE";
			break;
		case STATIC_PAGE_NUM:
			text = "STATIC_PAGE_NUM";
			break;
		case STATIC_PAGE_COUNT:
			text = "STATIC_PAGE_COUNT";
			break;
		case STATIC_CUR_DATE:
			text = "STATIC_CUR_DATE";
			break;
		case CRC32_PARAM:
			text = "CRC32_PARAM";
			break;
			//default:
		}
		if (text.IsEmpty())
		{
			//text = "[empty]";
		}

	}
	return text;
}

pdfAlignment apl::reportCtr::aux::hlpr::mkAlign( const CTextValue& txt_value )
{
	pdfAlignment Align = aplAlignCenter;
	{
		const DWORD& align = txt_value.m_align;
		//
		if (align & AT_LEFT)
		{
			Align = aplAlignLeft;
		} 
		else if(align & AT_RIGHT)
		{
			Align = aplAlignRight;
		}
	}
	return Align;
}

apl::reportCtr::pdfWriterHandler::pdfWriterHandler( const CString& fullName )
{
	hInst = NULL;
	CFileFind ff;
	BOOL bFound= ff.FindFile(fullName);
	if (!bFound)
	{
		AfxMessageBox(APL_T("Модуль не найден:"+ fullName));
		return;
	}
	hInst = LoadLibrary(fullName);
	if (hInst)
	{
		doResolve();
	}
	else
	{
		LPCTSTR lpszFunction = "LoadLibrary ";
		LPVOID lpMsgBuf;
		LPVOID lpDisplayBuf;
		DWORD dw = GetLastError();

		FormatMessage(
			FORMAT_MESSAGE_ALLOCATE_BUFFER |
			FORMAT_MESSAGE_FROM_SYSTEM |
			FORMAT_MESSAGE_IGNORE_INSERTS,
			NULL,
			dw,
			MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
			(LPTSTR)&lpMsgBuf,
			0, NULL);

		// Display the error message and exit the process

		lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
			(lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR));
		StringCchPrintf((LPTSTR)lpDisplayBuf,
			LocalSize(lpDisplayBuf) / sizeof(TCHAR),
			TEXT("%s failed with error %d: %s"),
			lpszFunction, dw, lpMsgBuf);
		MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);
		AfxMessageBox(CString("Не удалось загрузить модуль печати:")+fullName);
	}
}

apl::reportCtr::pdfWriterHandler::~pdfWriterHandler()
{
	if (hInst)
	{
		FreeLibrary(hInst);
	}
}

void apl::reportCtr::pdfWriterHandler::doResolve()
{
	using namespace aux;
	using namespace apl::hlprDll;
	//
	crtPageDef = resolveF<pf_crtPageSizeDef>("crtPageSizeDef", hInst);
	getPageSizePoint = resolveF<pf_getPageSizePoint>("getPageSizePoint", hInst);
	getPageSizeMM = resolveF<pf_getPageSizeMM>("getPageSizeMM", hInst);
	crtPageSize = resolveF<pf_crtPageSize>("crtPageSize", hInst);
	crtPageSizeMM = resolveF<pf_crtPageSizeMM>("crtPageSizeMM", hInst);
	//
	crtWriterDef = resolveF<pf_crtPdfWriterDef>("crtPdfWriterDef", hInst);
	crtPdfWriter = resolveF<pf_crtPdfWriter>("crtPdfWriter", hInst);
	getCurrPageSizeMM = resolveF<pf_getCurrPageSizeMM>("getCurrPageSizeMM", hInst);
	addPageDef = resolveF<pf_addPageDef>("addPageDef", hInst);
	addPage = resolveF<pf_addPage>("addPage", hInst);
	crtRect = resolveF<pf_crtRect>("crtRect", hInst);
	crtRectDef = resolveF<pf_crtRectDef>("crtRectDef", hInst);
	crtPainter = resolveF<pf_crtPainter>("crtPainter", hInst);
	//
	p_testPdf1 = resolveF<pf_testPdf1>("testPdf1", hInst);
	getCurrColor = resolveF<pf_getCurrColor>("getCurrColor", hInst);
	getColorDescr = resolveF<pf_getColorDescr>("getColorDescr", hInst);
	//
	crtColor = resolveF<pf_crtColor>("crtColor", hInst);
	crtColorByName = resolveF<pf_crtColorByName>("crtColorByName", hInst);
	setCurrColor = resolveF<pf_setCurrColor>("setCurrColor", hInst);
	//
	drawTextF = resolveF<pf_DrawTextF>("addTextF", hInst);
	drawText = resolveF<pf_DrawText>("addText", hInst);
	endDraw = resolveF<pf_endDraw>("endDraw", hInst);
	setPen = resolveF<pf_setPen>("setPen", hInst);
	crtPen = resolveF<pf_crtPen>("crtPen", hInst);
	crtPenDef = resolveF<pf_crtPenDef>("crtPenDef", hInst);
	setPenColor = resolveF<pf_setPenColor>("setPenColor", hInst);
	crtFont = resolveF<pf_crtFont>("crtFont", hInst);
	setFontSizeF = resolveF<pf_setFontSizeF>("setFontSizeF", hInst);
	setFontPixelSize= resolveF<pf_setFontPixelSize>("setFontPixelSize", hInst);
	setFont = resolveF<pf_setFont>("setFont", hInst);
	crtFontByName = resolveF<pf_crtFontByName>("crtFontByName", hInst);
	drawLine = resolveF<pf_DrawLine>("DrawLine", hInst);
	//
	setPenWidthF = resolveF<pf_setPenWidthF>("setPenWidthF", hInst);
	setPenWidth = resolveF<pf_setPenWidth>("setPenWidth", hInst);
	//
	drawTextRotate = resolveF<pf_addRotateText>("addRotateText", hInst);
	drawRect = resolveF<pf_DrawRect>("DrawRect", hInst);
	drawRectText = resolveF<pf_DrawRectText>("DrawRectText", hInst);
	DrawRectTextRotate = resolveF<pf_DrawRectTextRotate>("DrawRectTextRotate", hInst);
	DrawImage = resolveF<pf_DrawImage>("DrawImage", hInst);
	deleteFont = resolveF<pf_deleteFont>("deleteFont", hInst);
	deletePen = resolveF<pf_deletePen>("deletePen", hInst);
	deleteColor = resolveF<pf_deleteColor>("deleteColor", hInst);
	deletePainter = resolveF<pf_deletePainter>("deletePainter", hInst);
	deletePageSize = resolveF<pf_deletePageSize>("deletePageSize", hInst);
	deletePdfWriter = resolveF<pf_deletePdfWriter>("deletePdfWriter", hInst);
	deleteRect = resolveF<pf_deleteRect>("deleteRect", hInst);;
}

bool apl::reportCtr::pdfWriterHandler::isReady() const
{
	bool predResolved = crtPageDef && getPageSizePoint && getPageSizeMM && crtPageSize && crtPageSizeMM
		&& crtWriterDef && crtPdfWriter && getCurrPageSizeMM 
		&& addPageDef && addPage&& crtPainter && crtRect && crtRectDef
		&& p_testPdf1 && getCurrColor && getColorDescr
		&& crtColor && crtColorByName && setCurrColor && drawTextF && drawText&& endDraw
		&& setPen && crtPen && crtPenDef&& setPenColor && crtFont 
		&& setFontSizeF && setFontPixelSize
		&& setFont && crtFontByName 
		&& drawLine && setPenWidthF && setPenWidth && drawTextRotate
		&& drawRect && drawRectText && DrawRectTextRotate && DrawImage
		&& deleteFont && deletePen && deleteColor && deletePainter && deletePageSize && deletePdfWriter && deleteRect;
	//
	return predResolved;
}

QColor* apl::reportCtr::wrDll::getColor( const COLORREF& cRef, pdfWriterHandler& H )
{
	int r = GetRValue(cRef);
	int g = GetGValue(cRef);
	int b = GetBValue(cRef);
	//
	QColor* clr = H.crtColor(r,g,b);
	return clr;
}

QColor* apl::reportCtr::wrDll::getColorLine( const CReportElement& elem, pdfWriterHandler& H )
{
	const COLORREF& cRef = elem.m_color;
	//
	QColor* clr = getColor(cRef, H);
	return clr;
}

void apl::reportCtr::wrDll::setPen_v2( pdfWriterHandler& H, const CReportElement& elem, QPainter* dc )
{
	PenGuard pg(H.crtPenDef(), H);
	//
	{
		ColorGuard g(getColorLine(elem, H), H);
		H.setPenColor(g(), pg());
	}
	{
		int w0 = elem.m_line_width;
		//AfxMessageBox(CString("m_line_width=")+apl::reportCtr::aux::intToStr(w));
		//H.setPenWidthF(w, pg());
		H.setPenWidth(w0, pg());
	}
	//
	H.setPen(pg(), dc);
}

QFont * apl::reportCtr::wrDll::mkFontForText( const CTextValue& txt_value, pdfWriterHandler& H )
{
	QFont * font;
	{
		const LOGFONT& lf = txt_value.m_font;
		//
		bool italic = lf.lfItalic;
		bool bold = false;
		{
			const long& w = lf.lfWeight;
			if (w>=FW_BOLD)
			{
				bold = true;
			}
		}
		const char* fName = lf.lfFaceName;
		//
		font = H.crtFont(fName, FontDescr(italic, bold));
		if (true)
		{
			static const double& mult = apl::auxPdfWriter::magic::FontSize::getMult();
			H.setFontSizeF(lf.lfHeight*mult, font);
		}
		else
		{
		}

	}
	return font;
}

void apl::reportCtr::wrDll::drawElement( const CReportElement* p_elem, CReportSheet& sheet, pdfWriterHandler& H, QPainter *dc )
{
	if (p_elem==NULL)
	{
		return;
	}
	{
		const CReportElement& elem = *p_elem;
		const TReportElementType& type = elem.GetType();
		//
		if(type==E_LINE)
		{
			setPen_v2(H, elem, dc);
			apl::reportCtr::aux::hlpr::drawLine2(elem, H.drawLine, dc);
		}
		//else if (type==E_RECT)
		//{
		//	const CRectReportElement *p = dynamic_cast<const CRectReportElement*>(p_elem);
		//	if(p)
		//	{
		//		apl::reportCtr::wrDll::rect::draw(*p, elem, H, sheet, dc);
		//	}
		//} 
	}
}

void apl::reportCtr::dbg::tst_Color( pdfWriterHandler& H )
{
	using namespace apl::reportCtr::wrDll;
	ColorGuard cg(H.getCurrColor(), H);
	char* descrColor = H.getColorDescr(cg());
	AfxMessageBox(CString("Descr(defColor)=")+descrColor);
	//
	ColorGuard cg1(H.crtColor(255,255,0), H);
	H.setCurrColor(cg1());
	{
		char* descrColor = H.getColorDescr(H.getCurrColor());
		AfxMessageBox(CString("Descr(defColor)=")+descrColor);
	}
	{
		ColorGuard cg2(H.crtColorByName("red"), H);
		char* descrColor = H.getColorDescr(cg2());
		AfxMessageBox(CString("Descr(red)=")+descrColor);
	}
}

void apl::reportCtr::dbg::tst_qpdf2( pdfWriterHandler& H )
{
	{
		//QPageSize* psA3 = crtPageSize(pageSize::A3);
		apl::reportCtr::wrDll::PdfWriterGuard wg(H.crtWriterDef("d://qpdf-2.pdf"), H);
		//QPdfWriter* writer = H.crtWriterDef("d://qpdf-2.pdf");
		//QPdfWriter* writer = crtPdfWriter("d://qpdf-2.pdf", psA3);
		if(!true)
		{
			aux::ShowPageSize<QPdfWriter, double>("CurrentPage mm: ", wg(), H.getCurrPageSizeMM);
		}
		apl::reportCtr::wrDll::RectGuard rg(H.crtRectDef(210, 297), H);
		//QRect * rect = H.crtRectDef(210, 297);
		QPainter * dc = NULL;
		//bool flag = H.crtPainter(wg(), rg(), dc);
		dc = H.crtPainter(wg(), rg());
		{
			{
				using namespace apl::reportCtr::wrDll;
				{
					ColorGuard cg(H.crtColorByName("red"), H);
					PenGuard pg(H.crtPen(cg()), H);
					H.setPen(pg(), dc);
				}
				{
					FontGuard fg(H.crtFont("Times", FontDescr(true, false)), H);
					//QFont *f = H.CrtFont("Times", FontDescr(true, false));
					H.setFont(fg(), dc);
				}
				H.drawTextF(0,0,"THIS IS MY RED PDF TEXT Русские буквы.. (italic=true, bold=false)", dc);
				H.drawLine(0,0,100,200, dc);
			}
			using namespace apl::reportCtr::wrDll;
			{
				ColorGuard cg(H.crtColorByName("green"), H);
				PenGuard pg(H.crtPen(cg()), H);
				H.setPenWidthF(30, pg());
				H.setPen(pg(), dc);
				//
				FontGuard fg(H.crtFont("Helvetica [Cronyx]", FontDescr(true, true)), H);
				//QFont *f = H.CrtFont("Helvetica [Cronyx]", FontDescr(true, true));
				H.setFont(fg(), dc);
				H.drawTextF(0,500,"THIS IS MY GREEN PDF TEXT..(italic=true, bold=true)", dc);
				H.drawLine(0,0,100,600, dc);
				H.setPenWidth(60, pg());
				H.setPen(pg(), dc);
				H.drawLine(100,600,100,1100, dc);

			}
			{
				ColorGuard cg(H.crtColorByName("blue"), H);
				PenGuard pg(H.crtPen(cg()), H);
				H.setPen(pg(), dc);
				//
				using namespace apl::reportCtr::wrDll;
				FontGuard fg(H.crtFontByName("Courier"), H);
				H.setFont(fg(), dc);
				H.drawTextF(0,1000,"0,1000 float THIS IS MY BLUE PDF TEXT..", dc);
				//p_DrawTextF(100,1100,"100,1100 float THIS IS MY BLUE PDF TEXT..", dc);
				int x1 = 100;
				int y1 = 1100;
				int x2 = x1*2;
				int y2 = y1*2;
				H.drawText(x1,y1,"100,1100 (int)THIS IS MY BLUE PDF TEXT..", dc);
				H.drawText(x2,1100*2,"100*2,1100*2 (int)THIS IS MY BLUE PDF TEXT..", dc);
			}
			{
				H.drawTextRotate(45, 500, 500, "rotate", dc);
				H.drawRect(500, 500, 300, 100, dc );
			}
		}
		{
			//QPageSize* ps = crtPageSizeMM(297,210);
			bool res = H.addPageDef(wg());
			//bool res = addPage(writer, ps);
			H.drawTextRotate(45, 500, 500, "rotate", dc);
		}
		H.endDraw(dc);
	}
}

void apl::reportCtr::dbg::tst_3( pdfWriterHandler& H )
{
	if (true)
	{
		//QPageSize* psA3 = crtPageSizeMM(297,420);
		//apl::reportCtr::aux::ShowPageSizeParams("A3 by MM: ", psA3, getPageSizeMM);
	}
	if (false)
	{
		apl::reportCtr::wrDll::PageSizeGuard g( H.crtPageSize(pageSize::A3), H );
		apl::reportCtr::aux::ShowPageSizeParams("A3 by Name: ", g(), H.getPageSizeMM);
	}
	if(!true)
	{
		apl::reportCtr::wrDll::PageSizeGuard psg( H.crtPageDef(), H );
		apl::reportCtr::aux::ShowPageSizePoint("defPAge point size: ", psg(), H.getPageSizePoint);
		apl::reportCtr::aux::ShowPageSizeParams("defPage mm size: ", psg(), H.getPageSizeMM);
	}
	if (false)
	{
		apl::reportCtr::dbg::tst_qpdf2(H);
		H.p_testPdf1("d://qpdf.pdf");
		apl::reportCtr::dbg::tst_Color(H);
	}
}

bool apl::reportCtr::wrDll::rect::predShowBorder( const CRectReportElement& rectElem, const CTextValue& txt_value )
{
	bool out = true;
	{
		out = (rectElem.m_line_width>0) && (txt_value.m_border_visible);
	}
	return out;
}

void apl::reportCtr::wrDll::rect::drawImage( const CPictureElement& p, pdfWriterHandler& H, const CReportSheet& sheet, QPainter *dc )
{
	using namespace apl::reportCtr::aux;
	hlpr::Rect rect = hlpr::calcFromRC(p.m_org_pt.x, p.m_org_pt.y, p.m_size.cx, p.m_size.cy);

	char lpszTempPath[MAX_PATH] = { 0 };
	if (!GetTempPath(MAX_PATH, lpszTempPath))
		return;

	char lpszFilePath[MAX_PATH] = { 0 };
	if(!GetTempFileName(lpszTempPath, NULL, 0, lpszFilePath))
		return;

	CString filePath = lpszFilePath;		
	p.m_image->Save(filePath, p.m_image->GetType());

	H.DrawImage(rect.x_, rect.y_, rect.w_, rect.h_, filePath,  dc);
	::DeleteFile(filePath);		
}

void apl::reportCtr::wrDll::rect::draw( const CRectReportElement& p, const CReportElement& elem, pdfWriterHandler& H, const CReportSheet& sheet, QPainter *dc )
{
	using namespace apl::reportCtr::aux;
	//
	hlpr::Rect rect = hlpr::calcFromRC(elem.m_org_pt.x, elem.m_org_pt.y,elem.m_size.cx, elem.m_size.cy);
	const CTextValue& txt_value = p.m_value;
	setPen_v2(H, elem, dc);
	{//border
		bool showBorder = rect::predShowBorder(p, txt_value);
		if (showBorder)
		{
			H.drawRect(rect.x_, rect.y_, rect.w_, rect.h_, dc);
		}
	}
	{
		const COLORREF& cRef = txt_value.m_color;
		ColorGuard cg(getColor(cRef, H), H);
		PenGuard pg(H.crtPenDef(), H);
		H.setPenColor(cg(), pg());
		H.setPen(pg(), dc);
	}
	{
		using namespace apl::reportCtr::wrDll;
		FontGuard fg(mkFontForText(txt_value, H), H);
		H.setFont(fg(), dc);
	}
	CString text = hlpr::extractShowableText(txt_value, sheet);
	//
	double x = rect.x_;
	double y = rect.y_;
	double w = rect.w_;
	double h = rect.h_;
	//
	//H.drawRect(x, y, w, h, dc);
	{//correction
     //H.drawRect(x, y, w, h, dc);
	}
	pdfAlignment Align = hlpr::mkAlign(txt_value);
	double degree = apl::reportCtr::aux::hlpr::extractTextOrientation( txt_value );
	if (true)
	{
		H.DrawRectTextRotate(degree, x, y, w, h, text, Align, dc);
	} 
	else
	{
		H.drawTextRotate(degree, x, y, text, dc);
	}
}

apl::reportCtr::pdfWriterHandler apl::auxPdfWriter::hlp::mkHandler( const char* fullName )
{
	apl::reportCtr::pdfWriterHandler H(fullName);
	return H;
}

apl::reportCtr::pdfWriterHandler* apl::auxPdfWriter::hlp::mkPHandler( const char* fullName )
{
	reportCtr::pdfWriterHandler *H = new reportCtr::pdfWriterHandler(fullName);
	return H;
}

apl::reportCtr::pdfWriterHandler* apl::auxPdfWriter::hlp::mkPHandlerDef()
{
	static const char* defFullName = "pdfWriter.dll";
	//
	CString path = apl::reportCtr::aux::getExePath();
	CString fullPath = _T(path+"pdfWriter.dll");
	//AfxMessageBox(CString("[apl::auxPdfWriter::hlp::mkPHandlerDef] fullPath=")+fullPath);
	//
	return apl::auxPdfWriter::hlp::mkPHandler(fullPath);
}

void apl::auxPdfWriter::hlp::makePdfWithMgr( const CaplReportMgr& repMgr, reportCtr::pdfWriterHandler& H, const char* fullPdfName, int debugLevel )
{
	//AfxMessageBox("apl::auxPdfWriter::hlp::makePdfWithMgr");
	using namespace apl::reportCtr::aux;
	using namespace reportCtr::wrDll;
	//
	const CReportSheet& firstSheet = *repMgr.m_sheets[0];
	const CSize& size = firstSheet.m_size;
	apl::reportCtr::wrDll::RectGuard rg(H.crtRectDef(size.cx, size.cy), H);
	//QRect * qRectPainter = H.crtRectDef(size.cx, size.cy);
	apl::reportCtr::wrDll::PageSizeGuard psg( H.crtPageSizeMM(size.cx/10.0, size.cy/10.0), H );
	//QPageSize * qPageSizeWriter = H.crtPageSizeMM(size.cx/10.0, size.cy/10.0);
	//QPdfWriter* writer = H.crtWriterDef("d://_rep.pdf");
	//QPdfWriter* writer = H.crtPdfWriter(fullPdfName, psg());
	apl::reportCtr::wrDll::PdfWriterGuard wg(H.crtPdfWriter(fullPdfName, psg()), H);
	//
	//QPainter * dc = H.crtPainter(writer, qRectPainter);
	QPainter * dc = NULL;
	//bool flag = H.crtPainter(wg(), rg(), dc);
	dc = H.crtPainter(wg(), rg());
	//
	PainterGuard dcg(dc, H);
	//
	int cnt_sheets = repMgr.m_sheets.GetSize();
	for(int i=0; i<cnt_sheets; ++i)
	{
		if(i!=0)
		{
			bool res = H.addPageDef(wg());
		}
		SheetGuard shg(*repMgr.m_sheets[i]);
		//
		if(debugLevel>0)//print name
		{
			CString name = shg().m_name;
			H.drawTextF(100, 100, name, dcg());
		}
		{
			const RE_Array& elements = shg().m_els;
			const int size = elements.GetSize();
			// two loops:
			for (int j=0; j<size; ++j)
			{
				const CReportElement* p_elem = elements[j];
				if (p_elem==NULL)
				{
					return;
				}
				//
				const CReportElement& elem = *p_elem;
				const TReportElementType& type = elem.GetType();
				//
				if (type==E_RECT)
				{
					const CRectReportElement *p = dynamic_cast<const CRectReportElement*>(p_elem);
					if(p)
					{
						apl::reportCtr::wrDll::rect::draw(*p, elem, H, shg(), dc);
					}
				}
				else if(type == E_PICTURE)
				{
					const CPictureElement *p = dynamic_cast<const CPictureElement*>(p_elem);
					if(p)
					{
						apl::reportCtr::wrDll::rect::drawImage(*p, H, shg(), dc);
					}
				}
				//
				//drawElement(p_elem, shg(), H, dcg());
			}

			for (int j=0; j<size; ++j)
			{
				const CReportElement* p_elem = elements[j];
				drawElement(p_elem, shg(), H, dcg());
			}
		}
	}
}

int apl::auxPdfWriter::hlp::genRep( const char* fullDotName, const char* fullSourceName, const char* fullOutputReportName )
{
	int res = 0;//ok
	{
		CaplReportMgr mgr;
		bool predLoad = mgr.m_data_source.LoadFromFile(CString(fullSourceName));
		if (predLoad)
		{
			CString stub_m_ParamsName = "";
			bool bRes = GenerateReport(&mgr, fullDotName, stub_m_ParamsName, fullOutputReportName);
			if (bRes)
			{
				//AfxMessageBox(CString("GenerateReport is correct"));
			} 
			else
			{
				AfxMessageBox(CString("WRONG GenerateReport is NOT correct"));
				return 3;
			}
		} 
		else
		{
			AfxMessageBox(CString("WRONG! LoadFromFile is NOT correct"));
			return 2;;
		}
	}
	return res;
}

int apl::auxPdfWriter::hlp::mkPdf( const char* fullReportName, reportCtr::pdfWriterHandler& H, const char* fullPdfName, int debugLevel )
{
	//AfxMessageBox(CString("fullReportName=")+fullReportName);
	{
		CaplReportMgr mgr;
		CaplStepDataWithFile m_data;
		//
		struct hlpr2
		{
			static CString mkPictPath()
			{
				CString out = "";
				{
					char buf[1024]="";
					DWORD len = 1024;
					GetPrivateProfileString("Paths", "Dictionary", "", buf, len, "AplTransport.ini");
					out = buf;
					if(out=="")
					{
						apl::reportCtr::aux::GetExePath(out);
					}
					if(out[out.GetLength()-1]!='\\')
					{
						out+="\\";
					}
				}
				return out;
			}
			static CString mkDictDir()
			{
				CString out;
				{
					CString t_str;
					apl::reportCtr::aux::GetExePath(t_str);
					t_str = t_str.Left(t_str.ReverseFind('\\'));
					out = t_str;
				}
				return out;
			}
			static bool initStepData(CaplStepDataWithFile& m_data)
			{
				CString t_str;
				CString m_dict_path = hlpr2::mkPictPath();

				static const char* shema_filename = "report_constructor";
				CString m_cur_dict_dir = hlpr2::mkDictDir();
				if(!m_data.LoadDictionary(m_dict_path+shema_filename))
				{
					int err = m_data.GetLastError();
					if(err==APLAPIERR_DICT_FILE_NOT_OPEN)
					{
						t_str.Format("Ошибка загрузки словаря %s\\%s.dict",m_cur_dict_dir,shema_filename);
						AfxMessageBox(t_str);
						return FALSE;
					}
					else
					{
						AfxMessageBox(m_data.GetLastErrorDescription());
						return FALSE;
					}
				}
				return true;
			}
		};
		//
		{
			mgr.Init();
			hlpr2::initStepData(m_data);
			mgr.Attach(&m_data, NULL);
			bool res = mgr.LoadFromFile(fullReportName);
			//
			if (!res)
			{
				AfxMessageBox(CString("LoadFromFile is NOT correct"));
			}
		}
		{
			const int& s = mgr.m_sheets.GetSize();
			if (s==0)
			{
				AfxMessageBox(CString("WRONG! Sheet isnot loaded, count =0"));
			}
			//
			const CReportSheet& firstSheet = *mgr.m_sheets[0];
			const CSize& size = firstSheet.m_size;
			apl::auxPdfWriter::hlp::makePdfWithMgr(mgr, H, fullPdfName, debugLevel);
		}
	}
	return -1;
}

bool apl::auxPdfWriter::hlp::splitRep( const char* rep1, const char* rep2, const char* repRes )
{
	bool res = true;
	{
		CStringArray arr;
		arr.Add(rep1);
		arr.Add(rep2);
		return UnificationArrayReports(repRes, &arr);
	}
	return true;
}

apl::reportCtr::aux::SheetGuard::SheetGuard( CReportSheet& sheet ) :sheet_(sheet), needDoFree_(false)
{
	if (!sheet_.IsLoaded())
	{
		needDoFree_ = true;
		sheet_.LoadElementsFromFile();
	}
}

apl::reportCtr::aux::SheetGuard::~SheetGuard()
{
	if (sheet_.IsLoaded())
	{
		if (needDoFree_)
		{
			sheet_.FreeElements();
		}
	}
}
