// AG_MDAView.cpp : implementation of the CAG_MDAView class
//

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

#include "AG_MDADoc.h"
#include "AG_MDAView.h"

//**************************
//STL使用
//**************************
#pragma warning(disable : 4786)

#include<set>
#include<vector>
#include<algorithm>

using namespace std;

//functor
struct ltstr
{
  bool operator()(const CString* s1, const CString* s2) const
  {
	  return *s1<*s2;   
  }
};


typedef set<CString *,ltstr> STRINGSET;
typedef vector<STRINGSET*> VECTOROFSTRINGSET;

//全局量
VECTOROFSTRINGSET runOfProgram;
VECTOROFSTRINGSET runOfAG;

//*************************

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

#include "MainFrm.h"

/////////////////////////////////////////////////////////////////////////////
// CAG_MDAView
extern ShapeElement *m_CurrentElement;
extern CToolBar    m_AGToolBar;
CAG_MDAView *m_pView = NULL;
extern CObjTempl<TreeNode> m_Nodes;//节点
extern UMLClassPointerList m_Classes;//所有的类
extern ShapeElement *m_pRootShape ;

IMPLEMENT_DYNCREATE(CAG_MDAView, CView)

BEGIN_MESSAGE_MAP(CAG_MDAView, CView)
	//{{AFX_MSG_MAP(CAG_MDAView)
	ON_WM_LBUTTONDOWN()
	ON_COMMAND(ID_BUTTON_STATE_ACTION, OnButtonStateAction)
	ON_UPDATE_COMMAND_UI(ID_BUTTON_STATE_ACTION, OnUpdateButtonStateAction)
	ON_COMMAND(ID_BUTTON_STATE_FINISH, OnButtonStateFinish)
	ON_UPDATE_COMMAND_UI(ID_BUTTON_STATE_FINISH, OnUpdateButtonStateFinish)
	ON_COMMAND(ID_BUTTON_STATE_INIT, OnButtonStateInit)
	ON_UPDATE_COMMAND_UI(ID_BUTTON_STATE_INIT, OnUpdateButtonStateInit)
	ON_COMMAND(ID_BUTTON_STATE_SUB, OnButtonStateSub)
	ON_UPDATE_COMMAND_UI(ID_BUTTON_STATE_SUB, OnUpdateButtonStateSub)
	ON_COMMAND(ID_BUTTON_TRANS_EDGE, OnButtonTransEdge)
	ON_UPDATE_COMMAND_UI(ID_BUTTON_TRANS_EDGE, OnUpdateButtonTransEdge)
	ON_COMMAND(ID_BUTTON_SEL, OnButtonSel)
	ON_UPDATE_COMMAND_UI(ID_BUTTON_SEL, OnUpdateButtonSel)
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONUP()
	ON_WM_LBUTTONDBLCLK()
	ON_COMMAND(ID_BUTTON_STATE_SYNCH, OnButtonStateSynch)
	ON_UPDATE_COMMAND_UI(ID_BUTTON_STATE_SYNCH, OnUpdateButtonStateSynch)
	ON_COMMAND(ID_BUTTON_SWIMLANE, OnButtonSwimlane)
	ON_UPDATE_COMMAND_UI(ID_BUTTON_SWIMLANE, OnUpdateButtonSwimlane)
	ON_WM_SIZE()
	ON_COMMAND(ID_FILE_SAVE, OnFileSave)
	ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
	ON_COMMAND(ID_BUTTON_DEL, OnButtonDel)
	ON_COMMAND(ID_BUTTON_TEST, OnButtonActivityDiagramTest)
	ON_UPDATE_COMMAND_UI(ID_BUTTON_TEST, OnUpdateButtonActivityDiagramTest)
	ON_COMMAND(ID_BUTTON_PATH_COVERAGE_TEST, OnButtonPathCoverageTest)
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CAG_MDAView construction/destruction
CAG_MDAView::CAG_MDAView()  //初始化
{
	// TODO: add construction code here
	m_pView = this;
	m_OperationType = OPE_NONE;
	m_pForAddTransEdge = NULL;
	m_pSelElement = NULL;
	activityCoverage=0;
	edgeCoverage=0;
    
}

CAG_MDAView::~CAG_MDAView()
{
}

BOOL CAG_MDAView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CAG_MDAView drawing

void CAG_MDAView::OnDraw(CDC* pDC)
{
	CAG_MDADoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
	RECT r;
	GetClientRect(&r);
	
/*	pDC->SetMapMode(MM_ISOTROPIC);
	pDC->SetWindowExt( r.right - r.left , r.bottom - r.top );
	pDC->SetViewportExt( (r.right - r.left)*1 , (r.bottom - r.top)*1 );*/
	if( m_CurrentElement )
	{
		m_CurrentElement->DrawDefault( pDC );
	}
	if( m_pForAddTransEdge )
	{	
		int iLast = m_pForAddTransEdge->m_Points.GetSize();
		POINT pt;
		
		for( int i = 0 ; i < iLast ; i ++ )
		{
			pt = m_pForAddTransEdge->m_Points.GetAt( i );
			if( i )
			{
				pDC->LineTo( pt );
			}
			else
			{
				pDC->MoveTo( pt );
			}
		}
		pDC->LineTo( m_DownPoint );
	}

}

/////////////////////////////////////////////////////////////////////////////
// CAG_MDAView printing

BOOL CAG_MDAView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CAG_MDAView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CAG_MDAView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CAG_MDAView diagnostics

#ifdef _DEBUG
void CAG_MDAView::AssertValid() const
{
	CView::AssertValid();
}

void CAG_MDAView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CAG_MDADoc* CAG_MDAView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CAG_MDADoc)));
	return (CAG_MDADoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CAG_MDAView message handlers

void CAG_MDAView::OnLButtonDown(UINT nFlags, CPoint point) //根据工具栏中所按按钮的不同，选择不同的鼠标操作
{
	// TODO: Add your message handler code here and/or call default
	if( !m_CurrentElement )return;
	switch( m_OperationType )
	{
	case OPE_ADD_STATE_INIT:
		{
			AddStateInit( point );
			Invalidate();
		}
		break;
	case OPE_ADD_STATE_FINISH:
		{
			AddStateFinish( point );
			Invalidate();
		}
		break;
	case OPE_ADD_STATE_ACTION:
		{
			AddStateAction( point );
			Invalidate();
		}
		break;
	case OPE_ADD_STATE_SUB:
		{
			AddStateSub( point );
			Invalidate();
		}
		break;
	case OPE_ADD_STATE_SYNCH:
		{
			AddStateSynch( point );
			Invalidate();
		}
		break;
	case OPE_ADD_TRANS_EDGE:
		{
			AddTransEdge( point );
		}
		break;
	case OPE_ADD_SWIMLANE:
		{
			AddSwimlane( point );
			Invalidate();
		}
		break;
	case OPE_SEL:
		{
			m_DownPoint = point;
			m_pSelElement =FindSel( point );
			SetCapture();
		}
		break;
	case OPE_DEL:
		{
			DelSel( point );
			break;
		}
	}
	CView::OnLButtonDown(nFlags, point);
}


//一下是选择相应的按钮
void CAG_MDAView::OnButtonStateAction() 
{
	// TODO: Add your command handler code here
	SetAGButtons( ID_BUTTON_STATE_ACTION );
	m_OperationType = OPE_ADD_STATE_ACTION;
}

void CAG_MDAView::OnUpdateButtonStateAction(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->Enable( m_CurrentElement && m_CurrentElement->GetType() == SHAPE_ACTIVITYDIAGRAM );
}

void CAG_MDAView::OnButtonStateFinish() 
{
	// TODO: Add your command handler code here
	SetAGButtons( ID_BUTTON_STATE_FINISH );
	m_OperationType = OPE_ADD_STATE_FINISH;
}

void CAG_MDAView::OnUpdateButtonStateFinish(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->Enable( m_CurrentElement && m_CurrentElement->GetType() == SHAPE_ACTIVITYDIAGRAM );
}

void CAG_MDAView::OnButtonStateInit() 
{
	// TODO: Add your command handler code here
	SetAGButtons( ID_BUTTON_STATE_INIT );
	m_OperationType = OPE_ADD_STATE_INIT;
}

void CAG_MDAView::OnUpdateButtonStateInit(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->Enable( m_CurrentElement && m_CurrentElement->GetType() == SHAPE_ACTIVITYDIAGRAM );
}

void CAG_MDAView::OnButtonStateSub() 
{
	// TODO: Add your command handler code here
	SetAGButtons( ID_BUTTON_STATE_SUB );
	m_OperationType = OPE_ADD_STATE_SUB;
}

void CAG_MDAView::OnUpdateButtonStateSub(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->Enable( m_CurrentElement && m_CurrentElement->GetType() == SHAPE_ACTIVITYDIAGRAM );
}

void CAG_MDAView::OnButtonTransEdge() 
{
	// TODO: Add your command handler code here
	SetAGButtons( ID_BUTTON_TRANS_EDGE );
	m_OperationType = OPE_ADD_TRANS_EDGE;
}

void CAG_MDAView::OnUpdateButtonTransEdge(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->Enable( m_CurrentElement && m_CurrentElement->GetType() == SHAPE_ACTIVITYDIAGRAM );
}

void CAG_MDAView::OnButtonSel() 
{
	// TODO: Add your command handler code here
	SetAGButtons( ID_BUTTON_SEL );
	m_OperationType = OPE_SEL;
}

void CAG_MDAView::OnUpdateButtonSel(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->Enable( m_CurrentElement && m_CurrentElement->GetType() == SHAPE_ACTIVITYDIAGRAM );
}

void CAG_MDAView::SetAGButtons(int id)
{
	m_AGToolBar.GetToolBarCtrl().CheckButton( ID_BUTTON_STATE_INIT ,id == ID_BUTTON_STATE_INIT );
	m_AGToolBar.GetToolBarCtrl().CheckButton( ID_BUTTON_STATE_FINISH ,id == ID_BUTTON_STATE_FINISH );
	m_AGToolBar.GetToolBarCtrl().CheckButton( ID_BUTTON_STATE_ACTION ,id == ID_BUTTON_STATE_ACTION );
	m_AGToolBar.GetToolBarCtrl().CheckButton( ID_BUTTON_STATE_SUB ,id == ID_BUTTON_STATE_SUB );
	m_AGToolBar.GetToolBarCtrl().CheckButton( ID_BUTTON_TRANS_EDGE ,id == ID_BUTTON_TRANS_EDGE );
	m_AGToolBar.GetToolBarCtrl().CheckButton( ID_BUTTON_STATE_SYNCH ,id == ID_BUTTON_STATE_SYNCH );
	m_AGToolBar.GetToolBarCtrl().CheckButton( ID_BUTTON_SEL ,id == ID_BUTTON_SEL );
	m_AGToolBar.GetToolBarCtrl().CheckButton( ID_BUTTON_SWIMLANE ,id == ID_BUTTON_SWIMLANE );
	m_AGToolBar.GetToolBarCtrl().CheckButton( ID_BUTTON_DEL ,id == ID_BUTTON_DEL );
}

void CAG_MDAView::AddStateInit(CPoint pt)
{
	ActivityInitInfoDlg dlg ;
	if( dlg.DoModal() == IDOK )
	{
		ShapeActivityGraph *pSAG = (ShapeActivityGraph*)m_CurrentElement;
		ShapeActivity *pSA ;
		pSA = new ShapeActivity;
		pSA->m_pUMLActivity = new UMLActionActivity;
		//显示部分设置
		pSA->m_Pos = CRect(pt.x - 6 , pt.y - 6 ,pt.x + 6 , pt.y + 6 );
		//数据部分设置
		pSA->m_pUMLActivity->m_ActivityKind = ACTIVITY_INIT;
		//-设置活动所属的类：泳道或活动图
		if( pSAG->m_pShapeSwimlanes.GetUpperBound()>=0 )
		{
			//泳道
			for( int i = 0 ; i <= pSAG->m_pShapeSwimlanes.GetUpperBound() ; i ++ )
			{
				ShapeSwimlane *p = pSAG->m_pShapeSwimlanes.GetAt( i );
				if( p->In( pt ) )
				{
					pSA->m_pOwnedShape = p;
					pSA->m_pUMLActivity->m_pClass = p->m_pSwimlane->pType; //活动的由相应的甬道提供
					pSA->m_pUMLActivity->m_pOwnedElement = p->m_pSwimlane;

					p->m_pActivities.Add( pSA );//活动的图形加入到泳道
					p->m_pSwimlane->m_Activities.Add( pSA->m_pUMLActivity );//活动的元数据加入泳道
					break;
				}
			}
		}
		else
		{
			//活动图
			pSA->m_pUMLActivity->m_pClass = pSAG->m_pActivityGraph->m_pClass;
			pSA->m_pUMLActivity->m_pOwnedElement = pSAG->m_pActivityGraph;
			pSA->m_pOwnedShape = pSAG;
			pSAG->m_pShapeActivities.Add( pSA );//活动的图形加入到活动图
			pSAG->m_pActivityGraph->m_Activities.Add( pSA->m_pUMLActivity );//活动的元数据加入到活动图
		}
		pSA->m_pUMLActivity->name = dlg.m_Name;
	}
}

void CAG_MDAView::AddStateFinish(CPoint pt)
{
	ActivityInitInfoDlg dlg ;
	if( dlg.DoModal() == IDOK )
	{
		ShapeActivityGraph *pSAG = (ShapeActivityGraph*)m_CurrentElement;
		ShapeActivity *pSA ;
		pSA = new ShapeActivity;
		pSA->m_pUMLActivity = new UMLActionActivity;
		//显示部分设置
		pSA->m_Pos = CRect(pt.x - 10 , pt.y - 10 ,pt.x + 10 , pt.y + 10 );
		//数据部分设置
		pSA->m_pUMLActivity->m_ActivityKind = ACTIVITY_FINISH;
		//-设置活动所属的类：泳道或活动图
		if( pSAG->m_pShapeSwimlanes.GetUpperBound()>=0 )
		{
			//泳道
			for( int i = 0 ; i <= pSAG->m_pShapeSwimlanes.GetUpperBound() ; i ++ )
			{
				ShapeSwimlane *p = pSAG->m_pShapeSwimlanes.GetAt( i );
				if( p->In( pt ) )
				{
					pSA->m_pOwnedShape = p;
					pSA->m_pUMLActivity->m_pClass = p->m_pSwimlane->pType;
					pSA->m_pUMLActivity->m_pOwnedElement = p->m_pSwimlane;

					p->m_pActivities.Add( pSA );//活动的图形加入到泳道
					p->m_pSwimlane->m_Activities.Add( pSA->m_pUMLActivity );//活动的元数据加入泳道
					break;
				}
			}
		}
		else
		{
			//活动图
			pSA->m_pUMLActivity->m_pClass = pSAG->m_pActivityGraph->m_pClass;
			pSA->m_pUMLActivity->m_pOwnedElement = pSAG->m_pActivityGraph;
			pSA->m_pOwnedShape = pSAG;
			pSAG->m_pShapeActivities.Add( pSA );//活动的图形加入到活动图
			pSAG->m_pActivityGraph->m_Activities.Add( pSA->m_pUMLActivity );//活动的元数据加入到活动图
		}
		pSA->m_pUMLActivity->name = dlg.m_Name;
	}
}
void CAG_MDAView::AddStateSynch(CPoint pt)
{
		ShapeActivityGraph *pSAG = (ShapeActivityGraph*)m_CurrentElement;
		ShapeActivity *pSA ;
		pSA = new ShapeActivity;
		pSA->m_pUMLActivity = new UMLSynchActivity;
		//显示部分设置
		pSA->m_Pos = CRect(pt.x - 40 , pt.y - 2 ,pt.x + 40 , pt.y + 2 );
		//数据部分设置
		pSA->m_pUMLActivity->m_ActivityKind = ACTIVITY_SYNCH;
		pSA->m_pMarkElement = new MarkSynch;
		((MarkSynch*)pSA->m_pMarkElement)->m_SynchName.Format("m_Synch_%d",pSA->m_ID );
		((MarkSynch*)pSA->m_pMarkElement)->m_SynchType.Format("SYNCH_%d",pSA->m_ID);
		((MarkSynch*)pSA->m_pMarkElement)->m_SynchVisibility = VISIBILITY_PUBLIC;
		//-设置活动所属的类：泳道或活动图
		if( pSAG->m_pShapeSwimlanes.GetUpperBound()>=0 )
		{
			//泳道
			for( int i = 0 ; i <= pSAG->m_pShapeSwimlanes.GetUpperBound() ; i ++ )
			{
				ShapeSwimlane *p = pSAG->m_pShapeSwimlanes.GetAt( i );
				if( p->In( pt ) )
				{
					pSA->m_pOwnedShape = p;
					pSA->m_pUMLActivity->m_pClass = p->m_pSwimlane->pType;
					pSA->m_pUMLActivity->m_pOwnedElement = p->m_pSwimlane;

					p->m_pActivities.Add( pSA );//活动的图形加入到泳道
					p->m_pSwimlane->m_Activities.Add( pSA->m_pUMLActivity );//活动的元数据加入泳道
					break;
				}
			}
		}
		else
		{
			//活动图
			pSA->m_pUMLActivity->m_pClass = pSAG->m_pActivityGraph->m_pClass;
			pSA->m_pUMLActivity->m_pOwnedElement = pSAG->m_pActivityGraph;
			pSA->m_pOwnedShape = pSAG;
			pSAG->m_pShapeActivities.Add( pSA );//活动的图形加入到活动图
			pSAG->m_pActivityGraph->m_Activities.Add( pSA->m_pUMLActivity );//活动的元数据加入到活动图
		}
}
void CAG_MDAView::AddStateAction(CPoint pt)
{
	ActivityInitInfoDlg dlg ;
	if( dlg.DoModal() == IDOK )
	{
		ShapeActivityGraph *pSAG = (ShapeActivityGraph*)m_CurrentElement;
		ShapeActivity *pSA ;
		pSA = new ShapeActivity;
		pSA->m_pUMLActivity = new UMLActionActivity;
		//显示部分设置
		pSA->m_Pos = CRect(pt.x - 36 , pt.y - 12 ,pt.x + 36 , pt.y + 12 );
		//数据部分设置
		pSA->m_pUMLActivity->m_ActivityKind = ACTIVITY_ACTION;
		//-设置活动所属的类：泳道或活动图
		if( pSAG->m_pShapeSwimlanes.GetUpperBound()>=0 )
		{
			//泳道
			for( int i = 0 ; i <= pSAG->m_pShapeSwimlanes.GetUpperBound() ; i ++ )
			{
				ShapeSwimlane *p = pSAG->m_pShapeSwimlanes.GetAt( i );
				if( p->In( pt ) )
				{
					pSA->m_pOwnedShape = p;
					pSA->m_pUMLActivity->m_pClass = p->m_pSwimlane->pType;
					pSA->m_pUMLActivity->m_pOwnedElement = p->m_pSwimlane;

					p->m_pActivities.Add( pSA );//活动的图形加入到泳道
					p->m_pSwimlane->m_Activities.Add( pSA->m_pUMLActivity );//活动的元数据加入泳道
					break;
				}
			}
		}
		else
		{
			//活动图
			pSA->m_pUMLActivity->m_pClass = pSAG->m_pActivityGraph->m_pClass;
			pSA->m_pUMLActivity->m_pOwnedElement = pSAG->m_pActivityGraph;
			pSA->m_pOwnedShape = pSAG;
			pSAG->m_pShapeActivities.Add( pSA );//活动的图形加入到活动图
			pSAG->m_pActivityGraph->m_Activities.Add( pSA->m_pUMLActivity );//活动的元数据加入到活动图
		}
		pSA->m_pUMLActivity->name = dlg.m_Name;
		((UMLActionActivity*)pSA->m_pUMLActivity)->m_Expression = dlg.m_Expression ;
	}
}


//    子状态没有实现
void CAG_MDAView::AddStateSub(CPoint pt)
{
	ActivitySubInfoDlg dlg ;
	ShapeActivityGraph *pSAG = (ShapeActivityGraph*)m_CurrentElement;
	if( pSAG->m_pShapeSwimlanes.GetUpperBound() >= 0 )
	{
		for( int i = 0; i <= pSAG->m_pShapeSwimlanes.GetUpperBound() ; i ++ )
		{
			ShapeSwimlane *p = pSAG->m_pShapeSwimlanes.GetAt( i );
			if( p->In( pt ) )
			{
				dlg.pClass = p->m_pSwimlane->pType;
				
				break;
			}
		}
	}
	else
	{
		dlg.pClass = pSAG->m_pActivityGraph->m_pClass;
	}
	
	if( dlg.DoModal() == IDOK )
	{
		
		ShapeActivity *pSA ;
		pSA = new ShapeActivity;
		pSA->m_pUMLActivity = new UMLSubActivity;
		//显示部分设置
		pSA->m_Pos = CRect(pt.x - 45 , pt.y - 25 ,pt.x + 45 , pt.y + 25 );
		//数据部分设置
		pSA->m_pUMLActivity->m_ActivityKind = ACTIVITY_SUB;
		//-设置活动所属的类：泳道或活动图
		if( pSAG->m_pShapeSwimlanes.GetUpperBound()>=0 )
		{
			//泳道
			for( int i = 0 ; i <= pSAG->m_pShapeSwimlanes.GetUpperBound() ; i ++ )
			{
				ShapeSwimlane *p = pSAG->m_pShapeSwimlanes.GetAt( i );
				if( p->In( pt ) )
				{
					pSA->m_pUMLActivity->m_pClass = p->m_pSwimlane->pType;
					pSA->m_pUMLActivity->m_pOwnedElement = p->m_pSwimlane;
					pSA->m_pOwnedShape = p;
					p->m_pActivities.Add( pSA );//活动的图形加入到泳道
					p->m_pSwimlane->m_Activities.Add( pSA->m_pUMLActivity );//活动的元数据加入泳道
					break;
				}
			}
		}
		else
		{
			//活动图
			pSA->m_pUMLActivity->m_pClass = pSAG->m_pActivityGraph->m_pClass;
			pSA->m_pUMLActivity->m_pOwnedElement = pSAG->m_pActivityGraph;
			pSA->m_pOwnedShape = pSAG;

			pSAG->m_pShapeActivities.Add( pSA );//活动的图形加入到活动图
			pSAG->m_pActivityGraph->m_Activities.Add( pSA->m_pUMLActivity );//活动的元数据加入到活动图
		}
		pSA->m_pUMLActivity->name = dlg.m_Name;
		((UMLSubActivity*)pSA->m_pUMLActivity)->m_pActivityGraph = dlg.pSubActivity;	
	}
}

void CAG_MDAView::AddTransEdge(CPoint pt)
{
	ShapeElement *selEle;
	selEle = FindSel( pt );
	if( m_pForAddTransEdge )
	{
		if( selEle )
		{
			if( selEle->GetType() == SHAPE_ACTIVITY )
			{
				//添加完毕
				TransEdgeInfoDlg dlg;
				if( dlg.DoModal() == IDOK )
				{
					ShapeActivityGraph *pSAG = (ShapeActivityGraph*)m_CurrentElement;
					m_pForAddTransEdge->m_pTransEdge->m_pActivities[ 1 ] = ((ShapeActivity*)selEle)->m_pUMLActivity;
					m_pForAddTransEdge->m_pTransEdge->name = dlg.m_Name;
					m_pForAddTransEdge->m_pTransEdge->m_BoolExpression = dlg.m_Condiction;
					m_pForAddTransEdge->m_pActivity[ 1 ] = (ShapeActivity*)selEle;
					m_pForAddTransEdge->m_Points.Add( pt );
					m_pForAddTransEdge->AdjustHeadAndTail();
					m_pForAddTransEdge->m_pActivity[ 1 ]->m_pInTransEdges.Add( m_pForAddTransEdge );
					m_pForAddTransEdge->m_pActivity[ 0 ]->m_pOutTransEdges.Add( m_pForAddTransEdge );
					//加入到数据结构
					pSAG->m_pShapeTransEdges.Add( m_pForAddTransEdge );//加入到显示
					pSAG->m_pActivityGraph->m_Edges.Add( m_pForAddTransEdge->m_pTransEdge );//加入到元模型
					m_pForAddTransEdge->m_pActivity[ 0 ]->m_pUMLActivity->m_OutTransEdge.Add( m_pForAddTransEdge->m_pTransEdge );//建立活动与边的关系
					m_pForAddTransEdge->m_pActivity[ 1 ]->m_pUMLActivity->m_InTransEdge.Add( m_pForAddTransEdge->m_pTransEdge );
					m_pForAddTransEdge = NULL;
					Invalidate();
				}
				else
				{
					delete m_pForAddTransEdge->m_pTransEdge;
					delete m_pForAddTransEdge;
					m_pForAddTransEdge = NULL;
					Invalidate();
				}
			}
			else
			{
				//选错了对象，继续
				m_pForAddTransEdge->m_Points.Add( pt );
			}
		}
		else
		{
			//中间点
			m_pForAddTransEdge->m_Points.Add( pt );
		}
	}
	else
	{
		//新建一个边
		if( selEle )
		{
			if( selEle->GetType() == SHAPE_ACTIVITY )
			{
				m_pForAddTransEdge = new ShapeTransEdge;
				m_pForAddTransEdge->m_Points.Add( pt );
				m_pForAddTransEdge->m_pTransEdge = new UMLTransEdge;
				m_pForAddTransEdge->m_pTransEdge->m_pActivities[ 0 ] = ((ShapeActivity*)selEle)->m_pUMLActivity;
				m_pForAddTransEdge->m_pActivity[ 0 ] = (ShapeActivity*)selEle;
			}
			else
			{
			}
		}
		else
		{
		}
	}
}

void CAG_MDAView::OnMouseMove(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	if( !m_CurrentElement )return;
	if( m_OperationType == OPE_SEL )
	{
		int dx,dy;
		dx = point.x - m_DownPoint.x;
		dy = point.y -m_DownPoint.y;
		if( nFlags & MK_LBUTTON == 0)return;
		if( m_pSelElement )
		{
			//移动图形
			if( m_pSelElement->GetType() == SHAPE_ACTIVITY )
			{
				ShapeActivityGraph *pSAG = (ShapeActivityGraph*)m_CurrentElement;
				m_pSelElement->m_Pos.left += dx;
				m_pSelElement->m_Pos.right += dx;
				m_pSelElement->m_Pos.top += dy;
				m_pSelElement->m_Pos.bottom += dy;
				for( int i = 0 ; i <= pSAG->m_pShapeTransEdges.GetUpperBound() ; i++)
				{
					ShapeTransEdge *edge = pSAG->m_pShapeTransEdges.GetAt( i );
					if( edge->m_pActivity[ 0 ] == m_pSelElement || edge->m_pActivity[ 1 ] == m_pSelElement)
					{
						edge->AdjustHeadAndTail();
					}

				}
				Invalidate();
			}
		}
	}
	else if( m_OperationType == OPE_ADD_TRANS_EDGE )
	{
		if( m_pForAddTransEdge )
			Invalidate();
	}
	m_DownPoint = point;
	CView::OnMouseMove(nFlags, point);
}

void CAG_MDAView::OnLButtonUp(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	if( !m_CurrentElement )return;
	if( m_OperationType == OPE_SEL )
	{
		ShapeActivityGraph *p = (ShapeActivityGraph*)m_CurrentElement;
		if(p && m_pSelElement && m_pSelElement->GetType() == SHAPE_ACTIVITY && p->m_pShapeSwimlanes.GetUpperBound() >= 1)
		{//检查是否跨泳道，实现活动在泳道间自由拉动
			POINT center;
			ShapeActivity* sa = (ShapeActivity*)m_pSelElement;
			center.x = (m_pSelElement->m_Pos.left + m_pSelElement->m_Pos.right)/2;
			center.y = (m_pSelElement->m_Pos.top + m_pSelElement->m_Pos.bottom)/2;
			for( int i = 0 ; i <= p->m_pShapeSwimlanes.GetUpperBound() ; i ++ )
			{
				ShapeSwimlane *pSS = p->m_pShapeSwimlanes.GetAt( i );
				if( pSS->In( center ) && pSS != sa->m_pOwnedShape)
				{//跨泳道了，pSS为新的泳道,sa－>m_pSwimlane为原来的泳道
					UMLSwimlane* oldS,*newS;
					oldS = ((ShapeSwimlane*)sa->m_pOwnedShape)->m_pSwimlane;
					newS = pSS->m_pSwimlane;
					for( int j = 0 ; j<= ((ShapeSwimlane*)sa->m_pOwnedShape)->m_pActivities.GetUpperBound() ; j ++)
					{
						ShapeActivity *curp = ((ShapeSwimlane*)sa->m_pOwnedShape)->m_pActivities.GetAt( j );
						if( curp == sa )
						{
							//从原来的泳道中移出,先移图形，后处理元模型
							((ShapeSwimlane*)sa->m_pOwnedShape)->m_pActivities.RemoveAt( j );//从泳道中删除图形
							//从泳道元模型中删除活动
							for( int t = 0; t <= ((ShapeSwimlane*)sa->m_pOwnedShape)->m_pSwimlane->m_Activities.GetUpperBound() ; t ++)
							{
								UMLActivity *p = ((ShapeSwimlane*)sa->m_pOwnedShape)->m_pSwimlane->m_Activities.GetAt( t );
								if( p == sa->m_pUMLActivity )
								{
									((ShapeSwimlane*)sa->m_pOwnedShape)->m_pSwimlane->m_Activities.RemoveAt( t );
									break;
								}
							}
							break;
						}
					}
					
					//插到新的泳道中
					sa->m_pUMLActivity->m_pClass = pSS->m_pSwimlane->pType;//修改活动所属的类
					sa->m_pUMLActivity->m_pOwnedElement = pSS->m_pSwimlane;
					sa->m_pOwnedShape = pSS;//连接新泳道
					pSS->m_pActivities.Add( sa );//图形加入到新泳道
					((ShapeSwimlane*)sa->m_pOwnedShape)->m_pSwimlane->m_Activities.Add( sa->m_pUMLActivity );//元模型加入到新泳道
					//WRITE LOG
					{
						CString txt;
						txt.Format("Activity:%s move from swimlane:%s to swimlane:%s",LPCTSTR(sa->m_pUMLActivity->name),LPCTSTR(oldS->name) ,LPCTSTR(newS->name) );
						AppendLog( txt );
					}
				}
			}
		}
		::SetCapture( 0 );
		m_pSelElement = NULL;
	}
	CView::OnLButtonUp(nFlags, point);
}

ShapeElement* CAG_MDAView::FindSel(CPoint pt)
{
	ShapeActivityGraph *p = (ShapeActivityGraph*)m_CurrentElement;
	if( !p )return NULL;
	//先查找活动图中的活动
	for( int i = 0 ; i <= p->m_pShapeActivities.GetUpperBound() ; i ++ )
	{
		ShapeActivity *sp = p->m_pShapeActivities.GetAt( i );
		if( sp->In( pt ) )return sp;
	}
	//再查找泳道中的活动
	for( i = 0 ; i <= p->m_pShapeSwimlanes.GetUpperBound() ; i ++ )
	{
		ShapeSwimlane *ss = p->m_pShapeSwimlanes.GetAt( i );
		for( int j = 0 ; j<= ss->m_pActivities.GetUpperBound() ; j++)
		{
			ShapeActivity * pa = ss->m_pActivities.GetAt( j );
			if( pa->In( pt ) )return pa;
		}
	}
	//查找转换边
	for( i = 0 ; i <= p->m_pShapeTransEdges.GetUpperBound() ; i ++ )
	{
		ShapeTransEdge *edge = p->m_pShapeTransEdges.GetAt( i );
		if( edge->In( pt ) )return edge;
	}
	//最后查找泳道
	for( i = 0 ; i <= p->m_pShapeSwimlanes.GetUpperBound() ; i ++ )
	{
		ShapeSwimlane *ss = p->m_pShapeSwimlanes.GetAt( i );
		if( ss->In( pt ) ) return ss;
	}
	return NULL;
}

void CAG_MDAView::OnLButtonDblClk(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	if( !m_CurrentElement )return;
	if( m_OperationType == OPE_SEL )
	{
		ShapeElement *selEle;
		selEle = FindSel( point );
		if( !selEle ) return;
		if( selEle->GetType() == SHAPE_ACTIVITY )
		{
			ShapeActivity *pSA = (ShapeActivity*)selEle;
			switch( pSA->m_pUMLActivity->m_ActivityKind )
			{
			case ACTIVITY_INIT:
			case ACTIVITY_FINISH:
			case ACTIVITY_ACTION:
				{
					ActivityInitInfoDlg dlg;
					dlg.m_ID = selEle->m_ID;
					dlg.m_Name = pSA->m_pUMLActivity->name;
					dlg.m_Expression = ((UMLActionActivity*)pSA->m_pUMLActivity)->m_Expression ;
					if( dlg.DoModal() == IDOK )
					{
						pSA->m_pUMLActivity->name = dlg.m_Name;
						((UMLActionActivity*)pSA->m_pUMLActivity)->m_Expression = dlg.m_Expression;
						Invalidate();
					}
				}
				break;
			case ACTIVITY_SUB:
				{
					ActivitySubInfoDlg dlg;
					dlg.m_Name = pSA->m_pUMLActivity->name;
					dlg.pClass = pSA->m_pUMLActivity->m_pClass;
					dlg.pSubActivity = ((UMLSubActivity*)pSA->m_pUMLActivity)->m_pActivityGraph;
					if( dlg.DoModal() == IDOK )
					{
						pSA->m_pUMLActivity->name = dlg.m_Name;
						((UMLSubActivity*)pSA->m_pUMLActivity)->m_pActivityGraph = dlg.pSubActivity;
						Invalidate();
					}
				}
				break;
			case ACTIVITY_SYNCH:
				{
					ActivitySynchInfoDlg dlg;
					ShapeActivityGraph *pSAG = (ShapeActivityGraph*)m_CurrentElement;
					MarkSynch *syn = (MarkSynch*)pSA->m_pMarkElement;
					dlg.m_ID = selEle->m_ID;
					dlg.m_Name = pSA->m_pUMLActivity->name;
					dlg.m_SynchVisibility = syn->m_SynchVisibility ;
					dlg.m_SynchName = syn->m_SynchName ;
					dlg.m_SynchType = syn->m_SynchType;

					for( int i = 0 ; i <= pSAG->m_pShapeControlFlows.GetUpperBound() ; i ++ )
					{
						ShapeControlFlow *pSCF = pSAG->m_pShapeControlFlows.GetAt( i );
						if( pSCF->m_pUMLControlFlow->m_pBegin == ((ShapeActivity*)selEle)->m_pUMLActivity )
							dlg.m_MarkControlFlows.Add( *((MarkControlFlow*)(pSCF->m_pMarkElement)) );
					}
					if( dlg.DoModal() == IDOK )
					{
						int idx = 0;
						pSA->m_pUMLActivity->name = dlg.m_Name;
						syn->m_SynchVisibility = dlg.m_SynchVisibility ;
						syn->m_SynchName = dlg.m_SynchName ;
						syn->m_SynchType = dlg.m_SynchType;
						for( i = 0 ; i <= pSAG->m_pShapeControlFlows.GetUpperBound() ; i ++ )
						{
							ShapeControlFlow *pSCF = pSAG->m_pShapeControlFlows.GetAt( i );
							if( pSCF->m_pUMLControlFlow->m_pBegin != ((ShapeActivity*)selEle)->m_pUMLActivity ) continue;
							MarkControlFlow mcf = dlg.m_MarkControlFlows.GetAt( idx );
							MarkControlFlow *pMCF = (MarkControlFlow*)pSCF->m_pMarkElement;
							pMCF->m_Name = mcf.m_Name;
							pMCF->m_Type = mcf.m_Type;
							idx ++;
						}
					}
				}
				break;
			}
		}
		else if( selEle->GetType() == SHAPE_TRANSEDGE )
		{
			ShapeTransEdge *edge = (ShapeTransEdge*)selEle;
			TransEdgeInfoDlg dlg;
			dlg.m_Condiction = edge->m_pTransEdge->m_BoolExpression;
			dlg.m_Name = edge->m_pTransEdge->name;
			if( dlg.DoModal() == IDOK )
			{
				edge->m_pTransEdge->m_BoolExpression = dlg.m_Condiction ;
				edge->m_pTransEdge->name = dlg.m_Name ;
			}
		}
		else if( selEle->GetType() == SHAPE_SWIMLANE )
		{
			ShapeSwimlane *pSS = (ShapeSwimlane*)selEle;
			SwimlaneInfoDlg dlg;
			MarkSwimlane *pMSS = (MarkSwimlane*)pSS->m_pMarkElement;
			

			dlg.m_ParamOrRef = pMSS->m_ToParameter ? 0 : 1;
			dlg.m_BoolGet = pMSS->m_GetMethod;
			dlg.m_BoolSet = pMSS->m_SetMethod;
			dlg.m_Name = pSS->m_pSwimlane->name;
			dlg.pSelClass = pSS->m_pSwimlane->pType;
			dlg.pClasses = &m_Classes;
			if( pMSS->m_ToParameter == FALSE )
			{
				dlg.m_Visibility = pMSS->m_UMLAttribute.m_Visibility;
			}
			else
				dlg.m_Visibility = VISIBILITY_PUBLIC;
			if( dlg.DoModal() == IDOK )
			{
				pSS->m_pSwimlane->name = dlg.m_Name;
				pSS->m_pSwimlane->pType = dlg.pSelClass;

				pMSS->m_ToParameter = (dlg.m_ParamOrRef == 0 )?TRUE:FALSE;
				if(dlg.m_ParamOrRef == 0 )
				{//映射参数
					pMSS->m_UMLParameter.name = pSS->m_pSwimlane->name;
					pMSS->m_UMLParameter.m_pType = pSS->m_pSwimlane->pType;
				}
				else
				{//映射引用
					pMSS->m_GetMethod = dlg.m_BoolGet;
					pMSS->m_SetMethod = dlg.m_BoolSet;

					//设置属性
					pMSS->m_UMLAttribute.m_Multiplicity = "1";
					pMSS->m_UMLAttribute.m_Visibility = dlg.m_Visibility;
					pMSS->m_UMLAttribute.m_pType = pSS->m_pSwimlane->pType;
					pMSS->m_UMLAttribute.name = pSS->m_pSwimlane->name;
					if( dlg.m_BoolGet )
					{
						//设置Get操作
						
						pMSS->m_UMLOperationGet.m_Visibility = VISIBILITY_PUBLIC;
						pMSS->m_UMLOperationGet.m_ReturnType.m_pType = pSS->m_pSwimlane->pType;
						pMSS->m_UMLOperationGet.name = "GetRef";
						pMSS->m_UMLOperationGet.name += pSS->m_pSwimlane->name;
					}
					if( dlg.m_BoolSet )
					{
						//设置Set操作
						UMLParameter param;
						param.m_pType = pSS->m_pSwimlane->pType;
						param.name = pSS->m_pSwimlane->name;

						pMSS->m_UMLOperationSet.m_Visibility = VISIBILITY_PUBLIC;
						pMSS->m_UMLOperationSet.name = "SetRef";
						pMSS->m_UMLOperationSet.name += pSS->m_pSwimlane->name;

						pMSS->m_UMLOperationSet.m_TypedParameter.RemoveAll();
						pMSS->m_UMLOperationSet.m_TypedParameter.Add( param );
					}

				}
			}
		}
	}
	CView::OnLButtonDblClk(nFlags, point);
}



void CAG_MDAView::OnButtonStateSynch() 
{
	// TODO: Add your command handler code here
	SetAGButtons( ID_BUTTON_STATE_SYNCH );
	m_OperationType = OPE_ADD_STATE_SYNCH;
}

void CAG_MDAView::OnUpdateButtonStateSynch(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->Enable( m_CurrentElement && m_CurrentElement->GetType() == SHAPE_ACTIVITYDIAGRAM );
}

void CAG_MDAView::AddSwimlane(CPoint pt)
{
	ShapeActivityGraph *pSAG = (ShapeActivityGraph*)m_CurrentElement;
	SwimlaneInfoDlg dlg;
	dlg.pClasses = &m_Classes;
	if( dlg.DoModal() == IDOK )
	{
		ShapeSwimlane *pSS = new ShapeSwimlane;
		MarkSwimlane *pMSS = (MarkSwimlane*)pSS->m_pMarkElement;
		RECT r;
		GetClientRect( &r );
		pSS->m_pSwimlane = new UMLSwimlane;
		pSS->m_pSwimlane->name = dlg.m_Name;
		pSS->m_pSwimlane->pType = dlg.pSelClass;

		pMSS->m_ToParameter = (dlg.m_ParamOrRef == 0 )?TRUE:FALSE;
		if(dlg.m_ParamOrRef == 0 )
		{//映射参数
			pMSS->m_UMLParameter.name = pSS->m_pSwimlane->name;
			pMSS->m_UMLParameter.m_pType = pSS->m_pSwimlane->pType;
		}
		else
		{//映射引用
			pMSS->m_GetMethod = dlg.m_BoolGet;
			pMSS->m_SetMethod = dlg.m_BoolSet;

			//设置属性
			pMSS->m_UMLAttribute.m_Multiplicity = "1";
			pMSS->m_UMLAttribute.m_Visibility = dlg.m_Visibility;
			pMSS->m_UMLAttribute.m_pType = pSS->m_pSwimlane->pType;
			pMSS->m_UMLAttribute.name = pSS->m_pSwimlane->name;
			if( dlg.m_BoolGet )
			{
				//设置Get操作
				
				pMSS->m_UMLOperationGet.m_Visibility = VISIBILITY_PUBLIC;
				pMSS->m_UMLOperationGet.m_ReturnType.m_pType = pSS->m_pSwimlane->pType;
				pMSS->m_UMLOperationGet.name = "GetRef";
				pMSS->m_UMLOperationGet.name += pSS->m_pSwimlane->name;
			}
			if( dlg.m_BoolSet )
			{
				//设置Set操作
				UMLParameter param;
				param.m_pType = pSS->m_pSwimlane->pType;
				param.name = pSS->m_pSwimlane->name;

				pMSS->m_UMLOperationSet.m_Visibility = VISIBILITY_PUBLIC;
				pMSS->m_UMLOperationSet.name = "SetRef";
				pMSS->m_UMLOperationSet.name += pSS->m_pSwimlane->name;

				pMSS->m_UMLOperationSet.m_TypedParameter.Add( param );
			}

		}

		if( pSAG->m_pShapeSwimlanes.GetUpperBound()>=0 )
		{
			//如果点在左半边，则放前边，否则放后边
			for( int i = 0 ; i <= pSAG->m_pShapeSwimlanes.GetUpperBound() ; i ++ )
			{
				ShapeSwimlane *p = pSAG->m_pShapeSwimlanes.GetAt( i );
				if( p->In( pt ) )
				{
					CString txt;
					txt="Lay new swimlane at left of:";
					txt +=p->m_pSwimlane->name ;
					if( MessageBox(txt ,"Message", MB_YESNO ) == IDYES )
					{
						pSAG->m_pShapeSwimlanes.InsertAt( i , pSS );
					}
					else
					{
						pSAG->m_pShapeSwimlanes.InsertAt( i + 1 , pSS );
					}
					pSAG->m_pActivityGraph->m_Swimlanes.Add( pSS->m_pSwimlane );
					break;
				}
			}
			//调整所有泳道的位置
			int num = pSAG->m_pShapeSwimlanes.GetUpperBound() + 1;
			RECT r;
			int wid;
			GetClientRect( &r );
			wid = r.right;
			wid /= num;
			for( i = 0 ; i <= pSAG->m_pShapeSwimlanes.GetUpperBound() ; i ++ )
			{
				ShapeSwimlane *p = pSAG->m_pShapeSwimlanes.GetAt( i );
				CRect o,n;
				o = p->m_Pos;
				p->m_Pos = CRect( wid*i , 0 , wid*i + wid ,r.bottom );
				n = p->m_Pos;
				p->AdjustActivityPos(o,n);
			}
		}
		else
		{
			pSS->m_Pos = r;
			pSAG->m_pShapeSwimlanes.Add( pSS );
			pSAG->m_pActivityGraph->m_Swimlanes.Add( pSS->m_pSwimlane );
		}
	}
}

void CAG_MDAView::OnButtonSwimlane() 
{
	// TODO: Add your command handler code here
	SetAGButtons( ID_BUTTON_SWIMLANE );
	m_OperationType = OPE_ADD_SWIMLANE;
}

void CAG_MDAView::OnUpdateButtonSwimlane(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->Enable( m_CurrentElement && m_CurrentElement->GetType() == SHAPE_ACTIVITYDIAGRAM );
}

void CAG_MDAView::OnSize(UINT nType, int cx, int cy) 
{
	CView::OnSize(nType, cx, cy);
	
	// TODO: Add your message handler code here
	if( m_CurrentElement )
	{
		ShapeActivityGraph *pSAG = (ShapeActivityGraph*)m_CurrentElement;
		
		for( int i = 0 ; i <= pSAG->m_pShapeSwimlanes.GetUpperBound() ; i ++ )
		{
			int wid = cx / (pSAG->m_pShapeSwimlanes.GetUpperBound() + 1 );

			ShapeSwimlane* p = pSAG->m_pShapeSwimlanes.GetAt( i );
			CRect o,n;
			o = p->m_Pos;
			p->m_Pos.left = i * wid;
			p->m_Pos.right = p->m_Pos.left + wid;
			p->m_Pos.top = 0;
			p->m_Pos.bottom = cy;
			n = p->m_Pos;
			p->AdjustActivityPos(o,n);
		}
	}
}

void CAG_MDAView::AppendLog(CString txt)
{
	CMainFrame *frm =(CMainFrame*)AfxGetMainWnd();
	frm->AppendLog( txt );
}

void CAG_MDAView::OnFileSave() 
{
	// TODO: Add your command handler code here
	CFileDialog dlg(false ,"xml","*.xml",OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,"XML File(*.xml)|*.xml||");
	if( dlg.DoModal() == IDOK )
	{
		ShapeNamespace *pSN = (ShapeNamespace*)m_pRootShape;
		CFile file;
		if( file.Open( dlg.GetPathName() , CFile::modeCreate | CFile::modeWrite ) )
		{
			int tabnum = 0;
			pSN->Save( file , tabnum );
			file.Close();
		}
	}
}

void CAG_MDAView::OnFileOpen() 
{
	// TODO: Add your command handler code here
	CMainFrame *frm = (CMainFrame*)AfxGetMainWnd();
	frm->m_TreeDlg.OpenSource();
}

void CAG_MDAView::OnButtonDel() 
{
	// TODO: Add your command handler code here
	SetAGButtons( ID_BUTTON_DEL );
	m_OperationType = OPE_DEL;
}

void CAG_MDAView::DelSel(CPoint pt)
{
	ShapeElement* pSel = FindSel( pt );
	if( pSel )
	{
		switch( pSel->GetType() )
		{
		case SHAPE_ACTIVITY:
			{
				ShapeActivity* pSA = (ShapeActivity*)pSel;
				if( MessageBox( "删除活动" , "删除" , MB_YESNO)== IDNO)return;
				//将活动从泳道或活动图中取出
				if( pSA->m_pOwnedShape->GetType() == SHAPE_SWIMLANE )
				{
					ShapeSwimlane *pSS = (ShapeSwimlane*)pSA->m_pOwnedShape;

					int idx = pSS->m_pActivities.GetFirstIdx( pSA );
					pSS->m_pActivities.RemoveAt( idx );   //删除shape中的元素

					idx = pSS->m_pSwimlane->m_Activities.GetFirstIdx( pSA->m_pUMLActivity );
					pSS->m_pSwimlane->m_Activities.RemoveAt( idx );   //删除规约中的元素
 
				}
				else
				//将活动从活动图中删除
				{
					//找到owner，然后在shape中删除自己
					ShapeActivityGraph *pSAG = (ShapeActivityGraph*) pSA->m_pOwnedShape;
					int idx = pSAG->m_pShapeActivities.GetFirstIdx( pSA );
					pSAG->m_pShapeActivities.RemoveAt( idx );
					
					//在UMLMeta中删除自己
					idx = pSAG->m_pActivityGraph->m_Activities.GetFirstIdx( pSA->m_pUMLActivity );
					pSAG->m_pActivityGraph->m_Activities.RemoveAt( idx );
				}


				//取出连接该活动图的边，并从边的另一端节点中将该边删除
				CPtrTempl<ShapeTransEdge*>edges;
				ShapeActivityGraph *pSAG = (ShapeActivityGraph*)m_CurrentElement;
				for( int i = 0 ; i <= pSA->m_pInTransEdges.GetUpperBound() ; i ++ )
				{
					ShapeTransEdge *e = pSA->m_pInTransEdges.GetAt( i );
					int idx = e->m_pActivity[ 0 ]->m_pOutTransEdges.GetFirstIdx( e );
					e->m_pActivity[ 0 ]->m_pOutTransEdges.RemoveAt( idx );

					idx = e->m_pActivity[0]->m_pUMLActivity->m_OutTransEdge.GetFirstIdx( e->m_pTransEdge );
					e->m_pActivity[0]->m_pUMLActivity->m_OutTransEdge.RemoveAt( idx );
					if( !edges.Find( e ))edges.Add( e );
				}
				//另一个方向
				for( i = 0 ; i <= pSA->m_pOutTransEdges.GetUpperBound() ; i ++ )
				{
					ShapeTransEdge *e = pSA->m_pOutTransEdges.GetAt( i );
					int idx = e->m_pActivity[ 1 ]->m_pInTransEdges.GetFirstIdx( e );
					e->m_pActivity[ 1 ]->m_pInTransEdges.RemoveAt( idx );

					idx = e->m_pActivity[1]->m_pUMLActivity->m_InTransEdge.GetFirstIdx( e->m_pTransEdge );
					e->m_pActivity[1]->m_pUMLActivity->m_InTransEdge.RemoveAt( idx );
					
					if( !edges.Find( e ))edges.Add( e );
				}
				//删除所有连接该节点的边
				for( i = 0 ; i <= edges.GetUpperBound() ; i ++ )
				{
					ShapeTransEdge *e = edges.GetAt( i );
					int idx = pSAG->m_pShapeTransEdges.GetFirstIdx( e );
					pSAG->m_pShapeTransEdges.RemoveAt( idx );
					delete e->m_pTransEdge;
					delete e;
				}
				edges.RemoveAll();
				delete pSA->m_pUMLActivity;
				delete pSA;
				Invalidate();
			}
			break;
		case SHAPE_TRANSEDGE:
			{
				ShapeTransEdge* e = (ShapeTransEdge*)pSel;
				ShapeActivityGraph *pSAG = (ShapeActivityGraph*)m_CurrentElement;
				if( MessageBox( "删除边" , "删除" , MB_YESNO)== IDNO)return;

				int idx = e->m_pActivity[ 0 ]->m_pOutTransEdges.GetFirstIdx( e );
				e->m_pActivity[ 0 ]->m_pOutTransEdges.RemoveAt( idx );

				idx = e->m_pActivity[0]->m_pUMLActivity->m_OutTransEdge.GetFirstIdx( e->m_pTransEdge );
				e->m_pActivity[0]->m_pUMLActivity->m_OutTransEdge.RemoveAt( idx );

				idx = e->m_pActivity[ 1 ]->m_pInTransEdges.GetFirstIdx( e );
				e->m_pActivity[ 1 ]->m_pInTransEdges.RemoveAt( idx );

				idx = e->m_pActivity[1]->m_pUMLActivity->m_InTransEdge.GetFirstIdx( e->m_pTransEdge );
				e->m_pActivity[1]->m_pUMLActivity->m_InTransEdge.RemoveAt( idx );

				idx = pSAG->m_pShapeTransEdges.GetFirstIdx( e );
				pSAG->m_pShapeTransEdges.RemoveAt( idx );

				delete e->m_pTransEdge;
				delete e;
				Invalidate();
			}
			break;
		}
	}
}




//******************************************************
//下面的代码主要用来实现对活动图的测试工作
//******************************************************
void CAG_MDAView::OnButtonActivityDiagramTest() 
{
	//得到测试轨迹的list；
    	if((ShapeElement::m_AllShapes).GetSize()<=7)
		{
			 MessageBox("请选择活动图");
			 return;
		}
    	CFileDialog dlg(true ,"tcs","*.tcs",OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,"Test case set File(*.tcs)|*.tcs||");
		if( dlg.DoModal() == IDCANCEL)return;
		CString pathName=dlg.GetPathName();
		ReadTestCaseFromFile(pathName);  //从选择的文件中读取随机生成的测试用例，将其放入二维表testCaseSet

	//开始匹配与对比
		for(int i=0;i<testCaseSet.GetSize();i++)
		{
			if(UseTestCase(i))
			{
			//	CString str;
			//	str.Format("测试 %d 用例成功",i);
			//	MessageBox(str);
				ResotreColor();
				index.Add(i); //遍历了没有遍历的活动图元素
			}
			else
			{
			//	CString str;
			//	str.Format("测试 %d 用例失败",i);
			//	MessageBox(str);
				ResotreColor();
				RemoveAllSynTags();
			}
			 
			if(ActivityDiagramAllCoverd())
				break;
		}
    ResultColor();
	Invalidate();
	//将测试结果写入文件
	WriteTestResultToFile();
	//后期删除
    ResetTestResult();
	Invalidate();//重画原图形
}

void CAG_MDAView::OnUpdateButtonActivityDiagramTest(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	
}


//从文件中读取测试用例集合
void CAG_MDAView::ReadTestCaseFromFile(CString filePath)
{
	char c;
	CString str = "";
	CFile file;

	if(  !(file.Open( filePath , CFile::modeRead ))  )
	{
          MessageBox("不能打开文件！");
		  return;
	}
    
	BOOL readATestCaseSucc=true;
	//打开文件成功
	while( file.Read( &c , 1 ) && readATestCaseSucc)
	{
		if(c=='\r' || c=='\n' )
		   continue;

		if( c == '(' )
		{
		   readATestCaseSucc=ReadATestCase(file);  
		}
		else
		{
			if(c != ')')
			{
				ResetTestResult();
				MessageBox("读取测试用例失败");
				file.Close(); 
				return;
			}
		}
	}
    
	if(testCaseInput.GetSize()!=testCaseSet.GetSize())
	{
		MessageBox("读取测试用例失败");
	}

	file.Close();   //close the file

	return;
	
}

BOOL CAG_MDAView::ReadATestCase(CFile &file)
{
	char c;
	CString str = "";
	TESTCASE* tc=new TESTCASE();
	testCaseSet.Add(tc);

	while(file.Read( &c , 1 ))
	{
		if(c=='\r' || c=='\n' )
		   continue;
		if(c == ':')
		{
			//MessageBox("用例"+str);
			testCaseInput.Add(new CString(str));
			str="";
			file.Read(&c,1);
			if(c!='<')return false;
			break;
		}
		else
		{
			str+=c;
		}
	}

	while(file.Read( &c , 1 ))
	{ 
		if( c == '>' )
		{
			tc->Add(new CString(str));
			//	MessageBox("轨迹"+str);
			str = "";
			//MessageBox("轨迹"+str);
			return true;
		}
		else
		{
            if(c=='\r' || c=='\n')
			continue;

			if(c==',')
			{
				tc->Add(new CString(str));
			//	MessageBox("轨迹"+str);
				str = "";
				continue;
			}
			else
			{
				str+=c;
			}
		}
	}
	return false;
}

//向文件中写入测试结果
void CAG_MDAView::WriteTestResultToFile()
{
	double activities=0,activities_used=0;
	double edges=0,edges_used=0;

	for(int i=0;i<ShapeElement::m_AllShapes.GetSize();i++)
	{
		ShapeElement * se=ShapeElement::m_AllShapes.GetAt(i);
		if(se->GetType()==SHAPE_ACTIVITY)           //点覆盖率
		{
			activities++;
			if(se->GetBeUsed())activities_used++;
		} 

		if(se->GetType()==SHAPE_TRANSEDGE)          //边覆盖率
		{
			edges++;
			if(se->GetBeUsed())edges_used++;
		} 
	}


	if(activities!=0)
	 activityCoverage = activities_used / activities * 100;  
	if(edges!=0)
	 edgeCoverage = edges_used / edges * 100;
	 CString testResult="";
	 CString result1;
	 result1.Format("\r\n[活动覆盖率:]  -------------------- %.2f %%\r\n",activityCoverage);
	 result1=result1;
	 
	 CString result2;
	 result2.Format("\r\n[边覆盖率:  ]  ---------------------- %.2f %%\r\n",edgeCoverage);
	 result2="________________________________________________________________\r\n"+result2;
 
	 CString result3="";
     for(i=0;i<index.GetSize();i++)
	 {
		result3+=*testCaseInput.GetAt(index.GetAt(i))+", ";
	 }
	 result3.Delete(result3.GetLength()-1,2);
     result3="________________________________________________________________\r\n\r\n测试用例集合为： \r\n"+result3;
 
	 
	 CString result4="";
	 for(i=0;i<errorIndex.GetSize();i++)
	 {
		result4+=*testCaseInput.GetAt(errorIndex.GetAt(i))+", ";
	 }
	 result4.Delete(result4.GetLength()-1,2);
     result4="\r\n\r\n________________________________________________________________\r\n\r\n错误用例集合为： \r\n"+result4;

	 for(int x=0;x<index.GetSize();x++)
	 {
	//	 CString * csp=testCaseInput.GetAt(index.GetAt(x));//????????
		 testCaseInput.SetAt(index.GetAt(x),new CString("null"));
	//	 delete csp;
	 }

	 for(x=0;x<errorIndex.GetSize();x++)
	 {
	//	 CString * csp=testCaseInput.GetAt(index.GetAt(x));//????????
		 testCaseInput.SetAt(errorIndex.GetAt(x),new CString("null"));
	//	 delete csp;
	 }

	 CString result5="";
	 for(i=0;i<testCaseInput.GetSize();i++)
	 {
		if(*testCaseInput.GetAt(i)=="null")continue;
		result5+=*testCaseInput.GetAt(i)+", ";
	 }
	 result5.Delete(result5.GetLength()-1,2);
     result5="\r\n\r\n________________________________________________________________\r\n\r\n没有测试的用例集合为： \r\n"+result5;


	 testResult=result1+result2+result3+result4+result5;

	 index.RemoveAll();
	 errorIndex.RemoveAll();
     TestCoverageDlg tcdlg;
	 tcdlg.Display(testResult);
	 tcdlg.DoModal();
	 
}



//删除测试集合的二维表
void CAG_MDAView::ClearTestCaseSet()
{
	for(int i=0;i<testCaseSet.GetSize();i++)
	{
		for(int j=0;j<testCaseSet.GetAt(i)->GetSize();j++)
		{
			if(testCaseSet.GetAt(i)->GetAt(j))
				delete testCaseSet.GetAt(i)->GetAt(j);
		}
		testCaseSet.GetAt(i)->RemoveAll();
	}
	testCaseSet.RemoveAll();
	return;
}

//删除失败的测试集合的二维表
void CAG_MDAView::ClearFailedTestCaseSet()
{
/*	for(int i=0;i<failedTestCaseSet.GetSize();i++)
	{
		for(int j=0;j<failedTestCaseSet.GetAt(i)->GetSize();j++)
		{
			if(failedTestCaseSet.GetAt(i)->GetAt(j))
			    failedTestCaseSet.GetAt(i)->RemoveAt(j);
		}
	    failedTestCaseSet.RemoveAt(i);
	}
*/	return;
}

//删除测试用例的输入
void CAG_MDAView::ClearTestCaseInput()
{
	for(int i=0; i<testCaseInput.GetSize(); i++)
	{
		CString * temp=testCaseInput.GetAt(i);
		if(temp)delete temp;
	}
	testCaseInput.RemoveAll();
	return;
}


//重新设置测试数据
void CAG_MDAView::ResetTestResult()
{
	edgeCoverage=0;
	activityCoverage=0;
	ClearTestCaseSet();

//	ClearFailedTestCaseSet();
//	failedTestCaseSet.RemoveAll();
	
//	testCaseInput.RemoveAll();
	ClearTestCaseInput();

	index.RemoveAll();
	errorIndex.RemoveAll();

	currentPosition.RemoveAll();
	ClearAllTags();
}


BOOL CAG_MDAView::ActivityDiagramAllCoverd()
{
	BOOL coverAll=true;
	int elementNo=(ShapeElement::m_AllShapes).GetSize();
	for(int i=0;i<elementNo;i++)
	{
		ShapeElement *se=(ShapeElement::m_AllShapes).GetAt(i);
		if(se->GetType() == SHAPE_ACTIVITY ||se->GetType() ==SHAPE_TRANSEDGE )
		{
	       if(se->GetBeUsed()==false)return false;
		}
	}
	return coverAll;
}


//使用第i个测试用例
BOOL CAG_MDAView::UseTestCase(int i)
{
	BOOL changed=false; 
	ShapeActivity* sa=NULL;
    int elementNo=(ShapeElement::m_AllShapes).GetSize();
	for(int j=0;j<elementNo;j++)        //得到起始点
	{
		ShapeElement *se=(ShapeElement::m_AllShapes).GetAt(j);
		if(se->GetType() == SHAPE_ACTIVITY)
		{
		    sa=(ShapeActivity*)se;
	        if(sa->m_pUMLActivity->m_ActivityKind==ACTIVITY_INIT)
			break;
		}
	}
  
	ASSERT(sa);

//	currentPosition.RemoveAll();
//	if(!sa->GetBeUsed())sa->SetBeUsed(true);
  
	//如果没有遍历预览没有成功
	if(!ForwardWithTheTrace(i,sa,true))
	{
		errorIndex.Add(i);
		return false;
	}
	
//	currentPosition.RemoveAll();
	//预览成功，真实遍历
	changed=ForwardWithTheTrace(i,sa,false);  //开始利用遍历第i个trace遍历活动图
  //  if(changed)MessageBox("true");
	return changed;
}



//利用头节点以及后继的路径遍历活动图，如果preView为true则不用设定遍历状态
BOOL CAG_MDAView::ForwardWithTheTrace(int id, ShapeElement * head, BOOL preView)
{
   BOOL changed=false;
   BOOL preViewSucc=true;
   currentPosition.RemoveAll();
   TESTCASE * testcase=testCaseSet. GetAt(id);

   currentPosition.Add(head);  
   if( ((ShapeActivity*)head)->m_pUMLActivity->name != *(testcase->GetAt(0)) )
	return false;   //将起始节点放入当前位置

   if(!preView && !head->GetBeUsed())
   {
	   head->SetBeUsed(true);
	   changed=true;
   }
	
   if(preView)
   {
		for(int i=1;i<testcase->GetSize();i++) 
		{
		    //由当前位置与符号得到下一个当前位置
			if(!PreViewChangeCurrentPositionWith(testcase->GetAt(i)))			
				return false;
		//	MessageBox("下一步"+*testcase->GetAt(i));
		}
   }
   else
   {
	   	for(int i=1;i<testcase->GetSize();i++) 
		{
			//由当前位置与符号得到下一个当前位置
			if(ChangeCurrentPositionWith(testcase->GetAt(i)))
				changed=true;
		}
   }

   if(preView)
	   return preViewSucc;
   else
	   return changed;
}


//预览遍历中的一步
BOOL CAG_MDAView::PreViewChangeCurrentPositionWith(CString *nodeName)
{
  	for(int i=0;i<currentPosition.GetSize();i++)
	{
		CString str;
		ShapeElement *se=currentPosition.GetAt(i);
		if(se->GetType()==SHAPE_ACTIVITY)        //处理的是状态节点
		{
			ShapeActivity* sa=(ShapeActivity*)se;
			if(sa->m_pUMLActivity->m_ActivityKind!=ACTIVITY_SYNCH) //当前活动不是同步状态
			{
				for(int j=0;j<sa->m_pOutTransEdges.GetSize();j++)//考察当前节点的每条出边
				{
					ShapeTransEdge * pste=sa->m_pOutTransEdges.GetAt(j);
					ShapeActivity* psa=pste->m_pActivity[1];
					
					if( psa->m_pUMLActivity->name == *nodeName )//找到目标节点
					{
						//颜色表示遍历路径
						COLORREF m_LineColor=pste->m_LineColor;
						COLORREF m_FillColor=psa->m_FillColor;
						pste->m_LineColor=RGB(255,0,0);
						psa->m_FillColor=RGB(255,0,0);
						Invalidate();			

						if(psa->m_pUMLActivity->m_ActivityKind==ACTIVITY_SYNCH) //目标节点是同步节点
						{		
							sa->sync=true;
							if(!CheckSyncActivityInEdges(psa))
							{	
								currentPosition.RemoveAt(i);
								i--;
								//if(!currentPosition.Find(psa))
							//		currentPosition.Add(psa);
								break;
							}
							else
							{
								currentPosition.RemoveAt(i);
								i--;
								if(!currentPosition.Find(psa))
									currentPosition.Add(psa);
								return true;
							}

						}
			                               //目标节点不是同步节点
						currentPosition.RemoveAt(i);
						i--;
						if(!currentPosition.Find(psa))
							currentPosition.Add(psa);
						return true;
					}

				}
			  continue;
			}
			
			if(sa->m_pUMLActivity->m_ActivityKind==ACTIVITY_SYNCH) //当前活动是同步状态 
			{
                if(!CheckSyncActivityInEdges(sa))continue;   //输入没有完全
			
				for(int j=0;j<sa->m_pOutTransEdges.GetSize();j++)//考察当前节点的所有出边
				{
					ShapeTransEdge * pste=sa->m_pOutTransEdges.GetAt(j);
					ShapeActivity* psa=pste->m_pActivity[1];
				
					if( psa->m_pUMLActivity->name == *nodeName)//找到目标节点
					{
						//颜色表示遍历路径
						COLORREF m_LineColor=pste->m_LineColor;
						COLORREF m_FillColor=psa->m_FillColor;
						pste->m_LineColor=RGB(255,0,0);
						psa->m_FillColor=RGB(255,0,0);
						Invalidate();
				
						if(psa->sync) continue;

						psa->sync=true;

						if(CheckSyncActivityOutEdges(sa))   //如果当前节点可以删除
						{
							CheckSyncActivity(sa);
							currentPosition.RemoveAt(i);  
							i--;
						}

						if(psa->m_pUMLActivity->m_ActivityKind==ACTIVITY_SYNCH)//目标节点是同步的
						{
							sa->sync=true;
							if(CheckSyncActivityInEdges(psa))
							{
								if(!currentPosition.Find(psa))
								currentPosition.Add(psa);
								return true;
							}
							break;
						}
						else   //目标节点不是同步的
						{
							if(!currentPosition.Find(psa))
								currentPosition.Add(psa);
							return true;
						}
					}
				}//for
			}
		}
		
	}
	
    return false;
}

//真实遍历中的一步,需要记录覆盖率
BOOL CAG_MDAView::ChangeCurrentPositionWith(CString *nodeName)
{
	BOOL changed=false;
/*	CString cst="";
	for(int y=0;y<currentPosition.GetSize();y++)
	{
		cst+=((ShapeActivity*)(currentPosition.GetAt(y)))->m_pUMLActivity->name+",";
	}
   	MessageBox(cst+" next state is  "+*nodeName);//???????????????????
*/
	for(int i=0;i<currentPosition.GetSize();i++)
	{
		ShapeElement *se=currentPosition.GetAt(i);
		if(se->GetType()==SHAPE_ACTIVITY)
		{
			ShapeActivity* sa=(ShapeActivity*)se;
			if(sa->m_pUMLActivity->m_ActivityKind!=ACTIVITY_SYNCH) //活动不是同步状态
			{
				for(int j=0;j<sa->m_pOutTransEdges.GetSize();j++)//考察当前节点的所有出边
				{
					ShapeTransEdge * pste=sa->m_pOutTransEdges.GetAt(j);
					ShapeActivity* psa=pste->m_pActivity[1];     //下一个节点（活动）
									
					if( psa->m_pUMLActivity->name == *nodeName) //找到目标节点
					{
						if(psa->m_pUMLActivity->m_ActivityKind==ACTIVITY_SYNCH)//目标节点是同步节点
						{
							sa->sync=true;
							//改变了状态
							if(!pste->GetBeUsed())
							{
								pste->SetBeUsed(true);
								changed=true;
							}
							
							if(!CheckSyncActivityInEdges(psa))
							{	
								currentPosition.RemoveAt(i);
								i--;
								break;
							}
							else
							{
								currentPosition.RemoveAt(i);
								i--;
								if(!currentPosition.Find(psa))
									currentPosition.Add(psa);
								if(!psa->GetBeUsed())
								{
									psa->SetBeUsed(true);
									changed=true;
								}
								return changed;//TRUE TO CHANGED????????????????
							}
						
	                       
						}

						
						//目标节点非同步节点
						if(!pste->GetBeUsed())
						{
							pste->SetBeUsed(true);
							changed=true;
						}
						if(!psa->GetBeUsed())
						{
							psa->SetBeUsed(true);
							changed=true;
						}

						currentPosition.RemoveAt(i);
						i--;
						if(!currentPosition.Find(psa))
							currentPosition.Add(psa);
						return changed;
					}
				}
			}
			

			if(sa->m_pUMLActivity->m_ActivityKind==ACTIVITY_SYNCH) //活动是同步状态 
			{
                if(!CheckSyncActivityInEdges(sa))continue;   //输入没有完全
			
				for(int j=0;j<sa->m_pOutTransEdges.GetSize();j++)//考察当前节点的所有出边
				{
					ShapeTransEdge * pste=sa->m_pOutTransEdges.GetAt(j);
					ShapeActivity* psa=pste->m_pActivity[1];
				
					if( psa->m_pUMLActivity->name == *nodeName)
					{
						if(psa->sync) continue;
						psa->sync=true;

						if(CheckSyncActivityOutEdges(sa))
						{
							CheckSyncActivity(sa);
							currentPosition.RemoveAt(i); 
							i--;
						}

						if(psa->m_pUMLActivity->m_ActivityKind==ACTIVITY_SYNCH)
						{
							sa->sync=true;
							if(!pste->GetBeUsed())
							{
								pste->SetBeUsed(true);
								changed=true;
							}
							if(CheckSyncActivityInEdges(psa))
							{
								if(!psa->GetBeUsed())
								{
									psa->SetBeUsed(true);
									changed=true;
								}
								if(!currentPosition.Find(psa))
									currentPosition.Add(psa);
								return changed;//TRUE TO CHANGED?????????
							}
							break;

						}
                        else // 目标节点不是同步的
						{
							if(!pste->GetBeUsed())
							{
								pste->SetBeUsed(true);
								changed=true;
							}
							if(!psa->GetBeUsed())
							{
								psa->SetBeUsed(true);
								changed=true;
						
							}

							if(!currentPosition.Find(psa))
								currentPosition.Add(psa);
							return changed;
						}						
					}
				}
			}
		}
		
	}
	return changed;
}



//查明是否同步状态的入边都发生
BOOL CAG_MDAView::CheckSyncActivityInEdges(ShapeActivity *sa)
{
	for(int i=0;i<sa->m_pInTransEdges.GetSize();i++)
	{
		ShapeTransEdge * pste=sa->m_pInTransEdges.GetAt(i);
		if (!pste->m_pActivity[0]->sync)return false;
	}
	for(i=0;i<sa->m_pInTransEdges.GetSize();i++)
	{
		ShapeTransEdge * pste=sa->m_pInTransEdges.GetAt(i);
		if (!pste->m_pActivity[0]->sync)pste->m_pActivity[0]->sync=false;
	}
	return true;
}

//查明是否同步状态的出边都发生
BOOL CAG_MDAView::CheckSyncActivityOutEdges(ShapeActivity *sa)
{
	for(int i=0;i<sa->m_pOutTransEdges.GetSize();i++)
	{
		ShapeTransEdge * pste=sa->m_pOutTransEdges.GetAt(i);
		if (!pste->m_pActivity[1]->sync)return false;
	}

	for(i=0;i<sa->m_pOutTransEdges.GetSize();i++)
	{
		ShapeTransEdge * pste=sa->m_pOutTransEdges.GetAt(i);
		if (!pste->m_pActivity[1]->sync)pste->m_pActivity[1]->sync=false;
	}
	return true;
}

//取消同步状态的设定
BOOL CAG_MDAView::CheckSyncActivity(ShapeActivity *sa)
{
	for(int i=0;i<sa->m_pOutTransEdges.GetSize();i++)
	{
		ShapeTransEdge * pste=sa->m_pOutTransEdges.GetAt(i);
		pste->m_pActivity[1]->sync=false;
	}
	for( i=0;i<sa->m_pInTransEdges.GetSize();i++)
	{
		ShapeTransEdge * pste=sa->m_pInTransEdges.GetAt(i);
		pste->m_pActivity[0]->sync=false;
	}
	return true;
}

void CAG_MDAView::ClearAllTags()
{
    for(int i=0;i<ShapeElement::m_AllShapes.GetSize();i++)
	{
		ShapeElement * se=ShapeElement::m_AllShapes.GetAt(i);
		if(se->GetType()==SHAPE_ACTIVITY)
		{
			se->SetBeUsed(false);
			((ShapeActivity *)se)->sync=false;
			((ShapeActivity *)se)->m_FillColor=RGB( 255 , 255 , 0);
		}
		
		if(se->GetType()==SHAPE_TRANSEDGE)
		{
			se->SetBeUsed(false);
			((ShapeTransEdge *)se)->m_LineColor = RGB( 128 , 64 , 0);
		}
	}

	return;
}

void CAG_MDAView::RemoveAllSynTags()
{
	 for(int i=0;i<ShapeElement::m_AllShapes.GetSize();i++)
	{
		if(ShapeElement::m_AllShapes.GetAt(i)->GetType() == SHAPE_ACTIVITY)
		{
			((ShapeActivity*)ShapeElement::m_AllShapes.GetAt(i))->sync=false;
		}
	}
	return;

}

void CAG_MDAView::ResotreColor()
{
	for(int i=0;i<ShapeElement::m_AllShapes.GetSize();i++)
	{
		ShapeElement * se=ShapeElement::m_AllShapes.GetAt(i);
		if(se->GetType()==SHAPE_ACTIVITY)
		{
			((ShapeActivity *)se)->m_FillColor=RGB( 255 , 255 , 0);
		}
		
		if(se->GetType()==SHAPE_TRANSEDGE)
		{
			((ShapeTransEdge *)se)->m_LineColor = RGB( 128 , 64 , 0);
		}
	}

	return;

}

void CAG_MDAView::ResultColor()
{
	for(int i=0;i<ShapeElement::m_AllShapes.GetSize();i++)
	{
		ShapeElement * se=ShapeElement::m_AllShapes.GetAt(i);
		if(se->GetType()==SHAPE_ACTIVITY && se->GetBeUsed())
		{
			((ShapeActivity *)se)->m_FillColor=RGB( 255 , 0 , 0);
		}
		
		if(se->GetType()==SHAPE_TRANSEDGE && se->GetBeUsed())
		{
			((ShapeTransEdge *)se)->m_LineColor = RGB( 255 ,0 , 0);
		}
	}

	return;
}


//************************************************
//路进覆盖测试
//************************************************

void CAG_MDAView::OnButtonPathCoverageTest() 
{
	//得到测试轨迹的list；
   	if((ShapeElement::m_AllShapes).GetSize()<=7)
	{
		 MessageBox("请选择活动图");
		 return;
	}
   	CFileDialog dlg(true ,"tcs","*.tcs",OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,"Test case set File(*.tcs)|*.tcs||");
	if( dlg.DoModal() == IDCANCEL)return;
	CString pathName=dlg.GetPathName();
	ReadTestCaseFromFile(pathName);  //从选择的文件中读取随机生成的测试用例，将其放入二维表testCaseSet


	ShapeActivity * sa;
    int elementNo=(ShapeElement::m_AllShapes).GetSize();
	for(int j=0;j<elementNo;j++)        //得到起始点
	{
		ShapeElement *se=(ShapeElement::m_AllShapes).GetAt(j);
		if(se->GetType() == SHAPE_ACTIVITY)
		{
		    sa=(ShapeActivity*)se;
	        if(sa->m_pUMLActivity->m_ActivityKind==ACTIVITY_INIT)
			break;
		}
	}
	ASSERT(sa);

	//前期处理，清空数据结构
	currentTrace.RemoveAll();
	DFSStack.RemoveAll();
	DFSStack_usededges.RemoveAll();
	
	allTrace.RemoveAll();
	allLoop.RemoveAll();

//开始进行栈的操作
	CURRENTSTATE *cs=new CURRENTSTATE;
	USEDEDGESOFCURRENTSTATE * cs_usededges=new USEDEDGESOFCURRENTSTATE;
	cs->add(sa);
	cs->GetAt(0)->IncreaseVisitedNum();
	currentTrace.add(sa);
	DFSStack.Push(cs);//添加活动图的初始状态，初始状态中只有一个起始节点
	DFSStack_usededges.Push(cs_usededges);

	DFS();//开始深度遍历

	//开始匹配
	CompareTestCaseWithAllPath();
	//匹配结束

	//结果显示
	ResultColor();
    Invalidate();
	DisplayPathCoverageResult();

	ResetAfterPathCoverage();
	ResetTestResult();
	Invalidate();//重画原图形
	
}

void CAG_MDAView::DFS()
{
	while(DFSStack.GetSize()>0)
	{
		CURRENTSTATE * cs=NULL;
		DFSStack.Pop(cs);
		USEDEDGESOFCURRENTSTATE * cs_usededges=NULL;
		DFSStack_usededges.Pop(cs_usededges);
		//下面时执行一步栈的操作
		if(cs->GetSize()==1)//当前状态只有一个节点
		{
		//	CurrentStateWithOneElement(cs,cs_usededges); //处理当前状态只有一个节点的方法
			CurrentStateWithMoreThanOneElement(cs,cs_usededges);
		}
		if(cs->GetSize()>1)//当前状态里的活动个数大于1
		{
			CurrentStateWithMoreThanOneElement(cs,cs_usededges);//处理当前状态有多个节点的方法
		}
	}
	return;	
}


//当前系统只有一个进程
void CAG_MDAView::CurrentStateWithOneElement(CURRENTSTATE * cs,USEDEDGESOFCURRENTSTATE * cs_usededges)
{
	ShapeActivity * sa=cs->GetAt(0);  //当前活动图状态中只包含节点为sa

	//MessageBox(sa->m_pUMLActivity->name);

	BOOL hasEnabledTransEdge=false;
	int x=0;
	for(x=0;x<sa->m_pOutTransEdges.GetSize();x++)
	{
		if(sa->m_pOutTransEdges.GetAt(x)->GetEnabled())
		{
			hasEnabledTransEdge=true;
			break;
		}
	}

	if(sa->m_pUMLActivity->m_ActivityKind!=ACTIVITY_SYNCH && hasEnabledTransEdge)//当前状态不是并发状态，是普通节点
	{
		//下一个节点是循环的初始点
		if(sa->m_pOutTransEdges.GetAt(x)->m_pActivity[1]->GetVisitedNum()>=1)
		{
			sa->m_pOutTransEdges.GetAt(x)->SetEnabled(false);
			DFSStack.Push(cs);
			cs_usededges->RemoveAll();
			DFSStack_usededges.add(cs_usededges);
			return;
		}

		//下一个节点是普通节点或者同步状态,且不是循环点
		DFSStack.Push(cs);
		cs_usededges->RemoveAll();
		cs_usededges->add(sa->m_pOutTransEdges.GetAt(x));
		DFSStack_usededges.add(cs_usededges);

		sa->m_pOutTransEdges.GetAt(x)->SetEnabled(false);
		sa->m_pOutTransEdges.GetAt(x)->m_pActivity[1]->IncreaseVisitedNum();//入栈＋1
		CURRENTSTATE *ncs=new CURRENTSTATE;
		ncs->add(sa->m_pOutTransEdges.GetAt(x)->m_pActivity[1]);
		currentTrace.add(sa->m_pOutTransEdges.GetAt(x)->m_pActivity[1]);
	
		DFSStack.Push(ncs);
		DFSStack_usededges.add(new USEDEDGESOFCURRENTSTATE);
	
		return;		
	}
	else if(sa->m_pUMLActivity->m_ActivityKind==ACTIVITY_SYNCH && hasEnabledTransEdge)//当前状态是并发状态
	{
		//下一个节点是循环的初始点
		if(sa->m_pOutTransEdges.GetAt(x)->m_pActivity[1]->GetVisitedNum()>=1)
		{
			sa->m_pOutTransEdges.GetAt(x)->SetEnabled(false);
			DFSStack.Push(cs);
			cs_usededges->RemoveAll();
			DFSStack_usededges.add(cs_usededges);
			return;
		}
		
		//且不是循环点
		DFSStack.Push(cs);
		cs_usededges->RemoveAll();

		CURRENTSTATE *ncs=new CURRENTSTATE;
		for(int i=0;i<sa->m_pOutTransEdges.GetSize();i++)  //找到并发状态的所有下一个节点
		{	
			ShapeActivity * nsa=sa->m_pOutTransEdges.GetAt(i)->m_pActivity[1];
			sa->m_pOutTransEdges.GetAt(i)->SetEnabled(false);
			nsa->IncreaseVisitedNum();
			ncs->add(nsa);
			cs_usededges->add(sa->m_pOutTransEdges.GetAt(i));
			currentTrace.add(nsa);
		}
		DFSStack_usededges.add(cs_usededges);
		DFSStack.Push(ncs);
		DFSStack_usededges.Push(new USEDEDGESOFCURRENTSTATE);
		return;
	}

	if(!hasEnabledTransEdge)//当前节点无效
	{
		if(sa->m_pUMLActivity->m_ActivityKind==ACTIVITY_FINISH)
		{
			RecordCurrentTrace();
		}
		currentTrace.RemoveAt(currentTrace.GetSize()-1);
		if(currentTrace.GetSize()==0)  //程序结束
		{
			sa->DecreaseVisitedNum();
			for(int i=0;i<sa->m_pOutTransEdges.GetSize();i++)
			{
				sa->m_pOutTransEdges.GetAt(i)->SetEnabled(true);
			}
			cs->RemoveAll();
			delete cs;
			cs_usededges->RemoveAll();
			delete cs_usededges;
			return;
		}
		//**************************************************
		//如果当前状态是同步条且没有enable的边
		//**************************************************
		if(sa->m_pUMLActivity->m_ActivityKind==ACTIVITY_SYNCH)
		{
			sa->DecreaseVisitedNum();
			for(int i=0;i<sa->m_pOutTransEdges.GetSize();i++)
			{
				sa->m_pOutTransEdges.GetAt(i)->SetEnabled(true);
			}
			cs_usededges->RemoveAll();
			delete cs_usededges;
			cs->RemoveAll();
			delete cs;
			return;
		}
		//**************************************************
		//如果当前状态不是同步条，且没有enable的边
		//**************************************************
		sa->DecreaseVisitedNum();
		for(int i=0;i<sa->m_pOutTransEdges.GetSize();i++)
		{
			sa->m_pOutTransEdges.GetAt(i)->SetEnabled(true);
		}
		cs->RemoveAll();
		delete cs;
		cs_usededges->RemoveAll();
		delete cs_usededges;
		return;
	}

}

//当系统有多个进程执行时
void CAG_MDAView::CurrentStateWithMoreThanOneElement(CURRENTSTATE *cs,USEDEDGESOFCURRENTSTATE * cs_usededges)
{
	//******************************************
	//显示当前的状态；
	//******************************************
	CString temp;
	for(int x=0;x<cs->GetSize();x++)
	{
		temp+=cs->GetAt(x)->m_pUMLActivity->name+",";
	}
//	MessageBox("多线程"+temp);
   
	
	//******************************************
	//同步条以及同步条以下节点的调整
	//******************************************
	if( DFSStack.GetSize()>0 && DFSStack_usededges.GetSize()>0 )
	{
		USEDEDGESOFCURRENTSTATE *precs_usededges;
		DFSStack_usededges.GetTop(precs_usededges);
		for(int i=0;i<precs_usededges->GetSize();i++)
		{
			if(precs_usededges->GetAt(i)->m_pActivity[0]->m_pUMLActivity->m_ActivityKind==ACTIVITY_SYNCH)
			break;
		}
	
		if(i<precs_usededges->GetSize())
		{
			ShapeTransEdge * ste_synch=precs_usededges->GetAt(i);//得到同步条
			ShapeActivity * sa_synch=ste_synch->m_pActivity[0];
			
			int max=1;
			for(int y=0;y<sa_synch->m_pOutTransEdges.GetSize();y++)
			{
				if(sa_synch->m_pOutTransEdges.GetAt(y)->m_pActivity[1]->m_pUMLActivity->m_ActivityKind==ACTIVITY_SYNCH)continue;
				if( sa_synch->m_pOutTransEdges.GetAt(y)->m_pActivity[1]->m_pOutTransEdges.GetSize() > max )
					max = sa_synch->m_pOutTransEdges.GetAt(y)->m_pActivity[1]->m_pOutTransEdges.GetSize();
			}

			BOOL lessThanMaxWithNoEnabled=false;
			BOOL maxWithNoAllEnabled=false;
			for(i=0;i<sa_synch->m_pOutTransEdges.GetSize();i++)
			{
				ShapeActivity * nsa=sa_synch->m_pOutTransEdges.GetAt(i)->m_pActivity[1];
			
				if(nsa->m_pOutTransEdges.GetSize() < max || nsa->m_pUMLActivity->m_ActivityKind==ACTIVITY_SYNCH) //节点的出边小于max
				{
					for(int k=0; k<nsa->m_pOutTransEdges.GetSize(); k++)
					{
						if(nsa->m_pOutTransEdges.GetAt(k)->GetEnabled())
							break;
					}
					if( k == nsa->m_pOutTransEdges.GetSize() )
						lessThanMaxWithNoEnabled=true;
				}
                
				if(nsa->m_pOutTransEdges.GetSize() == max && nsa->m_pUMLActivity->m_ActivityKind!=ACTIVITY_SYNCH)//节点的出边等于max
				{
					int enabled_cnt=0;
					for(int j=0;j<nsa->m_pOutTransEdges.GetSize();j++)
					{
						if(nsa->m_pOutTransEdges.GetAt(j)->GetEnabled())
							enabled_cnt++;
					}
				
					if(enabled_cnt<max && enabled_cnt>0)
						maxWithNoAllEnabled=true;
				}
				
				if(lessThanMaxWithNoEnabled && maxWithNoAllEnabled) break;
			}


			if(lessThanMaxWithNoEnabled && maxWithNoAllEnabled)
			{
				for(int i=0;i<sa_synch->m_pOutTransEdges.GetSize();i++)
				{
					ShapeActivity *sa=sa_synch->m_pOutTransEdges.GetAt(i)->m_pActivity[1];
					if((sa->m_pOutTransEdges.GetSize()<max && !sa->m_pOutTransEdges.GetAt(0)->GetEnabled())|| sa->m_pUMLActivity->m_ActivityKind==ACTIVITY_SYNCH)
					{
						//MessageBox("hello:"+sa->m_pUMLActivity->name);
						for(int j=0;j<sa->m_pOutTransEdges.GetSize();j++)
						{
							sa->m_pOutTransEdges.GetAt(j)->SetEnabled(true);
							if(sa->m_pOutTransEdges.GetAt(j)->m_pActivity[1]->GetVisitedNum()>=1)
								sa->m_pOutTransEdges.GetAt(j)->m_pActivity[1]->DecreaseVisitedNum();
						}
					}
				}
			}
		}
	}

	//******************************************

	CURRENTSTATE * ncs=new CURRENTSTATE;  //下一个状态
	USEDEDGESOFCURRENTSTATE * ncs_usededges=new USEDEDGESOFCURRENTSTATE;//下一个状态的出边
	cs_usededges->RemoveAll();

	BOOL changed=false;  //当前活动图状态和下一个状态之间有没有变化

	for(int i=0;i<cs->GetSize();i++)//遍历活动图状态的每个节点
	{
		ShapeActivity *sa=cs->GetAt(i);  //当前状态为sa

		if(sa->m_pUMLActivity->m_ActivityKind!=ACTIVITY_SYNCH)//当前结点是简单的节点
		{
			BOOL hasEnabledEdge=false;
			for(int j=0;j<sa->m_pOutTransEdges.GetSize();j++)
			{
				if(sa->m_pOutTransEdges.GetAt(j)->GetEnabled())
				{
					hasEnabledEdge=true;break;
				}
			}

			if(!hasEnabledEdge)//如果状态的当前节点没有enabled的边
			{
				ncs->add(sa);
				continue;
			}
			else  //sa有enabled的边
			{
				ShapeTransEdge * edge=sa->m_pOutTransEdges.GetAt(j);//enabled的边

				//********************************************
				//下一节点是循环点
				//********************************************
				   if(edge->m_pActivity[1]->GetVisitedNum()>=1)
					{
					// MessageBox("循环点"+edge->m_pActivity[1]->m_pUMLActivity->name);
					//	for(int i=cs_usededges->GetSize()-1;i>=0;i--)
					//	{
					//		cs_usededges->GetAt(i)->SetEnabled(true);
					//		cs_usededges->GetAt(i)->m_pActivity[1]->DecreaseVisitedNum();	
					//		currentTrace.RemoveAt(currentTrace.GetSize()-1);
					//	}
						edge->SetEnabled(false);
						cs_usededges->RemoveAll();
						DFSStack.Push(cs);
						DFSStack_usededges.Push(cs_usededges);
						ncs->RemoveAll();delete ncs;
						ncs_usededges->RemoveAll();delete ncs_usededges;
						return;
					}
			    //***********************************************


				if(edge->m_pActivity[1]->m_pUMLActivity->m_ActivityKind!=ACTIVITY_SYNCH)//下一节点不是同步状态
				{
					cs_usededges->add(edge);
					ncs->add(edge->m_pActivity[1]);//
					changed=true;
					edge->SetEnabled(false);
					edge->m_pActivity[1]->IncreaseVisitedNum();	
					currentTrace.add(edge->m_pActivity[1]);
					continue;
				}					
				else//当前节点的下一个节点是同步节点
				{
					edge->SetEnabled(false);
				
					if(TestJoin(edge->m_pActivity[1]) )//同步节点可以触发
					{
						//MessageBox("同步节点可以触发");
						cs_usededges->add(edge);
						changed=true;
						edge->m_pActivity[1]->IncreaseVisitedNum();	
						currentTrace.add(edge->m_pActivity[1]);
						ncs->Add(edge->m_pActivity[1]);
					}
					else
					{
				    	ncs->add(sa);//
					}
				//	for(int y=0;y<edge->m_pActivity[1]->m_pInTransEdges.GetSize();y++)
				//	{
				//		ncs->Remove(edge->m_pActivity[1]->m_pInTransEdges.GetAt(y)->m_pActivity[0]);
				//	}
					continue;
				}
			}
		}
		else   //当前结点是同步的节点
		{
			if(sa->m_pOutTransEdges.GetAt(0)->GetEnabled())
			{
				for(int i=0;i<sa->m_pOutTransEdges.GetSize();i++)
				{
					ShapeTransEdge *edge=sa->m_pOutTransEdges.GetAt(i);
					cs_usededges->add(edge);
					edge->SetEnabled(false);
					edge->m_pActivity[1]->IncreaseVisitedNum();
					ncs->add(edge->m_pActivity[1]);
					currentTrace.add(edge->m_pActivity[1]);
				}
				changed=true;
			}
			else
			{
				ncs->add(sa);
			}
			continue;
		}
	}//end of for

	if(changed)
	{
		DFSStack.Push(cs);
		DFSStack_usededges.Push(cs_usededges);
		//********************
		for(int i=0;i<ncs->GetSize();i++)
		{
			ShapeActivity *s=ncs->GetAt(i);
			if(s->m_pUMLActivity->m_ActivityKind==ACTIVITY_SYNCH)
			{
				for(int j=0;j<s->m_pInTransEdges.GetSize();j++)
				{
					ncs->Remove(s->m_pInTransEdges.GetAt(j)->m_pActivity[0]);
				}
			}
		}
		//********************
		DFSStack.Push(ncs);
		ncs_usededges->RemoveAll();
		DFSStack_usededges.Push(ncs_usededges);
		return;
	}
	else
	{
		ncs->RemoveAll();
		delete ncs;
		ncs_usededges->RemoveAll();
		delete ncs_usededges;
	}
//当前活动状态的所有的节点都没有enable的边

		for(int j=0;j<cs->GetSize();j++)
		{
			if(cs->GetAt(j)->m_pUMLActivity->m_ActivityKind==ACTIVITY_FINISH)  //终止节点
			{
				RecordCurrentTrace();
				break;
			}
		}

		if(DFSStack.GetSize()==0)return;  //首节点不能继续向下走


		ShapeActivity * sa;
		CURRENTSTATE * precs;
		USEDEDGESOFCURRENTSTATE * precs_usededges;

		sa=currentTrace.GetAt(currentTrace.GetSize()-1);
	//	currentTrace.RemoveAt(currentTrace.GetSize()-1);//trace--
		if(currentTrace.GetSize()==1)       //遍历结束   
		{
			for(int i=0;i<sa->m_pOutTransEdges.GetSize();i++)
			{
				sa->m_pOutTransEdges.GetAt(i)->SetEnabled(true);
			}
			cs->RemoveAll();
			delete cs;
			cs_usededges->RemoveAll();
			delete cs_usededges;
			return;
		}

		DFSStack.GetTop(precs);
		DFSStack_usededges.GetTop(precs_usededges);

		cs->RemoveAll();
		cs_usededges->RemoveAll();
		delete cs;
		delete cs_usededges;

		for(i=0;i<precs_usededges->GetSize();i++)
		{
			sa=precs_usededges->GetAt(i)->m_pActivity[1];
		//	MessageBox("释放 ："+sa->m_pUMLActivity->name);
			sa->SetVisitedNum(0);
			for(int j=0;j<sa->m_pOutTransEdges.GetSize();j++)
			{
				sa->m_pOutTransEdges.GetAt(j)->SetEnabled(true);
				sa->m_pOutTransEdges.GetAt(j)->m_pActivity[1]->SetVisitedNum(0);
			}
			currentTrace.RemoveAt(currentTrace.GetSize()-1);//从currentTrace中pop出sa
		}
		
		precs_usededges->RemoveAll();
}




//记录当前的活动图的trace
void CAG_MDAView::RecordCurrentTrace()
{
   AGTRACE * agtrace=new AGTRACE();
   CString temp="";
   for(int i=0;i<currentTrace.GetSize();i++)
   {
	   agtrace->add(currentTrace.GetAt(i));
	   temp+=currentTrace.GetAt(i)->m_pUMLActivity->name;
   }
  // MessageBox(temp);
   allTrace.add(agtrace);
}

//测试同步条的入边是否都是disenabled的
BOOL CAG_MDAView::TestJoin(ShapeActivity *sa)
{
	for(int i=0;i<sa->m_pInTransEdges.GetSize();i++)
	{
		if(sa->m_pInTransEdges.GetAt(i)->GetEnabled())return false;
	}
	return true;
}

void CAG_MDAView::GetNextStateWhenAddSynchElement(CURRENTSTATE *cs, ShapeActivity *sa,CURRENTSTATE *ncs)
{
	ncs->RemoveAll();
	ncs->add(sa);
	for(int i=0;i<cs->GetSize();i++)
	{
    	ncs->add(cs->GetAt(i));
	}
	for(i=0;i<sa->m_pInTransEdges.GetSize();i++)
	{
		ncs->Remove(sa->m_pInTransEdges.GetAt(i)->m_pActivity[0]);
	}
	
	return;
}

void CAG_MDAView::GetNextStateWhenDeleteSynchElement(CURRENTSTATE *cs, ShapeActivity *sa, CURRENTSTATE *ncs)
{
	ncs->RemoveAll();
	for(int i=0;i<cs->GetSize();i++)
	{
		ncs->add(cs->GetAt(i));
	}
	ncs->Remove(sa);
	for(i=0;i<sa->m_pOutTransEdges.GetSize();i++)
	{
		ncs->add(sa->m_pOutTransEdges.GetAt(i)->m_pActivity[1]);
	}
	return;
}


//路径覆盖的结果
void CAG_MDAView::DisplayPathCoverageResult()
{
   	traceNum = allTrace.GetSize();

	 CString  testResult;
	 testResult.Format("有%d 条路径\r\n",allTrace.GetSize());
	 for(int i=0;i<allTrace.GetSize();i++)
	 {
		 AGTRACE * agtrace=allTrace.GetAt(i);
		 for(int j=0;j<agtrace->GetSize();j++)
		 {
			 testResult+=agtrace->GetAt(j)->m_pUMLActivity->name+",";
		 }
		 testResult+="\r\n";
	 }

	 double matchRunNum = traceNum - runOfAG.size();
	 double pathCoverage = matchRunNum / traceNum * 100.0;

	 
	 CString result1;
	 result1.Format("\r\n[路径覆盖率:]  -------------------- %.2f %%\r\n",pathCoverage);	 
	 result1="________________________________________________________________\r\n"+result1;


	 CString result2="";
     for(i=0;i<pathIndex.GetSize();i++)
	 {
		result2+=*testCaseInput.GetAt(pathIndex.GetAt(i))+", ";
	 }
	 result2.Delete(result2.GetLength()-1,2);
     result2="________________________________________________________________\r\n\r\n测试用例集合为： \r\n"+result2;
 
	 
	 CString result3="";
	 for(i=0;i<pathErrorIndex.GetSize();i++)
	 {
		result3+=*testCaseInput.GetAt(pathErrorIndex.GetAt(i))+", ";
	 }
	 result3.Delete(result3.GetLength()-1,2);
     result3="\r\n\r\n________________________________________________________________\r\n\r\n错误用例集合为： \r\n"+result3;

	 for(int x=0;x<pathIndex.GetSize();x++)
	 {
		// CString * csp=testCaseInput.GetAt(pathIndex.GetAt(x));//????????
		 testCaseInput.SetAt(pathIndex.GetAt(x),new CString("null"));
		// delete csp;
	 }

	 for(x=0;x<pathErrorIndex.GetSize();x++)
	 {
	// CString * csp=testCaseInput.GetAt(pathErrorIndex.GetAt(x));//????????
		 testCaseInput.SetAt(pathErrorIndex.GetAt(x),new CString("null"));
	//	 delete csp;
	 }

	 CString result4="";
	 for(i=0;i<testCaseInput.GetSize();i++)
	 {
		if(*testCaseInput.GetAt(i)=="null")continue;
		result4+=*testCaseInput.GetAt(i)+", ";
	 }
	 result4.Delete(result4.GetLength()-1,2);
     result4="\r\n\r\n________________________________________________________________\r\n\r\n没有测试的用例集合为： \r\n"+result4;


	 testResult+=result1+result2+result3+result4;

	 pathIndex.RemoveAll();
	 pathErrorIndex.RemoveAll();
	 TestCoverageDlg tcdlg;
	 tcdlg.Display(testResult);
	 tcdlg.DoModal();

}


//***************************
//路径覆盖后期处理
//***************************
void CAG_MDAView::ResetAfterPathCoverage()
{
	traceNum=0;

	//VECTOROFSTRINGSET runOfProgram;
    //VECTOROFSTRINGSET runOfAG;
	//********************************
	//删除比较时的中间数据
	//********************************]

	pathErrorIndex.RemoveAll();
	pathIndex.RemoveAll();
	index.RemoveAll();
	errorIndex.RemoveAll();

	while(runOfProgram.size()>0)
	{
		STRINGSET * ss=runOfProgram[0];
		runOfProgram.erase(runOfProgram.begin());
		delete ss;
	}
	runOfProgram.clear();

	while(runOfAG.size()>0)
	{
		STRINGSET * ss=runOfAG[0];
		runOfAG.erase(runOfAG.begin());
		delete ss;
	}
	runOfAG.clear();

	//*********************************


	for(int i=0;i<DFSStack.GetSize();i++)
	{
		CURRENTSTATE * cs;
		DFSStack.Pop(cs);
		cs->RemoveAll();
		delete cs;
	}
	DFSStack.RemoveAll();

	for(i=0;i<DFSStack_usededges.GetSize();i++)
	{
		USEDEDGESOFCURRENTSTATE * cs_usededges;
		DFSStack_usededges.Pop(cs_usededges);
		cs_usededges->RemoveAll();
		delete cs_usededges;
	}
	DFSStack.RemoveAll();

	for( i=allTrace.GetSize()-1;i>=0;i--)
	{
		AGTRACE* agtrace=allTrace.GetAt(i);
		agtrace->RemoveAll();
	}
	allTrace.RemoveAll();

	for( i=allLoop.GetSize()-1;i>=0;i--)
	{
		AGLOOP* agloop=allLoop.GetAt(i);
		agloop->RemoveAll();
	}
	allLoop.RemoveAll();


	for( i=0;i<ShapeElement::m_AllShapes.GetSize();i++)
	{
		if(ShapeElement::m_AllShapes.GetAt(i)->GetType() == SHAPE_ACTIVITY)
		{
			((ShapeActivity*)ShapeElement::m_AllShapes.GetAt(i))->visitedNum=0;
		}
		if(ShapeElement::m_AllShapes.GetAt(i)->GetType() == SHAPE_TRANSEDGE)
		{
			((ShapeTransEdge*)ShapeElement::m_AllShapes.GetAt(i))->SetEnabled(true);
		}
	}
	return;

}


//****************************************
//下面的函数s用来比较程序路径与活动图路径
//****************************************



void CAG_MDAView::CompareTestCaseWithAllPath()
{

	//allTrace是活动图的所有轨迹，testCaseSet是程序的所有轨迹

	//测试用例生成的程序执行轨迹
	for(int i=0;i<testCaseSet.GetSize();i++)
	{
		STRINGSET* ss=new STRINGSET;
		for(int j=0;j<testCaseSet.GetAt(i)->GetSize();j++)
		{
			ss->insert(testCaseSet.GetAt(i)->GetAt(j));
		}
		runOfProgram.push_back(ss);
	}

	//活动图生成的执行轨迹
	for(i=0;i<allTrace.GetSize();i++)
	{
		STRINGSET* ss=new STRINGSET;
		for(int j=0;j<allTrace.GetAt(i)->GetSize();j++)
		{
			ss->insert(&(allTrace.GetAt(i)->GetAt(j)->m_pUMLActivity->name));
		}
		runOfAG.push_back(ss);
	}

	//
	pathErrorIndex.RemoveAll();
	pathIndex.RemoveAll();

	//比较testCaseSet（字符串）与allTrace中（节点）
	for(i=0;i<runOfProgram.size();i++)
	{
		if(runOfAG.size()<=0)return;//活动图被完全路径覆盖

    	if(!CheckTestCase(i))// 满足活动图的语义
		{
		//	CString ss="";
		//	ss.Format("not stsisty the semantics in %d",i);
		//	MessageBox(ss);
		
			pathErrorIndex.Add(i);
    		continue;
		}
		
		//MessageBox("满足语义");
		if(testCaseIsAPath(i))//活动图的某个run是程序的run子集
		{
			pathIndex.Add(i);
		}

	}

}

//活动图的某个run是程序的run子集
BOOL CAG_MDAView::testCaseIsAPath(int i)
{
	if(runOfAG.size()<=0)return false;

	STRINGSET *tc=runOfProgram[i];//测试用例的轨迹

	for(int j=0;j<runOfAG.size();j++)//和活动图的轨迹一一比较
	{
		STRINGSET *ag=runOfAG[j];  
		set<CString *> result;
		
		set_difference(ag->begin(),ag->end(),tc->begin(),tc->end(),inserter(result, result.begin()),ltstr());
		
		if(result.size()==0)
		{
			runOfAG.erase(runOfAG.begin()+j);  //比较成功，活动图的run减少一条；
			delete ag;
			return true;
		}
	}
	return false;
}

//使用第i个测试用例是否合法，采用预览的方法
BOOL CAG_MDAView::CheckTestCase(int i)
{
    BOOL changed=false; 
	ShapeActivity* sa=NULL;
    int elementNo=(ShapeElement::m_AllShapes).GetSize();
	for(int j=0;j<elementNo;j++)        //得到起始点
	{
		ShapeElement *se=(ShapeElement::m_AllShapes).GetAt(j);
		if(se->GetType() == SHAPE_ACTIVITY)
		{
		    sa=(ShapeActivity*)se;
	        if(sa->m_pUMLActivity->m_ActivityKind==ACTIVITY_INIT)
			break;
		}
	}
  
	ASSERT(sa);

	//如果没有遍历预览没有成功
	if(!ForwardWithTheTrace(i,sa,true))
	{
		errorIndex.Add(i);
		return false;
	}
	ForwardWithTheTrace(i,sa,false);  //预览成功，标记活动图
	return true;
}
