// TreeDlg.cpp : implementation file
//

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

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#include "ag_mdadoc.h"
#include "ag_mdaview.h"
/////////////////////////////////////////////////////////////////////////////
// TreeDlg dialog
ShapeElement *m_CurrentElement = NULL;
extern CAG_MDAView *m_pView ;
extern void AddToLog(CString);
extern void ClearUpLog();
CObjTempl<TreeNode> m_Nodes;//节点
UMLClassPointerList m_Classes;//所有的类
ShapeElement *m_pRootShape = NULL;

TreeDlg::TreeDlg(CWnd* pParent /*=NULL*/)
	: CDialog(TreeDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(TreeDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	m_Images.Create( IDB_BITMAP_ELEMENT , 16 , 1 , RGB(255 ,255 , 255 ));
}
TreeDlg::~TreeDlg()
{
	TreeNode tn;
	while( m_Nodes.GetSize() )
	{
		tn = m_Nodes.GetAt( 0 );
		m_Nodes.RemoveAt( 0 );
		switch( tn.pShape->GetType() )
		{
		case SHAPE_NAMESPACE:
			{//删除名字空间
			}
			break;
		case SHAPE_CLASS:
			{//删除类
			}
			break;
		case SHAPE_ACTIVITYDIAGRAM:
			{//删除活动图
			}
			break;
		}
	}
}

void TreeDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(TreeDlg)
	DDX_Control(pDX, IDC_TREE1, m_TreeCtrl);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(TreeDlg, CDialog)
	//{{AFX_MSG_MAP(TreeDlg)
	ON_WM_SIZE()
	ON_WM_CONTEXTMENU()
	ON_COMMAND(ID_MENUITEM_DEL_ACTIVITY_DIAGRAM, OnMenuitemDelActivityDiagram)
	ON_COMMAND(ID_MENUITEM_DEL_CLASS, OnMenuitemDelClass)
	ON_COMMAND(ID_MENUITEM_DEL_CLASS_DIAGRAM, OnMenuitemDelClassDiagram)
	ON_COMMAND(ID_MENUITEM_DEL_PACKAGE, OnMenuitemDelPackage)
	ON_COMMAND(ID_MENUITEM_NEW_ACTIVITY_DIAGRAM, OnMenuitemNewActivityDiagram)
	ON_COMMAND(ID_MENUITEM_NEW_CLASS, OnMenuitemNewClass)
	ON_COMMAND(ID_MENUITEM_NEW_CLASS_DIAGRAM, OnMenuitemNewClassDiagram)
	ON_COMMAND(ID_MENUITEM_NEW_PACKAGE, OnMenuitemNewPackage)
	ON_COMMAND(ID_MENUITEM_SPEC, OnMenuitemSpec)
	ON_NOTIFY(NM_DBLCLK, IDC_TREE1, OnDblclkTree1)
	ON_COMMAND(ID_MENUITEM_TEMP_CODE, OnMenuitemTempCode)
	ON_COMMAND(ID_MENUITEM_REFRESH_CONTROLFLOW, OnMenuitemRefreshControlflow)
	ON_COMMAND(ID_MENUITEM_CREATE_JAVA, OnMenuitemCreateJava)
	ON_COMMAND(ID_MENUITEM_CLOSE, OnMenuitemClose)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// TreeDlg message handlers

void TreeDlg::OnSize(UINT nType, int cx, int cy) 
{
	CDialog::OnSize(nType, cx, cy);
	
	// TODO: Add your message handler code here
	if( ::IsWindow( m_TreeCtrl.m_hWnd ) )
	{
		m_TreeCtrl.SetWindowPos( NULL , 0 , 0 , cx , cy , 0 );
	}
}

BOOL TreeDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	// TODO: Add extra initialization here
	m_TreeCtrl.SetImageList( &m_Images , TVSIL_NORMAL );
	/*for( int i = 0 ; i < 5 ; i ++)
	{
		m_TreeCtrl.InsertItem( "aaa" , i , i );
	}*/
	ShapeNamespace *root,*common;
	TreeNode tn,tnCommon;
	

	//根
	root = new ShapeNamespace;
	m_pRootShape = root;
	root->m_pUMLNamespace = new UMLNamespace;
	root->m_pUMLNamespace ->name = "Root";
	root->m_pUMLNamespace ->m_pNamespace = NULL;
	//UML预定义的类型的包
	common = new ShapeNamespace;
	root->m_pOwnedShapes.Add( common );
	common->m_pUMLNamespace = new UMLNamespace;
	common->m_pUMLNamespace->name = "UML_TYPE";
	common->m_pUMLNamespace->m_pNamespace = root->m_pUMLNamespace;
	common->m_pShapeNamespace = root;

	tn.pShape = root;
	tn.item = m_TreeCtrl.InsertItem( "Root" , 0 , 0 );
	m_Nodes.Add( tn );

	tnCommon.pShape = common;
	tnCommon.item = m_TreeCtrl.InsertItem( "UML_TYPE" , 0 , 0 , tn.item);
	m_Nodes.Add( tnCommon );

	//UML预定义类型
	ShapeClass *pClass;


	pClass = new ShapeClass;
	common->m_pOwnedShapes.Add( pClass );
	pClass->m_pClass = new UMLClass;
	pClass->m_pClass->UMLGeneralizableElement::name = "void";
	pClass->m_pClass->UMLGeneralizableElement::m_pNamespace = common->m_pUMLNamespace;
	tn.pShape = pClass;
	tn.item = m_TreeCtrl.InsertItem( pClass->m_pClass->UMLGeneralizableElement::name , 3 ,3 , tnCommon.item );
	m_Nodes.Add( tn );
	m_Classes.Add( pClass->m_pClass );

	pClass = new ShapeClass;
	common->m_pOwnedShapes.Add( pClass );
	pClass->m_pClass = new UMLClass;
	pClass->m_pClass->UMLGeneralizableElement::name = "String";
	pClass->m_pClass->UMLGeneralizableElement::m_pNamespace = common->m_pUMLNamespace;
	tn.pShape = pClass;
	tn.item = m_TreeCtrl.InsertItem( pClass->m_pClass->UMLGeneralizableElement::name , 3 ,3 , tnCommon.item );
	m_Nodes.Add( tn );
	m_Classes.Add( pClass->m_pClass );

	pClass = new ShapeClass;
	common->m_pOwnedShapes.Add( pClass );
	pClass->m_pClass = new UMLClass;
	pClass->m_pClass->UMLGeneralizableElement::name = "Integer";
	pClass->m_pClass->UMLGeneralizableElement::m_pNamespace = common->m_pUMLNamespace;
	tn.pShape = pClass;
	tn.item = m_TreeCtrl.InsertItem( pClass->m_pClass->UMLGeneralizableElement::name , 3 ,3 , tnCommon.item );
	m_Nodes.Add( tn );
	m_Classes.Add( pClass->m_pClass );

	pClass = new ShapeClass;
	common->m_pOwnedShapes.Add( pClass );
	pClass->m_pClass = new UMLClass;
	pClass->m_pClass->UMLGeneralizableElement::name = "Boolean";
	pClass->m_pClass->UMLGeneralizableElement::m_pNamespace = common->m_pUMLNamespace;
	tn.pShape = pClass;
	tn.item = m_TreeCtrl.InsertItem( pClass->m_pClass->UMLGeneralizableElement::name , 3 ,3 , tnCommon.item );
	m_Nodes.Add( tn );
	m_Classes.Add( pClass->m_pClass );

	pClass = new ShapeClass;
	common->m_pOwnedShapes.Add( pClass );
	pClass->m_pClass = new UMLClass;
	pClass->m_pClass->UMLGeneralizableElement::name = "Real";
	pClass->m_pClass->UMLGeneralizableElement::m_pNamespace = common->m_pUMLNamespace;
	tn.pShape = pClass;
	tn.item = m_TreeCtrl.InsertItem( pClass->m_pClass->UMLGeneralizableElement::name , 3 ,3 , tnCommon.item );
	m_Nodes.Add( tn );
	m_Classes.Add( pClass->m_pClass );
	//UMLClass *p;
	//p = new UMLClass;
	//p->UMLGeneralizableElement::name = "String";
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

void TreeDlg::OnContextMenu(CWnd* pWnd, CPoint point) 
{
	// TODO: Add your message handler code here
	CMenu menu,*submenu;
	int iSel;
	HTREEITEM selItem;
	BOOL hasChild;
	selItem = m_TreeCtrl.GetSelectedItem();
	if( selItem == NULL )
	{
		iSel = -1;
		hasChild = FALSE;
	}
	else
	{
		hasChild = m_TreeCtrl.ItemHasChildren( selItem );
	}
	menu.LoadMenu( IDR_MENU_TREE ); 
	submenu = menu.GetSubMenu( 0 );
	m_TreeCtrl.GetItemImage( selItem , iSel , iSel );
	SetMenuState( submenu , iSel , hasChild);
	submenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,
            point.x, point.y,this);
}

void TreeDlg::SetMenuState(CMenu *menu, int selElementType ,BOOL hasChild)
{
	switch( selElementType )
	{
	case -1:
		{
			menu->EnableMenuItem( ID_MENUITEM_NEW_PACKAGE, MF_ENABLED);
			menu->EnableMenuItem( ID_MENUITEM_DEL_PACKAGE , MF_GRAYED);

			menu->EnableMenuItem( ID_MENUITEM_NEW_CLASS_DIAGRAM , MF_ENABLED );
			menu->EnableMenuItem( ID_MENUITEM_DEL_CLASS_DIAGRAM , MF_GRAYED );
			
			
			menu->EnableMenuItem( ID_MENUITEM_NEW_ACTIVITY_DIAGRAM , MF_GRAYED );
			menu->EnableMenuItem( ID_MENUITEM_DEL_ACTIVITY_DIAGRAM , MF_GRAYED );
			menu->EnableMenuItem( ID_MENUITEM_REFRESH_CONTROLFLOW , MF_GRAYED );

			menu->EnableMenuItem( ID_MENUITEM_NEW_CLASS , MF_ENABLED );
			menu->EnableMenuItem( ID_MENUITEM_DEL_CLASS , MF_GRAYED );

			menu->EnableMenuItem( ID_MENUITEM_SPEC , MF_GRAYED );
		}
		break;
	case 0:
		{//package
			menu->EnableMenuItem( ID_MENUITEM_NEW_PACKAGE, MF_ENABLED);
			if( hasChild )
				menu->EnableMenuItem( ID_MENUITEM_DEL_PACKAGE , MF_GRAYED);
			else
				menu->EnableMenuItem( ID_MENUITEM_DEL_PACKAGE , MF_ENABLED);

			menu->EnableMenuItem( ID_MENUITEM_NEW_CLASS_DIAGRAM , MF_ENABLED );
			menu->EnableMenuItem( ID_MENUITEM_DEL_CLASS_DIAGRAM , MF_GRAYED );
			
			menu->EnableMenuItem( ID_MENUITEM_NEW_ACTIVITY_DIAGRAM , MF_GRAYED );
			menu->EnableMenuItem( ID_MENUITEM_DEL_ACTIVITY_DIAGRAM , MF_GRAYED );
			menu->EnableMenuItem( ID_MENUITEM_REFRESH_CONTROLFLOW , MF_GRAYED );

			menu->EnableMenuItem( ID_MENUITEM_NEW_CLASS , MF_ENABLED );
			menu->EnableMenuItem( ID_MENUITEM_DEL_CLASS , MF_GRAYED );

			menu->EnableMenuItem( ID_MENUITEM_SPEC , MF_ENABLED );

		}
		break;
	case 1:
		{//class diagram
			menu->EnableMenuItem( ID_MENUITEM_NEW_PACKAGE, MF_GRAYED);
			menu->EnableMenuItem( ID_MENUITEM_DEL_PACKAGE , MF_GRAYED);

			menu->EnableMenuItem( ID_MENUITEM_NEW_CLASS_DIAGRAM , MF_GRAYED );
			if( hasChild )
				menu->EnableMenuItem( ID_MENUITEM_DEL_CLASS_DIAGRAM , MF_GRAYED );
			else
				menu->EnableMenuItem( ID_MENUITEM_DEL_CLASS_DIAGRAM , MF_ENABLED );
			
			menu->EnableMenuItem( ID_MENUITEM_NEW_ACTIVITY_DIAGRAM , MF_GRAYED );
			menu->EnableMenuItem( ID_MENUITEM_DEL_ACTIVITY_DIAGRAM , MF_GRAYED );
			menu->EnableMenuItem( ID_MENUITEM_REFRESH_CONTROLFLOW , MF_GRAYED );

			menu->EnableMenuItem( ID_MENUITEM_NEW_CLASS , MF_GRAYED );
			menu->EnableMenuItem( ID_MENUITEM_DEL_CLASS , MF_GRAYED );

			menu->EnableMenuItem( ID_MENUITEM_SPEC , MF_ENABLED );
		}
		break;
	case 2:
		{//activity diagram
			menu->EnableMenuItem( ID_MENUITEM_NEW_PACKAGE, MF_GRAYED);
			menu->EnableMenuItem( ID_MENUITEM_DEL_PACKAGE , MF_GRAYED);

			menu->EnableMenuItem( ID_MENUITEM_NEW_CLASS_DIAGRAM , MF_GRAYED );
			menu->EnableMenuItem( ID_MENUITEM_DEL_CLASS_DIAGRAM , MF_GRAYED );
			
			
			menu->EnableMenuItem( ID_MENUITEM_NEW_ACTIVITY_DIAGRAM , MF_GRAYED );
			if( hasChild )
				menu->EnableMenuItem( ID_MENUITEM_DEL_ACTIVITY_DIAGRAM , MF_GRAYED );
			else
				menu->EnableMenuItem( ID_MENUITEM_DEL_ACTIVITY_DIAGRAM , MF_ENABLED );
			menu->EnableMenuItem( ID_MENUITEM_REFRESH_CONTROLFLOW , MF_ENABLED );

			menu->EnableMenuItem( ID_MENUITEM_NEW_CLASS , MF_GRAYED );
			menu->EnableMenuItem( ID_MENUITEM_DEL_CLASS , MF_GRAYED );

			menu->EnableMenuItem( ID_MENUITEM_SPEC , MF_ENABLED );
		}
		break;
	case 3:
		{//class
			menu->EnableMenuItem( ID_MENUITEM_NEW_PACKAGE, MF_GRAYED);
			menu->EnableMenuItem( ID_MENUITEM_DEL_PACKAGE , MF_GRAYED);

			menu->EnableMenuItem( ID_MENUITEM_NEW_CLASS_DIAGRAM , MF_GRAYED );
			menu->EnableMenuItem( ID_MENUITEM_DEL_CLASS_DIAGRAM , MF_GRAYED );
			
			
			menu->EnableMenuItem( ID_MENUITEM_NEW_ACTIVITY_DIAGRAM , MF_ENABLED );
			menu->EnableMenuItem( ID_MENUITEM_DEL_ACTIVITY_DIAGRAM , MF_GRAYED );
			menu->EnableMenuItem( ID_MENUITEM_REFRESH_CONTROLFLOW , MF_GRAYED );

			menu->EnableMenuItem( ID_MENUITEM_NEW_CLASS , MF_GRAYED );
			if( hasChild )
				menu->EnableMenuItem( ID_MENUITEM_DEL_CLASS , MF_GRAYED );
			else
				menu->EnableMenuItem( ID_MENUITEM_DEL_CLASS , MF_ENABLED );

			menu->EnableMenuItem( ID_MENUITEM_SPEC , MF_ENABLED );
		}
		break;
	}
}

void TreeDlg::OnMenuitemDelActivityDiagram() 
{
	// TODO: Add your command handler code here
	
}

void TreeDlg::OnMenuitemDelClass() 
{
	// TODO: Add your command handler code here
	
}

void TreeDlg::OnMenuitemDelClassDiagram() 
{
	// TODO: Add your command handler code here
	
}

void TreeDlg::OnMenuitemDelPackage() 
{
	// TODO: Add your command handler code here
	
}


//建立新的活动图
void TreeDlg::OnMenuitemNewActivityDiagram() 
{
	// TODO: Add your command handler code here
	HTREEITEM selItem = m_TreeCtrl.GetSelectedItem();
	TreeNode tn;
	CString name;
	UMLActivityGraph *p = new UMLActivityGraph;//新建元数据
	ShapeActivityGraph *sp = new ShapeActivityGraph;//新建图形
	sp->m_pActivityGraph =p;//建立连接
	if( selItem )
	{//作为孩子加入
		ActivityDiagramInfoDlg dlg;
		//查找属于哪个类
		for( int i = 0 ; i < m_Nodes.GetSize() ; i ++ )
		{
			TreeNode node = m_Nodes.GetAt( i );
			if ( node.item == selItem )
			{//找到
				ShapeClass *pSC = (ShapeClass*)node.pShape;
				sp->m_pShapeClass = pSC;//建立图形上的逻辑关系
				p->m_pClass = pSC->m_pClass;//建立元模型上的逻辑关系
				break;
			}
		}
		//加入一个新的活动图
		if( dlg.DoModal() == IDOK )
		{
			MarkActivityGraph *pAG = (MarkActivityGraph*)sp->m_pMarkElement;
			pAG->m_UMLOperation.name = dlg.m_MappedMethodName;
			name = dlg.m_Name;
			tn.item = m_TreeCtrl.InsertItem( name , 2 , 2, selItem );
			m_TreeCtrl.Expand( selItem , TVE_EXPAND );
			tn.pShape = sp;
			p->name = name;
			m_Nodes.Add( tn );//加入到映射表
			p->m_pClass->m_ActivityGraphs.Add( p );//活动图元模型加入到类
			sp->m_pShapeClass->m_pShapeActivityGraphs.Add( sp );//活动图图形加入到类
		}
		else
		{
			delete p;
			delete sp;
		}
	}
	else
	{//作为根加入，这是不可能的
		delete p;
		delete sp;
	}
}

void TreeDlg::OnMenuitemNewClass() 
{
	// TODO: Add your command handler code here
	HTREEITEM selItem = m_TreeCtrl.GetSelectedItem();
	TreeNode tn;
	CString name;
	UMLClass *p = new UMLClass;
	ShapeClass *pSC = new ShapeClass;
	MarkClass *pMC = (MarkClass*)pSC->m_pMarkElement;
	pSC->m_pClass = p;
	if( selItem )
	{//作为孩子加入
		ClassInfoDlg dlg;
		dlg.m_pClassList = &m_Classes;
		//查找属于哪个包,并设置名字空间
		for( int i = 0 ; i < m_Nodes.GetSize() ; i ++ )
		{
			TreeNode node = m_Nodes.GetAt( i );
			if ( node.item == selItem )
			{
				ShapeNamespace *pSNS = (ShapeNamespace*)node.pShape;
				pSC->m_pShapeNamespace = pSNS;//设置图形所属的包
				p->UMLGeneralizableElement::m_pNamespace =pSNS->m_pUMLNamespace;//设置元数据对应的名字空间
				break;
			}
		}

		if( dlg.DoModal() == IDOK )
		{
			name = dlg.m_Name;
			tn.item = m_TreeCtrl.InsertItem( name , 3 , 3, selItem );
			m_TreeCtrl.Expand( selItem , TVE_EXPAND );
			tn.pShape = pSC;
			p->UMLGeneralizableElement::name = name;
			m_Classes.Add( p );
			m_Nodes.Add( tn );
			p->m_Operations = dlg.m_Operations ;
			p->m_Attributes = dlg.m_Attributes;

			if( pSC->m_pShapeNamespace )
			{//将类的图形加入到包图形
				pSC->m_pShapeNamespace->m_pOwnedShapes.Add( pSC );
			}
			pMC->m_CreateMainFunc = dlg.m_CreateMainFunc;
			pMC->m_MainExpression = dlg.m_MainFuncExpression;
		}
		else
		{
			delete p;
			delete pSC;
		}
	}
	else
	{//作为根加入
		ClassInfoDlg dlg;
		dlg.m_pClassList = &m_Classes;
		if( dlg.DoModal() == IDOK )
		{
			name = dlg.m_Name;
			tn.item = m_TreeCtrl.InsertItem( name , 3 , 3, TVI_ROOT );
			p->UMLGeneralizableElement::m_pNamespace = NULL;
			tn.pShape = pSC;
			p->UMLGeneralizableElement::name = name;
			m_Classes.Add( p );
			m_Nodes.Add( tn );
			p->m_Operations = dlg.m_Operations ;
			p->m_Attributes = dlg.m_Attributes;
		}
		else
		{
			delete p;
			delete pSC;
		}
	}	
}

void TreeDlg::OnMenuitemNewClassDiagram() 
{
	// TODO: Add your command handler code here
	
}

void TreeDlg::OnMenuitemNewPackage() 
{
	// TODO: Add your command handler code here
	HTREEITEM selItem = m_TreeCtrl.GetSelectedItem();
	TreeNode tn;
	CString name;
	UMLNamespace *p = new UMLNamespace;
	ShapeNamespace *pSN = new ShapeNamespace;
	pSN->m_pUMLNamespace = p;
	if( selItem )
	{//作为孩子加入
		//查找父包
		PackageInfoDlg dlg;
		for( int i = 0 ; i < m_Nodes.GetSize() ; i ++ )
		{
			TreeNode node = m_Nodes.GetAt( i );
			if ( node.item == selItem )
			{
				ShapeNamespace *pTemp = (ShapeNamespace*)node.pShape;
				pSN->m_pShapeNamespace = pTemp;
				p->m_pNamespace =pTemp->m_pUMLNamespace;
				break;
			}
		}
		dlg.m_Parent = p->m_pNamespace->name;
		if( dlg.DoModal() == IDOK )
		{
			name = dlg.m_Name;
			tn.item = m_TreeCtrl.InsertItem( name , 0 , 0, selItem );
			m_TreeCtrl.Expand( selItem , TVE_EXPAND );
			tn.pShape  = pSN;
			p->name = name;
			m_Nodes.Add( tn );
			if( pSN->m_pShapeNamespace )
			{
				pSN->m_pShapeNamespace->m_pOwnedShapes.Add( pSN );
			}
		}
		else
		{
			delete p;
			delete pSN;
		}
	}
	else
	{
		PackageInfoDlg dlg;
		if( dlg.DoModal() == IDOK )
		{
			name = dlg.m_Name;
			tn.item = m_TreeCtrl.InsertItem( name , 0 , 0, TVI_ROOT );
			p->m_pNamespace = NULL;
			tn.pShape  = pSN;
			p->name = name;
			m_Nodes.Add( tn );
		}
		else
		{
			delete p;
			delete pSN;
		}
	}
}

void TreeDlg::OnMenuitemSpec() 
{
	// TODO: Add your command handler code here
	HTREEITEM selItem = m_TreeCtrl.GetSelectedItem();
	int iImage;
	
	if( selItem == NULL ) return;
	m_TreeCtrl.GetItemImage( selItem , iImage , iImage );
	switch( iImage )
	{
	case 3:
		{
			UMLClass *pClass = NULL;
			ClassInfoDlg dlg;
			ShapeClass *pTemp = NULL;
			dlg.m_pClassList = &m_Classes;
			for( int i = 0 ; i < m_Nodes.GetSize() ; i ++ )
			{
				TreeNode tn = m_Nodes.GetAt( i );
				if( tn.item == selItem )
				{
					pTemp = (ShapeClass*)tn.pShape;
					MarkClass *pMC = (MarkClass*)pTemp->m_pMarkElement;
					dlg.m_CreateMainFunc = pMC->m_CreateMainFunc;
					dlg.m_MainFuncExpression = pMC->m_MainExpression ;
					pClass = pTemp->m_pClass;
					break;
				}
			}
			dlg.m_pClass = pClass;
			if( dlg.DoModal() == IDOK )
			{
				pClass->m_Attributes = dlg.m_Attributes;
				pClass->m_Operations = dlg.m_Operations;
				if( pTemp )
				{
					MarkClass *pMC = (MarkClass*)pTemp->m_pMarkElement;
					pMC->m_CreateMainFunc = dlg.m_CreateMainFunc;
					pMC->m_MainExpression = dlg.m_MainFuncExpression;
				}
			}
		}
		break;
	}
}


void TreeDlg::OnDblclkTree1(NMHDR* pNMHDR, LRESULT* pResult) 
{
	// TODO: Add your control notification handler code here
	HTREEITEM selItem = m_TreeCtrl.GetSelectedItem();
	int iImage;
	
	if( selItem == NULL ) return;
	m_TreeCtrl.GetItemImage( selItem , iImage , iImage );
	if( iImage == 2 )
	{//活动图
		for( int i = 0 ; i < m_Nodes.GetSize() ; i++ )
		{
			TreeNode nag = m_Nodes.GetAt( i );
			if( nag.item == selItem )
			{
				//找到了活动图的显示部分
				m_CurrentElement = (ShapeActivityGraph*)nag.pShape;
				if( m_pView )m_pView->Invalidate();
				return;
			}
		}
	}
	m_CurrentElement = NULL;
	if( m_pView )m_pView->Invalidate();

	*pResult = 0;
}


void TreeDlg::GenMiddleLanguage(CString fn)
{
	if( m_pRootShape )
	{
		ShapeNamespace *pRootNamespace = (ShapeNamespace*) m_pRootShape;
		DecodeQueue dest;
		for( int i = 0 ; i <= pRootNamespace->m_pOwnedShapes.GetUpperBound() ; i ++ )
		{
			ShapeElement *p = pRootNamespace->m_pOwnedShapes.GetAt( i );
			if( p->GetType() == SHAPE_NAMESPACE )
			{
				ShapeNamespace *pSN = (ShapeNamespace*)p;
				if( pSN->m_pUMLNamespace->name == "UML_TYPE" ) continue;
				GenFromNamespace( dest , (ShapeNamespace*)p);
			}
			else if( p->GetType() == SHAPE_CLASS )
			{
				GenFromClass( dest , (ShapeClass*) p );
			}
		}
		MiddleLanguage lan;
		while( dest.GetUpperBound() >= 0 )
		{
			CString *pStr = dest.GetAt( 0 );
			dest.RemoveAt( 0 );
			lan.AddTail( *pStr );
			delete pStr;
		}
		lan.WriteToFile2( fn );
	}
}

void TreeDlg::GenFromNamespace(DecodeQueue &que, ShapeNamespace *shape)
{
	CString txt;

	que.Add( new CString("<NAMESPACE>") );

	que.Add( new CString("<NAME>") );
	que.Add( new CString( shape->m_pUMLNamespace->name ) );
	que.Add( new CString("</NAME>") );

	/*que.Add( new CString("<ID>") );
	txt.Format("%d",shape->m_ID );
	que.Add( new CString( txt ) );
	que.Add( new CString("</ID>") );*/
	for( int i = 0 ; i <= shape->m_pOwnedShapes.GetUpperBound() ; i ++ )
	{
		ShapeElement* p = shape->m_pOwnedShapes.GetAt( i );

		if( p->GetType() == SHAPE_NAMESPACE )
		{
			GenFromNamespace( que, (ShapeNamespace*)p );
		}
		else if( p->GetType() == SHAPE_CLASS )
		{
			GenFromClass( que, (ShapeClass*)p);
		}
	}
	que.Add( new CString("</NAMESPACE>") );
}

void TreeDlg::GenFromClass(DecodeQueue &que, ShapeClass *shape)
{
	UMLClass *pClass = shape->m_pClass;
	MarkClass *pMC = (MarkClass*)shape->m_pMarkElement;
	CString txt;
	
	que.Add( new CString("<CLASS>") );

	que.Add( new CString("<NAME>") );
	que.Add( new CString( pClass->UMLGeneralizableElement::name ) );
	que.Add( new CString("</NAME>") );

	/*que.Add( new CString("<ID>") );
	txt.Format("%d",shape->m_ID );
	que.Add( new CString(txt) );
	que.Add( new CString("</ID>") );*/

	//Attributes
	for( int i = 0 ; i < pClass->m_Attributes.GetSize() ; i ++ )
	{
		UMLAttribute att = pClass->m_Attributes.GetAt( i );
		GenFromAttribute( que , att );
	}
	//map controlflow as attribute

	//operation
	for( i = 0 ; i < pClass->m_Operations.GetSize() ; i ++ )
	{
		UMLOperation ope = pClass->m_Operations.GetAt( i );

		GenFromOperation( que , ope );

	}
	//when no swimlane and have controlflow,activity in the controlflow should be operation
	//of this class
	for( i = 0 ; i <= shape->m_pShapeActivityGraphs.GetUpperBound() ; i ++ )
	{
		ShapeActivityGraph *pSAG = shape->m_pShapeActivityGraphs.GetAt( i );
		CPtrTempl<UMLActionActivity*>tn;
		if( pSAG->m_pShapeSwimlanes.GetUpperBound() >= 0 )continue;
		for( int j = 0 ; j <= pSAG->m_pShapeControlFlows.GetUpperBound() ; j ++ )
		{
			ShapeControlFlow* pSCF = pSAG->m_pShapeControlFlows.GetAt( j );
			for( int t = 0 ; t <= pSCF->m_pUMLControlFlow->m_pActivities.GetUpperBound() ; t ++ )
			{
				UMLActionActivity *pA = (UMLActionActivity*)pSCF->m_pUMLControlFlow->m_pActivities.GetAt( t );
				ShapeActivity *pSA = pSAG->FindShapeActivity( pA );
				if( tn.Find( pA ) )continue;//一个活动可能属于多个控制流，但是只能映射一次
				tn.Add( pA );
				que.Add( new CString( "<OPERATION>" ) );

				que.Add( new CString( "<NAME>" ) );
				que.Add( new CString( pA->name ) );
				que.Add( new CString( "</NAME>" ) );

				que.Add( new CString( "<RETURNTYPE>" ) );
				que.Add( new CString( "void" ) );
				que.Add( new CString( "</RETURNTYPE>" ) );

				que.Add( new CString( "<VISIBILITY>" ) );
				que.Add( new CString( "PUBLIC" ) );
				que.Add( new CString( "</VISIBILITY>" ) );

				if( pA->m_Expression.GetLength() )
				{
					que.Add( new CString( "<EXPRESSION>" ) );
					que.Add( new CString( TrunckEnter(pA->m_Expression) ) );
					que.Add( new CString( "</EXPRESSION>" ) );
				}
				
				que.Add( new CString( "</OPERATION>" ) );
			}
		}
	}
	//if have swimlane ,the activity in swimlane should be operation
	for( i = 0 ; i <= ShapeElement::m_AllShapes.GetUpperBound() ; i ++ )
	{
		ShapeElement *curShape = ShapeElement::m_AllShapes.GetAt( i );
		if( curShape->GetType() != SHAPE_ACTIVITY ) continue;
		else
		{
			ShapeActivity *pSA = (ShapeActivity*)curShape;
			if( pSA->m_pUMLActivity->m_ActivityKind == ACTIVITY_ACTION )
			{
				UMLActionActivity *pA = (UMLActionActivity*)pSA->m_pUMLActivity;
				if( pSA->m_pOwnedShape->GetType() == SHAPE_SWIMLANE )
				{
					ShapeSwimlane * pSS = (ShapeSwimlane*) pSA->m_pOwnedShape;
					if( pSS->m_pSwimlane->pType == shape->m_pClass )
					{
						que.Add( new CString( "<OPERATION>" ) );

						que.Add( new CString( "<NAME>" ) );
						que.Add( new CString( pA->name ) );
						que.Add( new CString( "</NAME>" ) );

						que.Add( new CString( "<RETURNTYPE>" ) );
						que.Add( new CString( "void" ) );
						que.Add( new CString( "</RETURNTYPE>" ) );

						que.Add( new CString( "<VISIBILITY>" ) );
						que.Add( new CString( "PUBLIC" ) );
						que.Add( new CString( "</VISIBILITY>" ) );

						if( pA->m_Expression.GetLength() )
						{
							que.Add( new CString( "<EXPRESSION>" ) );
							que.Add( new CString( TrunckEnter(pA->m_Expression) ) );
							que.Add( new CString( "</EXPRESSION>" ) );
						}
				
						que.Add( new CString( "</OPERATION>" ) );
					}
				}
			}
		}
	}
	//activity graph
	for( i = 0 ; i <= shape->m_pShapeActivityGraphs.GetUpperBound() ; i ++ )
	{
		ShapeActivityGraph *pSAG = shape->m_pShapeActivityGraphs.GetAt( i );
		GenFromActivityGraph( que , pSAG );
	}
	//main func
	if( pMC->m_CreateMainFunc )
	{
		que.Add( new CString( "<OPERATION>" ));

		que.Add( new CString( "<NAME>" ) );
		que.Add( new CString( "main" ) );
		que.Add( new CString( "</NAME>" ) );

		que.Add( new CString( "<VISIBILITY>" ) );
		que.Add( new CString( "PUBLIC" ) );
		que.Add( new CString( "</VISIBILITY>" ) );

		que.Add( new CString( "<RETURNTYPE>" ) );
		que.Add( new CString( "static void" ) );
		que.Add( new CString( "</RETURNTYPE>" ) );

		que.Add( new CString( "<PARAMETER>" ) );

		que.Add( new CString( "<TYPE>" ) );
		que.Add( new CString( "String" ) );
		que.Add( new CString( "</TYPE>" ) );

		que.Add( new CString( "<NAME>" ) );
		que.Add( new CString( "arg[]" ) );
		que.Add( new CString( "</NAME>" ) );

		que.Add( new CString( "</PARAMETER>" ) );

		que.Add( new CString( "<EXPRESSION>" ) );
		que.Add( new CString( TrunckEnter(pMC->m_MainExpression) ) );
		que.Add( new CString( "</EXPRESSION>" ) );

		que.Add( new CString( "</OPERATION>" ) );
	}
	//Sleep func
	que.Add( new CString( "<OPERATION>" ));

	que.Add( new CString( "<NAME>" ) );
	que.Add( new CString( "Sleep" ) );
	que.Add( new CString( "</NAME>" ) );

	que.Add( new CString( "<VISIBILITY>" ) );
	que.Add( new CString( "PUBLIC" ) );
	que.Add( new CString( "</VISIBILITY>" ) );

	que.Add( new CString( "<RETURNTYPE>" ) );
	que.Add( new CString( "synchronized void" ) );
	que.Add( new CString( "</RETURNTYPE>" ) );

	que.Add( new CString( "<PARAMETER>" ) );

	que.Add( new CString( "<TYPE>" ) );
	que.Add( new CString( "Integer" ) );
	que.Add( new CString( "</TYPE>" ) );

	que.Add( new CString( "<NAME>" ) );
	que.Add( new CString( "len" ) );
	que.Add( new CString( "</NAME>" ) );

	que.Add( new CString( "</PARAMETER>" ) );

	que.Add( new CString( "<EXPRESSION>" ) );
	que.Add( new CString( "try{wait( len );}catch(InterruptedException e){};" ) );
	que.Add( new CString( "</EXPRESSION>" ) );

	que.Add( new CString( "</OPERATION>" ) );

	que.Add( new CString("</CLASS>") );

	//control flow
	for( i = 0 ; i <= shape->m_pShapeActivityGraphs.GetUpperBound() ; i ++ )
	{
		ShapeActivityGraph *pSAG = shape->m_pShapeActivityGraphs.GetAt( i );
		for( int j = 0 ; j <= pSAG->m_pShapeControlFlows.GetUpperBound() ; j ++ )
		{
			ShapeControlFlow *pSCF = pSAG->m_pShapeControlFlows.GetAt( j );
			GenFromControlFlow( que , pSAG , pSCF );
		}
	}
	//synch 
	
	for( i = 0 ; i <= shape->m_pShapeActivityGraphs.GetUpperBound() ; i ++ )
	{
		ShapeActivityGraph *pSAG = shape->m_pShapeActivityGraphs.GetAt( i );
		CPtrTempl<ShapeActivity*>syns;
		for( int j = 0 ; j <= pSAG->m_pShapeControlFlows.GetUpperBound() ; j ++ )
		{
			ShapeControlFlow *pSCF = pSAG->m_pShapeControlFlows.GetAt( j );
			ShapeActivity *head,*tail;
			head = pSAG->FindShapeActivity( pSCF->m_pUMLControlFlow->m_pBegin );
			for( int k = 0 ; k <= pSCF->m_pUMLControlFlow->m_pEndList.GetUpperBound() ; k ++ )
			{
				UMLSynchActivity * pUSA = pSCF->m_pUMLControlFlow->m_pEndList.GetAt( k );
				tail = pSAG->FindShapeActivity( pUSA );
				if( !syns.Find( tail ) ) syns.Add( tail );
			}
			if( !syns.Find( head ) )syns.Add( head );
			
		}
		for( j = 0 ; j <= syns.GetUpperBound() ; j ++ )
		{
			ShapeActivity *pSA = syns.GetAt( j );
			GenFromSynch( que , pSAG , pSA );
		}
	}
}

void TreeDlg::OnMenuitemTempCode() 
{
	// TODO: Add your command handler code here
	CFileDialog dlg( false , "xml" , "*.xml" , OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT , "XML File(*.xml)|*.xml||");
	if( dlg.DoModal() == IDOK )
	{
		GenMiddleLanguage( dlg.GetPathName() );
	}
}

void TreeDlg::GenFromActivityGraph(DecodeQueue &que, ShapeActivityGraph *shape)
{
	//分解控制流
	MarkActivityGraph *pAG = (MarkActivityGraph*)shape->m_pMarkElement;
	if( shape->m_pShapeSwimlanes.GetUpperBound() >= 0 )
	{
		//包含泳道
		pAG->m_UMLOperation.m_TypedParameter.RemoveAll();
		for( int i = 0 ; i <= shape->m_pShapeSwimlanes.GetUpperBound(); i ++ )
		{
			ShapeSwimlane *pSS = shape->m_pShapeSwimlanes.GetAt( i );
			MarkSwimlane *pMS =(MarkSwimlane*)pSS->m_pMarkElement;
			if( pMS->m_ToParameter )
			{//泳道映射到参数
				pAG->m_UMLOperation.m_TypedParameter.Add( pMS->m_UMLParameter );
			}
			else
			{
			//泳道映射到引用
				ShapeClass *pClass = shape->m_pShapeClass;
				
				GenFromAttribute( que ,pMS->m_UMLAttribute );
				
				if( pMS->m_GetMethod )
				{
					//GenFromOperation( que , pMS->m_UMLOperationGet );
					CString txt;
					que.Add( new CString( "<OPERATION>" ) );

					que.Add( new CString( "<NAME>" ) );
					que.Add( new CString( pMS->m_UMLOperationGet.name ) );
					que.Add( new CString( "</NAME>" ) );

					que.Add( new CString( "<RETURNTYPE>" ) );
					que.Add( new CString( pMS->m_UMLAttribute.m_pType->UMLGeneralizableElement::name ) );
					que.Add( new CString( "</RETURNTYPE>" ) );

					que.Add( new CString( "<VISIBILITY>" ) );
					switch( pMS->m_UMLOperationGet.m_Visibility )
					{
					case VISIBILITY_PUBLIC:
						que.Add( new CString( "PUBLIC" ) );
						break;
					case VISIBILITY_PRIVATE:
						que.Add( new CString( "PRIVATE" ) );
						break;
					case VISIBILITY_PROTECTED:
						que.Add( new CString( "PROTECTED" ) );
						break;
					default:
						que.Add( new CString( "PACKAGE" ) );
					}
					que.Add( new CString( "</VISIBILITY>" ) );

					que.Add( new CString( "<EXPRESSION>" ) );
					txt = "return ";
					txt += pMS->m_UMLAttribute.name;
					txt +=";";
					que.Add( new CString( txt ) );
					que.Add( new CString( "</EXPRESSION>" ) );

					que.Add( new CString( "</OPERATION>" ) );
				}
				if( pMS->m_SetMethod )
				{
					CString txt;
					que.Add( new CString( "<OPERATION>" ) );

					que.Add( new CString( "<NAME>" ) );
					que.Add( new CString( pMS->m_UMLOperationSet.name ) );
					que.Add( new CString( "</NAME>" ) );

					que.Add( new CString( "<RETURNTYPE>" ) );
					que.Add( new CString( "void" ) );
					que.Add( new CString( "</RETURNTYPE>" ) );

					que.Add( new CString( "<PARAMETER>" ) );

					que.Add( new CString( "<NAME>" ) );
					que.Add( new CString( "arg" ) );
					que.Add( new CString( "</NAME>" ) );

					que.Add( new CString( "<TYPE>" ) );
					que.Add( new CString( pMS->m_UMLAttribute.m_pType->UMLGeneralizableElement::name ) );
					que.Add( new CString( "</TYPE>" ) );

					que.Add( new CString( "</PARAMETER>" ) );

					que.Add( new CString( "<VISIBILITY>" ) );
					switch( pMS->m_UMLOperationSet.m_Visibility )
					{
					case VISIBILITY_PUBLIC:
						que.Add( new CString( "PUBLIC" ) );
						break;
					case VISIBILITY_PRIVATE:
						que.Add( new CString( "PRIVATE" ) );
						break;
					case VISIBILITY_PROTECTED:
						que.Add( new CString( "PROTECTED" ) );
						break;
					default:
						que.Add( new CString( "PACKAGE" ) );
					}
					que.Add( new CString( "</VISIBILITY>" ) );

					que.Add( new CString( "<EXPRESSION>" ) );
					txt = pMS->m_UMLAttribute.name;
					txt +="= arg;";
					que.Add( new CString( txt ) );
					que.Add( new CString( "</EXPRESSION>" ) );

					que.Add( new CString( "</OPERATION>" ) );
				}

			}
			//映射并发活动
			for( int j = 0 ; j <= pSS->m_pActivities.GetUpperBound() ; j ++ )
			{
				ShapeActivity *pSA = pSS->m_pActivities.GetAt( j );
				if( pSA->m_pUMLActivity->m_ActivityKind == ACTIVITY_SYNCH )
				{
					MarkSynch *pMS = (MarkSynch*)pSA->m_pMarkElement;
					UMLSynchActivity *pUSA = (UMLSynchActivity*)pSA->m_pUMLActivity;
					if(pUSA->m_BeginControlFlow.GetUpperBound() < 0 && pUSA->m_EndControlFlow.GetUpperBound() < 0 )continue;
					//NAME,VISIBILITY,TYPE
					que.Add( new CString( "<ATTRIBUTE>" ) );
					que.Add( new CString( "<NAME>" ) );
					que.Add( new CString( pMS->m_SynchName ) );
					que.Add( new CString( "</NAME>" ) );
					que.Add( new CString( "<VISIBILITY>" ) );
					switch( pMS->m_SynchVisibility )
					{
					case VISIBILITY_PUBLIC:
						que.Add( new CString( "PUBLIC" ) );
						break;
					case VISIBILITY_PRIVATE:
						que.Add( new CString( "PRIVATE" ) );
						break;
					case VISIBILITY_PROTECTED:
						que.Add( new CString( "PROTECTED" ) );
						break;
					default:
						que.Add( new CString( "PACKAGE" ) );
						break;
					}
					que.Add( new CString( "</VISIBILITY>" ) );
					que.Add( new CString( "<TYPE>" ) );
					que.Add( new CString( pMS->m_SynchType ) );
					que.Add( new CString( "</TYPE>" ) );
					que.Add( new CString( "</ATTRIBUTE>" ) );
				}
			}
		}
		//注：一下这个语句GenFromOperation( que , pAG->m_UMLOperation );必须被替换，不仅仅要生成声明
		//还要生成状态切换表
		GenFromOperation( que , pAG->m_UMLOperation ,shape);
	}
	else
	{
		for( int j = 0 ; j <= shape->m_pShapeActivities.GetUpperBound() ; j ++ )
		{
				ShapeActivity *pSA = shape->m_pShapeActivities.GetAt( j );
				if( pSA->m_pUMLActivity->m_ActivityKind == ACTIVITY_SYNCH )
				{
					MarkSynch *pMS = (MarkSynch*)pSA->m_pMarkElement;
					//NAME,VISIBILITY,TYPE
					UMLSynchActivity *pUSA = (UMLSynchActivity*)pSA->m_pUMLActivity;
					if(pUSA->m_BeginControlFlow.GetUpperBound() < 0 && pUSA->m_EndControlFlow.GetUpperBound() < 0 )continue;
					que.Add( new CString( "<ATTRIBUTE>" ) );
					que.Add( new CString( "<NAME>" ) );
					que.Add( new CString( pMS->m_SynchName ) );
					que.Add( new CString( "</NAME>" ) );
					que.Add( new CString( "<VISIBILITY>" ) );
					switch( pMS->m_SynchVisibility )
					{
					case VISIBILITY_PUBLIC:
						que.Add( new CString( "PUBLIC" ) );
						break;
					case VISIBILITY_PRIVATE:
						que.Add( new CString( "PRIVATE" ) );
						break;
					case VISIBILITY_PROTECTED:
						que.Add( new CString( "PROTECTED" ) );
						break;
					default:
						que.Add( new CString( "PACKAGE" ) );
						break;
					}
					que.Add( new CString( "</VISIBILITY>" ) );
					que.Add( new CString( "<TYPE>" ) );
					que.Add( new CString( pMS->m_SynchType ) );
					que.Add( new CString( "</TYPE>" ) );
					que.Add( new CString( "</ATTRIBUTE>" ) );
				}
		}
		//不包含泳道
		GenFromOperation( que , pAG->m_UMLOperation ,shape);
	}
}

void TreeDlg::GenFromAttribute(DecodeQueue &que, UMLAttribute att)
{
	que.Add(new CString("<ATTRIBUTE>") );

	que.Add(new CString("<NAME>") );
	que.Add(new CString(att.name) );
	que.Add(new CString("</NAME>") );

	que.Add(new CString("<VISIBILITY>") );
	switch( att.m_Visibility )
	{
	case VISIBILITY_PUBLIC:
		que.Add( new CString("PUBLIC") );
		break;
	case VISIBILITY_PRIVATE:
		que.Add(new CString("PRIVATE") );
		break;
	case VISIBILITY_PROTECTED:
		que.Add(new CString("PROTECTED") );
		break;
	default:
		que.Add(new CString("PACKAGE") );
	}
	que.Add(new CString("</VISIBILITY>") );

	if( att.m_pType )
	{
		que.Add( new CString("<TYPE>"));
		que.Add( new CString(att.m_pType->UMLGeneralizableElement::name));
		que.Add( new CString("</TYPE>"));
	}
	if( att.m_InitialValue.GetLength() )
	{
		que.Add( new CString("<INIVALUE>"));
		que.Add( new CString( att.m_InitialValue ) );
		que.Add( new CString("</INIVALUE>"));
	}

	que.Add(new CString("</ATTRIBUTE>") );
}

void TreeDlg::GenFromOperation(DecodeQueue &que, UMLOperation ope ,ShapeActivityGraph*pAg)
{
		que.Add( new CString("<OPERATION>") );

		que.Add( new CString("<NAME>") );
		que.Add( new CString(ope.name) );
		que.Add( new CString("</NAME>") );

		que.Add( new CString("<VISIBILITY>") );
		switch( ope.m_Visibility )
		{
		case VISIBILITY_PUBLIC:
			que.Add( new CString("PUBLIC") );
			break;
		case VISIBILITY_PRIVATE:
			que.Add( new CString("PRIVATE") );
			break;
		case VISIBILITY_PROTECTED:
			que.Add( new CString("PROTECTED") );
			break;
		default:
			que.Add( new CString("PACKAGE") );
		}
		que.Add( new CString("</VISIBILITY>") );

		if( ope.m_ReturnType.m_pType )
		{
			que.Add( new CString("<RETURNTYPE>") );
			que.Add( new CString(ope.m_ReturnType.m_pType->UMLGeneralizableElement::name) );
			que.Add( new CString("</RETURNTYPE>") );
		}

		for( int j = 0 ; j < ope.m_TypedParameter.GetSize() ; j++ )
		{
			UMLParameter para = ope.m_TypedParameter.GetAt( j );

			que.Add( new CString("<PARAMETER>") );

			que.Add( new CString("<NAME>") );
			que.Add( new CString(para.name) );
			que.Add( new CString("</NAME>") );

			if( para.m_pType )
			{
				que.Add( new CString("<TYPE>") );
				que.Add( new CString( para.m_pType->UMLGeneralizableElement::name ) );
				que.Add( new CString("</TYPE>") );
			}

			if( para.m_DefaultValue.GetLength() )
			{
				que.Add( new CString("<DEFAULTVAL>") );
				que.Add( new CString( para.m_DefaultValue ) );
				que.Add( new CString("</DEFAULTVAL>") );
			}

			que.Add( new CString("</PARAMETER>") );
		}
		if( pAg )
		{
			//如果有是活动图得实现要添加转换表
			//-查找初始活动
			ShapeActivity *pInit = NULL;
			ShapeActivity *pFini = NULL;
			if( pAg->m_pShapeSwimlanes.GetUpperBound() >= 0)
			{//包含泳道
				for( int SwimIdx = 0 ; SwimIdx <= pAg->m_pShapeSwimlanes.GetUpperBound() ; SwimIdx ++ )
				{
					ShapeSwimlane *pSwim = pAg->m_pShapeSwimlanes.GetAt( SwimIdx );
					for( int ActIdx = 0 ; ActIdx <= pSwim->m_pActivities.GetUpperBound() ; ActIdx ++ )
					{
						ShapeActivity *pTemp = pSwim->m_pActivities.GetAt( ActIdx );
						if( pTemp->m_pUMLActivity->m_ActivityKind == ACTIVITY_INIT )
						{
							pInit = pTemp;
						}
						else if( pTemp->m_pUMLActivity->m_ActivityKind == ACTIVITY_FINISH )
						{
							pFini = pTemp;
						}
					}
					if( pInit && pFini) break;
				}
			}
			else
			{//不包含泳道
				for(  int idx = 0 ; idx <= pAg->m_pShapeActivities.GetUpperBound() ; idx ++ )
				{
					ShapeActivity *pTemp = pAg->m_pShapeActivities.GetAt( idx );
					if( pTemp->m_pUMLActivity->m_ActivityKind == ACTIVITY_INIT )
					{
						pInit = pTemp;
					}
					else if( pTemp->m_pUMLActivity->m_ActivityKind == ACTIVITY_FINISH )
					{
						pFini = pTemp;
					}
					if( pInit && pFini) break;
				}
			}
			//添加转换表
			que.Add( new CString("<TRANSTABLE>") );
			if( pInit && pFini)
			{
				//写设置初始活动ID和终止活动ID
				CString txt;
				CPtrTempl<ShapeActivity*>unPro;
				CPtrTempl<ShapeActivity*>pro;

				que.Add( new CString("<INITID>") );
				txt.Format("%d",pInit->m_ID );
				que.Add( new CString( txt ) );
				que.Add( new CString("</INITID>") );

				que.Add( new CString("<FINIID>") );
				txt.Format("%d",pFini->m_ID );
				que.Add( new CString( txt ) );
				que.Add( new CString("</FINIID>") );

				unPro.Add( pInit );

				//应该将以下改成从初始活动开始向后遍历
				while( unPro.GetUpperBound() >= 0 )
				{
					ShapeActivity *pTemp = unPro.GetAt( 0 );
					UMLActivity *pAc = pTemp->m_pUMLActivity;

					unPro.RemoveAt( 0 );
					if( !pro.Find( pTemp ) )
						pro.Add( pTemp );
						
					que.Add( new CString( "<ACTIVITY>" ) );
					que.Add( new CString( "<ID>" ) );
					txt.Format("%d",pTemp->m_ID);
					que.Add( new CString( txt ) );
					que.Add( new CString( "</ID>" ) );

					if( pTemp == pInit )
					{
						//在初始活动中添加创建并发、创建控制流、连接并发与控制流得代码
						CString code;
						CPtrTempl<ShapeActivity*>syns;
						//查找并发节点
						for( int i = 0 ; i <= pAg->m_pShapeControlFlows.GetUpperBound() ; i ++ )
						{
							ShapeControlFlow *pSCF = pAg->m_pShapeControlFlows.GetAt( i );
							ShapeActivity *pHead,*pTail;
							pHead = pAg->FindShapeActivity( pSCF->m_pUMLControlFlow->m_pBegin );
							for( int j = 0 ; j <= pSCF->m_pUMLControlFlow->m_pEndList.GetUpperBound() ; j ++)
							{
								UMLSynchActivity *pUSA = pSCF->m_pUMLControlFlow->m_pEndList.GetAt( j );
								pTail = pAg->FindShapeActivity( pUSA );
								if( !syns.Find( pTail ) )syns.Add( pTail );
							}
							if( !syns.Find( pHead ) )syns.Add( pHead );
						}
						//创建并发
						for( i = 0 ; i <= syns.GetUpperBound() ; i++ )
						{
							ShapeActivity *pA = syns.GetAt( i );
							MarkSynch* pMS = (MarkSynch*)pA->m_pMarkElement;
							code += pMS->m_SynchName ;
							code += " = new ";
							code += pMS->m_SynchType;
							code += "();";
							//建立连接:并发与泳道、控制流类
							if( pAg->m_pShapeSwimlanes.GetUpperBound() >= 0 )
							{
								//建立并发与泳道的连接
								for( int j  = 0 ; j <= pAg->m_pShapeSwimlanes.GetUpperBound() ; j ++ )
								{
									ShapeSwimlane *pSS = pAg->m_pShapeSwimlanes.GetAt( j );
									MarkSwimlane *pMSL = (MarkSwimlane*) pSS->m_pMarkElement;
									code += pMS->m_SynchName;
									code += ".";
									if( pMSL->m_ToParameter)
										code += pMSL->m_UMLParameter.name;
									else
										code += pMSL->m_UMLAttribute.name;
									code += " = ";
									if( pMSL->m_ToParameter)
										code += pMSL->m_UMLParameter.name;
									else
										code += pMSL->m_UMLAttribute.name;
									code +=";";
								}
							}
							code += pMS->m_SynchName;
							code += ".m_SynchOwner = this;";
						}
						
						
						que.Add( new CString( "<EXPRESSION>" ) );
						que.Add( new CString( TrunckEnter(code) ) );
						que.Add( new CString( "</EXPRESSION>" ) );
					}

					if( pTemp->m_pUMLActivity->m_ActivityKind == ACTIVITY_ACTION )
					{
						//要根据是否有泳道处理
						CString expression;
						UMLActionActivity *pAA = (UMLActionActivity*)(pTemp->m_pUMLActivity);
						if( pTemp->m_pOwnedShape->GetType() == SHAPE_SWIMLANE )
						{//如果活动属于泳道，那么要调用相应的类的操作
							ShapeSwimlane *pSS = (ShapeSwimlane*) pTemp->m_pOwnedShape;
							MarkSwimlane *pMS = (MarkSwimlane*) pSS->m_pMarkElement;
							if( pMS->m_ToParameter )
							{
								expression = pMS->m_UMLParameter.name;
							}
							else
							{
								expression = pMS->m_UMLAttribute.name;
							}
							expression += ".";
							expression += pAA->name;
							expression += "();";
						}
						else
						{//如果活动不属于泳道，那么直接调用语句
							expression = pAA->m_Expression;
						}
						if( pAA->m_Expression.GetLength() )
						{
							que.Add( new CString( "<EXPRESSION>" ) );
							que.Add( new CString( TrunckEnter(expression)  ) );
							que.Add( new CString( "</EXPRESSION>" ) );
						}
					}

					if( pAc->m_ActivityKind == ACTIVITY_SYNCH )
					{//是并发活动
						MarkSynch *pMS = (MarkSynch*)pTemp->m_pMarkElement;
						UMLSynchActivity *pSA = (UMLSynchActivity*)pAc;
						if(pSA->m_pSynchActivityNext )
						{//并发开始
							CString activateThreadText;
							ShapeActivity *pSANext = (ShapeActivity*)(pAg->FindShapeActivity( pSA->m_pSynchActivityNext ));

							if( !unPro.Find( pSANext ) && !pro.Find( pSANext) )
								unPro.Add( pSANext );

							activateThreadText = pMS->m_SynchName;
							activateThreadText += ".CreateThread();";
							activateThreadText += pMS->m_SynchName;
							activateThreadText += ".RunThread();";
							que.Add( new CString( "<EXPRESSION>" ) );
							que.Add( new CString( activateThreadText) );
							que.Add( new CString( "</EXPRESSION>" ) );

							que.Add( new CString( "<NEXT>" ) );

							que.Add( new CString( "<ID>" ) );
							txt.Format("%d" ,pSANext->m_ID );
							que.Add( new CString( txt ) );
							que.Add( new CString( "</ID>" ) );

							que.Add( new CString( "<CONDICTION>" ) );
							que.Add( new CString( "true" ) );
							que.Add( new CString( "</CONDICTION>" ) );
							
							que.Add( new CString( "</NEXT>" ) );

						}
						else
						{//并发终止
							if( pSA->m_BeginControlFlow.GetUpperBound() >= 0 || pSA->m_EndControlFlow.GetUpperBound() >= 0 )
							{
								que.Add( new CString( "<EXPRESSION>" ) );
								que.Add( new CString( pMS->m_SynchName + ".Wait();") );
								que.Add( new CString( "</EXPRESSION>" ) );
							}

							for( int iOut = 0 ; iOut <= pTemp->m_pOutTransEdges.GetUpperBound() ;iOut ++ )
							{
								ShapeTransEdge *pEdge = pTemp->m_pOutTransEdges.GetAt( iOut );
								ShapeActivity* next = pEdge->m_pActivity[ 1 ];
								que.Add( new CString("<NEXT>") );
								
								que.Add( new CString( "<ID>" ) );
								txt.Format("%d",next->m_ID );
								que.Add( new CString( txt ) );
								que.Add( new CString( "</ID>" ) );

								que.Add( new CString( "<CONDICTION>" ) );
								que.Add( new CString( "true" ) );
								que.Add( new CString( "</CONDICTION>" ) );

								que.Add( new CString("</NEXT>") );
								if( !unPro.Find( next ) && !pro.Find( next) )
									unPro.Add( next );
							}
						}
					}
					else
					{//不是并发活动
						for( int iOut = 0 ; iOut <= pTemp->m_pOutTransEdges.GetUpperBound() ;iOut ++ )
						{
							ShapeTransEdge *pEdge = pTemp->m_pOutTransEdges.GetAt( iOut );
							ShapeActivity* next = pEdge->m_pActivity[ 1 ];
							que.Add( new CString("<NEXT>") );

							que.Add( new CString( "<ID>" ) );
							txt.Format("%d",next->m_ID );
							que.Add( new CString( txt ) );
							que.Add( new CString( "</ID>" ) );

							que.Add( new CString( "<CONDICTION>" ) );
							que.Add( new CString( pEdge->m_pTransEdge->m_BoolExpression ) );
							que.Add( new CString( "</CONDICTION>" ) );

							que.Add( new CString("</NEXT>") );
							if( !unPro.Find( next ) && !pro.Find( next ))
								unPro.Add( next );
						}
					}
					que.Add( new CString( "</ACTIVITY>" ) );
				}
			}
			que.Add( new CString("</TRANSTABLE>") );
		}

		que.Add( new CString("</OPERATION>") );
}

void TreeDlg::OnMenuitemRefreshControlflow() 
{
	// TODO: Add your command handler code here
	HTREEITEM selItem = m_TreeCtrl.GetSelectedItem();
	AddToLog("Refreshing control of activity diagram");
	for(  int i = 0 ; i < m_Nodes.GetSize(); i ++ )
	{
		TreeNode tn = m_Nodes.GetAt( i );
		if( tn.item == selItem )
		{
			ShapeActivityGraph* pSAG = (ShapeActivityGraph*)tn.pShape;
				pSAG->m_pActivityGraph->GetControlFlows();
			for( int j = 0 ; j <= pSAG->m_pShapeControlFlows.GetUpperBound() ; j ++ )
			{
				ShapeControlFlow *pCF = pSAG->m_pShapeControlFlows.GetAt( j );
				delete pCF;
			}
			pSAG->m_pShapeControlFlows.RemoveAll();
			for( j = 0 ; j <= pSAG->m_pActivityGraph->m_ControlFlows.GetUpperBound() ; j ++ )
			{
				UMLControlFlow *pCF = pSAG->m_pActivityGraph->m_ControlFlows.GetAt( j );
				ShapeControlFlow *pSCF = new ShapeControlFlow;
				MarkControlFlow *pMCF = (MarkControlFlow*)pSCF->m_pMarkElement;
				pSCF->m_pUMLControlFlow = pCF;
				pMCF->m_Name.Format("m_ControlFlow_%d" , pSCF->m_ID );
				pMCF->m_Type.Format("ControlFlow_%d" , pSCF->m_ID );
				pSAG->m_pShapeControlFlows.Add( pSCF );
			}
			return;
		}
	}
}

void TreeDlg::GenFromControlFlow(DecodeQueue &que,ShapeActivityGraph *shapeAG , ShapeControlFlow *shape)
{
	MarkControlFlow *pMCF = (MarkControlFlow*)(shape->m_pMarkElement);
	UMLControlFlow *pCF = shape->m_pUMLControlFlow;
	ShapeActivity* begin;
	CPtrTempl<ShapeActivity*>endList;
	CPtrTempl<ShapeActivity*>unPro,pro;
	CString txt;
	begin = shapeAG->FindShapeActivity( pCF->m_pBegin );
	//end = shapeAG->FindShapeActivity( pCF->m_pEnd );

	que.Add( new CString("<THREAD>") );
	que.Add( new CString("<NAME>") );
	que.Add( new CString( pMCF->m_Type) );
	que.Add( new CString("</NAME>") );

	//将可达并发映射为属性
	for( int i = 0 ; i <= pCF->m_ReachableSynch.GetUpperBound() ; i ++ )
	{
		UMLSynchActivity *pUSA = pCF->m_ReachableSynch.GetAt( i );
		ShapeActivity *pEnd = shapeAG->FindShapeActivity(pUSA);
		MarkSynch *pMS = (MarkSynch*)pEnd->m_pMarkElement;
		que.Add( new CString( "<ATTRIBUTE>" ) );

		que.Add( new CString( "<NAME>" ) );
		que.Add( new CString( pMS->m_SynchName ) );
		que.Add( new CString( "</NAME>" ) );

		que.Add( new CString( "<TYPE>" ) );
		que.Add( new CString( pMS->m_SynchType ) );
		que.Add( new CString( "</TYPE>" ) );

		que.Add( new CString( "<VISIBILITY>" ) );
		que.Add( new CString( "PUBLIC" ) );
		que.Add( new CString( "</VISIBILITY>" ) );

		que.Add( new CString( "</ATTRIBUTE>" ) );
	}

	for( i = 0 ; i <= pCF->m_pEndList.GetUpperBound(); i ++ )
	{
		UMLSynchActivity *pUSA = pCF->m_pEndList.GetAt( i );
		ShapeActivity *pEnd = shapeAG->FindShapeActivity(pUSA);
		endList.Add( pEnd );
	}

	if( shapeAG->m_pShapeSwimlanes.GetUpperBound() >= 0 )
	{
		CPtrTempl<ShapeSwimlane*>owner;
		for( int i = 0 ; i <= pCF->m_pActivities.GetUpperBound() ; i ++ )
		{
			UMLActivity *pA = pCF->m_pActivities.GetAt( i );
			ShapeActivity *pSA = shapeAG->FindShapeActivity( pA );
			ShapeSwimlane* pOwner = (ShapeSwimlane*) pSA->m_pOwnedShape;
			if( !owner.Find( pOwner ) )
			{
				owner.Add( pOwner );
			}
		}
		//将泳道作为属性
		for( i = 0 ; i <= owner.GetUpperBound() ; i ++ )
		{
			UMLAttribute att;
			ShapeSwimlane *sl = owner.GetAt( i );
			att.m_Multiplicity = "1";
			att.m_pType = sl->m_pSwimlane->pType;
			att.m_Visibility = VISIBILITY_PUBLIC;
			att.name = sl->m_pSwimlane->name;
			GenFromAttribute( que , att );
		}
	}
	else
	{
		UMLAttribute att;
		att.m_Multiplicity = "1";
		att.m_pType = shapeAG->m_pActivityGraph->m_pClass;
		att.name = "m_pRefObj";
		GenFromAttribute( que , att );
	}
	//映射Lock操作，在线程启动前，先Lock，增加可达并发的引用数
	que.Add( new CString( "<OPERATION>" ) );

	que.Add( new CString( "<NAME>" ) );//线程入口名称
	que.Add( new CString( "LockMe" ) );
	que.Add( new CString( "</NAME>" ) );

	que.Add( new CString( "<RETURNTYPE>" ) );//线程入口操作无返回值
	que.Add( new CString( "synchronized void" ) );
	que.Add( new CString( "</RETURNTYPE>" ) );
	txt = "";
	for(i = 0 ; i <= pCF->m_ReachableSynch.GetUpperBound() ; i ++ )
	{
		UMLSynchActivity *pUSA = pCF->m_ReachableSynch.GetAt( i );
		ShapeActivity *pEnd = shapeAG->FindShapeActivity(pUSA);
		MarkSynch *pMS = (MarkSynch*)pEnd->m_pMarkElement;
		txt += pMS->m_SynchName;
		txt += ".Check(-1);";
	}
	que.Add( new CString("<EXPRESSION>"));
	que.Add( new CString( txt ) );
	que.Add( new CString("</EXPRESSION>") );
	que.Add( new CString( "</OPERATION>" ) );
	//映射动作
	que.Add( new CString( "<OPERATION>" ) );

	que.Add( new CString( "<NAME>" ) );//线程入口名称
	que.Add( new CString( "run" ) );
	que.Add( new CString( "</NAME>" ) );

	que.Add( new CString( "<RETURNTYPE>" ) );//线程入口操作无返回值
	que.Add( new CString( "void" ) );
	que.Add( new CString( "</RETURNTYPE>" ) );

	que.Add( new CString( "<TRANSTABLE>" ) );

	que.Add( new CString( "<INITID>" ) );//入口ID
	txt.Format("%d",begin->m_ID );
	que.Add( new CString( txt ) );
	que.Add( new CString( "</INITID>" ) );
	
	//出口不再唯一
	for( i = 0 ; i <= endList.GetUpperBound() ; i ++ )
	{
		ShapeActivity *pEnd = endList.GetAt( i );
		que.Add( new CString( "<FINIID>" ) );//出口ID
		txt.Format("%d",pEnd->m_ID);
		que.Add( new CString( txt ) );
		que.Add( new CString( "</FINIID>" ) );
	}

	unPro.Add( begin );
	while( unPro.GetUpperBound() >= 0 )
	{
		ShapeActivity *pSA = unPro.GetAt( 0 );
		UMLActivityPointerList curReachableSynch;
		if( pSA != begin )
		{//如果不是初始并发节点，计算其可达得并发
			shape->m_pUMLControlFlow->GetReachableSynch( pSA->m_pUMLActivity , curReachableSynch );
		}
		else
		{//如果是初始并发节点，其可达得并发等于其后得第一个节点得可达的并发节点
			shape->m_pUMLControlFlow->GetReachableSynch( shape->m_pUMLControlFlow->m_pFirstEdge->m_pActivities[ 1 ] , curReachableSynch );
		}
		que.Add( new CString( "<ACTIVITY>" ) );

		que.Add( new CString( "<ID>" ) );
		txt.Format("%d",pSA->m_ID);
		que.Add( new CString( txt ) );
		que.Add( new CString( "</ID>" ) );

		if( pSA->m_pUMLActivity->m_ActivityKind == ACTIVITY_ACTION )
		{
			if( pSA->m_pOwnedShape->GetType() == SHAPE_SWIMLANE )
			{
				ShapeSwimlane *pOwner = (ShapeSwimlane*)pSA->m_pOwnedShape;
				MarkSwimlane *pMark = (MarkSwimlane*)pOwner->m_pMarkElement;
				que.Add( new CString( "<EXPRESSION>" ) );
				if( pMark->m_ToParameter )
				{
					txt = pMark->m_UMLParameter.name;
					txt += ".";
					txt += pSA->m_pUMLActivity->name;
					txt += "();";
					que.Add( new CString( txt ) );
				}
				else
				{
					txt = pMark->m_UMLAttribute.name;
					txt += ".";
					txt += pSA->m_pUMLActivity->name;
					txt += "();";
					que.Add( new CString( txt ) );
				}
				que.Add( new CString( "</EXPRESSION>" ) );
			}
			else
			{
				ShapeActivityGraph *pOwner = (ShapeActivityGraph*)pSA->m_pOwnedShape;
				que.Add( new CString( "<EXPRESSION>" ) );
				txt = "m_pRefObj.";
				txt += pSA->m_pUMLActivity->name;
				txt += "();";
				que.Add( new CString( txt ) );
				que.Add( new CString( "</EXPRESSION>" ) );
			}
		}
		else if( endList.Find( pSA ) )
		{
			//到达终止并发节点，需要生成CHECK,检查退出前是否要调用创建操作
			MarkSynch *pMS;
			CString txt;
			
			for( int i = 0 ; i <= curReachableSynch.GetUpperBound() ; i ++ )
			{
				UMLSynchActivity * sa = (UMLSynchActivity*)curReachableSynch.GetAt( i );
				ShapeActivity* p = shapeAG->FindShapeActivity( sa );
				pMS = (MarkSynch*)p->m_pMarkElement;
				if( pSA->m_pUMLActivity == sa )
				{
					txt += pMS->m_SynchName;
					txt += ".SetWaiter();";
					txt += pMS->m_SynchName;
					txt += ".Check(1);";//引用数减1
				}
			}
			for(i = 0 ; i <= curReachableSynch.GetUpperBound() ; i ++ )
			{
				UMLSynchActivity * sa = (UMLSynchActivity*)curReachableSynch.GetAt( i );
				ShapeActivity* p = shapeAG->FindShapeActivity( sa );
				pMS = (MarkSynch*)p->m_pMarkElement;
				if( pSA->m_pUMLActivity != sa )
				{
					txt += pMS->m_SynchName;
					txt += ".Check(1);";//引用数减1
				}
			}

			que.Add( new CString( "<EXPRESSION>" ) );
			que.Add( new CString( txt ) );
			que.Add( new CString( "</EXPRESSION>" ) );

		}
		unPro.RemoveAt( 0 );
		if( !pro.Find( pSA ) )
			pro.Add( pSA );

		for(int i = 0 ; i <= pSA->m_pOutTransEdges.GetUpperBound() ; i ++ )
		{
			ShapeTransEdge *pEdge;
			UMLActivityPointerList nextReachableSynch;
			pEdge= pSA->m_pOutTransEdges.GetAt( i );
			if( pSA == begin )
			{
				if( pEdge->m_pTransEdge != shape->m_pUMLControlFlow->m_pFirstEdge )continue;
			}
			
			if( pCF->m_pActivities.Find( pEdge->m_pActivity[ 1 ]->m_pUMLActivity) || endList.Find( pEdge->m_pActivity[ 1 ] ))
			{
				if( !unPro.Find( pEdge->m_pActivity[ 1 ]) && !pro.Find( pEdge->m_pActivity[ 1 ] ) )
				{
					unPro.Add( pEdge->m_pActivity[ 1 ] );
				}
				shape->m_pUMLControlFlow->GetReachableSynch( pEdge->m_pTransEdge->m_pActivities[ 1 ] , nextReachableSynch );
				//查找提前CHECK的并发
				CString advanceCheck;
				for( int t = 0 ; t <= curReachableSynch.GetUpperBound() ; t ++ )
				{
					UMLActivity *pMeta = curReachableSynch.GetAt( t );
					if(! nextReachableSynch.Find( pMeta ) )
					{
						ShapeActivity *pShape = shapeAG->FindShapeActivity( pMeta );
						MarkSynch *pMark = (MarkSynch*)pShape->m_pMarkElement;
						advanceCheck += pMark->m_SynchName;
						advanceCheck += ".Check(1);";
					}
				}
				
				que.Add( new CString( "<NEXT>" ) );

				que.Add( new CString( "<ID>" ) );
				txt.Format("%d", pEdge->m_pActivity[ 1 ]->m_ID );
				que.Add( new CString( txt ) );
				que.Add( new CString( "</ID>" ) );

				que.Add( new CString( "<CONDICTION>" ) );
				que.Add( new CString( pEdge->m_pTransEdge->m_BoolExpression ) );
				que.Add( new CString( "</CONDICTION>" ) );

				if( advanceCheck.GetLength() )
				{
					que.Add( new CString("<EXPRESSION>"));
					que.Add( new CString(advanceCheck));
					que.Add( new CString("</EXPRESSION>"));
				}

				que.Add( new CString( "</NEXT>" ) );
			}
		}
		que.Add( new CString( "</ACTIVITY>" ));
	}

	que.Add( new CString( "</TRANSTABLE>" ) );

	que.Add( new CString( "</OPERATION>" ) );
	que.Add( new CString("</THREAD>") );
}

void TreeDlg::GenFromSynch(DecodeQueue &que,ShapeActivityGraph*shapeAG ,ShapeActivity *shape)
{
	MarkSynch *pMS = (MarkSynch*)shape->m_pMarkElement;
	CString txt;
	CString createThreadText;
	CPtrTempl<ShapeControlFlow*>in,out;
	CString strIniNumber;

	//获得所有的入控制流和出控制流
	for( int i = 0 ; i <= shapeAG->m_pShapeControlFlows.GetUpperBound() ; i ++ )
	{
		ShapeControlFlow *pSCF = shapeAG->m_pShapeControlFlows.GetAt( i );
		if( pSCF->m_pUMLControlFlow->m_pBegin == shape->m_pUMLActivity )
		{
			out.Add( pSCF );
		}
		else if( pSCF->m_pUMLControlFlow->m_pEndList.Find((UMLSynchActivity*)shape->m_pUMLActivity) )
		{
			in.Add( pSCF );
		}
	}

	que.Add( new CString("<SYNCH>") );

	que.Add( new CString("<NAME>") );
	que.Add( new CString( pMS->m_SynchType ) );
	que.Add( new CString("</NAME>") );

	//将活动图对应的类映射为属性：这样可以应用任何一个并发，因为线程中需要并发
	que.Add( new CString("<ATTRIBUTE>"));

	que.Add( new CString("<NAME>"));
	que.Add( new CString("m_SynchOwner"));//活动图对应的类
	que.Add( new CString("</NAME>"));

	que.Add( new CString("<TYPE>"));
	que.Add( new CString(shapeAG->m_pActivityGraph->m_pClass->UMLGeneralizableElement::name));
	que.Add( new CString("</TYPE>"));

	que.Add( new CString("<VISIBILITY>"));
	que.Add( new CString("PUBLIC"));
	que.Add( new CString("</VISIBILITY>"));

	que.Add( new CString("</ATTRIBUTE>"));
	//是否有控制流已经在等
	que.Add( new CString("<ATTRIBUTE>"));

	que.Add( new CString("<NAME>"));
	que.Add( new CString("m_HasWaiter"));//活动图对应的类
	que.Add( new CString("</NAME>"));

	que.Add( new CString("<TYPE>"));
	que.Add( new CString("Boolean"));
	que.Add( new CString("</TYPE>"));

	que.Add( new CString("<VISIBILITY>"));
	que.Add( new CString("PRIVATE"));
	que.Add( new CString("</VISIBILITY>"));

	que.Add( new CString("<INIVALUE>"));
	que.Add( new CString("false"));
	que.Add( new CString("</INIVALUE>"));

	que.Add( new CString("</ATTRIBUTE>"));
	//如果活动图包含泳道，并发因该有这些泳道的引用
	for( i = 0 ; i <= shapeAG->m_pShapeSwimlanes.GetUpperBound() ; i ++ )
	{
		ShapeSwimlane *pSS = shapeAG->m_pShapeSwimlanes.GetAt( i );
		MarkSwimlane *pMS = (MarkSwimlane*)pSS->m_pMarkElement;
		
		que.Add( new CString("<ATTRIBUTE>"));

		que.Add( new CString("<NAME>"));
		if( pMS->m_ToParameter )
			que.Add( new CString(pMS->m_UMLParameter.name));
		else
			que.Add( new CString(pMS->m_UMLAttribute.name));
		que.Add( new CString("</NAME>"));

		que.Add( new CString("<TYPE>"));
		if( pMS->m_ToParameter )
			que.Add( new CString(pMS->m_UMLParameter.m_pType->UMLGeneralizableElement::name));
		else
			que.Add( new CString(pMS->m_UMLAttribute.m_pType->UMLGeneralizableElement::name));
		que.Add( new CString("</TYPE>"));

		que.Add( new CString("<VISIBILITY>"));
		que.Add( new CString("PUBLIC"));
		que.Add( new CString("</VISIBILITY>"));

		que.Add( new CString("</ATTRIBUTE>"));
	}

	//将要创建的所有线程映射为属性
	CString runCmd;//启动线程语句
	CString lockCmd;//锁定语句
	createThreadText = "ResetWaiter();";
	for( i = 0 ; i <= out.GetUpperBound() ; i ++ )
	{
		ShapeControlFlow *pSCF = out.GetAt( i );
		MarkControlFlow *pMCF = (MarkControlFlow*)pSCF->m_pMarkElement;

		createThreadText += pMCF->m_Name;//新建线程对象
		createThreadText += " = new ";
		createThreadText += pMCF->m_Type;
		createThreadText += "();";

		//将控制流中涉及的并发连接到对象
		for( int j = 0 ; j <= pSCF->m_pUMLControlFlow->m_ReachableSynch.GetUpperBound() ; j ++ )
		{
			UMLSynchActivity *pEnd = pSCF->m_pUMLControlFlow->m_ReachableSynch.GetAt( j );
			ShapeActivity *pSEnd = shapeAG->FindShapeActivity( pEnd );
			MarkSynch *pMEnd = (MarkSynch*)pSEnd->m_pMarkElement;
			createThreadText += pMCF->m_Name;
			createThreadText += ".";
			createThreadText += pMEnd->m_SynchName;
			createThreadText += " = ";
			createThreadText += "m_SynchOwner.";
			createThreadText += pMEnd->m_SynchName;
			createThreadText += ";";
		}
		//判断是否需要添加主控制流的终止节点
		if( pSCF->m_pUMLControlFlow->m_pMainCFEnd && pSCF->m_pUMLControlFlow->m_pEndList.GetUpperBound()>0)
		{
			if( !pSCF->m_pUMLControlFlow->m_pEndList.Find(pSCF->m_pUMLControlFlow->m_pMainCFEnd))
			{
				UMLSynchActivity *pEnd = pSCF->m_pUMLControlFlow->m_pMainCFEnd;
				ShapeActivity *pSEnd = shapeAG->FindShapeActivity( pEnd );
				MarkSynch *pMEnd = (MarkSynch*)pSEnd->m_pMarkElement;
				createThreadText += pMCF->m_Name;
				createThreadText += ".";
				createThreadText += pMEnd->m_SynchName;
				createThreadText += " = ";
				createThreadText += "m_SynchOwner.";
				createThreadText += pMEnd->m_SynchName;
				createThreadText += ";";
			}
		}
		//将泳道或活动图对应的类连接到控制流
		if( shapeAG->m_pShapeSwimlanes.GetUpperBound() >= 0 )
		{
			CPtrTempl<ShapeSwimlane*>sl;
			for( int j = 0; j <= pSCF->m_pUMLControlFlow->m_pActivities.GetUpperBound() ; j ++ )
			{
				UMLActionActivity *pAA = (UMLActionActivity*)pSCF->m_pUMLControlFlow->m_pActivities.GetAt( j );
				ShapeActivity *pSA = shapeAG->FindShapeActivity( pAA );
				if( !sl.Find( (ShapeSwimlane*)pSA->m_pOwnedShape ) )
				{
					sl.Add( (ShapeSwimlane*)pSA->m_pOwnedShape ) ;
				}
			}
			for( j = 0 ; j <= sl.GetUpperBound() ;j ++ )
			{
				ShapeSwimlane *pSS = sl.GetAt( j );
				MarkSwimlane *pMS = (MarkSwimlane*)pSS->m_pMarkElement;
				createThreadText += pMCF->m_Name;
				createThreadText += ".";
				if( pMS->m_ToParameter )
				{
					createThreadText += pMS->m_UMLParameter.name;
				}
				else
				{
					createThreadText += pMS->m_UMLAttribute.name;
				}
				createThreadText += " = ";
				if( pMS->m_ToParameter )
				{
					createThreadText += pMS->m_UMLParameter.name;
				}
				else
				{
					createThreadText += pMS->m_UMLAttribute.name;
				}
				createThreadText += ";";
			}
		}
		else
		{
			createThreadText += pMCF->m_Name;
			createThreadText += ".m_pRefObj = ";
			createThreadText += "m_SynchOwner;";
		}

		runCmd += pMCF->m_Name;
		runCmd += ".start();";
		lockCmd += pMCF->m_Name;
		lockCmd += ".LockMe();";

		que.Add( new CString( "<ATTRIBUTE>" ) );

		que.Add( new CString( "<NAME>" ) );
		que.Add( new CString( pMCF->m_Name ) );
		que.Add( new CString( "</NAME>" ) );

		que.Add( new CString( "<TYPE>" ) );
		que.Add( new CString( pMCF->m_Type ) );
		que.Add( new CString( "</TYPE>" ) );

		que.Add( new CString( "<VISIBILITY>" ) );
		que.Add( new CString( "PUBLIC" ) );
		que.Add( new CString( "</VISIBILITY>" ) );

		que.Add( new CString( "</ATTRIBUTE>" ) );
	}
	//映射入转换个数属性
	que.Add( new CString( "<ATTRIBUTE>" ) );

	que.Add( new CString( "<NAME>" ) );
	que.Add( new CString( "m_InThreadNumber" ) );
	que.Add( new CString( "</NAME>" ) );

	que.Add( new CString( "<TYPE>" ) );
	que.Add( new CString( "Integer" ) );
	que.Add( new CString( "</TYPE>" ) );

	que.Add( new CString( "<VISIBILITY>" ) );
	que.Add( new CString( "PRIVATE" ) );
	que.Add( new CString( "</VISIBILITY>" ) );

	que.Add( new CString( "<INIVALUE>" ) );
	que.Add( new CString( "0" ) );
	que.Add( new CString( "</INIVALUE>" ) );

	que.Add( new CString( "</ATTRIBUTE>" ) );

	//映射CHECK操作
	que.Add( new CString( "<OPERATION>" ) );

	que.Add( new CString( "<NAME>" ) );
	que.Add( new CString( "Check" ) );
	que.Add( new CString( "</NAME>" ) );

	que.Add( new CString( "<PARAMETER>" ) );

	que.Add( new CString( "<NAME>" ) );
	que.Add( new CString( "num" ) );
	que.Add( new CString( "</NAME>" ) );

	que.Add( new CString( "<TYPE>" ) );
	que.Add( new CString( "Integer" ) );
	que.Add( new CString( "</TYPE>" ) );

	que.Add( new CString( "</PARAMETER>" ) );

	que.Add( new CString( "<RETURNTYPE>" ) );
	que.Add( new CString( "synchronized void" ) );
	que.Add( new CString( "</RETURNTYPE>" ) );

	que.Add( new CString( "<VISIBILITY>" ) );
	que.Add( new CString( "PUBLIC" ) );
	que.Add( new CString( "</VISIBILITY>" ) );

	que.Add( new CString( "<EXPRESSION>" ) );
	txt.Format("m_InThreadNumber -= num;if( m_InThreadNumber <= 0 && m_HasWaiter ){CreateThread();notifyAll();RunThread();}");
	que.Add( new CString( txt ) );
	que.Add( new CString( "</EXPRESSION>" ) );

	que.Add( new CString( "</OPERATION>" ) );
	//映射Wait操作
	que.Add( new CString( "<OPERATION>" ) );

	que.Add( new CString( "<NAME>" ) );
	que.Add( new CString( "Wait" ) );
	que.Add( new CString( "</NAME>" ) );

	que.Add( new CString( "<RETURNTYPE>" ) );
	que.Add( new CString( "synchronized void" ) );
	que.Add( new CString( "</RETURNTYPE>" ) );

	que.Add( new CString( "<VISIBILITY>" ) );
	que.Add( new CString( "PUBLIC" ) );
	que.Add( new CString( "</VISIBILITY>" ) );

	que.Add( new CString( "<EXPRESSION>" ) );
	que.Add( new CString( "try{if( m_InThreadNumber > 0 )wait();}catch(InterruptedException e){System.out.println(\"wait error\");}" ) );
	que.Add( new CString( "</EXPRESSION>" ) );

	que.Add( new CString( "</OPERATION>" ) );

	//映射SetWaiter操作
	que.Add( new CString( "<OPERATION>" ) );

	que.Add( new CString( "<NAME>" ) );
	que.Add( new CString( "SetWaiter" ) );
	que.Add( new CString( "</NAME>" ) );

	que.Add( new CString( "<RETURNTYPE>" ) );
	que.Add( new CString( "synchronized void" ) );
	que.Add( new CString( "</RETURNTYPE>" ) );

	que.Add( new CString( "<VISIBILITY>" ) );
	que.Add( new CString( "PUBLIC" ) );
	que.Add( new CString( "</VISIBILITY>" ) );

	que.Add( new CString( "<EXPRESSION>" ) );
	que.Add( new CString( "m_HasWaiter = true;" ) );
	que.Add( new CString( "</EXPRESSION>" ) );

	que.Add( new CString( "</OPERATION>" ) );

	//映射ResetWaiter操作
	que.Add( new CString( "<OPERATION>" ) );

	que.Add( new CString( "<NAME>" ) );
	que.Add( new CString( "ResetWaiter" ) );
	que.Add( new CString( "</NAME>" ) );

	que.Add( new CString( "<RETURNTYPE>" ) );
	que.Add( new CString( "synchronized void" ) );
	que.Add( new CString( "</RETURNTYPE>" ) );

	que.Add( new CString( "<VISIBILITY>" ) );
	que.Add( new CString( "PUBLIC" ) );
	que.Add( new CString( "</VISIBILITY>" ) );

	que.Add( new CString( "<EXPRESSION>" ) );
	que.Add( new CString( "m_HasWaiter = false;" ) );
	que.Add( new CString( "</EXPRESSION>" ) );

	que.Add( new CString( "</OPERATION>" ) );
	
	//映射CreateThread操作
	que.Add( new CString( "<OPERATION>" ) );

	que.Add( new CString( "<NAME>" ) );
	que.Add( new CString( "CreateThread" ) );
	que.Add( new CString( "</NAME>" ) );

	que.Add( new CString( "<RETURNTYPE>" ) );
	que.Add( new CString( "void" ) );
	que.Add( new CString( "</RETURNTYPE>" ) );

	que.Add( new CString( "<VISIBILITY>" ) );
	que.Add( new CString( "PUBLIC" ) );
	que.Add( new CString( "</VISIBILITY>" ) );

	createThreadText += lockCmd;
	if( createThreadText.GetLength() )
	{
		que.Add( new CString( "<EXPRESSION>" ) );
		que.Add( new CString( createThreadText ) );
		que.Add( new CString( "</EXPRESSION>" ) );
	}

	que.Add( new CString( "</OPERATION>" ) );

	//映射RunThread操作
	que.Add( new CString( "<OPERATION>" ) );

	que.Add( new CString( "<NAME>" ) );
	que.Add( new CString( "RunThread" ) );
	que.Add( new CString( "</NAME>" ) );

	que.Add( new CString( "<RETURNTYPE>" ) );
	que.Add( new CString( "void" ) );
	que.Add( new CString( "</RETURNTYPE>" ) );

	que.Add( new CString( "<VISIBILITY>" ) );
	que.Add( new CString( "PUBLIC" ) );
	que.Add( new CString( "</VISIBILITY>" ) );

	createThreadText += lockCmd;
	createThreadText += runCmd;
	if( createThreadText.GetLength() )
	{
		que.Add( new CString( "<EXPRESSION>" ) );
		que.Add( new CString( runCmd ) );
		que.Add( new CString( "</EXPRESSION>" ) );
	}

	que.Add( new CString( "</OPERATION>" ) );

	que.Add( new CString("</SYNCH>") );
}

void TreeDlg::OnMenuitemCreateJava() 
{
	// TODO: Add your command handler code here
	CFileDialog dlg( TRUE , "xml" , "*.xml" , OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT , "XML File(*.xml)|*.xml||");
	if( dlg.DoModal() == IDOK )
	{
		XMLToJava xml;
		CString dir = dlg.GetPathName();
		dir = dir.Left( dir.ReverseFind('\\')) ;
		xml.Do( dir , dlg.GetPathName() );
	}
}

CString TreeDlg::TrunckEnter(CString istr)
{
	int i = 0 ; 
	CString str = istr;
	while( i< str.GetLength() )
	{
		if( str.GetAt( i ) == '\r' )
		{
			str.Delete( i );
			continue;
		}
		else if( str.GetAt( i ) == '\n' )
		{
			str.Delete( i );
			continue;
		}
		i ++;
	}
	return str;
}

void TreeDlg::OnMenuitemClose() 
{
	// TODO: Add your command handler code here
	CFileDialog dlg(true ,"xml","*.xml",OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,"XML File(*.xml)|*.xml||");
	if( dlg.DoModal() == IDCANCEL)return;
	if( m_pRootShape )
	{
		delete m_pRootShape;
		m_pRootShape = NULL;
		m_Classes.RemoveAll();
		m_CurrentElement = NULL;
		m_Nodes.RemoveAll();
		m_TreeCtrl.DeleteAllItems();
		for(int i = 0 ; i <= ShapeElement::m_AllShapes.GetUpperBound();i ++ )
		{
			ShapeElement *p = ShapeElement::m_AllShapes.GetAt( i );
			CString txt;
			txt.Format("ERROR:type:%d id=%d not deleted!!!!!!!!!!!!!!!!!",p->GetType() , p->m_ID);
		//	Beep( 1000 , 200 );
			AddToLog(txt);
			delete p;
		}
		ShapeElement::m_AllShapes.RemoveAll();
		

			XMLToSource source;

			source.Do( dlg.GetPathName() );

			if( m_pRootShape ) AddNamespace( (ShapeNamespace*)m_pRootShape );
			m_pView->Invalidate();
	}
}

void TreeDlg::AddNamespace(ShapeNamespace *n ,HTREEITEM par)
{
	TreeNode tn;
	tn.pShape = n;
	if( par )
	{
		
		tn.item = m_TreeCtrl.InsertItem( n->m_pUMLNamespace->name , 0 , 0, par );
		m_Nodes.Add( tn );
		
	}
	else
	{
		tn.item = m_TreeCtrl.InsertItem( n->m_pUMLNamespace->name , 0 , 0, TVI_ROOT );
		m_Nodes.Add( tn );
	}
	for( int i = 0 ; i <= n->m_pOwnedShapes.GetUpperBound() ; i ++ )
	{
			ShapeElement *c = n->m_pOwnedShapes.GetAt( i );
			if( c->GetType() == SHAPE_NAMESPACE )
			{
				ShapeNamespace * child= (ShapeNamespace*)c;
				AddNamespace( child , tn.item );
			}
			else
			{
				ShapeClass *child = (ShapeClass*)c;
				AddClass( child , tn.item );
			}
	}
}

void TreeDlg::AddClass(ShapeClass *pc, HTREEITEM par)
{
	TreeNode tn;
	tn.item = m_TreeCtrl.InsertItem( pc->m_pClass->UMLGeneralizableElement::name , 3 , 3, par );
	tn.pShape = pc;
	m_Nodes.Add( tn );
	for( int i = 0 ; i <= pc->m_pShapeActivityGraphs.GetUpperBound() ; i ++ )
	{
		ShapeActivityGraph *pa = pc->m_pShapeActivityGraphs.GetAt( i );
		AddActivityGraph( pa , tn.item );
	}
}

void TreeDlg::AddActivityGraph(ShapeActivityGraph *sg, HTREEITEM par)
{
	TreeNode tn;
	tn.pShape = sg;
	tn.item = m_TreeCtrl.InsertItem( sg->m_pActivityGraph->name , 2 , 2, par );
	m_Nodes.Add( tn );
}

void TreeDlg::OpenSource()
{
	OnMenuitemClose();
}
