// ReportBound.cpp: implementation of the CReportBound class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
//#include "ReportConstuctor.h"
#include "ReportDict.h"

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

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

CBoundRect::CBoundRect(CReportSheet* sheet, CaplReportMgr* dict)
			:CReportElement(dict, E_RECT)
{
	ASSERT(sheet);
	m_bound_creation = false; // признак создания ракмки
	m_drag_status = false;

	m_work_elem = NULL;

	m_elem_drag_mode = 0;
	m_owner_sheet = sheet;
}

CBoundRect::~CBoundRect()
{
}

BOOL CBoundRect::TraceBoundRect(CPoint cp, CDC *pDC, double scale, bool bDraw)
{
	if(!pDC) return false;	
	int ROP = pDC->GetROP2(); 
	if(m_drag_status && bDraw)
	{
		pDC->SetROP2(R2_NOT);
		Draw(pDC, scale, 0);
	}
	else
		m_drag_status = true;
	Move(cp, m_elem_drag_mode);
	m_cur_pt = cp;
	pDC->SetROP2(ROP);
	if(bDraw)
		Draw(pDC, scale, 0);
	return true;
}

CReportElement * CBoundRect::EndBound()
{
	if(!m_bound_creation)
		return NULL;	
	CReportElement * elem  = NULL;
	if(m_type!=E_LINE)
	{
		if(m_size.cx<0)
		{
			m_size.cx = - m_size.cx;
			m_org_pt.x = m_org_pt.x-m_size.cx;
		}
		if(m_size.cy>0)
		{
			m_size.cy = - m_size.cy;
			m_org_pt.y = m_org_pt.y-m_size.cy;
		}
	}
	if(m_work_elem)
	{
		m_work_elem->m_org_pt = m_org_pt;
		m_work_elem->m_size = m_size;
		elem = m_work_elem;
	}
	ResetBound();
	return elem;	
}

BOOL CBoundRect::Draw(CDC *pDC, double scale, int draw_mode, UINT flag)
{	
	if(pDC==NULL) return FALSE;
	if(scale==0) return FALSE;
	if(!m_bound_creation)
		return false;
	CPen * old_pen  = NULL;
	//	CPen m_bound_pen(PS_DASH, 1, RGB(0,0,0));
	CRect rect;
	GetRect(rect, scale);
	CPen pen;
	int rop = pDC->SetROP2(R2_XORPEN);
	pen.CreatePen(PS_DOT,3,RGB(128,128,128));
	CPen *old = pDC->SelectObject(&pen);
	COLORREF col = pDC->SetBkColor(0);		
	switch(m_type)
	{
		case E_LINE:
			pDC->MoveTo(rect.TopLeft());
			pDC->LineTo(rect.BottomRight());
			break;
		default : 
			{
				pDC->MoveTo(rect.TopLeft());
				pDC->LineTo(CPoint(rect.right,rect.top));
				pDC->LineTo(rect.BottomRight());
				pDC->LineTo(CPoint(rect.left,rect.bottom));
				pDC->LineTo(rect.TopLeft());
			}
			break;
	}
	pDC->SetBkColor(col);
	pDC->SelectObject(old);
	pDC->SetROP2(rop);
	pen.DeleteObject();
	return true;

}

BOOL CBoundRect::ResetBound()
{
	m_bound_creation = false;
	m_work_elem = NULL;
	return true;
}

void CBoundRect::SetType(TReportElementType type)
{
	m_type = type;
}

void CBoundRect::StartObjOper(CReportElement *elem, int drag_mode, CPoint pt)
{
	if(drag_mode == NONE)
		return;
	ResetBound();
	m_drag_status = false;
	m_org_pt = CPoint(0,0);
	m_size = CSize(0,0);
	if(elem == NULL)
	{			
		// создание новых элемнтов
		CRect r(pt, CSize(0,0));
		SetRect(r, 1);
		switch(drag_mode)
		{
		case E_CREATE_LINE : 
			m_type = E_LINE;
			break;
		default : 
			m_type = E_RECT;
			break;
		}
	}
	else
	{		
		// перемещение или изменение размера элемента
		m_org_pt = elem->m_org_pt;
		m_size = elem->m_size;
		m_type = elem->GetType();
		m_work_elem = elem;	
	}

	m_cur_pt = pt;
	m_elem_drag_mode = drag_mode;	
	m_bound_creation = true;		
}


int CBoundRect::Move(CPoint pt, int drag_mode)
{
	CRect rect;
	GetRect(rect, 1, 1);
	switch(m_type)
	{
	case E_LINE:
		{
			switch(drag_mode)
			{
			case L_RESIZE :
				rect.TopLeft() = pt;
				break;
			case E_CREATE_LINE :
			case R_RESIZE :
				rect.BottomRight() = pt;
				break;
			case OBJ_MOVE :
				rect.OffsetRect(pt-m_cur_pt);
				break;
			}
		}	break;
	default : 
		{
			switch(drag_mode)
			{
			case TL_RESIZE : 
				rect.top = pt.y;
				rect.left = pt.x;
				break;
			case TR_RESIZE : 
				rect.top  = pt.y;
				rect.right = pt.x;
				break;
			case T_RESIZE :
				rect.top = pt.y;
				break;
			case  B_RESIZE:
				rect.bottom = pt.y;
				break;
			case L_RESIZE :
				rect.left = pt.x;
				break;
			case R_RESIZE :
				rect.right = pt.x;
				break;
			case E_SELECT_FRAME :
			case E_CREATE_RECT :
			case BR_RESIZE :
				rect.bottom = pt.y;
				rect.right = pt.x;
				break;
			case BL_RESIZE : 
				rect.bottom = pt.y;
				rect.left = pt.x;
				break;
			case OBJ_MOVE :
				rect.OffsetRect(pt-m_cur_pt);
				break;
			}			
		}	break;
	}
	SetRect(rect, 1);
	return drag_mode;
}
