// aplWFPView.cpp : implementation file
//

#include "stdafx.h"
#include "aplWfTemlateView.h"
#include "resource.h"
#include <math.h>


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

/////////////////////////////////////////////////////////////////////////////
// CaplWFTemplateView

IMPLEMENT_DYNCREATE(CaplWFTemplateView, CZoomView)

CaplWFTemplateView::CaplWFTemplateView()
{
	m_api=0;
	m_wf_mgr=0;

	m_prc=0;
	m_task_for_sel=0;
}

CaplWFTemplateView::~CaplWFTemplateView()
{
}


BEGIN_MESSAGE_MAP(CaplWFTemplateView, CZoomView)
	//{{AFX_MSG_MAP(CaplWFTemplateView)
	ON_COMMAND(ID_ZOOM_ALL_OBJECTS, OnZoomAllObj)
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_LBUTTONDBLCLK()
	ON_COMMAND(ID_PRINT_PREVIEW, OnPrintPreview)
	//}}AFX_MSG_MAP

END_MESSAGE_MAP()


#ifdef _DEBUG
void CaplWFTemplateView::AssertValid() const
{
	CZoomView::AssertValid();
}

void CaplWFTemplateView::Dump(CDumpContext& dc) const
{
	CZoomView::Dump(dc);
}
#endif //_DEBUG


void CaplWFTemplateView::GetFont(CaplInstance *font_inst, CFont &font)
{
	
	LOGFONT lf;
	memset(&lf,0,sizeof(LOGFONT));
	
	if(font_inst==0)
	{
		memcpy((void*)lf.lfFaceName,_T("Arial"),6);
		lf.lfHeight = 16;
		lf.lfWeight = FW_NORMAL;
		lf.lfItalic = 0;
		lf.lfCharSet = RUSSIAN_CHARSET;

	}
	else
	{
		CString str;
		int tmp;

		m_api->m_data.GetAttr(font_inst, m_wf_mgr->a_font_name,str );
		if(str==_T("")) str=_T("Arial");
		_strcpy(lf.lfFaceName,str);
		
		m_api->m_data.GetAttr(font_inst, m_wf_mgr->a_font_height,tmp);
		if(tmp==0) tmp=12;
		lf.lfHeight = tmp;
		
		m_api->m_data.GetAttr(font_inst, m_wf_mgr->a_font_weight, tmp);
		if(tmp==0) tmp=FW_NORMAL;
		lf.lfWeight = tmp;
		
		m_api->m_data.GetAttr(font_inst, m_wf_mgr->a_font_italic, tmp);
		lf.lfItalic = tmp;
		
		m_api->m_data.GetAttr(font_inst, m_wf_mgr->a_font_char_set, tmp);
		if(tmp==0) tmp=RUSSIAN_CHARSET;
		lf.lfCharSet = tmp;
	}
	font.CreateFontIndirect(&lf);
}

/////////////////////////////////////////////////////////////////////////////
// CaplWFTemplateView drawing
//********************************************************************

void CaplWFTemplateView::InitialUpdate()
{
	OnInitialUpdate();
}
//********************************************************************
void CaplWFTemplateView::OnInitialUpdate()
{
	CZoomView::OnInitialUpdate();

	ShowTemplate(m_prc,m_task_for_sel);
}

//********************************************************************
bool CaplWFTemplateView::ShowTemplate(CaplInstance *prc, CaplInstance *act)
{
	//if(m_prc==prc) return false;
	
	m_prc=prc;
	m_task_for_sel=act;
	int m_page_width,m_page_high;

	
	if(m_prc==0)
	{
		m_page_width=100;
		m_page_high=100;

		m_pages_x=1;
		m_pages_y=1;

		m_activities.Clear();
		m_connectors.Clear();

	}
	else
	{
		m_api->m_data.GetAttr(m_prc,m_wf_mgr->a_proc_tmpl_hight,m_page_high);
		m_api->m_data.GetAttr(m_prc,m_wf_mgr->a_proc_tmpl_width,m_page_width);

		m_api->m_data.GetAttr(m_prc,m_wf_mgr->a_proc_tmpl_cols,m_pages_x);
		m_api->m_data.GetAttr(m_prc,m_wf_mgr->a_proc_tmpl_rows,m_pages_y);

		m_wf_mgr->GetProcessComponents(m_prc,m_activities);
		m_wf_mgr->GetProcessConnectors(m_prc,m_connectors);

	}
	
	m_sizePage.cx=m_page_width*10;
	m_sizePage.cy=m_page_high*10;
		
	m_sizeTotal.cx=m_page_width*m_pages_x;
	m_sizeTotal.cy=m_page_high*m_pages_y;


	m_zoom=1;
	SetScrollSizes(MM_LOMETRIC, m_sizeTotal);
	ZoomAllObj();
	return true;
}
//********************************************************************
void CaplWFTemplateView::GetObjectsRect(RECT &rect)
{
	if(m_activities.GetSize()<1)
	{
		rect.left=0;
		rect.top=0;
		rect.right=m_sizeTotal.cx;
		rect.bottom=m_sizeTotal.cy;
		return;
	}

	int i;

	for(i=0;i<m_activities.GetSize();i++)
	{
		int x,y,cx,cy;
		CaplInstance *act=m_activities[i];
		CaplInstance *point;
		m_api->m_data.GetAttr(act,m_wf_mgr->a_act_tmpl_point,point);
		m_api->m_data.GetAttrBN(point,_T("x"),x);
		m_api->m_data.GetAttrBN(point,_T("y"),y);
		m_api->m_data.GetAttr(act,m_wf_mgr->a_act_tmpl_cx,cx);
		m_api->m_data.GetAttr(act,m_wf_mgr->a_act_tmpl_cy,cy);
		
		if(i==0)
		{
			rect.left=x;
			rect.right=x+cx;
			rect.top=y;
			rect.bottom=y+cy;
		}
		else
		{
			if(x<rect.left) rect.left=x;
			if(x+cx>rect.right) rect.right=x+cx;
			if(y<rect.top) rect.top=y;
			if(y+cy>rect.bottom) rect.bottom=y+cy;
		}
	}
}
//********************************************************************
void CaplWFTemplateView::OnDraw(CDC* pDC)
{
	//CZoomtestDoc* pDoc = GetDocument();
	// TODO: add draw code here
	int i,j;
	CString buf;

	CPen pen(PS_DOT,1,RGB(64,64,64));
	CPen *oldPen=pDC->SelectObject(&pen);

	int  all_cx=m_sizePage.cx*m_pages_x;
	int  all_cy=m_sizePage.cy*m_pages_y;
	
	for(i=1;i<m_pages_x+1;i++)
	{
		pDC->MoveTo(i*m_sizePage.cx,0);
		pDC->LineTo(i*m_sizePage.cx,-all_cy);

	}

	for(i=1;i<m_pages_y+1;i++)
	{
		pDC->MoveTo(0,-i*m_sizePage.cy);
		pDC->LineTo(all_cx,-i*m_sizePage.cy);
	}

	pDC->SelectObject(oldPen);
	pen.DeleteObject();

	
	for(i=0;i<m_activities.GetSize();i++)
	{
		int x,y,cx,cy,width;
		CaplInstance *act=m_activities[i];
		CaplInstance *point;
		m_api->m_data.GetAttr(act,m_wf_mgr->a_act_tmpl_point,point);
		m_api->m_data.GetAttr(point,m_wf_mgr->a_apl_point_x,x);
		m_api->m_data.GetAttr(point,m_wf_mgr->a_apl_point_y,y);
		m_api->m_data.GetAttr(act,m_wf_mgr->a_act_tmpl_cx,cx);
		m_api->m_data.GetAttr(act,m_wf_mgr->a_act_tmpl_cy,cy);
		m_api->m_data.GetAttr(act,m_wf_mgr->a_act_tmpl_width,width);
		if(width==0) width=3;

		CaplAggr aggr;
		m_api->m_data.GetAttr(act,m_wf_mgr->a_act_tmpl_color,aggr);
		int color,colortxt;
		aggr.GetByIndex(0,color);
		aggr.GetByIndex(1,colortxt);
		
		if(m_api->m_data.IsKindOf(act,m_wf_mgr->e_start_point))
		{
			// Начальная точка
			POINT pnts[4];
			pnts[0].x=x;	pnts[0].y=-y;
			pnts[1].x=x;	pnts[1].y=-y-cy;
			pnts[2].x=x+cx; pnts[2].y=-y-(cy/2);
			pnts[3]=pnts[0];
			
			CPen pen(PS_SOLID,1,color);
			CPen *oldPen=pDC->SelectObject(&pen);

			CBrush fonbrush(color);
			CBrush *oldBrush=pDC->SelectObject(&fonbrush);
			pDC->Polygon(&(pnts[0]),4);
			pDC->SelectObject(oldBrush);
			pDC->SelectObject(oldPen);
			fonbrush.DeleteObject();
			pen.DeleteObject();
			
		}
		else if(m_api->m_data.IsKindOf(act,m_wf_mgr->e_end_point))
		{
			// Конечная точка
			POINT pnts[4];
			pnts[0].x=x+cx;	pnts[0].y=-y;
			pnts[1].x=x+cx;	pnts[1].y=-y-cy;
			pnts[2].x=x; pnts[2].y=-y-(cy/2);
			pnts[3]=pnts[0];
			
			CPen pen(PS_SOLID,1,color);
			CPen *oldPen=pDC->SelectObject(&pen);

			CBrush fonbrush(color);
			CBrush *oldBrush=pDC->SelectObject(&fonbrush);
			pDC->Polygon(&(pnts[0]),4);
			pDC->SelectObject(oldBrush);
			pDC->SelectObject(oldPen);
			fonbrush.DeleteObject();
			pen.DeleteObject();
		}
		else
		{
			// Действие 
			CaplInstance *role;
			CString id,name,role_name;
			m_api->m_data.GetAttr(act,m_wf_mgr->a_action_id,id);

			bool bIsLogOp=m_wf_mgr->IsItemLogicalElement(act);
			if(bIsLogOp)
			{
				buf=id; id=buf.Right(buf.GetLength()-1);
				role_name=_T("");
			}

			m_api->m_data.GetAttr(act,m_wf_mgr->a_action_name,name);
			m_api->m_data.GetAttr(act,m_wf_mgr->a_activity_role,role);
			if(role != NULL)
				m_api->m_data.GetAttr(role,m_api->m_appr_mgr.a_po_role_name,role_name);

			CPen pen;
			CBrush fon_brush;

			if(act==m_task_for_sel)
			{
				pen.CreatePen(PS_SOLID,width*2,color);
				fon_brush.CreateSysColorBrush(COLOR_INFOBK);
				//fon_brush.CreateSolidBrush(RGB(198,198,198));
			}
			else
			{
				pen.CreatePen(PS_SOLID,width,color);
				fon_brush.CreateSolidBrush(RGB(255,255,255));
			}
			
			CBrush *old_fon_brush=pDC->SelectObject(&fon_brush);
			CPen *oldPen=pDC->SelectObject(&pen);

			pDC->SetBkMode(TRANSPARENT);

			pDC->Rectangle(x,-y,x+cx,-y-cy);

			int cx_stop=0;
			bool bStopAnotherTask;
			m_api->m_data.GetAttr(act,m_wf_mgr->a_activity_stop_another_task,bStopAnotherTask);
			if(bStopAnotherTask)
			{
				cx_stop=20;
				CPen pen_sel;
				CBrush brush_stoper; brush_stoper.CreateSolidBrush(RGB(255,0,0));
				pDC->SelectObject(&brush_stoper);
				pen_sel.CreatePen(PS_SOLID,0,RGB(255,0,0));
				oldPen=pDC->SelectObject(&pen_sel);
				pDC->Rectangle(x+1,-y-2,x+cx_stop,-y-cy+2);
				pDC->Rectangle(x+cx-cx_stop,-y-2,x+cx-1,-y-cy+2);
				pDC->SelectObject(&fon_brush);
				pDC->SelectObject(&pen);

				pDC->MoveTo(x+cx_stop,-y-2);
				pDC->LineTo(x+cx_stop,-y-cy+2);

				pDC->MoveTo(x+cx-cx_stop,-y-2);
				pDC->LineTo(x+cx-cx_stop,-y-cy+2);
			}

			int y1=-y-(cy*2/3);
			pDC->MoveTo(x+1+cx_stop,y1);
			pDC->LineTo(x+cx-1-cx_stop,y1);
			
			int x1=x+(cx*2/3);
			if(bIsLogOp) x1=x+(cx*1/3);

			pDC->MoveTo(x1,y1-1);
			pDC->LineTo(x1,-y-cy+1);

			pDC->SelectObject(oldPen);
			pen.DeleteObject();


			
			CaplInstance *font_inst;
			m_api->m_data.GetAttr(act,m_wf_mgr->a_act_tmpl_font,font_inst);

			CFont font;
			GetFont(font_inst,font);
			CFont *oldFont=pDC->SelectObject(&font);
			COLORREF old_txt_color=pDC->SetTextColor(colortxt);

			RECT rect; 
			rect.left=x+2+cx_stop;
			rect.right=x+cx-2-cx_stop;
			rect.top=-y-2;
			rect.bottom=y1+2;

			if(!bIsLogOp)
			{
				pDC->DrawText(name,&rect,DT_CENTER|DT_END_ELLIPSIS|DT_WORDBREAK|DT_NOPREFIX);

				rect.left=x+2+cx_stop;
				rect.right=x1-2;
				rect.top=y1-2;
				rect.bottom=-y-cy+2;
				pDC->DrawText(role_name,&rect,DT_CENTER|DT_END_ELLIPSIS|DT_WORDBREAK|DT_VCENTER|DT_SINGLELINE|DT_NOPREFIX);
			}
			else 
			{
				CFont op_font; 
				LOGFONT op_lf;
				font.GetLogFont(&op_lf);
				op_lf.lfHeight*=3;
				op_lf.lfWeight=FW_MEDIUM;

				op_font.CreateFontIndirect(&op_lf);
				pDC->SelectObject(&op_font);
				buf=_T("&");
				pDC->DrawText(buf,&rect,DT_CENTER|DT_VCENTER|DT_SINGLELINE|DT_WORDBREAK|DT_NOPREFIX);
				pDC->SelectObject(&font);
			}
			
			rect.left=x1+2;
			rect.right=x+cx-2-cx_stop;
			rect.top=y1-2;
			rect.bottom=-y-cy+2;

			pDC->DrawText(id,&rect,DT_CENTER|DT_END_ELLIPSIS|DT_WORDBREAK|DT_VCENTER|DT_SINGLELINE|DT_NOPREFIX);

			pDC->SetTextColor(old_txt_color);
			pDC->SelectObject(&old_fon_brush);
			pDC->SelectObject(oldFont);
			pDC->SelectObject(oldPen);
			fon_brush.DeleteObject();
			pen.DeleteObject();
			font.DeleteObject();

		}
	}
	for(i=0;i<m_connectors.GetSize();i++)
	{
		int x,y,x0,y0,x1,y1,width,arrow_size;
		CaplInstance *con=m_connectors[i];

		CaplAggr aggr;
		m_api->m_data.GetAttr(con,m_wf_mgr->a_act_rel_color,aggr);
		int color,colortxt;
		aggr.GetByIndex(0,color);
		aggr.GetByIndex(1,colortxt);

		m_api->m_data.GetAttr(con,m_wf_mgr->a_act_rel_width,width);
		if(width==0) width=3;
		m_api->m_data.GetAttr(con,m_wf_mgr->a_act_rel_arrow_size,arrow_size);
		if(arrow_size==0) arrow_size=10;


		CPen pen(PS_SOLID,width,color);
		CPen *oldPen=pDC->SelectObject(&pen);

	    CaplInstance *point;
		aplExtent points;
		m_api->m_data.GetAttr(con,m_wf_mgr->a_act_rel_points,points);
		if(points.Size>1)
		{
			point=points[0];
			m_api->m_data.GetAttr(point,m_wf_mgr->a_apl_point_x,x);
			m_api->m_data.GetAttr(point,m_wf_mgr->a_apl_point_y,y);
			pDC->MoveTo(x,-y);
			x0=x; y0=y;

			for(j=1;j<points.Size-1;j++)
			{
				point=points[j];
				m_api->m_data.GetAttr(point,m_wf_mgr->a_apl_point_x,x);
				m_api->m_data.GetAttr(point,m_wf_mgr->a_apl_point_y,y);
				
				pDC->LineTo(x,-y);
			}
			
				
				// рисование стрелки
			point=points[points.GetSize()-1];
			m_api->m_data.GetAttr(point,m_wf_mgr->a_apl_point_x,x);
			m_api->m_data.GetAttr(point,m_wf_mgr->a_apl_point_y,y);
			point=points[points.GetSize()-2];
			m_api->m_data.GetAttr(point,m_wf_mgr->a_apl_point_x,x1);
			m_api->m_data.GetAttr(point,m_wf_mgr->a_apl_point_y,y1);

			POINT p1={x,y};


			double dx=x-x1;
			double dy=y-y1;
			int l=width*arrow_size;
			double fi=atan2(dy,dx);
			double d1=l*sin(fi-0.3);
			double d2=l*cos(fi-0.3);
			double d3=l*sin(fi+0.3);
			double d4=l*cos(fi+0.3);
			double d5=(l+1)*sin(fi);
			double d6=(l+1)*cos(fi);

			POINT p[4],pe;
			pe.x=(long)(p1.x-d6);
			pe.y=-(long)(p1.y-d5);
			pDC->LineTo(pe);

			p[0].x=(long)(p1.x-cos(fi));
			p[0].y=-(long)(p1.y-sin(fi));
			p[1].x=(long)(p1.x-d4);
			p[1].y=-(long)(p1.y-d3);
			p[2].x=(long)(p1.x-d2);
			p[2].y=-(long)(p1.y-d1);
			p[3]=p[0];
		
			//dc->SelectObject(&m_SelPen);
			//pDC->MoveTo(p[0]);
			//pDC->PolylineTo(p,4);

			CBrush fonbrush(color);
			CBrush *oldBrush=pDC->SelectObject(&fonbrush);
			pDC->Polygon(&(p[0]),4);
			pDC->SelectObject(oldBrush);
			fonbrush.DeleteObject();
		}

		pDC->SelectObject(oldPen);
		pen.DeleteObject();

		CString name;
		m_api->m_data.GetAttr(con,m_wf_mgr->a_act_rel_name,name);
		CaplInstance *font_inst;
		m_api->m_data.GetAttr(con,m_wf_mgr->a_act_rel_font,font_inst);
		
		m_api->m_data.GetAttr(con,m_wf_mgr->a_act_rel_title_point,point);
		m_api->m_data.GetAttr(point,m_wf_mgr->a_apl_point_x,x);
		m_api->m_data.GetAttr(point,m_wf_mgr->a_apl_point_y,y);

		CFont font;
		GetFont(font_inst,font);
		CFont *oldFont=pDC->SelectObject(&font);
		COLORREF old_txt_color=pDC->SetTextColor(colortxt);

		pDC->TextOut(x+x0,-(y+y0),name);
		//pDC->DrawText(name,&name_rect,DT_CENTER|DT_END_ELLIPSIS|DT_WORDBREAK);

		pDC->SetTextColor(old_txt_color);
		pDC->SelectObject(oldFont);
		font.DeleteObject();
	}
}
//********************************************************************
void CaplWFTemplateView::ZoomAllObj()
{
	OnZoomAllObj() ;
}
//********************************************************************
void CaplWFTemplateView::OnZoomAllObj() 
{
	// TODO: Add your command handler code here
	RECT rect;
	GetObjectsRect(rect);
	rect.left-=10; if(rect.left<0) rect.left=0;
	rect.right+=10;
	rect.top=-10; if(rect.top<0) rect.top=0;
	rect.bottom+=10;

	ZoomRect(rect);
	
}
//********************************************************************
void CaplWFTemplateView::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	
	CZoomView::OnLButtonDown(nFlags, point);


}
//********************************************************************
void CaplWFTemplateView::OnLButtonUp(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	CZoomView::OnLButtonUp(nFlags, point);


}
//********************************************************************
void CaplWFTemplateView::OnLButtonDblClk(UINT nFlags, CPoint point) 
{
	CZoomView::OnLButtonDblClk(nFlags, point);

	POINT p=point;

	CPaintDC dc(this); // device context for painting
	OnPrepareDC(&dc);
	dc.DPtoLP(&p);
	p.x=(int)(p.x/m_zoom);	
	p.y=(int)(-p.y/m_zoom);	

	int i;

	for(i=0;i<m_activities.GetSize();i++)
	{
		int x,y,cx,cy;
		CaplInstance *act=m_activities[i];
		CaplInstance *point;
		m_api->m_data.GetAttr(act,m_wf_mgr->a_act_tmpl_point,point);
		m_api->m_data.GetAttrBN(point,_T("x"),x);
		m_api->m_data.GetAttrBN(point,_T("y"),y);
		m_api->m_data.GetAttr(act,m_wf_mgr->a_act_tmpl_cx,cx);
		m_api->m_data.GetAttr(act,m_wf_mgr->a_act_tmpl_cy,cy);

		if((p.x>x) && (p.x<x+cx) && (p.y>y) && (p.y<y+cy))
		{
			m_wf_mgr->ShowTmplProperties(act);
			break;
		}
	}
}
//********************************************************************



void CaplWFTemplateView::OnPrintPreview() 
{
	// TODO: Add your command handler code here
	CZoomView::OnFilePrintPreview();
	
}

void CaplWFTemplateView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo) 
{
	AfxMessageBox(_T("OnBeginPrinting"));
	// TODO: Add your specialized code here and/or call the base class
	
	//CZoomView::OnBeginPrinting(pDC, pInfo);
}

void CaplWFTemplateView::OnEndPrinting(CDC* pDC, CPrintInfo* pInfo) 
{
	AfxMessageBox(_T("OnEndPrinting"));
	// TODO: Add your specialized code here and/or call the base class
	
	//CZoomView::OnEndPrinting(pDC, pInfo);
}

BOOL CaplWFTemplateView::OnPreparePrinting(CPrintInfo* pInfo) 
{
	AfxMessageBox(_T("OnPreparePrinting"));
	// TODO: call DoPreparePrinting to invoke the Print dialog box
	return DoPreparePrinting(pInfo);
	
	//return CZoomView::OnPreparePrinting(pInfo);
}
