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

#include "stdafx.h"
#include "AG_MDA.h"
#include "ShapeActivity.h"

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

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

ShapeActivity::ShapeActivity()
{
	m_pUMLActivity = NULL;
	//m_pShapeSwimlane = NULL;
	//m_pShapeActivityGraph = NULL;
	m_pOwnedShape = NULL;
	m_ShowExpression = FALSE;
	m_Pos = CRect( 100, 500 , 150 , 550 );

	sync=false;
	visitedNum=0;

	checked=false;
	
}

ShapeActivity::~ShapeActivity()
{

}

void ShapeActivity::Draw(CDC *pDC)
{
	if( m_pUMLActivity )
	{
		CString id;
		id.Format("(%d)",m_ID);
		if( m_pUMLActivity->m_ActivityKind == ACTIVITY_ACTION || ACTIVITY_SUB == m_pUMLActivity->m_ActivityKind )
		{
			CPoint p;
			CRect r;
			p.x = m_Pos.right - m_Pos.left;
			p.x /= 6;
			p.y = m_Pos.bottom - m_Pos.top;
			r = m_Pos;
			r.left = m_Pos.left - p.x/2;
			r.right = m_Pos.right + p.x/2;
			pDC->RoundRect( r , p );
			if( ACTIVITY_SUB == m_pUMLActivity->m_ActivityKind )
			{
				CRect r1 , r2;
				int wid,hei;
				CPoint p1 , p2;
				wid = m_Pos.right - m_Pos.left;
				hei = m_Pos.bottom - m_Pos.top;
				wid /= 12;
				hei /= 12;
				r1.left = m_Pos.right - 3*wid;
				r1.top = m_Pos.bottom - 2*hei;
				r1.right = r1.left + wid;
				r1.bottom = r1.top + hei;
				p1.x = wid/12;
				p1.y = hei;

				r2.left = m_Pos.right - wid;
				r2.top = m_Pos.bottom - 3*hei;
				r2.right = r2.left + wid;
				r2.bottom = r2.top + hei;
				p2 = p1;

				SetTempPen( pDC , 1 , m_LineColor , PS_SOLID );

				pDC->RoundRect( r1 , p1 );
				pDC->RoundRect( r2 , p2 );
				pDC->MoveTo( r1.right , r1.top);
				pDC->LineTo( r2.left , r2.bottom );

				RestorePen( pDC );
			}
			DrawTextCenter( m_Pos , m_pUMLActivity->name, pDC );
		}
		else if( m_pUMLActivity->m_ActivityKind == ACTIVITY_FINISH )
		{
			CRect r;
			r = m_Pos;
			r.left += (m_Pos.right - m_Pos.left )/6;
			r.right -= (m_Pos.right - m_Pos.left )/6;
			r.top += (m_Pos.bottom - m_Pos.top )/6;
			r.bottom -= (m_Pos.bottom - m_Pos.top )/6;
			SetTempBrush( pDC , 0 );
			SetTempPen( pDC , 1 , m_LineColor , PS_SOLID );
			pDC->Ellipse( r );
			pDC->Arc( m_Pos , CPoint(m_Pos.left, m_Pos.top) , CPoint(m_Pos.left, m_Pos.top) );
			RestorePen( pDC );
			RestoreBrush( pDC );
			DrawTextLeft( CRect( m_Pos.right , m_Pos.top , m_Pos.right + 100 ,m_Pos.bottom),m_pUMLActivity->name ,pDC );
		}
		else if( m_pUMLActivity->m_ActivityKind == ACTIVITY_INIT )
		{
			CRect r;
			r = m_Pos;
			SetTempBrush( pDC , 0 );
			SetTempPen( pDC , 1 , m_LineColor , PS_SOLID );
			pDC->Ellipse( r );
			RestorePen( pDC );
			RestoreBrush( pDC );
			DrawTextLeft( CRect( m_Pos.right , m_Pos.top , m_Pos.right + 100 ,m_Pos.bottom),m_pUMLActivity->name ,pDC );
		}
		else if( m_pUMLActivity->m_ActivityKind == ACTIVITY_SYNCH )
		{
			SetTempBrush( pDC , 0 );
			pDC->Rectangle( m_Pos );
			RestoreBrush( pDC );
			DrawTextLeft( CRect( m_Pos.right , m_Pos.top -10, m_Pos.right + 100 ,m_Pos.bottom+10),m_pUMLActivity->name ,pDC );
		}
	}
}

BOOL ShapeActivity::In(CPoint pt)
{
	if( !m_pUMLActivity )return FALSE;
	if( m_pUMLActivity->m_ActivityKind == ACTIVITY_ACTION || ACTIVITY_SUB == m_pUMLActivity->m_ActivityKind )
	{
		if( m_Pos.PtInRect( pt ) )return TRUE;
		else
		{
			int x1,x2,y1,y2;
			int wid;
			wid = m_Pos.right - m_Pos.left;
			wid /= 12;
			x1 = m_Pos.left - wid;
			x2 = x1 + 2*wid;
			y1 = m_Pos.top;
			y2 = m_Pos.bottom;
			if( pt.x >= x1 && pt.x <= m_Pos.left )
			{
				CRgn rgn;
				rgn.CreateEllipticRgn( x1 , y1 , x2 , y2);
				return rgn.PtInRegion( pt );
			}
			x1 = m_Pos.right - wid;
			x2 = x1 + 2*wid;
			y1 = m_Pos.top;
			y2 = m_Pos.bottom;
			if( pt.x >= m_Pos.right && pt.x <= x2 )
			{
				CRgn rgn;
				rgn.CreateEllipticRgn( x1 , y1 , x2 , y2);
				return rgn.PtInRegion( pt );
			}
			else return FALSE;
		}
	}
	else if( m_pUMLActivity->m_ActivityKind == ACTIVITY_FINISH || m_pUMLActivity->m_ActivityKind == ACTIVITY_INIT)
	{
		CRgn rgn;
		rgn.CreateEllipticRgn( m_Pos.left , m_Pos.top , m_Pos.right , m_Pos.bottom );
		return rgn.PtInRegion( pt );
	}
	else if( m_pUMLActivity->m_ActivityKind == ACTIVITY_SYNCH )
	{
		return m_Pos.PtInRect( pt );
	}
	else return FALSE;
}

ShapeType ShapeActivity::GetType()
{
	return SHAPE_ACTIVITY;
}

void ShapeActivity::SaveAsText(CFile &file)
{

}

void ShapeActivity::Save(CFile &file , int &tabnum)
{
	CString txt;
	WriteTab( file ,tabnum );
	WriteTag( file , "<ACTIVITY>" );
	WriteEnter( file );
	tabnum ++;
	//id
	txt.Format("<ID>%d</ID>",m_ID );
	WriteTab( file , tabnum );
	WriteContent( file , txt );
	WriteEnter( file );
	//pos
	WritePos( file ,tabnum );
	//kind
	switch( m_pUMLActivity->m_ActivityKind )
	{
	case ACTIVITY_INIT:
		txt = "<KIND>INIT</KIND>";
		break;
	case ACTIVITY_ACTION:
		txt = "<KIND>ACTION</KIND>";
		break;
	case ACTIVITY_FINISH:
		txt = "<KIND>FINISH</KIND>";
		break;
	case ACTIVITY_SUB:
		txt = "<KIND>SUB</KIND>";
		break;
	case ACTIVITY_SYNCH:
		txt = "<KIND>SYNCH</KIND>";
	}
	WriteTab( file , tabnum );
	WriteContent( file , txt );
	WriteEnter( file );
	//detail
	txt = "";
	switch( m_pUMLActivity->m_ActivityKind )
	{
	case ACTIVITY_INIT:
	case ACTIVITY_ACTION:
	case ACTIVITY_FINISH:
		{
			UMLActionActivity *pAA = (UMLActionActivity*)m_pUMLActivity;
			if( pAA->m_Expression.GetLength() )
			{
				txt = "<EXPRESSION>";
				txt += ShapeClass::RemoveEnter( pAA->m_Expression );
				txt += "</EXPRESSION>";
			}
		}
		break;
	case ACTIVITY_SYNCH:
		break;
	case ACTIVITY_SUB:
		{
			UMLSubActivity *pSA = (UMLSubActivity*)m_pUMLActivity;
			txt.Format("<SUBID>%d</SUBID>",FindActivityGraphID(pSA->m_pActivityGraph ) );
		}
		break;
	}
	if( txt.GetLength() )
	{
		WriteTab( file , tabnum );
		WriteContent( file , txt );
		WriteEnter( file );
	}
	//name
	if( m_pUMLActivity->name.GetLength() )
	{
		txt = "<NAME>";
		txt += m_pUMLActivity->name ;
		txt += "</NAME>";
		WriteTab( file , tabnum );
		WriteContent( file , txt );
		WriteEnter( file );
	}
	//mark
	if( m_pUMLActivity->m_ActivityKind == ACTIVITY_SYNCH )
	{
		MarkSynch *pMS = (MarkSynch*)m_pMarkElement;
		WriteTab( file , tabnum );
		WriteTag( file , "<MARK>" );
		WriteEnter( file );
		tabnum ++;
		//name
		txt = "<NAME>";
		txt += pMS->m_SynchName ;
		txt += "</NAME>";
		WriteTab( file , tabnum );
		WriteTag( file , txt );
		WriteEnter( file );
		//type
		txt = "<TYPE>";
		txt += pMS->m_SynchType ;
		txt += "</TYPE>";
		WriteTab( file , tabnum );
		WriteTag( file , txt );
		WriteEnter( file );
		//visibility
		switch( pMS->m_SynchVisibility )
		{
		case VISIBILITY_PUBLIC:
			txt = "<VISIBILITY>PUBLIC</VISIBILITY>";
			break;
		case VISIBILITY_PRIVATE:
			txt = "<VISIBILITY>PRIVATE</VISIBILITY>";
			break;
		case VISIBILITY_PROTECTED:
			txt = "<VISIBILITY>PROTECTED</VISIBILITY>";
			break;
		default:
			txt = "<VISIBILITY>PACKAGE</VISIBILITY>";
		}
		WriteTab( file , tabnum );
		WriteTag( file , txt );
		WriteEnter( file );

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

ShapeNamespace* ShapeActivity::GetShapeNamespace()
{
	if( m_pOwnedShape->GetType() == SHAPE_SWIMLANE )
	{
		return ((ShapeSwimlane*)m_pOwnedShape)->GetShapeNamespace();
	}
	else
	{
		return ((ShapeActivityGraph*)m_pOwnedShape)->GetShapeNamespace();
	}
}

void ShapeActivity::IncreaseVisitedNum()
{
	visitedNum++;
}

void ShapeActivity::DecreaseVisitedNum()
{
	visitedNum--;
}

void ShapeActivity::ClearVisitedNum()
{
	visitedNum=0;
}

int ShapeActivity::GetVisitedNum()
{
	return visitedNum;
}

//DEL void ShapeActivity::RecordCurrentTrace()
//DEL {
//DEL 
//DEL }

void ShapeActivity::SetChecked(BOOL c)
{
checked=c;
}

BOOL ShapeActivity::GetChecked()
{
return checked;
}

void ShapeActivity::SetVisitedNum(int n)
{
	visitedNum=n;
}
