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

#include "stdafx.h"
#include "AG_MDA.h"
#include "ShapeSwimlane.h"

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

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
extern void AddToLog(CString);
ShapeSwimlane::ShapeSwimlane()
{
	m_pSwimlane = NULL;
	m_pShapeActivityGraph = NULL;
	m_pMarkElement = new MarkSwimlane;
}

ShapeSwimlane::~ShapeSwimlane()
{
	//删除包含得所有活动
	for( int i = 0; i <= m_pActivities.GetUpperBound() ; i ++ )
	{
		ShapeActivity *p = m_pActivities.GetAt( i );
		delete p;
	}
}

BOOL ShapeSwimlane::In(CPoint pt)
{
	return m_Pos.PtInRect( pt );
}

void ShapeSwimlane::Draw(CDC *pDC)
{
	if( m_pSwimlane )
	{
		CRect r;
		CString tp =":";
		tp += m_pSwimlane->pType->UMLGeneralizableElement::name;
		r = m_Pos;
		r.bottom = r.top + m_TextFont.lfHeight*2;
		DrawTextCenter( r , m_pSwimlane->name + tp, pDC );
		SetTempPen( pDC , 1 , 0 ,PS_SOLID );
		pDC->MoveTo( m_Pos.left , m_Pos.top );
		pDC->LineTo( m_Pos.right , m_Pos.top );
		pDC->LineTo( m_Pos.right , m_Pos.bottom );
		pDC->LineTo( m_Pos.left , m_Pos.bottom );
		pDC->LineTo( m_Pos.left , m_Pos.top );
		RestorePen( pDC );
	}
	for( int i = 0 ; i <= m_pActivities.GetUpperBound() ; i ++ )
	{
		ShapeActivity *pa = m_pActivities.GetAt( i );
		pa->DrawDefault( pDC );
	}
}

ShapeType ShapeSwimlane::GetType()
{
	return SHAPE_SWIMLANE;
}

void ShapeSwimlane::AdjustActivityPos(RECT o , RECT n , ShapeActivity *sa)
{
	if( !sa )
	{//调整泳道中所有的活动
		for( int i = 0 ; i <= m_pActivities.GetUpperBound() ; i ++ )
		{
			ShapeActivity *p = m_pActivities.GetAt( i );
			int awid;
			float rx,ry;
			int dx,dy;
			POINT center;
			rx = (p->m_Pos.right + p->m_Pos.left)/2 - o.left;
			ry = (p->m_Pos.bottom + p->m_Pos.top)/2 - o.top;
			rx /= (o.right - o.left);
			ry /= (o.bottom - o.top);

			center.x = (n.right - n.left)*rx + n.left;
			center.y = (n.bottom - n.top)*ry + n.top;
			
			dx = p->m_Pos.right - p->m_Pos.left;
			dy = p->m_Pos.bottom - p->m_Pos.top;
			dx /=2;
			dy/=2;

			p->m_Pos.left = center.x - dx;
			p->m_Pos.right = center.x + dx;
			p->m_Pos.top = center.y - dy;
			p->m_Pos.bottom = center.y +dy;

		
			for( int j = 0 ; j <= p->m_pOutTransEdges.GetUpperBound() ; j ++ )
			{
				ShapeTransEdge *edge = p->m_pOutTransEdges.GetAt( j );
				edge->AdjustHeadAndTail();
			}
			for( j = 0 ; j <= p->m_pInTransEdges.GetUpperBound() ; j ++ )
			{
				ShapeTransEdge *edge = p->m_pInTransEdges.GetAt( j );
				edge->AdjustHeadAndTail();
			}
		}
	}
	else
	{//调整某个活动
		int dx;
		int awid;
		dx = m_Pos.right - m_Pos.left;
		awid = sa->m_Pos.right - sa->m_Pos.left;
		dx -= awid;
		dx /= 2;
		sa->m_Pos.left = m_Pos.left + dx;
		sa->m_Pos.right = sa->m_Pos.left + awid;
		for( int j = 0 ; j <= sa->m_pOutTransEdges.GetUpperBound() ; j ++ )
		{
			ShapeTransEdge *edge = sa->m_pOutTransEdges.GetAt( j );
			edge->AdjustHeadAndTail();
		}
		for( j = 0 ; j <= sa->m_pInTransEdges.GetUpperBound() ; j ++ )
		{
			ShapeTransEdge *edge = sa->m_pInTransEdges.GetAt( j );
			edge->AdjustHeadAndTail();
		}
	}
}

ShapeNamespace* ShapeSwimlane::GetShapeNamespace()
{
	return m_pShapeActivityGraph->GetShapeNamespace();
}

void ShapeSwimlane::Save(CFile &file, int &tabnum)
{
	CString txt;
	WriteTab( file ,tabnum );
	WriteTag( file , "<SWIMLANE>" );
	WriteEnter( file );
	tabnum ++;
	//id
	txt.Format("<ID>%d</ID>",m_ID );
	WriteTab( file , tabnum );
	WriteContent( file , txt );
	WriteEnter( file );
	//pos
	WritePos( file ,tabnum );
	//type
	txt.Format("<TYPE>%d</TYPE>",FindClassID(m_pSwimlane->pType));
	WriteTab( file , tabnum );
	WriteContent( file , txt );
	WriteEnter( file );
	//name
	txt = "<NAME>";
	txt += m_pSwimlane->name ;
	txt += "</NAME>";
	WriteTab( file , tabnum );
	WriteContent( file , txt );
	WriteEnter( file );
	//activity
	for( int i = 0 ; i<= m_pActivities.GetUpperBound() ; i ++ )
	{
		ShapeActivity *pSA = m_pActivities.GetAt( i );
		pSA->Save( file ,tabnum );
	}
	//mark
	MarkSwimlane *pMS =(MarkSwimlane*)m_pMarkElement;
	WriteTab( file , tabnum );
	WriteTag( file , "<MARK>" );
	WriteEnter( file );
	tabnum ++;
	if( pMS->m_ToParameter )
	{
		txt = "<TOPARAM>TRUE</TOPARAM>";
	}
	else
	{
		txt = "<TOPARAM>FALSE</TOPARAM>";
	}
	WriteTab( file , tabnum );
	WriteTag( file , txt );
	WriteEnter( file );

	if( pMS->m_ToParameter )
	{
		WriteParameter( file ,pMS->m_UMLParameter , tabnum );
	}
	else
	{
		if( pMS->m_GetMethod )
		{
			txt = "<GETMETHOD>TRUE</GETMETHOD>";
		}
		else
		{
			txt = "<GETMETHOD>FALSE</GETMETHOD>";
		}
		WriteTab( file ,tabnum);
		WriteContent( file , txt );
		WriteEnter( file );
		if( pMS->m_SetMethod )
		{
			txt = "<SETMETHOD>TRUE</SETMETHOD>";
		}
		else
		{
			txt = "<SETMETHOD>FALSE</SETMETHOD>";
		}
		WriteTab( file ,tabnum);
		WriteContent( file , txt );
		WriteEnter( file );
		WriteAttribute( file ,pMS->m_UMLAttribute , tabnum );
	}

	tabnum -- ;
	WriteTab( file , tabnum );
	WriteTag( file , "</MARK>" );
	WriteEnter( file );

	tabnum --;
	WriteTab( file ,tabnum );
	WriteTag( file , "</SWIMLANE>" );
	WriteEnter( file );
}
