// CTableElement.cpp: implementation of the CTableElement class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "resource.h"
#include "ReportDict.h"
#include "SectionPropDlg.h"
#include "PropertyDlg.h"

//#include "TableProperDlg.h"

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

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CTableElement::CTableElement(CaplReportMgr* dict):CReportElement(dict, E_TABLE)
{
	m_row_height = 10;
	m_cur_page = -1;

	// УСТАНАВЛИВАЕМ ШРИФТ ПО УМОЛЧАНИЮ
	m_row_lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
	m_row_lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
	m_row_lf.lfQuality = DEFAULT_QUALITY;
	m_row_lf.lfPitchAndFamily = DEFAULT_PITCH;
	m_row_lf.lfWidth = 0;
	m_row_lf.lfOrientation = 0;
	m_row_lf.lfStrikeOut = 0;
	m_row_lf.lfItalic = 255;
	m_row_lf.lfUnderline = 0;
	m_row_lf.lfEscapement = 0;
	m_row_lf.lfWeight = FW_NORMAL;
	m_row_lf.lfCharSet = RUSSIAN_CHARSET;
	_strcpy(m_row_lf.lfFaceName,_T("Arial"));
	m_row_lf.lfHeight = 120; // размер в точках

	m_name = APL_T("Таблица");

	cur_sheet = NULL;
}

CTableElement::~CTableElement()
{
	m_sections.RemoveAll();
}

BOOL CTableElement::Draw(CDC *pDC, double scale, int draw_mode, UINT flag)
{
	if(pDC==NULL) return FALSE;
	if(scale==0) return FALSE;

	CRect rect;
	GetRect(rect,scale,pDC->IsPrinting());

	rect.NormalizeRect();

	CPen m_obj_pen, *old_p;
	CBrush m_bg_brush, *old_b;
	CString str;
	
	m_obj_pen.CreatePen(PS_SOLID | PS_GEOMETRIC,int(m_line_width*scale),OBJ_COLOR);
	m_bg_brush.CreateSolidBrush(BG_COLOR);

	if(m_line_width==0 && draw_mode==0)
	{
		m_obj_pen.DeleteObject();
		m_obj_pen.CreatePen(PS_SOLID|PS_GEOMETRIC,1, RGB(192,192,192));
	}
	old_p = pDC->SelectObject(&m_obj_pen);
	old_b = pDC->SelectObject(&m_bg_brush);
	if(draw_mode==0)
	{
		m_obj_pen.DeleteObject();
		m_obj_pen.CreatePen(PS_SOLID | PS_GEOMETRIC,int(m_line_width*scale), RGB(192,192,192));
		pDC->SelectObject(&m_obj_pen);
		
		int y = rect.bottom-int(rect.Height()*0.1);
		pDC->MoveTo(rect.left, y);
		pDC->LineTo(rect.right, y);
		int x = rect.left+int(rect.Width()*0.4);
		pDC->MoveTo(x, rect.top);
		pDC->LineTo(x, rect.bottom);
		x = rect.left+int(rect.Width()*0.7);
		pDC->MoveTo(x, rect.top);
		pDC->LineTo(x, rect.bottom);
		
		m_obj_pen.DeleteObject();
		m_obj_pen.CreatePen(PS_SOLID | PS_GEOMETRIC,int(m_line_width*scale),OBJ_COLOR);
		pDC->SelectObject(&m_obj_pen);
	}

	if(m_line_width>0 || draw_mode==0)
	{
		pDC->MoveTo(rect.TopLeft());
		pDC->LineTo(rect.right,rect.top);
		pDC->LineTo(rect.BottomRight());
		pDC->LineTo(rect.left,rect.bottom);
		pDC->LineTo(rect.TopLeft());
	}

	if(m_select && !pDC->IsPrinting() && flag &&DRAW_SEL)
		DrawSelPoints(pDC, scale);

	pDC->SelectObject(old_p);
	pDC->SelectObject(old_b);
	m_obj_pen.DeleteObject();
	m_bg_brush.DeleteObject();

	return true;

}

int CTableElement::ShowContextMenu(CPoint pt, CWnd *wnd, int mode)
{
	if(wnd == NULL) return false;
	
	wnd->ClientToScreen(&pt);

	CMenu menu;
	CMenu *pPopup;

	HINSTANCE hInst = AfxGetResourceHandle();
	AfxSetResourceHandle(dllInst);
	menu.LoadMenu(IDR_CONTEXT_MENU);
	pPopup = menu.GetSubMenu(2);
	
	if(mode>0)
	{
		pPopup->EnableMenuItem(ID_TABLEITEM_ADD_SECTION,MF_BYCOMMAND|MF_GRAYED);
		pPopup->EnableMenuItem(ID_DELETE,MF_BYCOMMAND|MF_GRAYED);
		pPopup->EnableMenuItem(ID_FIXED,MF_BYCOMMAND|MF_GRAYED);
	}
	if(m_fixed)
		pPopup->ModifyMenu(ID_FIXED,MF_BYCOMMAND|MF_STRING,ID_FIXED,APL_T("Расфиксировать"));

	int res = pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD,pt.x, pt.y, wnd);
	AfxSetResourceHandle(hInst);
	if(res == ID_TABLEITEM_ADD_SECTION) AddSection();
	else if(res==ID_ALIGN) Align();
	else if(res==ID_FIXED)
	{
		if(m_fixed>0) m_fixed=0;
		else m_fixed=1;
	}
	return ExecuteCmd(res);
}

bool CTableElement::ElemProper(const int mode)
{
	RE_Array array;
	array.Add(this);
	HINSTANCE hInst = AfxGetResourceHandle();
	AfxSetResourceHandle(dllInst);
	CPropertyDlg dlg;
	dlg.m_elements = &array;
	dlg.mode = mode;
	if(dlg.DoModal()==IDOK)
	{
		AfxSetResourceHandle(hInst);
		return true;
	}
	AfxSetResourceHandle(hInst);
	return false;
}

bool CTableElement::AddSection()
{
	CReportSection* sec = new CReportSection(m_ReportMgr);
	HINSTANCE hInst = AfxGetResourceHandle();
	AfxSetResourceHandle(dllInst);
	CSectionPropDlg dlg;
	dlg.m_section = sec;
	if(dlg.DoModal()==IDOK)
	{
		sec = dlg.m_section;
		sec->CreateSection(m_ReportMgr);
		m_sections.Add(sec);
	}
	else delete sec;
	AfxSetResourceHandle(hInst);
	return true;	
}

void CTableElement::Update(bool set)
{
	if(set)
	{
		if(m_inst==0)
			m_inst = m_ReportMgr->m_data->CreateInstance(m_ReportMgr->e_report_table);
		CaplInstance* tmp = 0;
		m_ReportMgr->m_data->GetAttr(m_inst,m_ReportMgr->a_table_row_font,tmp);
		if(tmp==0)
			tmp = m_ReportMgr->m_data->CreateInstance(m_ReportMgr->e_font);
		m_ReportMgr->SetFontValue(tmp,m_row_lf);
		m_ReportMgr->m_data->PutAttr(m_inst,m_ReportMgr->a_table_row_height,m_row_height);
		m_ReportMgr->m_data->PutAttr(m_inst,m_ReportMgr->a_elem_name,m_name);
		m_ReportMgr->m_data->PutAttr(m_inst,m_ReportMgr->a_table_row_font,tmp);
		m_ReportMgr->m_data->PutAttr(m_inst,m_ReportMgr->a_elem_line_width,m_line_width);
		aplExtent ext;
		for(int i=0; i<m_sections.GetSize();i++)
		{
			m_sections.GetAt(i)->Update(set);
			ext.Add(m_sections.GetAt(i)->m_inst);
		}
		m_ReportMgr->m_data->PutAttr(m_inst,m_ReportMgr->a_elem_fixed,m_fixed);
		m_ReportMgr->m_data->PutAttr(m_inst,m_ReportMgr->a_table_sections,ext);
		m_ReportMgr->PutPoint(m_inst,m_ReportMgr->a_elem_org_pt,m_org_pt);
		m_ReportMgr->PutPoint(m_inst,m_ReportMgr->a_elem_size,m_size);
		
		m_ReportMgr->m_data->PutAttr(m_inst, m_ReportMgr->a_elem_textcolor, (int)m_color);
		m_ReportMgr->m_data->PutAttr(m_inst, m_ReportMgr->a_elem_backgroundcolor, (int)m_background_color);
	}
	else
	{
		if(m_inst==0)
		{
			TRACE(APL_T("Не прочитал таблицу\n"));
			return;
		}
		CaplInstance* tmp = 0;
		m_ReportMgr->m_data->GetAttr(m_inst,m_ReportMgr->a_table_row_font,tmp);
		m_ReportMgr->GetFontValue(tmp,m_row_lf);
		m_ReportMgr->m_data->GetAttr(m_inst,m_ReportMgr->a_table_row_height,m_row_height);
		m_ReportMgr->m_data->GetAttr(m_inst,m_ReportMgr->a_elem_name,m_name);
		
		int tmp_color;
		m_ReportMgr->m_data->GetAttr(m_inst, m_ReportMgr->a_elem_textcolor, tmp_color);
		m_color = (COLORREF)tmp_color;
		m_ReportMgr->m_data->GetAttr(m_inst, m_ReportMgr->a_elem_backgroundcolor, tmp_color);
		m_background_color= (COLORREF)tmp_color;
		
		m_sections.RemoveAll();

		aplExtent ext;
		m_ReportMgr->m_data->GetAttr(m_inst,m_ReportMgr->a_table_sections,ext);
		
		for(int i=0; i<ext.GetSize();i++)
		{
			CReportSection* sec = new CReportSection(m_ReportMgr);
			sec->m_inst = ext[i];
			sec->Update(set);
			m_sections.Add(sec);
		}
		m_ReportMgr->GetPoint(m_inst,m_ReportMgr->a_elem_org_pt,m_org_pt);
		m_ReportMgr->GetPoint(m_inst,m_ReportMgr->a_elem_size,m_size);
		m_ReportMgr->m_data->GetAttr(m_inst,m_ReportMgr->a_elem_line_width,m_line_width);
		m_ReportMgr->m_data->GetAttr(m_inst,m_ReportMgr->a_elem_fixed,m_fixed);
	}
}

int CTableElement::GetMemSize()
{
	int int_size = sizeof(int);
	int size = CReportElement::GetMemSize();
	size+=int_size;//размер массива секций;
	size+=int_size;//высота строки;
	size+=sizeof(LOGFONT);//шрифт строки таблицы;
	for(int i=0; i<m_sections.GetSize();i++)
		size+=m_sections.GetAt(i)->GetMemSize();
	return size;
}

void CTableElement::Delete()
{
	if(m_inst==NULL) return;
	CaplInstance* font_inst;
	m_ReportMgr->m_data->GetAttr(m_inst,m_ReportMgr->a_table_row_font,font_inst);
	m_ReportMgr->m_data->DeleteInstance(font_inst);
	int cnt = m_sections.GetSize();
	for(int i=0; i<cnt;i++)
	{
		CReportSection* sec = m_sections.GetAt(i);
		sec->Delete();
	}
	if(m_inst==0) return;
	
	CaplInstance* inst;
	//Удаление точек
	m_ReportMgr->m_data->GetAttr(m_inst, m_ReportMgr->a_elem_org_pt, inst);
	if(inst)
		m_ReportMgr->m_data->DeleteInstance(inst);
	m_ReportMgr->m_data->GetAttr(m_inst, m_ReportMgr->a_elem_size, inst);
	if(inst)
		m_ReportMgr->m_data->DeleteInstance(inst);
}