// ReportDict.h: interface for the CaplReportMgr class.
//
//////////////////////////////////////////////////////////////////////
//#include "ReportConstructorDoc.h"
#if !defined(AFX_REPORTDICT_H__D01922C7_39B2_4D02_A7DF_983FA844EF89__INCLUDED_)
#define AFX_REPORTDICT_H__D01922C7_39B2_4D02_A7DF_983FA844EF89__INCLUDED_

#ifdef APL_REPORTMGR_IMPL
#define CLASS_DECL_APL_REPORTMGR	_declspec(dllexport)
#else
#define CLASS_DECL_APL_REPORTMGR	_declspec(dllimport)
#ifdef _DEBUG
#ifdef UNICODE
#pragma comment (lib,"aplReportMgr_ud.lib")
#else
#pragma comment (lib,"aplReportMgr_d.lib")
#endif
#else
#ifdef UNICODE
#pragma comment (lib,"aplReportMgr_u.lib")
#else
#pragma comment (lib,"aplReportMgr.lib")
#endif
#endif
#endif

#include <afxtempl.h>
//#include "apl_api.h"
#include <aplStepDataWithFile.h>
#include <aplNetStepData.h>
#include <math.h>
#include <apl_gui.h>
#include <gdiplus.h>

#include <set>
#include <vector>
#include <string>

#ifndef APL_REPORTMGR_IMPL
#ifdef _DEBUG
#ifdef UNICODE
#pragma comment (lib,"aplReportMgr_ud.lib")
#else
#pragma comment (lib,"aplReportMgr_d.lib")
#endif
#else
#ifdef UNICODE
#pragma comment (lib,"aplReportMgr_u.lib")
#else
#pragma comment (lib,"aplReportMgr.lib")
#endif
#endif
#endif

#define APL_LEVEL_CLIPBOARD_DATA _T("APL_LEVEL_CLIPBOARD_DATA")

class CReportElement;
class CaplReportMgr;
class CReportParam;
class CReportSection;
class CRParamsArray;
class CaplImage;
class CTableRow;
class CSectionArray;
class CTableContent;
class CGroupCol;
class CGroupColArray;
class CConditionArray;

#define Report_AdditionalCoordinateValString _T("$%@Lege~!@")
#define Report_AdditionalLineGistogramString _T("$%@Line~!@")

//Модифицирует текст для того, чтобы он корректно выводился в качестве дополнительной подписи под столбцом гистограммы
inline CString Report_ConvertStringToAdditionalCoordinateVal(CString str)
{
	CString ret = Report_AdditionalCoordinateValString;
	ret += str;
	return ret;
}

//Возвращает строку, которая при построении гистограммы будет интерпретироваться как необходимость
//вывести дополнительную вертикальную полосу
inline CString Report_GetStringOfAdditionalLineGistogram()
{
	return Report_AdditionalLineGistogramString;
}

struct Timeline_values_struct
{
	double begin;
	bool is_value_begin;
	double value_begin;
	double end;
	bool is_value_end;
	double value_end;
	double type;
	Timeline_values_struct()
	{
		begin = value_begin = end = value_end = type = 0.0;
		is_value_begin = is_value_end = false;
	}
};

inline bool Report_ConvertStrAggr2Array(const CString& str, CStringArray& array, CStringArray& AdditionalCoordinateArray, bool& bAdditionalLine, bool bTrim = true)
{
	array.RemoveAll();
	CString buf=str;
	buf.Replace(_T(" "),_T(""));
	if (buf.IsEmpty()) return false;
	buf = str;

	//обработка ситуации, при которой запятой в конце списка нет 
	int cnt=buf.GetLength();
	if(cnt>0 && buf[cnt-1]!=_T(';'))
		buf+=_T(";");

	int sInd = 0, ind;
	CString sVal;
	while ( (ind = buf.Find(_T(';'), sInd)) != -1)
	{
		sVal = buf.Mid(sInd, ind - sInd);
		//sVal.Trim();
		if (sVal.IsEmpty())
			break;

		array.Add(static_cast<LPCTSTR>(sVal));

		sInd = ind + 1;
	}

	//ищем дополнительные подписи под столбцом гистограммы
	AdditionalCoordinateArray.RemoveAll();
	sInd = 0;
	while(sInd < array.GetSize())
	{
		ind = array[sInd].Find(Report_AdditionalCoordinateValString);
		if(ind != -1)
		{
			buf = array[sInd].Right(array[sInd].GetLength()-_strlen(Report_AdditionalCoordinateValString)-ind);
			AdditionalCoordinateArray.Add(buf.TrimLeft());
			array.RemoveAt(sInd);
		}
		else
			sInd++;
	}

	//ищем признак необходимости вывести дополнительную вертикальную полосу
	bAdditionalLine = false;
	sInd = 0;
	while(sInd < array.GetSize())
	{
		ind = array[sInd].Find(Report_AdditionalLineGistogramString);
		if(ind != -1)
		{
			array.RemoveAt(sInd);
			bAdditionalLine = true;
		}
		else
			sInd++;
	}

	if(bTrim)
	{
		sInd = 0;
		while(sInd < array.GetSize())
		{
			buf = array[sInd];
			buf.Replace(_T(" "), _T(""));
			if (buf.IsEmpty())
				array.RemoveAt(sInd);
			else
			{
				array[sInd] = buf;
				sInd++;
			}
		}
	}

	return true;
}

inline bool Report_ConvertAggr2TimeLine(CStringArray& array, Timeline_values_struct& val)
{
	if(array.GetSize()>0)
		val.type = __atof(array[0]);
	else
		val.type = 0.0;
	if(array.GetSize()>1)
	{
		COleDateTime dt;
		aplString2Date(array[1], dt);
		val.begin = dt.m_dt;
	}
	else
		val.begin = 0.0;
	if(array.GetSize()>2)
	{
		COleDateTime dt;
		aplString2Date(array[2], dt);
		val.end = dt.m_dt;
	}
	else
		val.end = 0.0;
	if(array.GetSize()>3)
	{
		val.is_value_begin = true;
		val.value_begin = __atof(array[3]);
	}
	else
	{
		val.is_value_begin = false;
		val.value_begin = 0.0;
	}
	if(array.GetSize()>4)
	{
		val.is_value_end = true;
		val.value_end = __atof(array[4]);
	}
	else
	{
		val.is_value_end = false;
		val.value_end = 0.0;
	}

	return true;
}

inline bool Report_GetMinMaxTime(CArray<Timeline_values_struct>& values, double& min_time, double& max_time)
{
	for(int i=0; i<values.GetSize(); i++)
	{
		if(i==0)
		{
			min_time = values[i].begin;
			max_time = values[i].end;
		}
		else
		{
			if(min_time>values[i].begin)
				min_time = values[i].begin;
			if(max_time<values[i].end)
				max_time = values[i].end;
		}
	}

	return true;
}

bool Report_SortTimeLine(CArray<Timeline_values_struct>& values, bool bEnd = false); // сортировка по началу (bEnd==false) или по концу (bEnd==true) интервала

typedef struct 
{
	UINT	m_Flags;
	int		col_num;
	bool	bSortAsString;
	int		direction;
} TSortParam;

typedef CArray<CReportElement*, CReportElement*> RE_Array;
typedef CArray<CPoint, CPoint> PointArray; // массив точек
typedef CArray<CTableRow*, CTableRow*> TR_Array;
typedef CArray<TSortParam, TSortParam> ISortArray;


typedef std::vector<CGroupCol*> TGroupColVector;

__declspec (dllexport) CDC *aplRCGetPrinterDC();
__declspec (dllexport) bool aplRCCreatePrinterDC();
__declspec (dllexport) bool ShowElemProperties(RE_Array* m_eles, int mode);
__declspec (dllexport) bool ShowSimplDialog(TCHAR* title, CString &str, int mode = 0);
__declspec (dllexport) CString GetAttrEx(CaplInstance* inst, TCHAR* attr, CaplNetStepData* data);
//
#define APL_SPEC_EXPORT __declspec (dllexport)
APL_SPEC_EXPORT bool GenerateReport(CaplReportMgr* ReportMgr, CRParamsArray *RParams, LPCTSTR DotName, LPCTSTR OutFileName, CaplNetStepData* net_data = NULL, BOOL bWriteDataSource = FALSE, int *piTotalPages = NULL, bool bShowAutoTemplateDlg = true);
//
namespace Apl
{
namespace aux
{
	typedef _std_string tStr;
	typedef std::pair<tStr, tStr> tPairStr;
	typedef std::vector<tPairStr> tVecPairStr;
	typedef std::vector<tStr> tVecStr;
}
}
//
extern "C" APL_SPEC_EXPORT CRParamsArray* mkParamsArray(const Apl::aux::tVecPairStr& vec);
extern "C" APL_SPEC_EXPORT void freeParamsArray(CRParamsArray* p);
extern "C" APL_SPEC_EXPORT CaplReportMgr* mkDict( const std::vector<std::pair<_std_string, int>>& vecHeader, const Apl::aux::tVecStr& vecTableRow );
extern "C" APL_SPEC_EXPORT void addRowToDict( const Apl::aux::tVecStr& vecTableRow, CaplReportMgr* dict );
extern "C" APL_SPEC_EXPORT void freeDict(CaplReportMgr* p);
//
extern "C" APL_SPEC_EXPORT bool GenerateReport_T1(CaplReportMgr* ReportMgr, CRParamsArray *RParams, const _std_string& DotName, const _std_string& OutFileName, CaplNetStepData* net_data = NULL, bool bWriteDataSource = FALSE, int *piTotalPages = NULL, bool bShowAutoTemplateDlg = true);
extern "C" APL_SPEC_EXPORT bool GeneratePdf(CaplReportMgr* ReportMgr, const _std_string& aplRepFile);
//
__declspec (dllexport) bool GenerateReport(CaplReportMgr* ReportMgr, LPCTSTR DotName, LPCTSTR ParamName, LPCTSTR OutFileName, CaplNetStepData* net_data = NULL, BOOL bWriteDataSource = FALSE, int *piTotalPages = NULL);
__declspec (dllexport) bool GenerateReport(CaplReportMgr* ReportMgr, LPCTSTR DotName, LPCTSTR OutFileName, CaplNetStepData* net_data = NULL, BOOL bWriteDataSource = FALSE, int *piTotalPages = NULL, bool bShowAutoTemplateDlg = true);
__declspec (dllexport) bool GetSheetTextValues(LPCTSTR reportPath, int nSheetNum, CStringArray &textItems);
__declspec (dllexport) bool SaveBitmapAs(HBITMAP hBM, LPCTSTR FileName, int DPI = -1, BOOL bColor = TRUE, DWORD CompressionMode=0);
__declspec(dllexport) bool UnificationTIFF(CStringArray *strs, CString sFileName);
__declspec (dllexport) CString GetAsString(CaplValue* val);
__declspec (dllexport) bool UnificationReports(const CString& filename1, const CString& filename2);
__declspec (dllexport) bool UnificationArrayReports(const CString& filename1, const CStringArray *filenames, CProgressCtrl* progress = NULL, const CStringArray* object_names = NULL);
__declspec (dllexport) bool SaveToFile(CaplReportMgr* mgr, LPCTSTR outFileName = NULL);
__declspec(dllexport) bool CalcCenterRect(const CRect OutRect, CRect &ItemRect);
__declspec (dllexport) bool ReadDots(LPCTSTR FileName, LPCTSTR SecName, CStringArray* res);

//Обновление значений параметров в отчете
__declspec(dllexport) bool UpdateReportParametrs(CaplReportMgr* pReportMgr);
__declspec(dllexport) bool UpdateReportParametrs(CaplReportMgr* pReportMgr, LPCTSTR lpszParamsFileName);

#define AT_TOP			1
#define AT_VCENTER		2
#define AT_BOTTOM		4
#define AT_LEFT			8
#define AT_CENTER		16
#define AT_RIGHT		32
#define AT_EVEN_TOP		64
#define AT_EVEN_VCENTER	128
#define AT_EVEN_BOTTOM	256
#define AT_EVEN_LEFT	512
#define AT_EVEN_CENTER	1024
#define AT_EVEN_RIGHT	2048
#define AT_USE_EVEN		4096

#define ID_STRING_EVEN APL_T("Четная")
#define ID_STRING_ODD APL_T("Нечетная")



#define APL_SHOW_LEVEL 1
#define APL_SORT_COLUMN 2

//флаги для ф-ции DRAW
#define DRAW_SEL 1
#define DRAW_PICTURE 2
#define DRAW_TEXT 4

typedef enum { E_LINE, E_RECT, E_TABLE, E_SHEET,E_TABLE_MAP, E_PICTURE, E_TABLE_CONTENT_TITLE, E_REFERENCE_ELEMENT, 
				E_DIAGRAM, E_GISTOGRAM} TReportElementType;

typedef enum {NOTYPE_PARAM = -1, STRING_PARAM=0, INT_PARAM, DATE_PARAM, OBJ_PARAM, PAGE_PARAM, PAGE_COUNT, CURRENT_DATE, STATIC_PAGE_NUM,
		STATIC_PAGE_COUNT, STATIC_CUR_DATE, CRC32_PARAM} TParamTypes;

enum { NONE,SELECT, TL_RESIZE,TR_RESIZE ,T_RESIZE, B_RESIZE , L_RESIZE, R_RESIZE, BL_RESIZE,BR_RESIZE,OBJ_MOVE, ON_SEL_PT ,
		ON_BORDER, E_CREATE_RECT, E_CREATE_LINE,E_CREATE_FIELD,E_SELECT_FRAME,OBJ_SEL, OBJ_FIXED};
enum { NONE_VAL,TEXT_VAL, INST_VAL }; // тип текстового знаячения
enum { HORIZ_TEXT=0, VERT_TEXT, RHORZ_TEXT, RVERT_TEXT}; // ориентация текста

enum {aplSpacePara15=0, aplSpacePara1, aplSpacePara2};

//LegendMode
enum {aplLegendMode_1, aplLegendMode_2, aplLegendMode_3};
//LegendPosition
enum {aplLegendPositionNone, aplLegendPositionTop, aplLegendPositionBottom, aplLegendPositionRight, aplLegendPositionLeft};
enum {aplLegendPositionCenter, aplLegendPositionLess, aplLegendPositionMore};

enum	{aplVALUE, aplSUMM, aplAVERANGE, aplCOUNT, aplSTRCONST};
enum	{aplAZ=0, aplZA, aplSortNone};

typedef enum {aplText_Horz, //Горизонтально
				aplText_Angle //Под углом
			 } TTextVector;

typedef enum {aplShowValue = 0, aplShowSumm, aplShowCount, aplShowAverage} TShowValueType;

#define aplEQUAL 0
#define aplNOEQUAL 1
#define aplMORE 2
#define aplBELOW 3
#define aplCOMPARE_AND	16
#define aplCOMPARE_OR	32

#define STICK_TOP 1
#define STICK_BOTTOM 2
#define STICK_LEFT 4
#define STICK_RIGHT 8

#define DM_FIT_TO_RECT	1
#define DM_FIT_SCALE	2

#define APL_DS_COLUMN 0
#define APL_ATTR_COLUMN 1
#define APL_COMBINE_COLUMN 2
#define APL_SUM_IN_GROUP 16

#define BG_COLOR ::GetSysColor(COLOR_WINDOW)
#define OBJ_COLOR m_color

#define APL_COLUMN_SHOW_LEVEL_NAME	0x0001
#define APL_COLUMN_SHOW_ROW_NUM		0x0002
#define APL_COLUMN_NOT_SHOW_ZERO	0x0004
#define APL_COLUMN_SHOWASDATE		0x0010
#define APL_COLUMN_SHOWASDATETIME	0x0020
#define APL_COLUMN_SHOWASTIME		0x0040
#define APL_COLUMN_SHOW_TOP_LINE	0x0080

//Для уровней секций
#define APL_SEC_LEVEL_SKIP_IF_EMPTY						0x00001
#define APL_SEC_LEVEL_NOT_BREAK_STRING					0x00002
#define APL_SEC_LEVEL_AUTOCLAC_HEIGHT					0x00004
#define APL_SEC_LEVEL_USE_MULTIPLE_HEIGHT				0x00008
#define APL_SEC_LEVEL_NOT_SHOW_EMPTY_ROWS_ON_NEW_PAGE	0x00010
#define APL_SEC_LEVEL_USE_ROW_COLOR						0x00020

//флаги для элементов отчета
#define	APL_RE_FILL_BACKGROUND			0x00001

class CLASS_DECL_APL_REPORTMGR CReportSheet //Элемент страница
{
	friend class CaplReportMgr;

protected:
	void DeleteItems();
	CPoint m_org_pt;  // координаты верх-левого угла
	bool m_isLoaded;
	RE_Array	m_DeletedItems;
public:
	bool SelectElement(CReportParam* param);
	bool SelectRow(int row);
	void Delete();
	bool RestoreItem(CReportElement* elem, int pos=-1);

	/** Конструктор класса*/
	CReportSheet(CaplReportMgr* dict);
	/** Деструктор класса*/
	virtual ~CReportSheet();
	/** Функция возвращает загружены ли элементы страницы в память или нет
		return <b>true</b> если елементы загружены и <b>false</b> в противном случае*/
	bool IsLoaded();
	/** Обновляет параметры страницы и параметры всех элементов находящихся на ней
		param set - если значение параметра true значит обновляется база данных значениями из памяти, если значение параметра false - обновляется значения в памяти из базы	*/
	virtual void Update(bool set = true);
	/**	Устанавливает смещение начала координат страницы
		param pt - смещение координат относительно левого верхнего угла
		return установленное до этого смещение начала координат*/
	CPoint SetOrgPt(CPoint pt);
	/**	Возврящает смещение начала координат*/
	CPoint GetOrgPt()const;
	/**	Ищет в массиве елемент страницы
		param array - массив, в котором ищется элемент
		param elem - елемент, который необходимо найти
		return индекс найденого элемента в массиве и -1 если элемент не найден*/
	static int FindElement(RE_Array* array, CReportElement* elem);
	/** Проверяет прямогугольник на необходимость прилипания
		param t_elem - текущий элемент (сам к себе не прилипает)
		param rect - прямоугольник ограничивающий элемент или группу элементов.
		param pt - вернет координату стороны элемента к которой надо приклеиться
		param flag - возвращает сторону к которой приклеиться	
		return указатель на элемент к которому надо приклеиться*/
	CReportElement* TestMoveRect(CReportElement *t_elem, CRect rect, CPoint &pt, UINT &flag);
	/**	Удаляет элемент из БД и из памяти
		param elem - елемент, который необходимо удалить
		param showDlg -	отображать предупреждающие сообщения*/
	void DeleteElement(CReportElement * elem, bool showDlg = true);
	/**	Помечает элементы. ноходящиеся в заданном прямойгольнике
		param pt - начало прямоугольника
		param sz - размеры прямоугольника
		param scale - текущий масштаб отображения
		return	TRUE если в рамку попал хотябы один элемент*/
	BOOL SelectByFrame(CPoint pt, CSize sz, double scale);
	/**	Создает елемент на странице
		param pt - начало элемента
		param sz - размеры элемента
		param type - тип элемента
		return 	указатель на созданный элемент и NULL в случае ошибки*/
	CReportElement * CreateReportElem(CPoint pt, CSize sz, TReportElementType type = E_RECT);
	/**	Преобразует координаты страницы в координаты экрана*/
	void PtSheetToLog(CPoint &pt);
	/**	Преобразует координаты экрана в координаты страницы*/
	void PtLogToSheet(CPoint &pt);
	/**	Возвращает размеры и положение страницы на экране
		param scalse - текущий масштаб отображения*/
	CRect GetRect(double scale);
	/**	Определяет элементы, которым принадлежит точка
		param pt - точка,к оторую проверяем
		param out_elems(out) - список элементов. которым принадлежит точка
		param scale - текущий масштаб отображения*/
	void TestElem(CPoint pt,RE_Array & out_elems, double scale);
	/**	Помечает элемент как выделенный
		param elem - елемент, который необходимо выделить
		param sel - режим выделения: 0 - снять выделение, 1 - выделить, 2 - инфертировать выделение, 
		return установленный режим выделения (0 или 1) и -1 в случае ошибки*/
	int Select(CReportElement * elem,int sel);
	/**	Добавляет элемент на страницу
		param elem - элемент, который необходимо добавить
		return индекс добавленного элемента в массиве элементов находящихся на странице*/
	int Add(CReportElement * elem);
	/**	Снимает выделение со всех выделенных элементов*/
	bool UnselectAll();
	/**	Устанавливает новые размеры страницы
		param rect - новые размеры страницы*/
	void SetRect(CRect & r);
	/**	Отображает страницу в указанном контексте устройства
		param pDC - указатель на контекст устройства
		param scale - масштаб отображения*/
	virtual BOOL Draw(CDC * pDC, double scale);
	/**	Читает элементы из БД в память*/
	bool LoadElementsFromFile();
	/**	Удаляет эолементы из памяти (за исключением таблиц)*/
	void FreeElements();

	//attr
	CaplReportMgr* m_ReportMgr;
	int m_sheet_num;
	CString m_name; // имя листа
	CaplInstance * m_inst; // инстанс объекта
	RE_Array m_els; // элементы 
	RE_Array m_sel_els; //selected elems

	CSize m_offset; 
	CSize m_size; //размер элемента
	CRect m_print_offset_rect;//отступы при печати

	int m_index; // позиция страницы
	int m_type;//0 - обычная страница; 1 - повторяющаяся.
};

#define APL_TP_FITTORECT		1
#define APL_TP_NOTBREAKSTRING	2
#define APL_TP_HIDE_FOR_ONE_PAGE	4

class CLASS_DECL_APL_REPORTMGR CTextValue 
{
public:
	CString m_text;
	CReportParam* m_val;//Отображаемый параметр;
	int m_type;
public:
	CaplInstance* m_inst;//Инстанс значения
	int		m_border_visible; // отображать или нет рамку
	LOGFONT m_font; // шрифт
	COLORREF	m_color;//цвет текста
	DWORD	m_align; // выравнивание
	DWORD	m_direction; // шаправление текста
	UINT	m_space_para;//межстрочный интервал
	int		m_text_params; //Вписывать текст в заданный прямоугольник методом подбора шрифта
						//Переновить строки
						//Не отображать если в отчете одна страница
	CaplInstance* m_font_inst;

	CTextValue();
	~CTextValue();
	CTextValue& operator = (CTextValue val);
	bool LoadDataFromMem(BYTE* pByte, int &ind);
	void CopyToMem(BYTE* pByte, int &ind);
	int GetMemSize();
	CReportParam* GetParam()const;
	void SetText(CReportParam* param);
	CTextValue* CreateFromInst(CaplInstance* inst, CaplReportMgr* dict);
	void UpdateData(CaplReportMgr* dict);
	void CreateInst(CaplReportMgr* dict);
	int GetType()const;
	CString GetText()const;
	static int BreakString(CStringArray *strs, int cx, CDC *pDC, CString &str);
	int BreakString(CStringArray *strs, int cx, CDC *pDC, CString* str = NULL);
	void SetFont(LOGFONT & lf);
	void SetText(CString str);
	void Delete(CaplReportMgr* dict);
};

class CLASS_DECL_APL_REPORTMGR CReportElement
{
protected:
	void ConvertLOMETRICtoTEXT(CDC *pDC, CRect &rect);

	TReportElementType m_type; //тип объекта
public:

	CReportElement(CaplReportMgr* ReportMgr, TReportElementType type);
	virtual ~CReportElement();

	void Align();
	virtual bool LoadDataFromMem(BYTE* pByte, int &ind);
	virtual void CopyToMem(BYTE* pByte, int &ind);
	virtual int GetMemSize();

	CRect GetLeftRect(int size);// Возвращает прямоугольник вокруг левого края элемента ширина = 2*size высота = высоте элемента
	CRect GetTopRect(int size);	// Возвращает прямоугольник вокруг верхнего края элемента ширина = ширене элемента высота = 2*size
	CRect GetRightRect(int size);// Возвращает прямоугольник вокруг правого края элемента ширина = 2*size высота = высоте элемента
	CRect GetBottomRect(int size);// Возвращает прямоугольник вокруг нижнего края элемента ширина = ширене элемента высота = 2*size
	int GetRange(CRect& r);
	CRect GetSelPtRect(CPoint pt);
	void SetRect(CRect r, double scale);

	// mode = 0, преобразовать к координатам вида = 1 , не преобразовывать
	virtual void GetRect(CRect& r, double scale, int mode=0 ); //
	virtual int GetSelPts(PointArray & pts, CDC *pDC, double scale);
	virtual bool ElemProper(const int mode);
	virtual int ShowContextMenu(CPoint pt,CWnd * wnd, int mode);
	virtual int ExecuteCmd(const UINT cmd);
	virtual int GetDragMode(CPoint pt, int &, double scale);
	virtual void DrawSelPoints(CDC* pDC, double scale);
	virtual BOOL Draw(CDC* pDC, double scale, int draw_mode, UINT flag = DRAW_SEL|DRAW_PICTURE|DRAW_TEXT);
	virtual void Delete();

	void DrawRect(CDC *pDC, CRect r);
	void DrawLine(CDC * pDC, CPoint start, CPoint end);

	virtual CReportElement* CreateClon();
	virtual void Update(bool set = true);

	inline TReportElementType GetType()const{return m_type;};

	CString	GetTypeName(TReportElementType type);	

	// attrs
	CaplInstance	*m_inst;

	COLORREF		m_color; //цвет линии
	COLORREF		m_background_color; //цвет фона
	bool			m_bNeedFillBackground;//Использовать заливку

	int				m_line_width;//Толщина линии
	int				m_select; // признак выделения объекта
	COLORREF		m_erase_color; //цвет стирания
	CPoint			m_org_pt;  // координаты верх-левого угла
	CSize			m_size; //размер элемента
	CString			m_name; // имя элемента
	int				m_sel_pt_width;  //толщина линий точек выделения
	CSize			m_sel_pt_sz; // размер точки выделения
	COLORREF		m_sel_pt_color; // цвет точки выделения
	COLORREF		m_sel_pt_bg_color; // цвет фона точки выделения
	CReportSheet	*m_owner_sheet; // указатель на страницу владельца 
	CaplReportMgr	*m_ReportMgr;
	int				m_fixed;
	bool			m_bCreateTableContent;	
};

#define APL_RRE_SHOW_TOP_LINE	0x0001

class CLASS_DECL_APL_REPORTMGR CRectReportElement : public CReportElement
{
protected:
public:
	CRectReportElement(CaplReportMgr *ReportMgr);
	virtual ~CRectReportElement();

	virtual bool LoadDataFromMem(BYTE* pByte, int &ind) override;
	virtual void CopyToMem(BYTE* pByte, int &ind) override;
	virtual int GetMemSize() override;

	// mode = 0, преобразовать к координатам вида = 1 , не преобразовывать
	virtual int ShowContextMenu(CPoint pt,CWnd * wnd, int mode) override;
	virtual BOOL Draw(CDC* pDC, double scale, int draw_mode, UINT flag = DRAW_SEL|DRAW_PICTURE|DRAW_TEXT) override;
	virtual void Delete() override;
	
	void DrawText(CDC * pDC, double scale, int mode);
	void ReportDrawText(CDC *pDC, CRect r, CString str, DWORD flags, double scale);
	
	virtual CReportElement* CreateClon() override;
	virtual void Update(bool set = true) override;
	
	bool GetElemDSRowCol(int &row, int &col);
	bool IsWin7OrLater();

	// attrs
	int m_dsfrow;
	int m_dsfcol;

	CTextValue m_value; // текстоваое значение эелемента

	/*
	#define APL_RRE_SHOW_TOP_LINE
	*/
	UINT	m_Flags;//Дополнительные флаги объекта
};

class CLASS_DECL_APL_REPORTMGR CLineReportElement : public CReportElement
{
protected:
public:
	CLineReportElement(CaplReportMgr *ReportMgr);
	virtual ~CLineReportElement();

	virtual bool LoadDataFromMem(BYTE* pByte, int &ind) override;
	virtual void CopyToMem(BYTE* pByte, int &ind) override;
	virtual int GetMemSize() override;
	
	// mode = 0, преобразовать к координатам вида = 1 , не преобразовывать
	virtual int ShowContextMenu(CPoint pt,CWnd * wnd, int mode) override;
	virtual int GetDragMode(CPoint pt, int &, double scale) override;
	virtual BOOL Draw(CDC* pDC, double scale, int draw_mode, UINT flag = DRAW_SEL|DRAW_PICTURE|DRAW_TEXT) override;
	virtual void Delete() override;
	
	virtual CReportElement* CreateClon() override;
	virtual void Update(bool set = true) override;
};

class CLASS_DECL_APL_REPORTMGR CSectionArray
{
protected:
	CArray<CReportSection*, CReportSection*> m_Data; //загруженные секциии
public:
	CSectionArray();
	~CSectionArray();
	CReportSection* GetAt(int i);
	void RemoveAt(int i);
	void RemoveAll();
	void Replace(CReportSection* sec, int delta);
	void Replace(int oPos, int nPos);
	int Add(CReportSection* nSec);
	int GetSize();
};

class CLASS_DECL_APL_REPORTMGR CTableElement : public CReportElement
{
public:
	virtual void Delete() override;
	virtual bool LoadDataFromMem(BYTE* pByte, int &ind) override;
	virtual void CopyToMem(BYTE* pByte, int &ind) override;
	virtual int GetMemSize() override;

	CReportSheet* GenTable();
	int GetRows();
	virtual CReportElement* CreateClon() override;
	virtual void Update(bool set = true) override;
	bool AddSection();
	virtual bool ElemProper(const int mode) override;
	virtual int ShowContextMenu(CPoint pt,CWnd * wnd,int mode) override;
	virtual BOOL Draw(CDC* pDC, double scale, int draw_mode, UINT flag = DRAW_SEL|DRAW_PICTURE|DRAW_TEXT) override;
	CTableElement(CaplReportMgr* dict);
	virtual ~CTableElement();
	int m_cur_page;
	int m_row_height; // высота строки в таблице
	CSectionArray m_sections; //загруженные секциии
	LOGFONT m_row_lf; // шрифт в строках данных

	CReportSheet* cur_sheet;
};

class CLASS_DECL_APL_REPORTMGR CTableMapElement : public CReportElement  
{
protected:
	HICON m_TableMapElement_hIcon;
public:
	CTableMapElement(CaplReportMgr* dict);
	virtual ~CTableMapElement();

	virtual BOOL Draw(CDC* pDC, double scale, int draw_mode, UINT flag = DRAW_SEL|DRAW_PICTURE|DRAW_TEXT) override;
	virtual void Delete() override;
	
	virtual CReportElement* CreateClon() override;
	
	bool SelectTable();
	CTableElement* m_table;

	virtual void CopyToMem(BYTE* pByte, int &ind) override;
	virtual int GetMemSize() override;
	virtual int ShowContextMenu(CPoint pt, CWnd *wnd, int mode) override;
	
	virtual void Update(bool set = true) override;
};

class CLASS_DECL_APL_REPORTMGR CPictureElement : public CReportElement
{
public:
	CPictureElement(CaplReportMgr* dict);
	virtual ~CPictureElement();
	//Attributes
	CaplImage *m_image;
	int m_mode;
	CString m_pictureId;

	//Implementation
	virtual CReportElement* CreateClon() override;
	virtual bool LoadDataFromMem(BYTE* pByte, int &ind) override;
	virtual void CopyToMem(BYTE* pByte, int &ind) override;
	virtual int GetMemSize() override;
	BOOL LoadPicture(CString pathname);

	virtual BOOL Draw(CDC* pDC, double scale, int draw_mode, UINT flag = DRAW_SEL|DRAW_PICTURE|DRAW_TEXT) override;
	virtual int ShowContextMenu(CPoint pt,CWnd * wnd, int mode) override;
	virtual void Delete() override;

	virtual void Update(bool set = true) override;
protected:
	CaplImage* m_fictive_image;
private:
};

class CLASS_DECL_APL_REPORTMGR CBoundRect : public CReportElement  
{
	friend class CBoundArray;
protected:
	BOOL TraceBoundRect(CPoint point, CDC *pDC, double scale, bool bDraw);
	int Move(CPoint pt, int drag_mode);
	void StartObjOper(CReportElement * elem, int drag_mode,CPoint pt);
	CBoundRect(CReportSheet* sheet, CaplReportMgr* dict);

public:
	virtual ~CBoundRect();

	CReportElement * EndBound();
	void SetType(TReportElementType type);
	BOOL ResetBound();
	virtual BOOL Draw(CDC *pDC, double scale, int draw_mode, UINT flag = DRAW_SEL|DRAW_PICTURE|DRAW_TEXT) override;

	// attr
	int m_bound_creation;
	int m_drag_status;
	int m_elem_drag_mode;

	CPoint m_cur_pt;

	CReportElement * m_work_elem;

};


class CLASS_DECL_APL_REPORTMGR CBoundArray  
{
private:
	CArray<CBoundRect*, CBoundRect*> m_Data;
	
public:
	CBoundArray();
	virtual ~CBoundArray();
	
	CRect GetRect(double scale);
	CPoint GetTopLeft(double scale = 1);	//Возвращает точку верхнего левого угла прямоугольника описывающего все элементы
	//в массиве.
	CPoint GetBottomRight(double scale = 1);// Нижний правый угол.
	void RemoveAll();		// удаляет все и очищает память
	int GetSize();
	void RemoveAt(int ind);
	CBoundRect* GetAt(int ind);
	CBoundRect* operator [](int ind){return GetAt(ind);};
	void Add(CBoundRect* br);

	BOOL TraceBoundRect(CPoint cp, CDC *pDC, double scale, bool TestElems = true, bool bDraw = true);
	void StartObjOper(CReportSheet *pSheet, CReportElement * elem, int drag_mode,CPoint pt, double scale);
};

class CLASS_DECL_APL_REPORTMGR CaplReportValue : public CaplValue
{
public:
	CaplReportValue();
	virtual ~CaplReportValue();

	//members
	COLORREF	m_text_color;
	COLORREF	m_line_color;
	COLORREF	m_background_color;

	BOOL		m_bStrikeOut;

	BOOL		m_bold;
	BOOL		m_italic;
protected:
private:
};

class CLASS_DECL_APL_REPORTMGR CHeaderColumn
{
protected:
	CaplReportMgr		*m_ReportMgr;
public:
	void Delete();
	CString GetFunct();
	CString GetName();
	CString GetType();
	void Update(bool bStoring);

	int		m_col_type;
	CString	m_name;
	CString m_sFormat;//Формат (используется пока только в aplREAL = %g)
	int		m_type;
	CaplInstance* m_inst;

	CHeaderColumn(CaplReportMgr* ReportMgr)
	{
		m_ReportMgr = ReportMgr;

		m_inst=NULL;
		m_name = _T("");
		m_type = aplNOTYPE;
		m_col_type = APL_DS_COLUMN;
		m_sFormat = _T("%g");
	};
	~CHeaderColumn(){};
	CHeaderColumn& operator =(const CHeaderColumn &header);
};

class CLASS_DECL_APL_REPORTMGR CHeader
{
private:
	CArray<CHeaderColumn*, CHeaderColumn*> m_Data;
	
	CaplReportMgr		*m_ReportMgr;

	bool	m_bBaseSource;
public:
	CaplInstance *m_inst;

	CHeader(CaplReportMgr *reportmgr = NULL, bool bBaseSource = true);
	virtual ~CHeader();

	void Clear();
	void Delete();
	int Find(CString name);
	int Find(CaplInstance* inst);
	void Update(bool set = true);
	int AddColumn(CHeaderColumn* val);
	int AddColumn(CString name, int type);
	int InsertColumn(int pos=-1, CHeaderColumn *col=NULL);
	CHeaderColumn* GetColumn(int pos);
	int GetColumnType(int pos);
	int GetSize();
	int Find(CHeaderColumn* val);
	void RemoveAll();
	void RemoveAt(int pos);

	void GetAsCSVRow(CString &sRow, char pSep = _T(';'));
};
          
class CLASS_DECL_APL_REPORTMGR CTableRow  
{
private:
	bool m_bCorrectQuotes;
	CArray<CaplReportValue*, CaplReportValue*> m_Data;
	CString CorrectQuotes(const CString& sValue);
public:
	bool SetAt(int i, CaplReportValue* val);
	bool SetAt(int i, CString sVal);
	int InsertColumn(int pos=-1, CaplReportValue *col=NULL);
	CTableRow(bool bCorrectQuotes = false);
	virtual ~CTableRow();
	int AddColumn(CaplReportValue* val);
	int AddColumn(CString val, COLORREF text_color = ::GetSysColor(COLOR_WINDOWTEXT));
	int AddColumn(int val);
	int AddColumn(double val);
	int AddColumn(CaplInstance* val);
	int AddColumn(CaplAggr& val);
	int GetColumnType(int pos);
	CaplReportValue* GetColumn(int pos);
	CString GetAsString(int pos);
	void RemoveAll();
	void RemoveAt(int pos);
	int GetSize();
	int Find(CaplReportValue* val);

	void GetAsCSVRow(CString &sRow, char pSep = _T(';'));
};

class CLASS_DECL_APL_REPORTMGR CReportParam  
{
	friend class CDataSource;
	friend class CParamArray;
public:
	CaplReportMgr* GetDict();
	bool ShowProp();
	void SetType(TParamTypes type);
	CString GetText();
	TParamTypes GetType()const;
	void SetParam(CString val, TParamTypes mode = STRING_PARAM);
	void SetParam(int val);
	void SetParam(CaplInstance* val);
	virtual void Update(bool set);
	CReportParam(CaplReportMgr* dict);
	virtual ~CReportParam();
	CString m_name;
	CaplInstance* m_inst;
protected:

	TParamTypes m_type;
	int m_int_val;
	int m_crc32_val;
	CString m_str_val;
	CaplInstance* m_inst_val;
	CaplReportMgr* m_ReportMgr;
};

class CLASS_DECL_APL_REPORTMGR CParamArray
{
public:
	bool SaveToBuf(CString &buf);
	void Clear();
	bool IsUnique(CString name, CReportParam* par);
	int Add(CReportParam* par);
	int Find(int type);
	int Find(CaplInstance* inst);
	int Find(CString &name);
	int Find(CReportParam* par);
	void RemoveAt(int i);
	void RemoveAll();
	void DeleteAll();
	CReportParam* GetAt(int i);
	CReportParam* operator [](int ind){return GetAt(ind);};
	int GetSize();
	CParamArray(){m_Data.RemoveAll();};
	~CParamArray(){RemoveAll();};
protected:
private:
	CArray<CReportParam*, CReportParam*> m_Data;
};

class CLASS_DECL_APL_REPORTMGR CaplRParam
{
public:
	CaplRParam(LPCTSTR lpszName, TParamTypes type, int color = 0)
	{
		m_name = lpszName;
		m_value.Empty();
		m_type = type;
		m_color = color;
	}
	CaplRParam(LPCTSTR lpszName, LPCTSTR lpszValue, int color = 0)
	{
		m_name = lpszName;
		m_value = lpszValue;
		m_type = STRING_PARAM;
		m_color = color;
	}
	CaplRParam(CaplRParam &RParam)
	{
		m_name = RParam.m_name;
		m_value = RParam.m_value;
		m_type = RParam.m_type;
		m_color = RParam.m_color;
	}
	CaplRParam()
	{
		m_name.Empty();
		m_value.Empty();
		m_type = NOTYPE_PARAM;
		m_color = 0;
	}

	virtual ~CaplRParam(){};

	CString		m_name;
	CString		m_value;
	TParamTypes	m_type;
	int m_color;			// цвет закраски прямоугольника (для выделения параметра)
};

class CLASS_DECL_APL_REPORTMGR CRParamsArray
{
private:
	CArray<CaplRParam*, CaplRParam*> m_Data;
public:
	CRParamsArray();
	virtual ~CRParamsArray();

	int Add(CaplRParam* par);
	int Add(LPCTSTR nName, LPCTSTR nValue, int color = 0);
	int Add(LPCTSTR nName, TParamTypes type = STRING_PARAM, int color = 0);
	int Append(CRParamsArray &RParamArr);
	CaplRParam* GetAt(int i);
	CaplRParam* operator [] (int i){return GetAt(i);};
	int GetSize();
	void RemoveAll();
	bool Set(CString name, CString value);
	bool LoadFromFile(LPCTSTR file_name, bool LoadNamesOnly = false);
};

class CLASS_DECL_APL_REPORTMGR CDataSource
{
	friend class CDiagramElement;
	friend class CGistogramElement;
protected:
	int m_rows;
	int m_cols;
	CHeader* m_header;
	TR_Array m_Data;

	CaplReportMgr	*m_ReportMgr;

	CaplInstance *m_inst;

	virtual void Update(bool set = true);

	bool LoadParams(CStdioFile &file);
	bool LoadData(CStdioFile &file);
	bool LoadParams(CStringArray* arr);
	bool LoadData(CStringArray* arr);

	static bool GetFunctionValue(CString &sFunction, CString &val, CTableRow *row, CHeader* header, CHeader* header_ex, CParamArray *params, CDataSource* pDS);

public:
	bool TestHeader(CHeader *pHeader);
	void Delete();
	CDataSource(CHeader* header=NULL, CaplReportMgr *ReportMgr=NULL);
	~CDataSource();

	CTableRow* FindRow(int col, CString sVal);
	bool GetRowsInGroup(CGroupColArray* pGroups, CGroupCol* Group, int GroupLastRow, CArray<CTableRow*,  CTableRow*> *Data, CConditionArray* pConditions = NULL);
	double GetSummInGroup(int start_row, CGroupColArray* pGroups, CGroupCol* gc, CHeaderColumn* col, CConditionArray* pConditions = NULL, int *pRows = NULL);
	double GetCountInGroup(int start_row, CGroupColArray* pGroups, CGroupCol* gc, CHeaderColumn* col, CString sCondition, CConditionArray* pConditions = NULL);
	double GetAverangeInGroup(int start_row, CGroupColArray* pGroups, CGroupCol* gc, CHeaderColumn* col, CConditionArray* pConditions = NULL, int *pRows = NULL);

	bool GetRowsInGroup(CHeaderColumn* Group, int GroupLastRow, CArray<CTableRow*,  CTableRow*> *Data, CConditionArray* pConditions = NULL);
	double GetSummInGroup(int start_row, CHeaderColumn* gc, CHeaderColumn* col, CConditionArray* pConditions = NULL);
	double GetCountInGroup(int start_row, CHeaderColumn* gc, CHeaderColumn* col, CString sCondition, CConditionArray* pConditions = NULL);
	double GetAverangeInGroup(int start_row, CHeaderColumn* gc, CHeaderColumn* col, CConditionArray* pConditions = NULL);


	//Возвращает значение параметра полученного как совокупность уникальных значений в ИД
	//если параметр bArray = false, то значение параметра будет равно первому найденному
	bool GetParametrFromDataSource(LPCTSTR lpszColumnName, CaplRParam *param, bool bArray = false);

	static bool ReplaceBreaks(CString &buf);
	static bool GetDoubleAsString(double dVal, CString &sVal);
	static bool ParseAttr(CString &Attr, CString &entity, CString &attr);
	static bool ParseFunction(CString funct, CString &val, CTableRow* row, CHeader* header, CHeader* header_ex, CParamArray *params, CDataSource* pDS = NULL);
	static bool ParseCondition(CString condition, CTableRow* row, CHeader* header, CParamArray *params, CDataSource* pDS = NULL);
	/**Функция сравнивает два CaplValue.
	return 1 ecли val1>val2 -1 - если val1<val2, 0 - если они равны*/
	static BOOL Compare(CaplReportValue* val1, CaplReportValue* val2, bool bStringCompareAsString = false);
	static bool GetStringPart(CString str, CString &res);

	bool CloneDataSource(CDataSource& DS, CaplReportMgr* ReportMgr = NULL);
	bool Append(CDataSource& DS);
	bool SaveToBuf(CString &buf, bool bGenerated = true);
	char m_Separator;

	CParamArray		m_params;//Используется в сгенерированных отчетах
	CRParamsArray	m_RParams;//Используется при генерации отчетов

	//Модификация текста легенды
	void SetUserLegendText(bool bUseUserLegendText, CStringArray& sUserLegendText);
	void GetUserLegendText(CStringArray& sUserLegendText); // Пользовательские значения для легенды
	bool GetUseUserLegendText(); //Использовать для легенды пользовательские значения из GetUserLegendText
	void SetAdditionalUserLegendText(bool bUseUserLegendText, CStringArray& sUserLegendText);
	void GetAdditionalUserLegendText(CStringArray& sUserLegendText); // Значения для дополнительной легенды
	bool GetUseAdditionalUserLegendText(); //Выводить дополнительную легенду из GetAdditionalUserLegendText
	void CloneUserLegendText(CDataSource& DS, CaplReportMgr* ReportMgr);

	//Пользовательские цвета
	void SetUserColors(bool bUseUserColors, CArray<COLORREF>& UserColors);
	void GetUserColors(CArray<COLORREF>& UserColors);
	bool GetUseUserColors();

	//Пользовательский цвет для столбика нулевой высоты
	void SetUserNullColor(bool bUseUserColor, COLORREF UserColor);
	COLORREF GetUserNullColor();
	bool GetUseUserNullColor();

	//Флаг отображения значений
	void SetShowValues(bool bShowValues);
	bool GetShowValues();

	//Флаг отображения значений горизонтально
	void SetShowValuesHorz(bool bShowValuesHorz);
	bool GetShowValuesHorz();

	//Флаг использования GDI+
	void SetUseGDIPlus(bool bUseGDIPlus);
	bool GetUseGDIPlus();

	//Флаг, показывающий что в оси Y максимальное значение должно быть целым
	void SetIntegerMaxY(bool bIntegerMaxY);
	bool GetIntegerMaxY();

	//Флаг преобразования значений из double в формат времени
	void SetTimeYFormat(bool bTimeYFormat);
	bool GetTimeYFormat();

	bool GetNextWord(CString &buf, CString &word, bool bUseQuote = false);
	bool ParseFunction(CString funct, CString &val, CTableRow* row);
	bool ParseCondition(CString condition, CTableRow* row);
	int GetColumnInd(CHeaderColumn* col);
	void Clear();
	bool Extend(CHeader* add, CaplNetStepData* data);
	CaplReportValue* GetAt(int row, CHeaderColumn* col);
	CaplReportValue* GetAt(int row, int col);
	bool GetAt(int row, int col, double& Val);
	bool GetAt(int row, int col, int& Val);
	bool GetAt(int row, int col, CString& Val);
	bool GetColorAt(int row, int col, COLORREF& color);
	bool GetBoldAt(int row, int col, BOOL& bold);
	bool GetItalicAt(int row, int col, BOOL& italic);
	CHeaderColumn* GetColumn(int i);
	bool LoadFromFile(CString &file_name);
	bool LoadHeader(CString &file_name);
	bool SaveToFile(CString file_name, bool bCSVFormat = false);
	bool GetSize(int &rows, int &cols);
	bool Load(CStringArray* arr);
	
	CHeader* GetHeader();//заголовок
	CHeader* SetHeader(CHeader* header, bool bDeleteOldHeader = false);//Задать заголовок

	int AddRow(CTableRow* row);//Добавить строку в таблицу
	int AddRow();//Добавить строку в таблицу
	int InsertRow(CTableRow* row, int pos = -1);//Вставить строку если задано -1 - добавить в конец таблицы
	
	bool SetAt(int row, int col, CaplReportValue* val);//Вставить значение в позицию (row, col)
	bool SetAt(int row, int col, LPCTSTR val);//Вставить значение в позицию (row, col)
	bool SetAt(int row, int col, int val);//Вставить значение в позицию (row, col)
	bool SetAt(int row, int col, double val);//Вставить значение в позицию (row, col)
	bool SetAt(int row, int col, CaplInstance* val);//Вставить значение в позицию (row, col)

	bool SetAt(int row, LPCTSTR col, CaplReportValue* val);//Вставить значение в позицию (row, col)
	bool SetAt(int row, LPCTSTR col, LPCTSTR val);//Вставить значение в позицию (row, col)
	bool SetAt(int row, LPCTSTR col, int val);//Вставить значение в позицию (row, col)
	bool SetAt(int row, LPCTSTR col, double val);//Вставить значение в позицию (row, col)
	bool SetAt(int row, LPCTSTR col, CaplInstance* val);//Вставить значение в позицию (row, col)
	
	int AddColumn();//Добавить пустое поле;
	int InsertColumn(int pos);//Вставить пустое поле
	bool DeleteColumn(int pos);//Удалить поле
	bool DeleteRow(int pos);//Удалить строку
	void RemoveAll();//Очистить таблицу;
	void Sort(ISortArray *cols, TR_Array* pData=NULL);
	void Sort(CHeaderColumn* col, bool bSortAsString, int SortDirection);
	void Sort(int col, TR_Array *Data, bool bSortAsString, int SortDirection);
	void Sort(char* name, bool bSortAsString, int SortDirection);
	CTableRow* GetRow(int ind);
	int FindRow(CTableRow* row);


	inline int GetRows(){return m_rows;};
	inline int GetCols(){return m_cols;};
private:
	bool LoadXMLFile(LPCTSTR FileName);
};

class CLASS_DECL_APL_REPORTMGR CCondition
{
protected:
	CaplReportMgr* m_report_mgr;
public:
	void Delete(CaplReportMgr* mgr);
	CString GetText();
	void Update(bool set);
	bool Compare(CaplReportValue* val);
	bool Compare(double val);
	bool Compare(int val);
	bool Compare(CString &val);
	void Set(int type, double val);
	void Set(int type, CString &val);
	void Set(int type, int val);
	CCondition(CaplReportMgr* mgr);
	~CCondition();

	CaplInstance* m_inst;//бъект БД
	CHeaderColumn* m_column;//колонка на которую ссылается условие
	int m_type;//тип условия
	int m_value_type;//тип значения
	CString m_str_value;//значение
	int m_int_value;
	double m_double_value;
	int m_flag;//Тип сравнения условия: "И" и "ИЛИ"
protected:
private:
};

class CLASS_DECL_APL_REPORTMGR CColumn
{
protected:
	CaplReportMgr *m_ReportMgr;

public:
	CString m_name;//Наименование
	CString m_TextCnst;//Если отображается константа, то она находится здесь.
	CString	m_sCondition;//Условие
	int m_width;//Ширина
	int m_ind;//индекс
	int m_show_flag;//Отображать уровень, номер строки в разделе
	int m_align;//Выравнивание столбца
	int m_border;//Отображать или не отображать рамку и какой толщины
	int m_SpacePara;//межстрочный интервал
	int m_fit_to_rect;//Вписывать текст в ячейку подбором шрифта
	int m_ColumnType;//Тип колонки
	int m_RowsCount;//Количество строк в ячейке.
	int m_params;//APL_COL_SHOWASTIME||APL_COL_SHOWASDATE||APL_COL_SHOWASDATETIME
	CHeaderColumn* m_ds_column;//Указатель на источник данных
	CaplInstance* m_inst;

	CColumn(CaplReportMgr *ReportMgr);
	~CColumn();
	CColumn& operator =(CColumn& Column);
	void Update(bool set = true);
	bool LoadDataFromMem(BYTE* pByte, int &ind);
	void CopyToMem(BYTE* pByte, int &ind, bool bIncludeDSCol = false);
	int GetMemSize(bool bIncludeDSCol = false);
};

class CLASS_DECL_APL_REPORTMGR CColumnArray
{
protected:
	CaplReportMgr *m_ReportMgr;
private:
	CArray<CColumn*, CColumn*> m_Data;
public:
	CColumnArray(CaplReportMgr *ReportMgr);
	virtual ~CColumnArray();

	bool LoadDataFromMem(BYTE *pByte, int &ind);
	void CopyToMem(BYTE* pByte, int &ind, bool bIncludeDSCol = false);
	int GetMemSize(bool bIncludeDSCol = false);
	int Move(CColumn* col, int ind);
	int Find(CaplInstance* inst);
	void GetExtent(aplExtent& ext);
	void Update(bool set = true);
	CColumnArray& operator=(CColumnArray& ColArr);
	void Clear()
	{
		m_Data.RemoveAll();
	};
	int Add(CColumn* column)
	{
		if(column==0) return -1;
		return m_Data.Add(column);
	};
	void RemoveAt(int i)
	{
		if(i<0 || i>m_Data.GetSize()) return;
		CColumn* col = m_Data.GetAt(i);
		delete col;
		m_Data.RemoveAt(i);
	};
	int GetSize()
	{
		return m_Data.GetSize();
	};
	void RemoveAll();
	CColumn* GetAt(int i)
	{
        if(i<0 || i>m_Data.GetSize()) return NULL;
        return m_Data.GetAt(i);             
    };
	CColumn* operator [](int ind){return GetAt(ind);};
	int Find(CString name);
	int Find(int ind)
	{
		for(int i=0;i<m_Data.GetSize();i++)
		{
			CColumn* c = m_Data.GetAt(i);
			if(c->m_ind==ind) return i;
		}
		return -1;
	};
	int Find(CColumn* col)
	{
		for(int i=0;i<m_Data.GetSize();i++)
		{
			CColumn* c = m_Data.GetAt(i);
			if(c==col) return i;
		}
		return -1;
	};
};

class CLASS_DECL_APL_REPORTMGR CSectionLevel
{
public:
	CaplReportMgr* m_ReportMgr;
	CaplInstance* m_inst;
	CString m_name;//Внутреннее имя уровня
	CColumnArray m_columns;//Колонки
	int			m_height;		//Высота строки уровня
	int			m_flag;			//Флаг отображения секции (пока реализовано только: отображать строку если не пустая)
								//Разрешить перенос строк
								//Исполльзовать автоматическую подборку высоты
								//использовать кратный подбор высоты
								//если минимальное кол-во строк >1, то этот флаг позволяет исключить отображение пустых строк на следующих струнацах
	int			m_MinRows;		//Минимальное количество строк уровня для отображения одной строки ИД
	int			m_space_para;	//межстрочный интервал (используется только при установленном флаге APL_SEC_LEVEL_AUTOCLAC_HEIGHT и неустановленном APL_SEC_LEVEL_USE_MULTITLE_HEIGHT)
	COLORREF	m_row_color;	//цвет строки

	CSectionLevel(CaplReportMgr* dict);
	virtual ~CSectionLevel();
	CSectionLevel& operator = (CSectionLevel& SecLevel);
	void Delete();
	bool LoadDataFromMem(BYTE *pByte, int &ind);
	void CopyToMem(BYTE* pByte, int &ind, bool bIncludeDSCol = false);
	int GetMemSize(bool bIncludeDSCol = false);
	virtual CSectionLevel* CreateClon();
	CColumn* GetColumn(CaplInstance* inst);
	bool Update(bool set = true);
};

#define APL_SECTION_LINING_TO_END 1

class CLASS_DECL_APL_REPORTMGR CSectionLevelArray
{
private:
	CArray<CSectionLevel*, CSectionLevel*> m_Data;
public:
	void Delete();
	CString GetSortColumnName();
	bool LoadDataFromMem(BYTE *pByte, int &ind);
	void CopyToMem(BYTE* pByte, int &ind);
	int GetMemSize();
	CColumn* GetTitleColumn(CaplInstance* inst);
	void GetExtent(aplExtent &ext);
	void Update(bool set = true);
	void Clear();
	int Add(CSectionLevel* level);
	void RemoveAt(int i);
	CSectionLevel* GetAt(int i);
	CSectionLevel* operator [](int ind){return GetAt(ind);};
	void RemoveAll();
	int GetSize();
	int Find(CSectionLevel* level);
	int Find(CString name);
	CSectionLevelArray& operator = (CSectionLevelArray& SLA);
	
	CSectionLevelArray();
	~CSectionLevelArray();
};
class CLASS_DECL_APL_REPORTMGR CConditionArray
{
protected:
	CaplReportMgr*	m_report_mgr;
public:
	void Delete();
	void GetExtent(aplExtent& ext);
	bool Compare(int ind);
	int GetSize();
	void Update(bool set = true);
	CConditionArray(CaplReportMgr* mgr);
	~CConditionArray();
	int Add(CCondition* cond);
	void RemoveAt(int ind);
	void RemoveAll();
	CCondition* GetAt(int ind);
	CCondition* operator [](int ind){return GetAt(ind);};
	CConditionArray& operator = (CConditionArray& CondArr);
protected:
	CArray<CCondition*, CCondition*> m_data;
private:
};

class CLASS_DECL_APL_REPORTMGR CSortColumn
{
protected:
	CaplReportMgr* m_report_mgr;

public:
	CSortColumn(CaplReportMgr* mgr);
	~CSortColumn();

	int		m_SortDirection;
	bool	m_bSortAsString;
	CHeaderColumn*	m_column;
	CaplInstance*	m_inst;

	void Delete();
	void Update(bool bSet=true);
	CSortColumn& operator = (const CSortColumn& col);
};

class CLASS_DECL_APL_REPORTMGR CSortColumnArray
{
private:
	CArray<CSortColumn*, CSortColumn*> m_Data;

public:
	
	CSortColumnArray();
	~CSortColumnArray();

	CSortColumn* operator [](int index);
	CSortColumn* GetAt(int index);
	void RemoveAt(int index);
	void RemoveAll();
	void Clear(){m_Data.RemoveAll();};
	int Add(CSortColumn* nSortCol);
	inline int GetSize();
	int Find(CSortColumn* SortCol);
	void Remove(CSortColumn* SortCol);
	void Move(int ind, int nInd);
};

//Флаги для групп
#define APL_GROUP_SORT_BY_ROWS_COUNT						0x0001
#define APL_GROUP_ALLOW_BREAK_ROWS							0x0002
#define APL_GROUP_SHOW_OTHER_ROW_IF_ONE_ROW_IN_GROUP		0x0004
#define APL_GROUP_DONOT_SHOW_LAST_ROW_IF_ONE_ROW_IN_GROUP	0x0008

class CLASS_DECL_APL_REPORTMGR CGroupCol
{
protected:

public:
	//Attributes
	int m_draw_first_row;
	LOGFONT m_lf;
	CaplReportMgr* m_ReportMgr;
	CaplInstance *m_inst;//Инстанс Поля группировки
	CHeaderColumn* m_col;//Поле источника данных
	CSectionLevelArray m_row;
	CSectionLevelArray m_last_row;
	CSectionLevelArray m_one_row;
	CConditionArray	m_conditions;
	
	bool	m_bSortAsString;
	int		m_SortDirection;
/*
#define APL_GROUP_SORT_BY_ROWS_COUNT						0x0001
#define APL_GROUP_ALLOW_BREAK_ROWS							0x0002
#define APL_GROUP_SHOW_OTHER_ROW_IF_ONE_ROW_IN_GROUP		0x0004
#define APL_GROUP_DONOT_SHOW_LAST_ROW_IF_ONE_ROW_IN_GROUP	0x0008
*/
	int		m_Flags;

	CString			m_name;//Наименование группы для формирования содержания.

	//Implementation
	CGroupCol(CaplReportMgr* dict);
	~CGroupCol();
	CGroupCol& operator = (CGroupCol& GC);
	bool Update(bool set = true);
	void Delete();

	int	m_last_draw_row;	//только для генерации отчета.
};

class CLASS_DECL_APL_REPORTMGR CGroupColArray
{
public:
	bool Move(int oPos, int nPos);
	void Append(CGroupColArray* arr);
	void Clear();
	void GetExtent(aplExtent& ext);
	int GetSize();
	CGroupColArray();
	~CGroupColArray();
	int Add(CGroupCol* cond);
	void RemoveAt(int ind);
	void RemoveAll();
	CGroupCol* GetAt(int ind);
	CGroupCol* operator [](int index){return GetAt(index);};
	CGroupColArray& operator = (CGroupColArray& GCArr);
protected:
	CArray<CGroupCol*, CGroupCol*> m_data;
private:
};

class CLASS_DECL_APL_REPORTMGR CReportSection  
{
private:
	CStringArray	m_ColumnsWithZerroWidth;
protected:
	CTableContent*	m_CurTableContent;
	int				m_CurentDrawRow;
public:
	void ZerroInsts();
	void Delete();
	void DeleteSection();
	bool LoadDataFromMem(BYTE *pByte, int &ind);
	void CopyToMem(BYTE* pByte, int &ind);
	int GetMemSize();
	CReportElement* GetNextSheet(CReportSheet* current_sheet, CReportElement* table);
	int AddTitle(CReportElement *table, int &row, int &y_pos, UINT flag = 0);
	int AddRow(CDataSource *ds, CReportElement **table,int ind, int &row, int &y_pos, CGroupCol* group_col = NULL, UINT flag = 0);
	CReportElement* GenSection(CReportElement* table, int &start_row, int &y_pos, UINT flag = 0);
	int GetRows();
	void Update(bool set = true);
	int CreateSection(CaplReportMgr* dict);

	CReportSection(CaplReportMgr * dict);
	virtual ~CReportSection();
	CReportSection& operator = (CReportSection &sec);

	// attributes	
	CConditionArray m_conditions;
	CGroupColArray m_groups;//Поля группировки
	CSortColumnArray m_sorts;//Поля сортировки
	CSectionLevelArray	m_levels;//Уровни секции
	CaplInstance * m_inst;//Секция
	CaplReportMgr * m_ReportMgr;
	CTextValue m_title; //  заголовок таблицы
	int m_num;//положение секции;
	CString m_name;//Наименование секции
	CColumn* m_title_column;
	int m_show_empty_string_in_title;
};

class CLASS_DECL_APL_REPORTMGR CTableContent
{
protected:
public:
	//Attributes
	CaplReportMgr	*m_ReportMgr;
	CaplInstance*	m_inst;//Сам элемент;
	CString m_Title;//строка, которую необходимо отобразить
	CArray<CTableContent*, CTableContent*> m_Childs;//Входящие элементы (подгруппы) (0:?)
	CArray<CReportSheet*, CReportSheet*> m_sheets;//Указатели на страницы (1:?)

	//Implementation
	CTableContent(CaplReportMgr* mgr);
	~CTableContent();
	void Update(bool bSet = true);//Обновить элемент (true записать false прочитать)
	int FindSheet(CReportSheet* Sheet);
	int AddSheet(CReportSheet* Sheet);
};

class CLASS_DECL_APL_REPORTMGR CTableContentTitleLevel
{
public:
	double	m_ParaDelta;//Отступ параграфа относительно предыдущего уровня
	LOGFONT	m_Font;//Шрифт
	CaplInstance	*m_inst;
	CaplReportMgr	*m_ReportMgr;

	CTableContentTitleLevel(CaplReportMgr* Mgr);
	~CTableContentTitleLevel();

	void Update(bool bSet = true);//Обновить элемент (true записать false прочитать)
};
class CLASS_DECL_APL_REPORTMGR CTableContentTitle
{
public:
	void Delete();
	void DelLevel(CTableContentTitleLevel* level);
	void DelLevel(int Level);
	
	CTableContentTitleLevel* AddLevel();
	CaplInstance	*m_inst;
	CaplReportMgr	*m_ReportMgr;
	CArray<CTableContentTitleLevel*, CTableContentTitleLevel*> m_Levels;

	CTableContentTitle(CaplReportMgr* Mgr);
	~CTableContentTitle();
	void Update(bool bSet = true);//Обновить элемент (true записать false прочитать)
};

class CLASS_DECL_APL_REPORTMGR CPageReferenceElement : public CRectReportElement
{
public:
	CPageReferenceElement(CaplReportMgr* dict);
	~CPageReferenceElement();

	virtual CReportElement* CreateClon() override;
	virtual void Update(bool set=true) override;
	CReportSheet* m_Sheet;
	virtual BOOL Draw(CDC* pDC, double scale, int draw_mode, UINT flag = DRAW_SEL|DRAW_PICTURE|DRAW_TEXT) override;
};

class CLASS_DECL_APL_REPORTMGR CTableContentElement : public CReportElement
{
protected:
	CReportSheet* m_CloneSheet;
public:
	CTableContentElement(CaplReportMgr* dict);
	virtual ~CTableContentElement();

	CTableContentTitle*	m_TableContentTitle;
	double	m_PageWidth;
	double  m_TextWidth;
	int m_iHeight;
	CString m_sTitle;
	LOGFONT	m_lfTitleFont;

	bool AddRow(CTableContent *tc, CTableContentElement **elem, int &y, int Paragraph, int level);
	bool GenContent();
	void DrawText(CDC *pDC, CRect r, CString str, double scale);
	virtual CReportElement* CreateClon() override;

	virtual void Update(bool set = true) override;
	virtual bool LoadDataFromMem(BYTE *pByte, int &ind) override;
	virtual int ShowContextMenu(CPoint pt,CWnd * wnd, int mode) override;
	virtual void CopyToMem(BYTE* pByte, int &ind) override;
	virtual int GetMemSize() override;
	virtual void Delete() override;
	virtual BOOL Draw(CDC* pDC, double scale, int draw_mode, UINT flag = DRAW_SEL|DRAW_PICTURE|DRAW_TEXT) override;
};

class CLASS_DECL_APL_REPORTMGR CDiagramItem
{
protected:
	CaplReportMgr* m_ReportMgr;

private:
public:
	CDiagramItem(CaplReportMgr *ReportMgr);
	virtual ~CDiagramItem();

	CString			m_name;
	int				m_line_width;
	TShowValueType  m_show_mode;
	COLORREF		m_color;
	CHeaderColumn	*m_pDSColumn;
	
	CaplInstance	*m_inst;//DiagramItem

	bool NeedDraw(CDataSource *pDataSource);

	CString GetColumnName();
	virtual void Update(bool set = true);
	virtual bool LoadDataFromMem(BYTE *pByte, int &ind);
	virtual void CopyToMem(BYTE* pByte, int &ind);
	virtual int GetMemSize();
	virtual void Delete();
};

class CLASS_DECL_APL_REPORTMGR CLegendElement
{
protected:
	CaplReportMgr* m_ReportMgr;
private:
public:
	CLegendElement(CaplReportMgr *ReportMgr);
	virtual ~CLegendElement();

	LOGFONT			m_LogFont;
	COLORREF		m_TextColor;
	int				m_LegendMode;
	int				m_LegendPosition;
	int				m_LegendPosition2;

	CaplInstance	*m_inst;//Legend
	CaplInstance	*m_font_inst;//шрифт

	virtual void Update(bool set = true);
	virtual bool LoadDataFromMem(BYTE *pByte, int &ind);
	virtual void CopyToMem(BYTE* pByte, int &ind);
	virtual int GetMemSize();
	virtual void Delete();

	CLegendElement& operator = (const CLegendElement &Legend);
};

class CLASS_DECL_APL_REPORTMGR CCoordinateLine
{
	friend class CCoordinatePropPage;
	friend class CDiagramElement;
	friend class CGistogramElement;
protected:
	CaplReportMgr	*m_ReportMgr;

	int				m_skip_elements;
	bool			m_bShowLines;
	bool			m_bHideValues;
	bool			m_bProRata;
	bool			m_bCalcFromZero;
	bool			m_bShowNames;
	bool			m_bShowPercents;

	CGistogramElement		*m_pGistogram;

	int				m_NumRowsInGroup;

	int	CalcCaptionRows(CDC *pDC, CRect rect, double scale, CDataSource* pDS, double dMin, double &dRange, bool bDraw = false);
	CRect CalcCaptionCycle(CDC *pDC, CRect rect, double scale, CDataSource* pDS, double dMin, double &dRange, bool bDraw = false, Gdiplus::Graphics* graphics = NULL);
	// Функция пытается вписать текст в сегмент круговой диаграммы
	// Находит координату x по координате y. В случае неуспеха возвращает 0.
	//    @y - координата y верхнего края надписи, для которой смотрится, достаточно ли ширины для вписывания текста
	//    @width - ширина текста
	//    @height - высота текста
	//    @iBorderOldAngleX, @iBorderOldAngleY, @iBorderOldAngleNum - массивы координат x и y начального радиуса сегмента, и количество элементов в массивах
	//    @iBorderPieAngleX, @iBorderPieAngleY, @iBorderPieAngleNum - массивы координат x и y конечного радиуса сегмента, и количество элементов в массивах
	//    @iBorderEllipseX, @iBorderEllipseY, @iBorderEllipseNum - массивы координат x и y дуги сегмента, и количество элементов в массивах
	//    @out_width - возвращает ширину сегмента для координаты y
	//    @out_x - возвращает координату x для центрированного вывода текста, даже, если текст пересекает границы сегмента
	int CalcCycleYText( int y, int width, int height,
						int* iBorderOldAngleX, int* iBorderOldAngleY, int iBorderOldAngleNum,
						int* iBorderPieAngleX, int* iBorderPieAngleY, int iBorderPieAngleNum,
						int* iBorderEllipseX, int* iBorderEllipseY, int iBorderEllipseNum,
						int& out_width, int& out_x);
	void DrawCycleGistogram(CDC *pDC, CRect rect, double scale, CDataSource* pDS, double dMin, double &dRange, Gdiplus::Graphics* graphics = NULL);
	void DrawTimeLineGistogram(CDC *pDC, CRect rect, double scale, CDataSource* pDS, double dMin, double &dRange);
public:
	CCoordinateLine(CaplReportMgr* ReportMgr);
	virtual ~CCoordinateLine();

	CaplInstance	*m_inst;
	CaplInstance	*m_font_inst;

	CString			m_name;
	CReportParam	*m_pParam;

	int				m_line_width;
	COLORREF		m_line_color;
	COLORREF		m_lines_color;
	LOGFONT			m_font;
	COLORREF		m_font_color;

	TTextVector		m_TextVector; //Направление текста.

	CHeaderColumn	*m_pDSColumn;

	CCoordinateLine& operator=(const CCoordinateLine& CLine);

	virtual void OffsetDrawRect(CDC *pDC, CRect &rect, double scale, CDataSource* pDS, double dMin, double &dRange);
	virtual void Draw(CDC *pDC, CRect rect, double scale, CDataSource* pDS, double dMin, double &dRange, Gdiplus::Graphics* graphics = NULL);
	virtual void Update(bool set = true);
	virtual bool LoadDataFromMem(BYTE *pByte, int &ind);
	virtual void CopyToMem(BYTE* pByte, int &ind);
	virtual int GetMemSize();
	virtual void Delete();
};

class CLASS_DECL_APL_REPORTMGR CDiagramElement : public CReportElement
{
private:
	double m_dXMin;
	double m_dXMax;
	double m_dYMin;
	double m_dYMax;
	double m_dXRange;
	double m_dYRange;

	int				m_XIndex;

	bool RecalcLayout();
protected:
	CDataSource	m_DataSource;

	bool GetLegendNeedSizes(CDC *pDC, CRect rect, CSize &sizes, int &cols);
	bool DrawLegeng(CDC *pDC, CRect &rect);

public:
	CDiagramElement(CaplReportMgr* ReportMgr);
	virtual ~CDiagramElement();
//Members
	
	CaplTAggr<CDiagramItem*, CDiagramItem*, APLAGGR_LIST_OR_AUTOKILLREF>	m_Elements;
	CCoordinateLine	m_XLine;
	CCoordinateLine	m_YLine;
	CLegendElement	m_Legend;
	CHeaderColumn	*m_pGroupColumn;
	int		m_SortDirection;

//functions
	virtual void Update(bool set = true) override;
	virtual bool LoadDataFromMem(BYTE *pByte, int &ind) override;
	virtual void CopyToMem(BYTE* pByte, int &ind) override;
	virtual int GetMemSize() override;
	virtual void Delete() override;
	virtual BOOL Draw(CDC* pDC, double scale, int draw_mode, UINT flag = DRAW_SEL|DRAW_PICTURE|DRAW_TEXT) override;

	CDiagramElement& operator=(const CDiagramElement& Elem);
	bool GenerateDiagram();
};

#define APL_GISTOGRAM_VIEW_TYPE_COLUMN	0x0000
#define APL_GISTOGRAM_VIEW_TYPE_CYCLE	0x0001
#define APL_GISTOGRAM_VIEW_TYPE_TIMELINE 0x0002

// Гистограмма может быть следующих типов:
//    Столбики
//       Значение координаты x должно содержать текстовое название столбика.
//       Значение координаты y может быть создано как с типов double, так и с типом CaplAggr.
//       (примечание: т.к. все значение все равно преобразуются к типу CString, то с типом CaplAggr могут быть трудности
//       лучше создавать тип CString, значения в котором разделены ';')
//       Для второго случая столбик будет раскрашен в несколько цветов.
//    Временная
//       Значение координаты x должно содержать текстовый формат времени (например, "%d.%m.%Y %H:%M:%S").
//       Координата y должна создана с типом CaplAggr. В нем должно быть три значения:
//       первое - тип временного интервала (попросту некоторое int-значения, которое влияет на цвет раскраски)
//       второе и третье - начало и конец временного интервала в любых единицах измерения,
//       (примечание: т.к. все значение все равно преобразуются к типу CString, то с типом CaplAggr могут быть трудности
//       лучше создавать тип CString, значения в котором разделены ';')
//    Круговая
//       Значение координаты x должно содержать текстовое название сегмента круга.
//       Значение координаты y должно быть создано с типом double.
class CLASS_DECL_APL_REPORTMGR CGistogramElement : public CReportElement
{
	friend class CCoordinateLine;
	friend class CGistogramPropDlg;
private:
	double m_dXMin;
	double m_dXMax;
	double m_dYMin;
	double m_dYMax;
	double m_dXRange;
	double m_dYRange;

	COLORREF m_UseColorRef;
	int m_UserColorParts;
	CArray<COLORREF> m_UseColors;
	
	int				m_XIndex;

#ifdef _DEBUG
	int m_assert_count;
#endif
	
	bool RecalcLayout();
	COLORREF HSV2RGBeasy(double Hue, double Saturation, double ValueBr);
protected:
	CDataSource	m_DataSource;
	
	BOOL DrawColumn(CDC* pDC, double scale, int draw_mode, UINT flag);
	BOOL DrawTimeLine(CDC* pDC, double scale, int draw_mode, UINT flag);
	BOOL DrawCycle(CDC* pDC, double scale, int draw_mode, UINT flag);

	bool GetLegendNeedSizes(CDC *pDC, CRect rect, CSize &sizes, int &cols);
	bool DrawLegeng(CDC *pDC, CRect &rect);
	bool GetLegendNeedSizesCycle(CDC *pDC, CRect rect, CSize &sizes, int &cols);
	bool DrawLegengCycle(CDC *pDC, CRect &rect);
	
	void Draw3DRect(int x1, int y1, int x2, int y2, double scale, CDC* pDC, COLORREF color_brush, int y_min, int y_max, bool bAdditional);
	void Draw3DRectDuo(int y_bottom, int x_left, int y_top_left, int x_right, int y_top_rigth, double scale, CDC* pDC, COLORREF color_brush, bool bRight);

	void DrawRectValueString(double value, int x1, int y1, int x2, int y2, double scale, CDC *pDC, COLORREF color_brush, int y_min, int y_max, bool bLast);

	Gdiplus::Graphics* CreateGDIPlusGraphics(HDC hDC, Gdiplus::GraphicsContainer& container);
	bool DeleteGDIPlusGraphics(Gdiplus::Graphics** graphics, Gdiplus::GraphicsContainer& container);

	int		m_Angel;
	int		m_Volume;
	int		m_ViewType;
public:
	CGistogramElement(CaplReportMgr* ReportMgr);
	virtual ~CGistogramElement();
	//Members
	
	CaplTAggr<CDiagramItem*, CDiagramItem*, APLAGGR_LIST_OR_AUTOKILLREF>	m_Elements;
	CCoordinateLine	m_XLine;
	CCoordinateLine	m_YLine;
	CLegendElement	m_Legend;
	CHeaderColumn	*m_pGroupColumn;
	int		m_SortDirection;

	// Получить цвет для закраски сегмента круговой диаграммы
	//    @base_color - базовый цвет диаграммы (цвет первого сегмента)
	//    @parts - количество сегментов диаграммы
	//    @colors - возвращаемый массив цветов
	bool GetColor(COLORREF base_color, int parts, CArray<COLORREF>& colors);
	void GetGradientColors(COLORREF base_color, Gdiplus::Color& color_main, Gdiplus::Color& color_dark, Gdiplus::Color& color_light);

	//functions
	virtual void Update(bool set = true) override;
	virtual bool LoadDataFromMem(BYTE *pByte, int &ind) override;
	virtual void CopyToMem(BYTE* pByte, int &ind) override;
	virtual int GetMemSize() override;
	virtual void Delete() override;
	virtual BOOL Draw(CDC* pDC, double scale, int draw_mode, UINT flag = DRAW_SEL|DRAW_PICTURE|DRAW_TEXT) override;
	
	CGistogramElement& operator=(const CGistogramElement& Elem);

	bool GenerateGistogram();
};
//Менеджер
class CLASS_DECL_APL_REPORTMGR CaplReportMgr
{
protected:
	CString m_dict_path;
public:
	/** Создает новый параметр (отображает диалоговое окно)*/
	CReportParam* CreateParam();

	bool LoadFromFile(LPCTSTR lpszFileName);
	int FindSheetInd(CReportSheet* sheet);
	/** Читает и создает элементы содержания*/
	bool LoadTableContents();
	/**	Обновляет параметры отчета*/
	bool Update(bool bSet=true);
	/** Обновление имен страниц.*/
	void UpdateSheets();
	/** Поиск колонки источника данных по её Instance*/
	CHeaderColumn* FindColumnByInst(CaplInstance* inst);
	/** Инициализация менеджера. обнуление всех массивов.*/
	bool Init();
	/** Удалить все страницы из памяти*/
	void RemoveAllSheets();
	/** Дублировать страницу и все её елементы
		param sheet - указатель на страницу
		param ind - позиция в которую необходимо вставить страницу
		return новая страница*/
	CReportSheet* CloneSheet(CReportSheet *sheet, int ind = -1);
	/** Поиск таблицы по ее Instance*/
	CTableElement* FindTable(CaplInstance *inst);
	/** Получение аттрибута содержащего размер или точку
		param inst - Instance для которой берется атрибут
		param attr - аттрибут
		param size - переменная в которую записывается результат	*/
	int GetPoint(CaplInstance *inst, CaplAttr *attr, CSize &size);
	/** Получение аттрибута содержащего размер или точку
		param inst - Instance для которой берется атрибут
		param attr - аттрибут
		param pt - переменная в которую записывается результат	*/
	int GetPoint(CaplInstance *inst,CaplAttr *attr, CPoint & pt);
	/** Получение аттрибута содержащего координаты и размеры прямоугольника
		param inst - Instance для которой берется атрибут
		param attr - аттрибут
		param rect - переменная в которую записывается результат
		return возвращает false в случае ошибки.*/
	bool GetRect(CaplInstance* inst, CaplAttr *attr, CRect &rect);
	/** Получение аттрибута содержащего координаты и размеры прямоугольника
		param inst - Instance для которой берется атрибут
		param attr - аттрибут
		return координаты и размеры прямоугольника*/
	CRect GetRect(CaplInstance* inst, CaplAttr *attr);
	/**	Получение аттрибута содержащего координаты и размеры прямоугольника
		param inst - Instance для которой берется атрибут
		param attr - аттрибут
		param rect - переменная в которую записывается результат
		return false в случае ошибки.*/
	bool SetRect(CaplInstance* inst, CaplAttr *attr, CRect rect);

	CString GetReportName() const;
	void SetReportName(const CString& sValue);

	int GetReportVersion() const;
	void SetReportVersion(int iValue);

	/**	Создает новый элемент по данным из БД
		param inst - Инстансе элемента в БД
		param owner_sheet - страница, на которой должен буть расположен элеимент
		return Указатель на созданный эелемент*/
	CReportElement *CreateElemObj(CaplInstance * inst,CReportSheet *owner_sheet= NULL);

	bool GetReportOneSheetOnly() const { return m_bReportOneSheetOnly; };
	void SetReportOneSheetOnly(bool bValue) { m_bReportOneSheetOnly = bValue; };

	bool GetMergeMultiRow() const { return m_bMergeMultiRow; }
	void SetMergeMultiRow(bool bValue) { m_bMergeMultiRow = bValue; }

	int  GetLastReportRow() const { return m_nLastReportRow; };
	void SetLastReportRow(int nRow) { m_nLastReportRow = nRow; };

	CString GetDefaultPrinterName();
	CString GetPdfPrinterName();
	bool ExportToPdf(LPCTSTR fileName);	
	void SetupDefaultPrinter(CString &sPrinterName);

	void SetFontValue(CaplInstance* inst, LOGFONT lf);
	LOGFONT GetFontValue(CaplInstance* inst);
	void GetFontValue(CaplInstance * font_inst, LOGFONT & lf);
	int PutPoint(CaplInstance* inst,CaplAttr* attr, CPoint pt);
	void Attach(CaplStepDataWithFile *data, LPCTSTR dict_path);
	void Detach();
	CString GetDictPath();
	CaplReportMgr();
	virtual ~CaplReportMgr();

	inline HINSTANCE OpenAplrepFile(LPCTSTR lpFile)
	{
		HINSTANCE ret = ShellExecute(NULL, _T("open"), lpFile, NULL, NULL, SW_SHOW);
		if( (int)ret == SE_ERR_NOASSOC )
		{
			CString rundll = _T("shell32.dll, OpenAs_RunDLL ");
			rundll += lpFile;
			return ShellExecute(NULL, _T("open"), _T("rundll32.exe"), (LPCTSTR)rundll, NULL, SW_SHOW);
		}
		else
			return ret;
	}

	//properties
	bool	m_bFitToPage;
	bool	m_bSplitPageToA4;

	//attr
	CaplStepDataWithFile *m_data;
	
	CaplEntity *e_apl_report;
	CaplAttr *a_apl_report_fit_to_page;
	CaplAttr	*a_apl_report_def_ro_access;

	CaplEntity	*e_apl_report_sheet;
	CaplAttr	*a_apl_report_sheet_top_offset;
	CaplAttr	*a_apl_report_sheet_bottom_offset;
	CaplAttr	*a_apl_report_sheet_left_offset;
	CaplAttr	*a_apl_report_sheet_right_offset;


	CaplEntity *e_apl_point;

	CaplEntity *e_report_sheet_elem;
	CaplEntity *e_report_rect;
	CaplEntity *e_report_line;
	CaplEntity *e_report_table;
	
	CaplEntity *e_report_section;
	CaplAttr *a_apl_rep_section_conditions;
	CaplAttr *a_apl_rep_section_show_es;

	CaplEntity *e_apl_condition;//Условие
	CaplAttr *a_apl_condition_type;
	CaplAttr *a_apl_condition_ds_column;
	CaplAttr *a_apl_condition_value_type;
	CaplAttr *a_apl_condition_value;
	
	CaplEntity *e_apl_select;//Запрос;
	CaplAttr* a_apl_sel_cols;
	
	CaplEntity *e_apl_result_select;//Запрос;
	CaplAttr* a_apl_res_sel_cols;

	CaplEntity *e_apl_data_src_col;//Колонка источника данных
	CaplAttr *a_apl_col_name;//Наименование колонки
	CaplAttr *a_apl_col_type;//тип содержимого колонки
	CaplAttr *a_apl_col_type_col;//тип колонки

	CaplEntity  *e_report_map;//Продолжение таблицы
	CaplAttr *a_map_src;
	
	CaplAttr *a_rep_name;
	CaplAttr *a_rep_version;
	CaplAttr *a_rep_sheets;
	CaplAttr *a_rep_params;
	CaplAttr *a_rep_mode;
	CaplAttr *a_rep_binding;

	CaplAttr *a_rep_sheet_els; 
	CaplAttr *a_rep_sheet_type; // тип страницы отчета ( first, next, last)

	CaplAttr *a_elem_name;
	CaplAttr *a_elem_org_pt;
	CaplAttr *a_elem_size;
	CaplAttr *a_elem_text_val;
	CaplAttr *a_elem_line_width;
	CaplAttr *a_elem_fixed;
	CaplAttr *a_elem_dsfcol;
	CaplAttr *a_elem_dsfrow;
	CaplAttr *a_elem_textcolor;
	CaplAttr *a_elem_backgroundcolor;
	CaplAttr *a_elem_create_tc;
	CaplAttr *a_elem_flags;
	CaplAttr *a_elem_id;

	CaplAttr *a_rect_elem_flags;

	CaplAttr *a_point_x;
	CaplAttr *a_point_y;

	CaplEntity * e_param;
	CaplAttr *a_param_name;
	CaplAttr *a_param_type;
	CaplAttr *a_param_expr;
	CaplAttr *a_param_parent;
	CaplAttr *a_param_inst_type;
	CaplAttr *a_param_value; 

	CaplEntity *e_apl_column;
	CaplAttr *a_apl_column_level;
	CaplAttr *a_apl_column_align;
	CaplAttr *a_apl_column_border;
	CaplAttr *a_apl_column_fit_text;
	CaplAttr *a_apl_column_name;
	CaplAttr *a_apl_column_width;
	CaplAttr *a_apl_column_height;
	CaplAttr *a_apl_column_ds_col;
	CaplAttr *a_apl_column_type;
	CaplAttr *a_apl_column_condition;
	CaplAttr *a_apl_column_text_const;
	CaplAttr *a_apl_column_rows;
	CaplAttr *a_apl_column_space_para;
	CaplAttr *a_apl_column_params;

	CaplEntity * e_level;
	CaplAttr *a_level_name;
	CaplAttr *a_level_cols;
	CaplAttr *a_level_height;
	CaplAttr *a_level_flag;
	CaplAttr *a_level_spacepara;
	CaplAttr *a_level_min_rows;
	CaplAttr *a_level_row_color;

	CaplAttr *a_section_data_src, *a_section_data_rel, *a_section_name, *a_section_title;
	CaplAttr *a_section_title_font, *a_section_row_height;
	CaplAttr *a_section_title_height, *a_section_title_col;
	CaplAttr *a_section_levels;
	CaplAttr *a_section_sort;//Поля сортировки
	CaplAttr *a_section_groups;//Поля группировки

	CaplAttr *a_table_sections, *a_table_row_height, *a_table_row_font; 

	CaplEntity *e_font; // шрифт
	CaplAttr *a_font_name;
	CaplAttr *a_font_height;
	CaplAttr *a_font_weight;
	CaplAttr *a_font_italic;
	CaplAttr *a_font_charset;
	CaplAttr *a_font_underline;
	CaplAttr *a_font_strikeout;

	CaplEntity * e_value; // текстовоке значение элемента
	CaplAttr * a_val_inst;
	CaplAttr *a_val_type;
	CaplAttr *a_val_text;
	CaplAttr *a_val_orient;
	CaplAttr *a_val_font;
	CaplAttr *a_val_color;
	CaplAttr *a_val_align;
	CaplAttr *a_val_border_state;
	CaplAttr *a_val_text_params;
	CaplAttr *a_val_space_para;

	CaplEntity *e_apl_group_col;//Поле 
	CaplAttr *a_apl_gr_font;//Шрифт
	CaplAttr *a_apl_gr_col;//Солонка ИД
	CaplAttr *a_apl_gr_sortasstring;//сортировать как строки
	CaplAttr *a_apl_gr_row;//Строка (уровни и поля) заголовок
	CaplAttr *a_apl_gr_last_row;//Строка (уровни и поля) подитог
	CaplAttr *a_apl_gr_one_row;//Строка (уровни и поля) если в группе одна строка (при этом игнорируется только заголовок)
	CaplAttr *a_apl_gr_show_fr;//Отображать строки начиная с первой строки группы.
	CaplAttr *a_apl_gr_conditions;//Условия отображения группы
	CaplAttr *a_apl_gr_name;//Наименование группы
	CaplAttr *a_apl_gr_sort_direction;//Направление сортировки
	CaplAttr *a_apl_gr_flags;//флаги:
	//Сортировать по количеству строк в группе
	//Отображать группу по другому для одной строки в группе

	CaplEntity *e_report_pic;//Элемент эскиз
	CaplAttr* a_pic_picture;//Эскиз
	CaplAttr* a_pic_mode;//Режим отрисовки

	CaplEntity* e_apl_rect;
	CaplAttr*	a_apl_rect_top;
	CaplAttr*	a_apl_rect_left;
	CaplAttr*	a_apl_rect_bottom;
	CaplAttr*	a_apl_rect_right;
	
	CaplEntity*	e_apl_user;
	CaplAttr*	a_apl_user_name;
	CaplAttr*	a_apl_user_password;
	CaplAttr*	a_apl_user_access_mode;

	CaplEntity	*e_apl_table_content;
	CaplAttr	*a_apl_tc_sheets;
	CaplAttr	*a_apl_tc_childs;
	CaplAttr	*a_apl_tc_title;

	CaplEntity	*e_apl_table_content_title;
	CaplAttr	*a_apl_tct_levels;

	CaplEntity	*e_apl_table_content_title_level;
	CaplAttr	*a_apl_tctl_paradelta;
	CaplAttr	*a_apl_tctl_font;

	CaplEntity	*e_apl_table_content_element;
	CaplAttr	*a_apl_tce_tct;
	CaplAttr	*a_apl_tce_pWidth;
	CaplAttr	*a_apl_tce_pTWidth;
	CaplAttr	*a_apl_tce_height;
	CaplAttr	*a_apl_tce_title;
	CaplAttr	*a_apl_tce_font;

	CaplEntity	*e_apl_reference_element;
	CaplAttr	*a_apl_ref_elem_element;

	CaplEntity	*e_apl_sort_column;
	CaplAttr	*a_apl_sc_column;
	CaplAttr	*a_apl_sc_sort_as_string;
	CaplAttr	*a_apl_sc_sort_direction;
	
	CaplEntity	*e_apl_diagram_element;
	CaplAttr	*a_apl_diagram_element_elements;
	CaplAttr	*a_apl_diagram_element_xline;
	CaplAttr	*a_apl_diagram_element_yline;
	CaplAttr	*a_apl_diagram_element_legend;
	CaplAttr	*a_apl_diagram_element_group_column;
	CaplAttr	*a_apl_diagram_element_data_source;
	CaplAttr	*a_apl_diagram_element_sort_type;

	CaplEntity	*e_apl_diagram_item;
	CaplAttr	*a_apl_diagram_item_title;
	CaplAttr	*a_apl_diagram_item_color;
	CaplAttr	*a_apl_diagram_item_line_width;
	CaplAttr	*a_apl_diagram_item_ds_column;
	CaplAttr	*a_apl_diagram_item_show_mode;

	CaplEntity	*e_apl_legend;
	CaplAttr	*a_apl_legend_position;
	CaplAttr	*a_apl_legend_mode;
	CaplAttr	*a_apl_legend_font;
	CaplAttr	*a_apl_legend_font_color;

	CaplEntity	*e_apl_coordinate_line;
	CaplAttr	*a_apl_coordinate_line_name;
	CaplAttr	*a_apl_coordinate_line_line_width;
	CaplAttr	*a_apl_coordinate_line_line_color;
	CaplAttr	*a_apl_coordinate_line_font;
	CaplAttr	*a_apl_coordinate_line_font_color;
	CaplAttr	*a_apl_coordinate_line_parametr;
	CaplAttr	*a_apl_coordinate_line_ds_column;
	CaplAttr	*a_apl_coordinate_line_lines_color;
	CaplAttr	*a_apl_coordinate_line_flags;

	CaplEntity	*e_apl_gistogram_element;
	CaplAttr	*a_apl_gistogram_element_legend;
	CaplAttr	*a_apl_gistogram_element_elements;
	CaplAttr	*a_apl_gistogram_element_xline;
	CaplAttr	*a_apl_gistogram_element_yline;
	CaplAttr	*a_apl_gistogram_element_group_column;
	CaplAttr	*a_apl_gistogram_element_data_source;
	CaplAttr	*a_apl_gistogram_element_volume;
	CaplAttr	*a_apl_gistogram_element_angel;
	CaplAttr	*a_apl_gistogram_element_sort_type;
	CaplAttr	*a_apl_gistogram_element_view_type;

	CaplEntity	*e_apl_data_source;
	CaplAttr	*a_apl_ds_columns;

	CaplEntity	*e_apl_data_source_column;
	CaplAttr	*a_apl_ds_column_name;
	CaplAttr	*a_apl_ds_column_values;

	CaplEntity	*e_apl_data_source_real_value;
	CaplAttr	*a_apl_dsrv_value;
	CaplEntity	*e_apl_data_source_string_value;
	CaplAttr	*a_apl_dssv_value;
	//Data

	CArray<CTableContent*, CTableContent*>	m_TableContents;
	CArray<CReportSheet*,CReportSheet*> m_sheets;//Страницы
	CArray<CReportElement*, CReportElement*> m_non_create_table_maps;//Не созданные сразу ссылки на таблицы
	CArray<CReportElement*, CReportElement*> m_UpdateReference;//Не созданные сразу ссылки на таблицы
	CArray<CTableElement*, CTableElement*> m_tables;//Не созданные сразу ссылки на таблицы
	CReportSheet* m_dot_sheet;
	CDataSource m_data_source;//Источник данных
	CHeader* m_base_query;//Основные поля ИД
	CHeader* m_header;//Расширенные поля ИД

	int m_nLastReportRow;
	bool m_bReportOneSheetOnly;
	bool m_bMergeMultiRow;	// объединять многострочные строки в один прямоугольник
	bool m_bFillBackground;	//Заливать или нет фон в элементах. может указываться только программно.
							//Может когда то это станет атрибутом объекта (свойством)
							//По умолчанию не заливать (false)

	CaplInstance* m_pReport;	// указатель на инстанс отчета

// GDI+
private:
	Gdiplus::GdiplusStartupInput m_gdiplusStartupInput;
	ULONG_PTR m_gdiplusToken;
};

class CTMGroupCol
{
public:
	CTMGroupCol(){iMode =0; pColumn=NULL;};
	int iMode;
	//iMode = 0 - отображение в режиме заголовка
	//iMode = 1 - отображение в режиме строки
	CHeaderColumn* pColumn;
};

class CTMColumn
{
public:
	CTMColumn(){iWidth = 0; pColumn=NULL; sTitle.Empty();bGroup = false;};
	CHeaderColumn* pColumn;
	int iWidth;
	CString sTitle;

	bool bGroup;
};

#include "ReportView.h"

#endif // !defined(AFX_REPORTDICT_H__D01922C7_39B2_4D02_A7DF_983FA844EF89__INCLUDED_)
