// aplBPTreeItem.cpp

#include "stdafx.h"
#include "aplTreeItem.h"
#include "apl_lot_item.h"
#include "apl_prd_inst_item.h"

#include "stdafx.h"
#include "PSMDoc.h"
#include "resource.h"
//#include "HackDefence.h"

#include "aplTopLevelItem.h"
#include "aplTreeApprovalItem.h"
#include "aplTreeCharacteristicItem.h"
#include "aplCharacteristicGroupTreeItem.h"
#include "aplDocTreeItem.h"
#include "aplPersonTreeItem.h"
#include "aplOrganizationTreeItem.h"
#include "TreeProductItem.h"
#include "TabView.h"
#include "aplBPTreeItem.h"
#include "aplBPInstTreeItem.h"
#include "act_res_treeitem.h"
#include "BPResDlg.h"
#include "Defence.h"
#include "aplProjectTreeItem.h"
#include "aplClassifierTreeItem.h"

#define _APL_TREE_ITEM_CHEK_PARAM \
        if(m_tree==0) return false;\
        if(m_doc==0) return false;

//****************************************************************
//****************************************************************
//****************************************************************
CaplBPTreeItem::CaplBPTreeItem(CTreeCtrl *tree, CPSMDoc *doc,
		CaplInstance *inst)
{
	m_type=APL_TREE_ITEM_BP;
	m_tree=tree;
	m_doc=doc;
	m_inst=inst;
	m_folder=0;
	m_classifier=0;
	m_index=-1;
	m_subitem=0;
	m_rel=0;
	m_par_bp=0;
	m_rev=0;
	m_pLockInfo=0;
	m_parent=0;
	m_parent_bp_item=0;
	m_has_version=false;
	m_project=0;
	m_bWhereUsed=false;
	if(doc!=0) doc->m_items.Add(this);
}
//****************************************************************
bool CaplBPTreeItem::CreateTreeItem(HTREEITEM parent_item)
{
//	_APL_TREE_ITEM_CHEK_PARAM
	CString buf;
	GetName(buf);
	int ico=ICON_BP;
	ico = m_doc->m_api.GetInstIco(m_inst);
/*
	CaplAggr aggr0;
	CaplInstance *ver=0;
	if(m_doc->m_api.m_bp_mgr.m_bUseVersions)
	{
		CaplInstance *lock=m_doc->m_api.m_bp_mgr.CheckMyLock(m_inst,false);
		if(m_rev) 
		{
			//m_doc->m_api.m_bp_mgr.LoadBPInfo(m_rev);
			ver=m_rev;
		}
		else 
			ver=lock;
	}
	if(ver)
		m_doc_data.GetAttr(ver,m_doc->m_api.m_bp_mgr.a_bp_ver_elements,aggr0);
	else
		m_doc_data.GetAttr(m_inst,m_doc->m_api.m_bp_mgr.a_bp_elements,aggr0);
	if(aggr0.GetSize()<=0) ico++;
	if(m_subitem!=0)ico+=2;
*/

	InsetItem(buf,ico,parent_item);
	SetItemImage(ico, IDX_IL_TREE_ITEM);

//	if(aggr0.GetSize()>0)
	m_fictive_item=m_tree->InsertItem(_T("fictive"),0,0,m_item);
	return true;
}
//****************************************************************
bool CaplBPTreeItem::GetName(CString &name)
{
	_APL_TREE_ITEM_CHEK_PARAM_BOOL
	CHECK_GET_NAME(m_inst);

	CaplInstance *ver=0,*lock=0;
	if(m_doc->m_api.m_bp_mgr.m_bUseVersions)
	{
		lock=m_doc->m_api.m_bp_mgr.CheckMyLock(m_inst,false);
		if(m_rev) 
		{
			m_doc->m_api.m_bp_mgr.LoadBPInfo(m_rev);
			ver=m_rev;
		}
		else 
			ver=lock;
	}

	name=_T("?");

	CString buf;

	if(m_rev)
	{
		m_doc_data.GetAttr(m_rev,m_doc->m_api.m_bp_mgr.a_bp_ver_num,name);
		if(m_rev==lock)
			name=_T("~")+name;
	}
		
/*
	if(CaplBPManager::m_bShowId)
	{
		if(ver)	
			m_doc_data.GetAttr(ver,m_doc->m_api.m_bp_mgr.a_bp_ver_id,buf);
		else 
			m_doc_data.GetAttr(m_inst,m_doc->m_api.m_bp_mgr.a_bp_id,buf);
		if(buf!=_T(""))
		{
			if(name!=_T('?')) name+=_T(" : "); else name=_T("");
			name+=buf;
		}
	}
	if(CaplBPManager::m_bShowName)
	{
		if(ver)
			m_doc_data.GetAttr(ver,m_doc->m_api.m_bp_mgr.a_bp_ver_name,buf);
		else
			m_doc_data.GetAttr(m_inst,m_doc->m_api.m_bp_mgr.a_bp_name,buf);
		if(buf!=_T(""))
		{
			if(name!=_T('?')) name+=_T(" : "); else name=_T("");
			name+=buf;
		}
	}
	if(CaplBPManager::m_bShowType)
	{
		CaplInstance *inst;
		if(ver)
			m_doc_data.GetAttr(ver,m_doc->m_api.m_bp_mgr.a_bp_ver_type,inst);
		else
			m_doc_data.GetAttr(m_inst,m_doc->m_api.m_bp_mgr.a_bp_type,inst);
		if(inst!=0)
		{
			m_doc_data.GetAttr(inst,m_doc->m_api.m_bp_mgr.a_bp_type_name,buf);
			if(buf!=_T(""))
			{
				if(name!=_T('?')) name+=_T(" : ");  else name=_T("");
				name+=buf;
			}
		}
	}*/
	CaplInstance *inst = ver==0 ? m_inst : ver;
	CString tmp;
	m_doc->m_api.GetItemName(inst,tmp);
	if(!m_rev && m_doc->m_api.m_show.m_BPNum)
	{
		if(m_index>=0)
			name.Format(_T("%3i : %s"),m_index,tmp); 
		else
			name = tmp;
	}
	else
		name = tmp;

	return true;
}
//****************************************************************
bool CaplBPTreeItem::RefreshItem()
{
	if(!m_inst)
		return false;
	
	CString buf;
	GetName(buf);
	if(m_tree!=0) m_tree->SetItemText(m_item,buf);

	m_doc_data.GetAttr(m_inst,m_doc->m_api.m_bp_mgr.a_bp_lock,m_pLockInfo);
	int ico;

	bool bCustomized=false, bOptional=false;

	if(m_rev)
	{
		ico = m_doc->m_api.GetInstIco(m_rev);
		CaplInstance *act=0;
		m_doc_data.GetAttr(m_inst,m_doc->m_api.m_bp_mgr.a_bp_act,act);
		m_doc_data.GetAttr(m_rev,m_doc->m_api.m_bp_mgr.a_bp_ver_customized,bCustomized);
		m_doc_data.GetAttr(m_rev,m_doc->m_api.m_bp_mgr.a_bp_ver_optional,bOptional);
		SetItemImage(ICO_REL_VER, IDX_IL_TREE_REL_TYPE);
		if(act==m_rev)
			SetItemImage(ICO_REL_ACTIVE_VER, IDX_IL_TREE_REL_TYPE);
	}
	else
	{
		ico = m_doc->m_api.GetInstIco(m_inst);
		if(m_subitem)
			SetItemImage(ICO_REL_WHERE_USED,IDX_IL_TREE_REL_TYPE);
		if(m_has_version)
		{ 
			HideAllVersion();	
			ShowAllVersion();
		}
		m_doc_data.GetAttr(m_inst, m_doc->m_api.m_bp_mgr.a_bp_state, buf);
		m_doc_data.GetAttr(m_inst, m_doc->m_api.m_bp_mgr.a_bp_customized,bCustomized);
		m_doc_data.GetAttr(m_inst, m_doc->m_api.m_bp_mgr.a_bp_optional,bOptional);
		SetItemImage(aplState2Ico(buf,-1), IDX_IL_TREE_STATE);
	}
	SetItemImage(ico, IDX_IL_TREE_ITEM);

	if(m_bWhereUsed)  SetItemImage(ICO_REL_WHERE_USED, IDX_IL_TREE_REL_TYPE);

	if(m_bWOForNote)
		SetItemImage(ICO_REL_WO_4NOTE, IDX_IL_TREE_REL_TYPE);

	if(0!=m_pLockInfo)
	{
		m_doc_data.GetAttr(m_pLockInfo,m_doc->m_api.m_bp_mgr.a_bp_ver_customized,bCustomized);
		m_doc_data.GetAttr(m_pLockInfo,m_doc->m_api.m_bp_mgr.a_bp_ver_optional,bOptional);
	}

#ifdef _UNICODE  // Эти иконки используем только для сербов
	if(bOptional) SetItemImage(ICO_EFF_EFF, IDX_IL_TREE_EFF);
	else SetItemImage(ICO_EFF_NO, IDX_IL_TREE_EFF);

	if(bCustomized) SetItemImage(ICO_SUBTYPE_UNIFIED+1, IDX_IL_TREE_ITEM_SUBTYPE);
	else SetItemImage(ICO_SUBTYPE_UNIFIED, IDX_IL_TREE_ITEM_SUBTYPE);
#endif


	if(m_doc->m_tab_view->m_item_old==this) m_doc->ChangeItem(this);
	return true;
}
//****************************************************************
bool CaplBPTreeItem::RefreshAllThisBPItem()
{
	int i;
	for(i=0;i<m_doc->m_items.Size;i++)
	{
		if(m_doc->m_items[i]!=this)
		{
			if(m_doc->m_items[i]->m_type==m_type)
			{
				CaplBPTreeItem *item=(CaplBPTreeItem*)m_doc->m_items[i];
				if(item->m_inst==m_inst && !item->m_rev) 
					item->RefreshItem();
			}
		}
	}
	RefreshItem();
	return true;
}
//****************************************************************
void CaplBPTreeItem::ShowProperties()
{
	if(m_doc==0) return;
	if(m_inst==0) return;
	
	CaplInstance *bp=m_inst;
	bool is_ok;
	if(m_rev) bp=m_rev;
	if(m_doc->m_api.m_bp_mgr.ShowBPProperties(bp,m_rel,&is_ok))	
	{
		if(!m_rev && is_ok)
		{
			bool has_version=m_has_version;
			if(m_fictive_item==0)
			{
				Expand(1); 
				MyExpand();
			}
			m_has_version=has_version;
		}
	}
	if(is_ok)
	{
		RefreshAllThisBPItem();	
	}

}
//****************************************************************
bool CaplBPTreeItem::ExpandTree(const aplExtent &extTree, int index)
{
	//if(bCollapse) Expand(TVE_COLLAPSE);

	if(index > extTree.GetSize()) return true;

	// Expand(TVE_EXPAND); так нельзя, т.к. создаются подэлементы, но дерево не раскрыватся 
	MyExpand();
	//m_tree->Select(m_item,TVGN_FIRSTVISIBLE);
	m_tree->Select(m_item,TVGN_CARET);
	m_tree->Select(m_item,TVGN_DROPHILITE);

	CaplInstance *nextBp=extTree[index];

	CaplBPTreeItem *nextBpTreeItem=0;

	HTREEITEM hChildItem = m_tree->GetChildItem(m_item);

	while (hChildItem != NULL)
	{
		CaplTreeItem *item=(CaplTreeItem*)m_tree->GetItemData(hChildItem);
		if(item!=0)
		{
			if(item->m_type==m_type)
			{

				CaplBPTreeItem *bpItem=(CaplBPTreeItem*)item;
				if(bpItem->m_inst==nextBp)
				{
					nextBpTreeItem=bpItem;
					break;
				}
			}
		}
		hChildItem = m_tree->GetNextItem(hChildItem, TVGN_NEXT);
	}

	if(0!=nextBpTreeItem) return nextBpTreeItem->ExpandTree(extTree, index+1);
	return true;
}
//****************************************************************
bool CaplBPTreeItem::Expand(UINT action)
{
	if(action==TVE_EXPAND)
	{
		StartBusy();
		m_doc->m_api.m_bp_mgr.LoadBPInfo(m_inst);
		CaplInstance *ver=0;
		if(m_doc->m_api.m_bp_mgr.m_bUseVersions)
		{
			if(m_rev) 
				ver=m_rev;
			else
				ver=m_doc->m_api.m_bp_mgr.CheckMyLock(m_inst,false);
		}
		CaplAggr aggr0;
		if(ver==0) m_doc_data.GetAttr(m_inst,m_doc->m_api.m_bp_mgr.a_bp_elements,aggr0);
		else m_doc_data.GetAttr(ver,m_doc->m_api.m_bp_mgr.a_bp_ver_elements,aggr0);

		if(m_expanded) return true;
		if(m_fictive_item!=0)
		{
			m_tree->DeleteItem(m_fictive_item);
			m_fictive_item=0;
		}
		if(m_hasSubItem)Expand(1);
		if(m_ShowContentsOnExpand)
		{
			CaplInstance *inst;
			int i;
			aplExtent ext;

			for(i=0;i<aggr0.GetSize();i++)
			{

				aggr0.GetByIndex(i,inst);
				if(inst==0) continue;
				if(inst->GetType()==0) continue;
				ext.Add(inst);
			}
			m_doc->m_api.m_bp_mgr.LoadBPInfo(ext);

			for(i=0;i<aggr0.GetSize();i++)
			{
				aggr0.GetByIndex(i,inst);
				if(inst==0) continue;
				if(inst->GetAccessmode()>aplRO) continue;
				if(inst->GetType()==0) continue;

				CaplBPTreeItem *new_item=0;
				InsertInstInTree(inst,m_item,m_doc,m_tree,m_sub_bps,0,(CaplTreeItem **)(&new_item));
				if(new_item!=0)
				{
					new_item->m_index=m_sub_bps.Size;
					new_item->m_par_bp=m_inst;
					new_item->RefreshItem();
				}

			}
		}
		bool old = m_bShowNoFoundMessage;
		m_bShowNoFoundMessage = false;
		m_ExecMyExpand = false;
		if(m_doc->m_auto_expand_items.m_showintree_bp&APL_SHOW_DOC)
			ShowAllDocs(false,false);
		if(m_doc->m_auto_expand_items.m_showintree_bp&APL_SHOW_CHARACT)
			ShowAllCharacteristic(false);
		if(m_doc->m_auto_expand_items.m_showintree_bp&APL_SHOW_APPROVAL)
			ShowAllApproval(false);
		if(m_doc->m_auto_expand_items.m_showintree_bp&APL_SHOW_VER)
			ShowAllVersion(false);
		if(m_doc->m_auto_expand_items.m_showintree_bp&APL_SHOW_BPINST)
			ShowAllBPInst();
		if(m_doc->m_auto_expand_items.m_showintree_bp&APL_SHOW_RES)
			ShowAllResources(false);
		m_bShowNoFoundMessage = old;
		m_ExecMyExpand = true;

		StopBusy();
	}
	else if(action==TVE_COLLAPSE)
	{
		if(m_rev) return true;
		CollapseItem(true);

		m_all_res.Clear();
		m_sub_bps.Clear();
		m_parent_bps.Clear();
		m_has_version=false;
		m_tree->Expand(m_item,TVE_COLLAPSE);
	}
	return true;
}

//****************************************************************
bool CaplBPTreeItem::TrackPopupMenu(CWnd *wnd, CPoint &point, UINT view_mode)
{
	if(m_inst==0) return false;
	if(m_doc==0) return false;
	CMenu menu;  gSetPsmResourceHandle();
	VERIFY(menu.LoadMenu(IDR_TREE_CONTEXT_MENU));
	CaplMenu::Install(wnd);//	VERIFY(CaplMenu::Install(wnd, ePopupMenu ));
    CMenu* pPopup = menu.GetSubMenu(INDEX_ACTION_MENU);
    ASSERT(pPopup != NULL);
	if(pPopup==0) return false;
	
	AppendAddIn((CMenu*)pPopup);
	UpdateMenu((CMenu**)&pPopup, view_mode);
//---------------------------------Состояния-----------------------------------

	aplExtent instances;
	GetAccessedInstances(instances);
	if(m_doc_data.IsKindOf(instances[0],m_doc->m_api.m_bp_mgr.e_bp))
	{
		CStringArray states;
		CString val = m_doc->m_api.m_doc_mgr.GetPossibleWFState(m_inst,states);
			
			if(val==_T("approved"))
			{
				pPopup->EnableMenuItem(ID_REVISION_MAKE_ACTIVE,MF_BYCOMMAND|MF_GRAYED);
				//pPopup->EnableMenuItem(ID_CREATE_APPROVAL, MF_BYCOMMAND | MF_GRAYED);
				pPopup->EnableMenuItem(ID_CREATE_DOC, MF_BYCOMMAND | MF_GRAYED);
//				pPopup->EnableMenuItem(ID_CREATE_CHARACTERISTIC, MF_BYCOMMAND | MF_GRAYED);
//				pPopup->EnableMenuItem(ID_CREATE_CHARACTERISTIC_GROUP, MF_BYCOMMAND | MF_GRAYED);
//				pPopup->EnableMenuItem(ID_CREATE_CHARACTERISTIC, MF_BYCOMMAND | MF_GRAYED);
//				pPopup->EnableMenuItem(ID_CREATE_BP, MF_BYCOMMAND | MF_GRAYED);
			}
			else if(val==_T("approving") || val==_T("approving_change"))
			{
				pPopup->EnableMenuItem(ID_REVISION_MAKE_ACTIVE,MF_BYCOMMAND|MF_GRAYED);
				pPopup->EnableMenuItem(ID_CREATE_DOC, MF_BYCOMMAND | MF_GRAYED);
//				pPopup->EnableMenuItem(ID_CREATE_CHARACTERISTIC, MF_BYCOMMAND | MF_GRAYED);
//				pPopup->EnableMenuItem(ID_CREATE_CHARACTERISTIC_GROUP, MF_BYCOMMAND | MF_GRAYED);
//				pPopup->EnableMenuItem(ID_CREATE_CHARACTERISTIC, MF_BYCOMMAND | MF_GRAYED);
//				pPopup->EnableMenuItem(ID_CREATE_BP, MF_BYCOMMAND | MF_GRAYED);
			}
			else if(val==_T("canceled"))
			{
				pPopup->EnableMenuItem(ID_REVISION_MAKE_ACTIVE,MF_BYCOMMAND|MF_GRAYED);
				pPopup->EnableMenuItem(ID_ITEM_CHECK_IN, MF_BYCOMMAND | MF_GRAYED);
				pPopup->EnableMenuItem(ID_ITEM_UNDO_CHECK_OUT, MF_BYCOMMAND | MF_GRAYED);
				pPopup->EnableMenuItem(ID_EDIT_DOCUMENT, MF_BYCOMMAND | MF_GRAYED);
				pPopup->EnableMenuItem(ID_EDIT_DOCUMENT_AS, MF_BYCOMMAND | MF_GRAYED);
				pPopup->EnableMenuItem(ID_ITEM_CHECK_OUT, MF_BYCOMMAND | MF_GRAYED);
				pPopup->EnableMenuItem(ID_DELETE_DOCUMENT_REL, MF_BYCOMMAND | MF_GRAYED);
				pPopup->EnableMenuItem(ID_CREATE_APPROVAL, MF_BYCOMMAND | MF_GRAYED);
				pPopup->EnableMenuItem(ID_CREATE_DOC, MF_BYCOMMAND | MF_GRAYED);
				pPopup->EnableMenuItem(ID_CREATE_CHARACTERISTIC, MF_BYCOMMAND | MF_GRAYED);
				pPopup->EnableMenuItem(ID_CREATE_CHARACTERISTIC_GROUP, MF_BYCOMMAND | MF_GRAYED);
				pPopup->EnableMenuItem(ID_CREATE_CHARACTERISTIC, MF_BYCOMMAND | MF_GRAYED);
				pPopup->EnableMenuItem(ID_CREATE_BP, MF_BYCOMMAND | MF_GRAYED);
				pPopup->EnableMenuItem(ID_CREATE_RESOURCE, MF_BYCOMMAND | MF_GRAYED);
			}
	}
	else
	{
// 		pPopup->DeleteMenu(4,MF_BYPOSITION); при удалении сепаратора падает - причем только в релизе, и видимо только под 2008 студией...
// 		pPopup->DeleteMenu(4,MF_BYPOSITION);
 		pPopup->EnableMenuItem(4, MF_BYPOSITION | MF_GRAYED);
 		pPopup->EnableMenuItem(ID_EXPORT_ITEM, MF_BYPOSITION | MF_GRAYED);
	}
//---------------------------------Состояния-----------------------------------

	if(m_folder==0)pPopup->EnableMenuItem(ID_REMOVE_FROM_FOLDER, MF_BYCOMMAND | MF_GRAYED);
	if(m_classifier==0){pPopup->EnableMenuItem(ID_REMOVE_FROM_CLASSIFIER, MF_BYCOMMAND | MF_GRAYED);}
	if(m_rel==0&& m_par_bp==0 && m_project==0)pPopup->EnableMenuItem(ID_DELETE_DOCUMENT_REL, MF_BYCOMMAND | MF_GRAYED);
	if(m_rev)pPopup->EnableMenuItem(ID_CREATE_BP, MF_BYCOMMAND | MF_GRAYED);
	if(m_rev)pPopup->EnableMenuItem(ID_SHOW_ALL_BP_INST, MF_BYCOMMAND | MF_GRAYED);
	if(m_rev)pPopup->EnableMenuItem(ID_SHOW_BP_CHANGES, MF_BYCOMMAND | MF_GRAYED);
	if(m_rev)pPopup->EnableMenuItem(ID_CREATE_BP_INST, MF_BYCOMMAND | MF_GRAYED);
	if(m_rev)pPopup->EnableMenuItem(ID_CREATE_DOC, MF_BYCOMMAND | MF_GRAYED);
	if(m_rev)pPopup->EnableMenuItem(ID_CREATE_RESOURCE, MF_BYCOMMAND | MF_GRAYED);
	if(m_rev)pPopup->EnableMenuItem(ID_CREATE_CHARACTERISTIC, MF_BYCOMMAND | MF_GRAYED);
	if(m_rev)pPopup->EnableMenuItem(ID_CREATE_CHARACTERISTIC_GROUP, MF_BYCOMMAND | MF_GRAYED);
	if(m_rev)pPopup->EnableMenuItem(ID_SHOW_ALL_VERSION, MF_BYCOMMAND | MF_GRAYED);
	if(m_rev)pPopup->EnableMenuItem(ID_SHOW_ALL_DOCS, MF_BYCOMMAND | MF_GRAYED);
	if(m_rev)pPopup->EnableMenuItem(ID_SHOW_PROJECTS, MF_BYCOMMAND | MF_GRAYED);
	if(!m_rev)pPopup->EnableMenuItem(ID_REVISION_MAKE_ACTIVE, MF_BYCOMMAND | MF_GRAYED);
	if(!m_doc->m_api.m_bp_mgr.m_bUseVersions)
		pPopup->RemoveMenu(ID_ITEM_CHECK_OUT, MF_BYCOMMAND);

	if(m_rev && !m_parent_bp_item)
	{
		pPopup->RemoveMenu(ID_ITEM_CHECK_IN, MF_BYCOMMAND);
		pPopup->RemoveMenu(ID_ITEM_UNDO_CHECK_OUT, MF_BYCOMMAND);
		pPopup->RemoveMenu(ID_ITEM_CHECK_OUT, MF_BYCOMMAND);
	}
	else
	{
		if(m_rev || !m_doc->m_api.m_bp_mgr.m_bUseVersions)
		{
			pPopup->RemoveMenu(ID_ITEM_CHECK_IN, MF_BYCOMMAND);
			pPopup->RemoveMenu(ID_ITEM_UNDO_CHECK_OUT, MF_BYCOMMAND);
		}
		if (m_pLockInfo != NULL)
		{
			pPopup->RemoveMenu(ID_ITEM_CHECK_OUT, MF_BYCOMMAND);
			pPopup->EnableMenuItem(ID_REVISION_MAKE_ACTIVE, MF_BYCOMMAND | MF_GRAYED);
		}
		else
		{
			pPopup->RemoveMenu(ID_ITEM_CHECK_IN, MF_BYCOMMAND);
			pPopup->RemoveMenu(ID_ITEM_UNDO_CHECK_OUT, MF_BYCOMMAND);
			if(m_inst->GetAccessmode()>aplRW) pPopup->EnableMenuItem(ID_REVISION_MAKE_ACTIVE, MF_BYCOMMAND | MF_GRAYED);
		}
	}

	if(0!=m_rev || m_inst->GetAccessmode()>=aplRO)
	{
		pPopup->EnableMenuItem(ID_MAKE_UNIFIED_RECURSIVE, MF_BYCOMMAND | MF_GRAYED);
		pPopup->EnableMenuItem(ID_MAKE_CUSTOMIZED_RECURSIVE, MF_BYCOMMAND | MF_GRAYED);
	}

	pPopup->EnableMenuItem(ID_CONVERT_TO_CUSTOMIZED_COPY, MF_BYCOMMAND | MF_GRAYED);
	if(0==m_rev && 0==m_rel && 0==m_pLockInfo && m_inst->GetAccessmode()<aplRO)
	{
		bool bCustomized=false;
		m_doc->m_api.m_data.GetAttr(m_inst, m_doc->m_api.m_bp_mgr.a_bp_customized, bCustomized);
		if(!bCustomized) pPopup->EnableMenuItem(ID_CONVERT_TO_CUSTOMIZED_COPY, MF_BYCOMMAND | MF_ENABLED);
	}

	BOOL res=pPopup->TrackPopupMenu(TPM_LEFTALIGN|
		TPM_RIGHTBUTTON|TPM_RETURNCMD,point.x, point.y,wnd);
	switch(res)
	{
	case ID_SHOW_CONTAINED_FOLDER:
		ShowContainedFolder(m_inst);
		break;
	case ID_SHOW_CONTAINED_CLASSIFIER:
		ShowContainedClassifier(m_inst);
		break;
		
	case ID_SHOW_BP_CHANGES:m_doc->m_api.m_bp_mgr.ShowBPChanges(m_inst);break;
	case ID_SHOW_ALL_VERSION: ShowAllVersion();break;
	case ID_OPEN_ITEM_IN_NEW_WINDOW:
		m_doc->OpenInstanceInNewWindow(m_inst);
		//else if(m_inst!=0) m_doc->OpenInstanceInNewWindow(m_inst);
		break;
	case ID_REMOVE_FROM_FOLDER:
		if(m_folder!=0)
		{
			if(m_doc->m_api.m_folder_mgr.RemoveFromFolder(m_folder,m_inst))
				m_doc->m_items.Remove(m_doc->m_items.Find(this));
		}
		break;
	case ID_REMOVE_FROM_CLASSIFIER:
		if(m_classifier!=0)
		{
			if(m_classifier->GetAccessmode()>aplRW)	{AfxMessageBox(ID_NO_ACCESS_RIGHT,MB_OK|MB_ICONSTOP); return true;}
			if(m_doc->m_api.m_classifier_mgr.DeleteClassifierAssociation(m_inst,m_classifier))
				m_doc->m_items.Remove(m_doc->m_items.Find(this));
		}
		break;
	case ID_DELETE_DOCUMENT_REL:RemoveRelation();break;
	case ID_DELETE:
		{
			if(m_rev)
			{
				if(m_rev->GetAccessmode()>aplOWN)
				{
					AfxMessageBox(ID_NO_ACCESS_RIGHT,MB_OK|MB_ICONSTOP);
					return true;
				}
				if(AfxMessageBox( APL_T("Вы действительно хотите удалить версию бизнес-процесса ?"),MB_YESNO)==IDYES)
				{
					StartBusy();
					if(m_doc->m_api.m_bp_mgr.DeleteBP(m_rev))
					{
						for(int i=0;i<m_doc->m_items.Size;i++)
						{
							if(m_doc->m_items[i]!=this)
							{
								if(m_doc->m_items[i]->m_type==m_type)
								{
									CaplBPTreeItem *item1=
										(CaplBPTreeItem*)m_doc->m_items[i];
									{
										if(item1->m_inst==m_inst && item1->m_rev==m_rev)
										{m_doc->m_items.Remove(i); i--;}
									}
								}
							}
						}
						m_doc->m_items.Remove(m_doc->m_items.Find(this));
					}
					StopBusy();
				}
			}
			else if(m_inst)
			{	
				if(m_inst->GetAccessmode()>aplOWN)
				{
					AfxMessageBox(ID_NO_ACCESS_RIGHT,MB_OK|MB_ICONSTOP);
					return true;
				}
				CString state;
				m_doc->m_api.m_data.GetAttr(m_inst,m_doc->m_api.m_bp_mgr.a_bp_state,state);
				if( ! ((state==_T("")) || (state==_T("working")) || (state==_T("canceled")) ))
				{
					CString buf;
					buf.Format(APL_T("Бизнес-процесс находится в состоянии \"%s\" !\n\nЕго нельзя удалить!"), LPCTSTR(m_doc->m_api.m_bp_mgr.GetWFStateName(state)));
					AfxMessageBox(buf,MB_OK|MB_ICONSTOP);
					return true;
				}
				if(AfxMessageBox( APL_T("Вы действительно хотите удалить описание бизнес-процесса ?"),MB_YESNO)==IDYES)
				{
					StartBusy();
					if(m_doc->m_api.m_bp_mgr.DeleteBP(m_inst))
					{
						for(int i=0;i<m_doc->m_items.Size;i++)
						{
							if(m_doc->m_items[i]!=this)
							{
								if(m_doc->m_items[i]->m_type==m_type)
								{
									CaplBPTreeItem *item1=
										(CaplBPTreeItem*)m_doc->m_items[i];
									{
										if(item1->m_inst==m_inst)
										{m_doc->m_items.Remove(i); i--;}
									}
								}
							}
						}
						m_doc->m_items.Remove(m_doc->m_items.Find(this));
					}
					StopBusy();
				}
			}
		}
		break;
	case ID_CREATE_BP: if(!m_rev) CreateBP(m_inst);break;
	case ID_CREATE_BP_INST: if(!m_rev) CreateBPInst();break;
	case ID_CREATE_RESOURCE:if(!m_rev) CreateBPResource();break;
	case ID_SHOW_ALL_BP_RESOURCE: ShowAllResources(); break;
	case ID_SHOW_ALL_BP_INST: ShowAllBPInst(); break;
	
	case ID_PRODUCT_WHERE_USED:
		{
			if(m_inst->GetAccessmode()>aplRO){AfxMessageBox(ID_NO_ACCESS_RIGHT,MB_OK|MB_ICONSTOP); return true;}
			aplExtent ext0;
			m_doc->m_api.m_bp_mgr.WhereUsedBP(m_inst,ext0);
			for(int i=0;i<ext0.Size;i++)
			{
				CaplTreeItem *new_item=0;
				InsertInstInTree(ext0[i],m_item,m_doc,m_tree,m_parent_bps,0,&new_item);
				if(0!=new_item)
				{
					((CaplBPTreeItem*)new_item)->m_bWhereUsed=true;
					((CaplBPTreeItem*)new_item)->RefreshItem();
				}
			}
			ShowAllBaseObjects();
			MyExpand();
		}
		break;
	case ID_CREATE_CHARACTERISTIC: if(!m_rev) CreateCharacteristic(); break;
	case ID_CREATE_CHARACTERISTIC_GROUP: if(!m_rev) CreateCharacteristicGroup();break;
//	case ID_FREZEE_ALL_PRODUCT_CONTENTS:
//		{
//			aplExtent ext; ext.Add(m_inst);
//			GetAllSubBP(m_inst,ext);
//			if(ext.Size>0)
//				m_doc_data.NET_SetInstancesAccess(&ext,(CaplInstance *)0,
//					(aplAccessModeType)-1);		
//		}
//		break;
	case ID_ITEM_CHECK_IN:CheckIn();break;
	case ID_ITEM_CHECK_OUT:CheckOut();break;
	case ID_ITEM_UNDO_CHECK_OUT:UndoCheckOut();break;

	case ID_REVISION_MAKE_ACTIVE:
		{
			if(m_doc->m_api.m_bp_mgr.MakeBPVersionActive(m_rev))
			{
				if(m_parent_bp_item) 
				{
					CaplBPTreeItem *parent_item=m_parent_bp_item;
					bool has_version=parent_item->m_has_version;
					parent_item->Expand(1);
					parent_item->Expand(2);
					parent_item->m_has_version=has_version;
					parent_item->RefreshAllThisBPItem();
				}
			}
		}
		break;
	case ID_SUBSCRIPTION:
			m_doc->m_api.m_message_mgr.EditItemSubscribeList(m_inst);
		break;
	case ID_WFS_CHANGE:
		if(m_doc->m_api.m_doc_mgr.ChangeWFState(m_inst,_T("")))
		{
			m_doc->OnRefreshAll();
		}
		break;
	case ID_WFS_HISTORY: m_doc->m_api.m_doc_mgr.ShowWFStateHistory(m_inst);
		break;
	case ID_SHOW_PROJECTS: ShowAllProjects(m_inst); break;

	case ID_EXPORT_ITEM:
		if(0!=m_inst) m_doc->ExportItem(m_inst);
		break;

	case ID_MAKE_UNIFIED_RECURSIVE:
			if(m_inst->GetAccessmode()>aplRW){AfxMessageBox(ID_NO_ACCESS_RIGHT,MB_OK|MB_ICONSTOP); return true;}
			if(IDYES!=AfxMessageBox( APL_T("Вы действительно хотите сделать бизнес-процесс и все в него входящие унифицированным ?"),MB_YESNO)) return false;
			if(m_doc->m_api.m_bp_mgr.SetCustomizedRecursive(m_inst,false))
			{
				m_doc->RefreshAllItemsByType(m_type);
			}
			return true;
		break;
	case ID_MAKE_CUSTOMIZED_RECURSIVE:
		if(m_inst->GetAccessmode()>aplRW){AfxMessageBox(ID_NO_ACCESS_RIGHT,MB_OK|MB_ICONSTOP); return true;}
		if(IDYES!=AfxMessageBox( APL_T("Вы действительно хотите сделать бизнес-процесс и все в него входящие индивидуальными ?"),MB_YESNO)) return false;
		if(m_doc->m_api.m_bp_mgr.SetCustomizedRecursive(m_inst,true))
		{
			m_doc->RefreshAllItemsByType(m_type);
		}
		return true;
		break;

	case ID_CONVERT_TO_CUSTOMIZED_COPY:
		if(IDYES!=AfxMessageBox( APL_T("Вы действительно хотите заменить бизнес-процесс на индивидуальную копию ?"),MB_YESNO)) return false;
		ConvertToCustomizedCopy();
		break;

	default: PrepareContextMenu(res); 
	}
	return true;
}
//*****************************************************************************
void CaplBPTreeItem::ShowAllBaseObjects()
{
	if(m_doc==0) return;
	if(m_inst==0) return;
	if(m_inst->GetType()==0) return;
		
	int i;//,j;
	aplExtent out_ext,ext;
	CaplInstance *inst;
	if(m_inst->GetId()!=0)
	{
		// Чтение из базы
		StartBusy();	
		if(m_doc_data.IsConnected())
		{
			CaplLoadData ld(&(m_doc->m_api.m_data),DEF_SOURCE);
			CaplLoadData ld_pdf(&(m_doc->m_api.m_data),DEF_SOURCE), ld_prd(&(m_doc->m_api.m_data),DEF_SOURCE);
			bool load_pdf=false, load_prd=false;

			// ссылка
			i=ld.AddQuery(_T('b'), m_inst->GetId(), m_doc->m_api.m_bp_mgr.e_bp_ref,m_doc->m_api.m_bp_mgr.a_bp_ref_process, true);
			  ld.AddQuery(_T('d'), i, 0,m_doc->m_api.m_bp_mgr.a_bp_ref_process, true);
			  ld.AddQuery(_T('d'), i, 0,m_doc->m_api.m_bp_mgr.a_bp_ref_frames_of_reference, true);
			i=ld.AddQuery(_T('d'), i, 0,m_doc->m_api.m_bp_mgr.a_bp_ref_item, true);

		  if (!ld.LoadEx())
				AfxMessageBox(IDS_ERROR_LOAD_DATA_APL,MB_OK|MB_ICONSTOP);
			
			m_doc_data.GetEntityExtent(m_doc->m_api.m_bp_mgr.e_bp_ref,out_ext);

		
			for(i=0;i<out_ext.Size;i++)
			{
				m_doc_data.GetAttr(out_ext[i],m_doc->m_api.m_bp_mgr.a_bp_ref_process,inst);
				if(inst!=m_inst) continue;
				if(m_doc->m_cur_context!=0)
					if(!m_doc->m_api.m_bp_mgr.IsItemInContext(out_ext[i],m_doc->m_cur_context,m_doc->m_api.m_bp_mgr.a_bp_ref_frames_of_reference)) continue;
				m_doc_data.GetAttr(out_ext[i],m_doc->m_api.m_bp_mgr.a_bp_ref_item,inst);
				
				ext.Add(inst);

				/* Заменено на LoadExtentInfo

				if(m_doc_data.IsKindOf(inst,m_doc->m_api.m_prd_mgr.e_prd))
				{
					// Изделие
					ld_prd.AddQuery(0,inst);
					load_prd=true;
				}
				else if(m_doc_data.IsKindOf(inst,m_doc->m_api.m_prd_mgr.e_pdf))
				{
					// Версия изделия
					ld_pdf.AddQuery(0,inst);
					load_pdf=true;
				}*/
			}
			
			
			/* Заменено на LoadExtentInfo
			// Изделия
			if(load_prd==true)
			{
				i=0;
				ld_prd.AddQuery(_T('d'), i, 0, m_doc->m_api.m_prd_mgr.a_prd_id, true);
				ld_prd.AddQuery(_T('d'), i, 0, m_doc->m_api.m_prd_mgr.a_prd_name, true);
				ld_prd.AddQuery(_T('d'), i, 0, m_doc->m_api.m_prd_mgr.a_prd_descr, true);
				if (!ld_prd.LoadEx())
					AfxMessageBox(IDS_ERROR_LOAD_DATA_APL,MB_OK|MB_ICONSTOP);
			}
			// Версии изделия
			if(load_pdf==true)
			{
				i=0;
					ld_pdf.AddQuery(_T('d'), i, 0, m_doc->m_api.m_prd_mgr.a_pdf_descr, true);
					ld_pdf.AddQuery(_T('d'), i, 0, m_doc->m_api.m_prd_mgr.a_apl_pdf_type, true);
					ld_pdf.AddQuery(_T('d'), i, 0, m_doc->m_api.m_prd_mgr.a_apl_pdf_standard, true);
				j=	ld_pdf.AddQuery(_T('d'), i, 0, m_doc->m_api.m_prd_mgr.a_pdf_prd, true);
					ld_pdf.AddQuery(_T('d'), j, 0, m_doc->m_api.m_prd_mgr.a_prd_id, true);
					ld_pdf.AddQuery(_T('d'), j, 0, m_doc->m_api.m_prd_mgr.a_prd_name, true);
					ld_pdf.AddQuery(_T('d'), j, 0, m_doc->m_api.m_prd_mgr.a_prd_descr, true);
				if (!ld_pdf.LoadEx())
					AfxMessageBox(IDS_ERROR_LOAD_DATA_APL,MB_OK|MB_ICONSTOP);
			}*/
		}
		StopBusy();
	}
	// Поиск связанных объектов
	m_doc_data.GetEntityExtent(m_doc->m_api.m_bp_mgr.e_apl_bp_inst,out_ext);
	for(i=0;i<out_ext.Size;i++)
	{
		m_doc_data.GetAttr(out_ext[i],m_doc->m_api.m_bp_mgr.a_bp_ref_process,inst);
		if(inst!=m_inst) continue;
		if(m_doc->m_cur_context!=0)
			if(!m_doc->m_api.m_bp_mgr.IsItemInContext(out_ext[i],m_doc->m_cur_context,m_doc->m_api.m_bp_mgr.a_bp_ref_frames_of_reference)) continue;
		m_doc_data.GetAttr(out_ext[i],m_doc->m_api.m_bp_mgr.a_bp_ref_item,inst);
		ext.Add(inst);
	}

	m_doc->m_api.LoadExtentInfo(ext);

	// Создание item-ов для связанных объектов
	for(i=0;i<ext.Size;i++)
	{
		InsertInstInTree(ext[i],m_item,m_doc,m_tree,m_parent_bps,m_inst);
	}
	//Проекты
	ShowAllProjects(m_inst,false);

	if(m_ExecMyExpand)
		MyExpand(false);
}
//****************************************************************
void CaplBPTreeItem::ShowAllResources(bool showMsg)
{
	if(m_rev)
	{
		if(m_rev->GetAccessmode()>aplRO){AfxMessageBox(ID_NO_ACCESS_RIGHT,MB_OK|MB_ICONSTOP); return;}
	}
	else
	{
		CHECK_INSTANCE_ITEM(m_inst);
		if(m_inst->GetAccessmode()>aplRO){AfxMessageBox(ID_NO_ACCESS_RIGHT,MB_OK|MB_ICONSTOP); return;}
	}
	aplExtent ext;
	StartBusy();
	if(m_doc->m_api.m_bp_mgr.m_bUseVersions && m_rev)
	{
		m_doc->m_api.m_bp_mgr.LoadAllBPResources(m_rev,ext);
	}
	else
	{
		m_doc->m_api.m_bp_mgr.LoadAllBPResources(m_inst,ext);
	}
	StopBusy();

	int i;
	if(!ext.Size)
	{
		if(m_bShowNoFoundMessage && showMsg) AfxMessageBox( APL_T("Новые ресурсы не найдены!"));
		return;
	}
	
	for(i=0;i<ext.Size;i++)
	{
		if(m_all_res.Find(ext[i])>=0) continue;
		CaplBPResourceTreeItem *item= new CaplBPResourceTreeItem(m_tree,m_doc,ext[i]);
		m_all_res.Add(ext[i]);
		item->CreateTreeItem(m_item);
		item->m_bp_rev=m_rev;
		item->RefreshItem();
	}
	if(m_ExecMyExpand)
		MyExpand(false);
}
//****************************************************************
void CaplBPTreeItem::GetAccessedInstances(aplExtent &ext)
{
	ext.Clear();
	if(m_rev){if(m_rev->GetType()!=0)ext.Add(m_rev);}
	else if(m_inst!=0){if(m_inst->GetType()!=0)ext.Add(m_inst);}
	if(m_addInCall && m_rel!=0){if(m_rel->GetType()!=0) ext.Add(m_rel);}
}
//****************************************************************
bool CaplBPTreeItem::ShowInListCtrl(CListCtrl *list)
{
	if(list==0) return false;
	CHECK_SHOW_LIST_CTRL(m_inst);
	if(m_doc==0)return false;
	if(m_rev) 
	{
		if(m_rev->GetType()==0)return false;
		if(m_rev->GetAccessmode()>aplRO)return false;
	}
	else if(m_inst->GetAccessmode()>aplRO)return false;

	int i;
	CString buf1;
	CString buf[9];
	int num[9];
	CaplInstance *inst;

	CaplInstance *ver=0;
	if(m_doc->m_api.m_bp_mgr.m_bUseVersions)
	{
		if(m_rev) 
		{
			m_doc->m_api.m_bp_mgr.LoadBPInfo(m_rev);
			ver=m_rev;
		}
		else 
			ver=m_doc->m_api.m_bp_mgr.CheckMyLock(m_inst,false);
	}

	num[0]=list->InsertItem(0, APL_T("Обозначение:"));
	num[1]=list->InsertItem(1, APL_T("Код:"));
	num[2]=list->InsertItem(2, APL_T("Наименование:"));
	num[3]=list->InsertItem(3, APL_T("Описание:"));
	num[4]=list->InsertItem(4, APL_T("Тип:"));

	int index =list->InsertItem(list->GetItemCount(),_T(""));
	index =list->InsertItem(list->GetItemCount(), APL_T("Состояние:"));
	CString state;
	m_doc_data.GetAttr(m_inst,m_doc->m_api.m_bp_mgr.a_bp_state,state);
	list->SetItemText(index,1,m_doc->m_api.m_bp_mgr.GetWFStateName(state));
	list->InsertItem(list->GetItemCount(),_T(""));

	if(ver)
		num[5]=list->InsertItem(list->GetItemCount(),_T(""));
	else
		num[5]=list->InsertItem(list->GetItemCount(), APL_T("Владелец:"));
		
	num[6]=list->InsertItem(list->GetItemCount(), APL_T("Метка:"));
	if(m_rel)
		num[7]=list->InsertItem(list->GetItemCount(), APL_T("Контексты:"));
	else
		num[7]=list->InsertItem(list->GetItemCount(),_T(""));
	buf1= APL_T("Доступ:");
	if(m_rev || ver) buf1= APL_T("Доступ к бизнес-процессу:");
	num[8]=list->InsertItem(list->GetItemCount(),buf1);
	
	if(ver)
	{
		m_doc_data.GetAttrBN(ver,S::id,buf[0]);
		m_doc_data.GetAttrBN(ver,S::code,buf[1]);
		m_doc_data.GetAttrBN(ver,S::name,buf[2]);
		m_doc_data.GetAttrBN(ver,S::description,buf[3]);
		m_doc_data.GetAttr(ver,m_doc->m_api.m_bp_mgr.a_bp_ver_type,inst);
		buf[4].Empty();
		if(inst) m_doc_data.GetAttr(inst,m_doc->m_api.m_bp_mgr.a_bp_type_name,buf[4]);
		buf[5].Empty();
		m_doc_data.GetAttr(ver,m_doc->m_api.m_bp_mgr.a_bp_ver_label,buf[6]);
		buf[7].Empty();
		if(m_rel && m_rel->GetType())
		{
			aplExtent m_bp_ref_contexts;
			m_doc_data.GetAttr(m_rel,m_doc->m_api.m_bp_mgr.a_bp_ref_frames_of_reference,m_bp_ref_contexts);
			if(m_bp_ref_contexts.GetSize()>0)
				m_doc->m_api.m_bp_mgr.PrintItemContextInString(m_bp_ref_contexts,buf[7]);
			else buf[7]=CaplTranslate::Translate(S::all_context());
		}
	}
	else
	{
		m_doc_data.GetAttrBN(m_inst,S::id,buf[0]);
		m_doc_data.GetAttrBN(m_inst,S::code,buf[1]);
		m_doc_data.GetAttrBN(m_inst,S::name,buf[2]);
		m_doc_data.GetAttrBN(m_inst,S::description,buf[3]);
		m_doc_data.GetAttr(m_inst,m_doc->m_api.m_bp_mgr.a_bp_type,inst);
		buf[4].Empty();
		if(inst) m_doc_data.GetAttr(inst,m_doc->m_api.m_bp_mgr.a_bp_type_name,buf[4]);
		m_doc_data.GetAttr(m_inst,m_doc->m_api.m_bp_mgr.a_bp_parent,inst);
		buf[5].Empty();
		if(inst) m_doc_data.GetAttr(inst,m_doc->m_api.m_bp_mgr.a_bp_id,buf[5]);
		m_doc_data.GetAttr(m_inst,m_doc->m_api.m_bp_mgr.a_bp_label,buf[6]);
		buf[7].Empty();
		if(m_rel && m_rel->GetType())
		{
			aplExtent m_bp_ref_contexts;
			m_doc_data.GetAttr(m_rel,m_doc->m_api.m_bp_mgr.a_bp_ref_frames_of_reference,m_bp_ref_contexts);
			if(m_bp_ref_contexts.GetSize()>0)
				m_doc->m_api.m_bp_mgr.PrintItemContextInString(m_bp_ref_contexts,buf[7]);
			else buf[7]=CaplTranslate::Translate(S::all_context());
		}
	}
	GetAccessName(m_inst,buf[8]);
	for(i=0;i<9;i++)
		list->SetItemText(num[i],1,buf[i]);

	
	if(m_rev!=0)
	{
		i=list->InsertItem(list->GetItemCount(), APL_T("Доступ к версии:"));
		GetAccessName(m_rev,buf1);
		list->SetItemText(i,1,buf1);
		
		i=list->InsertItem(list->GetItemCount(),_T(""));

		buf1.Empty();
		CaplInstance *user=0,*po=0;
		m_doc_data.GetAttr(m_rev,m_doc->m_api.m_bp_mgr.a_bp_ver_author,user);
		if(user!=0)
		{
			i=list->InsertItem(list->GetItemCount(), APL_T("Автор:"));
			m_doc_data.GetAttr(user,m_doc->m_api.m_appr_mgr.a_apl_user_po,po);
			if(po==0) m_doc_data.GetAttr(user,m_doc->m_api.m_appr_mgr.a_apl_user_name,buf1);
			//else m_doc->m_api.m_appr_mgr.GetPersonName(po,buf1);
			else m_doc->m_api.GetItemName(po,buf1);
			list->SetItemText(i,1,buf1);
		}

		m_doc_data.GetAttr(m_rev,m_doc->m_api.m_bp_mgr.a_bp_ver_basis,buf1);
		i=list->InsertItem(list->GetItemCount(), APL_T("Обоснование:"));
		list->SetItemText(i,1,buf1);
		
		m_doc_data.GetAttr(m_rev,m_doc->m_api.m_bp_mgr.a_bp_ver_start,buf1);
		if(!buf1.IsEmpty())
		{
			i=list->InsertItem(list->GetItemCount(), APL_T("Начало редактирования:"));
			COleDateTime odt;
			aplString2Date(buf1,odt);	
			buf1=odt.Format(_T("%d.%m.%Y  %H:%M:%S"));
			list->SetItemText(i,1,buf1);
		}
		m_doc_data.GetAttr(m_rev,m_doc->m_api.m_bp_mgr.a_bp_ver_end,buf1);
		if(!buf1.IsEmpty())
		{
			i=list->InsertItem(list->GetItemCount(), APL_T("Завершение редактирования:"));
			COleDateTime odt;
			aplString2Date(buf1,odt);	
			buf1=odt.Format(_T("%d.%m.%Y  %H:%M:%S"));
			list->SetItemText(i,1,buf1);
		}
	}
	else if(m_pLockInfo!=0 && m_pLockInfo->GetType())
	{
		i=list->InsertItem(list->GetItemCount(),_T(""));

		buf1.Empty();
		CaplInstance *user=0,*po=0;
		m_doc_data.GetAttr(m_pLockInfo,m_doc->m_api.m_bp_mgr.a_bp_ver_author,user);
		if(user!=0)
		{
			i=list->InsertItem(list->GetItemCount(), APL_T("Редактирует:"));
			m_doc_data.GetAttr(user,m_doc->m_api.m_appr_mgr.a_apl_user_po,po);
			if(po==0) m_doc_data.GetAttr(user,m_doc->m_api.m_appr_mgr.a_apl_user_name,buf1);
			//else m_doc->m_api.m_appr_mgr.GetPersonName(po,buf1);
			else m_doc->m_api.GetItemName(po,buf1);
			list->SetItemText(i,1,buf1);
		}
		
		m_doc_data.GetAttr(m_pLockInfo,m_doc->m_api.m_bp_mgr.a_bp_ver_start,buf1);
		if(!buf1.IsEmpty())
		{
			i=list->InsertItem(list->GetItemCount(), APL_T("Начало редактирования:"));
			COleDateTime odt;
			aplString2Date(buf1,odt);	
			buf1=odt.Format(_T("%d.%m.%Y  %H:%M:%S"));
			list->SetItemText(i,1,buf1);
		}
		m_doc_data.GetAttr(m_pLockInfo,m_doc->m_api.m_bp_mgr.a_bp_ver_basis,buf1);
		i=list->InsertItem(list->GetItemCount(), APL_T("Обоснование:"));
		list->SetItemText(i,1,buf1);
	}

	if(m_project)
	{
		CaplInstance *rel=m_doc->m_project_mgr->FindAssociation(m_project,m_inst);
		if(rel) 
		{
			CaplInstance *control_status=0;
			m_doc_data.GetAttr(rel,m_doc->m_project_mgr->a_project_ref_control_status,control_status);
			CString buf0= APL_T("Рабочий объект");
			if(control_status) buf0= APL_T("Контрольный объект");
			list->InsertItem(list->GetItemCount(),_T(""));
			i=list->InsertItem(list->GetItemCount(), APL_T("Тип объекта:"));
			list->SetItemText(i,1,buf0);
			if(control_status) 
			{
				i=list->InsertItem(list->GetItemCount(), APL_T("Контрольный статус:"));
				m_doc_data.GetAttr(control_status,m_doc->m_api.m_appr_mgr.a_appr_status_name,buf0);
				list->SetItemText(i,1,buf0);
			}
		}
	}
	
	aplExtent ext;
	CStringArray  comment;

	if(m_inst!=0){
		comment.Add(_T("m_inst"));
		ext.Add(m_inst);
	}
	if(m_folder!=0){
		comment.Add(_T("m_folder"));
		ext.Add(m_folder);
	}
	if(m_subitem!=0){
		comment.Add(_T("m_subitem"));
		ext.Add(m_subitem);
	}
	if(m_rel!=0){
		comment.Add(_T("m_rel"));
		ext.Add(m_rel);
	}
	if(m_par_bp!=0){
		comment.Add(_T("m_par_bp"));
		ext.Add(m_par_bp);
	}
	if(m_rev!=0){
		comment.Add(_T("m_rev"));
		ext.Add(m_rev);
	}
	if(m_pLockInfo!=0){
		comment.Add(_T("m_pLockInfo"));
		ext.Add(m_pLockInfo);
	}
	if(m_classifier!=0){
		CaplInstance* classif_ref;
		m_doc->m_api.m_classifier_mgr.TestClassifierAssociation(m_inst,m_classifier,&classif_ref);
		if(classif_ref!=0){
			comment.Add(_T("classifier association"));
			ext.Add(classif_ref);
		}
		comment.Add(_T("m_classifier"));
		ext.Add(m_classifier);
	}
	
	ShowInstanceInfoInListCtrl(ext,list,&comment);
	
	return true;
}
//****************************************************************
void CaplBPTreeItem::CreateCharacteristic(CaplInstance *val)
{
	CaplInstance *new_val=0,*new_ver=0;

	if(m_rev) {AfxMessageBox( APL_T("Нельзя присоединять характеристику к версии бизнес-процесса!"),MB_OK|MB_ICONSTOP); return;}
	
	m_doc->m_api.m_bp_mgr.LoadBPInfo(m_inst);
	CaplInstance *lock=0,*char_lock=0;
	if(m_doc->m_api.m_charact_mgr.m_bUseVersions)
	{
		if(!m_doc->m_api.m_bp_mgr.CheckMyLockAndCheckOut(m_inst))
			return;
		RefreshItem();
		lock=m_doc->m_api.m_bp_mgr.CheckMyLock(m_inst,false);
		if(!lock) return;
	}
	CaplTreeItem::CreateCharacteristic(m_inst, val);
	/*
	if(m_doc->m_api.m_charact_mgr.CreateCharacteristic(m_inst,val, &new_val,0,&new_ver,true))
	{
		m_doc_data.NET_SaveChanges();
		CaplCharacteristicTreeItem *characteristic_item=
			new CaplCharacteristicTreeItem(m_tree,m_doc,new_val);
		characteristic_item->CreateTreeItem(m_item);
		m_all_caracteristic.Add(new_val);
		MyExpand();
		m_doc->ChangeItem(0);m_doc->ChangeItem(this);
	}*/
}
//****************************************************************
void CaplBPTreeItem::ShowCmd(long cmd)
{
	switch (cmd)
	{
		case ID_CREATE_BP:if(!m_rev) CreateBP(m_inst);break;	
		case ID_CREATE_CHARACTERISTIC: if(!m_rev) CreateCharacteristic(); break;
		case ID_EXPAND_ALL: {int i=1; ExpandAll(i);} break;
		case ID_SHOW_ALL_BP_RESOURCE: ShowAllResources(); break;
		case ID_SHOW_ALL_CONTENTS: MyExpand(); break;
		case ID_ITEM_VIEW: ShowProperties(); RefreshAllThisBPItem();break;
		case ID_ITEM_CHECK_IN:CheckIn();break;
		case ID_ITEM_CHECK_OUT:CheckOut();break;
		case ID_ITEM_UNDO_CHECK_OUT:UndoCheckOut();break;
		case ID_CREATE_BP_INST: CreateBPInst();	break;
		case ID_SHOW_ALL_BP_INST: ShowAllBPInst();	break;
		default: PrepareContextMenu(cmd);break;
	}
}

BOOL CaplBPTreeItem::ShowToolBarButton(CCmdUI* pCmdUI)
{
	if(m_inst==0) return FALSE;
	if(m_inst->GetType()==0) return FALSE;

	if(pCmdUI->m_nID==ID_SET_INST_ACCSESS)
	{
		aplExtent instances;
		GetAccessedInstances(instances);
		if(instances.GetSize()>0)
		{
			if(instances[0]->GetAccessmode()==aplOWN) return TRUE;
		}
		return FALSE;
	}


	if(!m_doc->m_api.m_bp_mgr.m_bUseVersions)
	{
		if(pCmdUI->m_nID==ID_ITEM_CHECK_OUT) return FALSE;
		if(pCmdUI->m_nID==ID_SHOW_ALL_VERSION) return FALSE;
	}
	if(m_rev && !m_parent_bp_item)
	{
		if(pCmdUI->m_nID==ID_ITEM_UNDO_CHECK_OUT)  return FALSE;
		if(pCmdUI->m_nID==ID_ITEM_CHECK_IN)  return FALSE;
		if(pCmdUI->m_nID==ID_ITEM_CHECK_OUT) return FALSE;
	}	
	if(m_rev || !m_doc->m_api.m_bp_mgr.m_bUseVersions)
	{
		if(pCmdUI->m_nID==ID_ITEM_UNDO_CHECK_OUT)  return FALSE;
		if(pCmdUI->m_nID==ID_ITEM_CHECK_IN)  return FALSE;
	}
	if(pCmdUI->m_nID==ID_SHOW_ALL_VERSION)
	{
		if(m_rev!=0)return FALSE;
		pCmdUI->Enable(TRUE); return TRUE;
	}

	if (m_pLockInfo)
	{
		if(pCmdUI->m_nID==ID_ITEM_CHECK_OUT) return FALSE;
	}
	else
	{
		if(pCmdUI->m_nID==ID_ITEM_UNDO_CHECK_OUT)  return FALSE;
		if(pCmdUI->m_nID==ID_ITEM_CHECK_IN)  return FALSE;
	}
	if(m_rev)
	{
		if(pCmdUI->m_nID==ID_CREATE_BP) return FALSE; 
		if(pCmdUI->m_nID==ID_CREATE_CHARACTERISTIC) return FALSE;
		if(pCmdUI->m_nID==ID_CREATE_CHARACTERISTIC_GROUP) return FALSE;
		if(pCmdUI->m_nID==ID_CREATE_DOC) return FALSE;
		if(pCmdUI->m_nID==ID_SHOW_ALL_DOCS) return FALSE;
		if(!m_doc->m_api.m_charact_mgr.m_bUseVersions)
			if(pCmdUI->m_nID==ID_SHOW_ALL_DOCS) return FALSE;
	}

	switch(pCmdUI->m_nID)
	{
	case ID_CREATE_BP:
	case ID_SHOW_ALL_DOCS:
	case ID_SHOW_ALL_CHARACTERISTIC:
	case ID_SHOW_ALL_BP_RESOURCE:
	case ID_SHOW_ALL_APPROVAL:
//	case ID_PRODUCT_SHOW_ALL_ZAGOTOV:
//	case ID_SHOW_ALL_LOT:
//	case ID_SHOW_ALL_PRD_INST:
	case ID_CREATE_APPROVAL:
//	case ID_SHOW_ALL_VERSION:
//	case ID_CREATE_PRODUCT:
	case ID_CREATE_CHARACTERISTIC:
	case ID_CREATE_DOC:
	case ID_ITEM_VIEW:
	case ID_ITEM_CHECK_OUT:
	case ID_ITEM_CHECK_IN:
	case ID_ITEM_UNDO_CHECK_OUT:
	case ID_CREATE_BP_INST:
	case ID_SHOW_ALL_BP_INST:
	case ID_SHOW_NOTES:
	case ID_CREATE_NOTE:
		pCmdUI->Enable(TRUE); return TRUE; break;
	}
	return FALSE;
}
//****************************************************************
bool CaplBPTreeItem::PasteItem(CaplTreeItem *item, CPoint *point)
{
	if(item==0) return false;
	if (item->m_type != APL_TREE_ITEM_DOCUMENT)
		if (item->m_type != APL_TREE_ITEM_CHARACTERISTIC)
			if (item->m_type != APL_TREE_ITEM_CHARACTERISTICGROUP)
				if (item->m_type != APL_TREE_ITEM_BP)
					if (item->m_type != APL_TREE_ITEM_PRODUCT)
						if (item->m_type != APL_TREE_ITEM_PRDINST)
							if (item->m_type != APL_TREE_ITEM_LOT)
								if (item->m_type != APL_TREE_ITEM_BPRES)
									if (item->m_type != APL_TREE_ITEM_PERSON)
										if (item->m_type != APL_TREE_ITEM_ORGANIZATION)
											if (item->m_type != APL_TREE_ITEM_CLASSIFIERLEVEL)
												return false;
	if(m_tree==0) return false;
	if(m_doc==0) return false;
	if(m_inst==0)return false;
	if(m_inst->GetType()==0)return false;
	if(m_rev)return false; 
	if(m_inst->GetAccessmode()>aplRW){AfxMessageBox(ID_NO_ACCESS_RIGHT,MB_OK|MB_ICONSTOP); return false;}

	CaplAggr aggr;
	CaplInstance *res=0,*res_obj=0,*lock=0;
	m_doc->m_api.m_bp_mgr.LoadBPInfo(m_inst);
	if ( (item->m_type == APL_TREE_ITEM_PRODUCT) || (item->m_type ==APL_TREE_ITEM_PRDINST) || (item->m_type ==APL_TREE_ITEM_LOT)
		|| (item->m_type ==APL_TREE_ITEM_PERSON)|| (item->m_type ==APL_TREE_ITEM_ORGANIZATION)
		|| (item->m_type ==APL_TREE_ITEM_CLASSIFIERLEVEL))
	{
		CaplInstance *obj=0, *base_pdr=0;; 

		if(item->m_type == APL_TREE_ITEM_PRODUCT)
		{
			obj=((CaplProductTreeItem*)item)->m_prd;
			if(((CaplProductTreeItem*)item)->m_pdf!=0)
			{
				obj=((CaplProductTreeItem*)item)->m_pdf;
				base_pdr=((CaplProductTreeItem*)item)->m_nauo;
			}
			else
			{	// Сделано по просьбе ЦКБА 22.12.2017
				AfxMessageBox(APL_T("Ресурсом может быть только конкретная версия!"),MB_OK|MB_ICONWARNING); 
				return false; 
			}
		}
		else if(item->m_type == APL_TREE_ITEM_PRDINST) obj=((CaplPrdInstTreeItem*)item)->m_inst;
		else if(item->m_type == APL_TREE_ITEM_LOT)  obj=((CaplLotTreeItem*)item)->m_lot;
		else if(item->m_type == APL_TREE_ITEM_PERSON) obj=((CaplPersonTreeItem*)item)->m_person;
		else if(item->m_type == APL_TREE_ITEM_ORGANIZATION)  obj=((CaplOrganizationTreeItem*)item)->m_inst;
		else if(item->m_type == APL_TREE_ITEM_CLASSIFIERLEVEL)  obj=((CaplClassifierTreeItem*)item)->m_inst;

		if(obj==0) return false;
		if(obj->GetType()==0) return false;
		if(obj->GetAccessmode()>aplRO){AfxMessageBox(ID_NO_ACCESS_RIGHT,MB_OK|MB_ICONSTOP); return false;}

		CaplInstance *new_res=m_doc->m_api.m_bp_mgr.CreateBPResource(m_inst,0,obj);
		if(new_res)
		{
			RefreshAllThisBPItem();
			CaplBPResourceTreeItem *item= new CaplBPResourceTreeItem(m_tree,m_doc,new_res);
			m_all_res.Add(new_res);
			item->CreateTreeItem(m_item);
			item->RefreshItem();
		}
		MyExpand();
		return true;
	}
	else if (item->m_type == APL_TREE_ITEM_BPRES)
	{

		CaplInstance *base_res=((CaplBPResourceTreeItem*)item)->m_inst;
		if(!base_res) return false;if(base_res->GetAccessmode()>aplRO) {AfxMessageBox(ID_NO_ACCESS_RIGHT,MB_OK|MB_ICONSTOP);return false;}
		
		CaplInstance *new_res=m_doc->m_api.m_bp_mgr.CreateBPResource(m_inst,base_res);
		if(new_res)
		{
			RefreshAllThisBPItem();
			CaplBPResourceTreeItem *item= new CaplBPResourceTreeItem(m_tree,m_doc,new_res);
			m_all_res.Add(new_res);
			item->CreateTreeItem(m_item);
			item->RefreshItem();
		}
		MyExpand();
		return true;
	}
	else if (item->m_type == APL_TREE_ITEM_BP)
	{
		if(((CaplBPTreeItem*)item)->m_rev) return false;
		if(m_doc->m_api.m_bp_mgr.m_bUseVersions && m_inst)
		{
			if(!m_doc->m_api.m_bp_mgr.CheckMyLockAndCheckOut(m_inst))
				return false;
		}

		CaplInstance *act=((CaplBPTreeItem*)item)->m_inst;
		if(!m_doc->m_api.m_bp_mgr.AddBPToBP(act,m_inst))
			return false;

		StartBusy();
		CaplBPTreeItem *new_item=0;
		InsertInstInTree(act,m_item,m_doc,m_tree,m_sub_bps,0,(CaplTreeItem **)(&new_item));
		if(new_item!=0)
		{
			new_item->m_par_bp=m_inst;
			new_item->m_index=m_sub_bps.Size-1;
			new_item->RefreshItem();
		}
		m_doc_data.NET_SaveChanges();
		Expand(1);
		Expand(2);
		m_doc->RefreshAllItemsByType(APL_TREE_ITEM_BP);
		MyExpand();
		StopBusy();
		return true;
	}

	CMenu menu;  gSetPsmResourceHandle();
	CMenu *pPopup;
	VERIFY(menu.LoadMenu(IDR_PASTE_ITEM_MENU));
//	VERIFY(menu.LoadToolBar(IDR_MENU_ICONS));
	CaplMenu::Install(m_tree); //	VERIFY(CaplMenu::Install(m_tree, ePopupMenu ));

	//if(item->m_type == APL_TREE_ITEM_PRODUCT)
	//	pPopup = menu.GetSubMenu(INDEX_PRODUCT_MENU);
	//else
	if(item->m_type == APL_TREE_ITEM_DOCUMENT)
	{
		aplExtent ext;
		item->GetAccessedInstances(ext);
		CString state;
		m_doc_data.GetAttr(ext[0],m_doc->m_api.m_bp_mgr.a_bp_state,state);
		if(state!=_T("working") && state!=_T("changing") && state!=_T(""))
		{
			AfxMessageBox( APL_T("Документ находится в состоянии \"")+m_doc->m_api.m_bp_mgr.GetWFStateName(state)+ APL_T("\" и не может быть изменен"));
			return false;
		}
		GetAccessedInstances(ext);
		m_doc_data.GetAttr(ext[0],m_doc->m_api.m_bp_mgr.a_bp_state,state);
		if(state!=_T("working") && state!=_T("changing") && state!=_T(""))
		{
			AfxMessageBox( APL_T("Бизнес процесс находится в состоянии \"")+m_doc->m_api.m_bp_mgr.GetWFStateName(state)+ APL_T("\" и не может быть изменен"));
			return false;
		}
		pPopup = menu.GetSubMenu(INDEX_DOCUMENT_MENU);
	}
	else if(item->m_type == APL_TREE_ITEM_CHARACTERISTIC)
		pPopup = menu.GetSubMenu(INDEX_CHARACTERISTIC_MENU);
	else if(item->m_type == APL_TREE_ITEM_CHARACTERISTICGROUP)
		pPopup = menu.GetSubMenu(INDEX_CHARACTERISTIC_MENU);
	
	if(pPopup!=0)
	{
		POINT pnt;
		if(point==0)
		{
			RECT rect;
			m_tree->GetItemRect(m_item,&rect,TRUE);
			m_tree->ClientToScreen(&rect);
			pnt.x=rect.right;
			pnt.y=rect.bottom;
		}
		else
		{
			pnt.x=point->x;
			pnt.y=point->y;
		}

		HTREEITEM parent = m_tree->GetNextItem(item->m_item,TVGN_PARENT);
		CaplTreeItem *parent_item = (CaplTreeItem*)m_tree->GetItemData(parent);
		if(parent_item && parent_item->m_type==APL_TREE_ITEM_QUERY)
		{
			pPopup->EnableMenuItem(ID_DOCUMENT_MOVE, MF_BYCOMMAND|MF_GRAYED);
		}
		BOOL res=pPopup->TrackPopupMenu(TPM_LEFTALIGN|
			TPM_RIGHTBUTTON|TPM_RETURNCMD,pnt.x,pnt.y,m_tree);

		// Вставка документа
		if (res == ID_DOCUMENT_COPY)
		{
			CaplInstance *i_doc=((CaplDocTreeItem *)item)->m_inst;
			
			HTREEITEM ht = m_tree->GetNextItem(item->m_item,TVGN_PARENT);
			CaplTreeItem *Item = (CaplTreeItem*)m_tree->GetItemData(ht);
			aplAccessModeType access = aplOWN;
			if(Item)
			{
				aplExtent instances;
				Item->GetAccessedInstances(instances);
				if (instances.GetSize())
					access = instances.GetAt(0)->GetAccessmode();
			}

			if(m_inst->GetAccessmode()>aplRW || access>aplRO)
			{
				AfxMessageBox( APL_T("Нет доступа к объекту"));
				return false;
			}
			if(CaplDocTreeItem::InsertDoc(m_doc,this,&m_all_documents,i_doc,m_inst, false))
				ShowCmd(ID_SHOW_ALL_DOCS);
		}
		//создание по образцу
		else if(res == ID_DOCUMENT_BYDOT)
		{
			CaplInstance *i_doc = ((CaplDocTreeItem *)item)->m_inst;
			
			aplExtent instances;
			GetAccessedInstances(instances);
			if(m_doc->m_api.m_doc_mgr.CreateDocumentByDot(i_doc,instances[0]))
				ShowCmd(ID_SHOW_ALL_DOCS);
		}
		//премещение документа
		else if(res == ID_DOCUMENT_MOVE)
		{
			CaplDocTreeItem *d_item = (CaplDocTreeItem*)item;
			HTREEITEM parent = m_tree->GetNextItem(d_item->m_item,TVGN_PARENT);
			CaplTreeItem *parent_item = (CaplTreeItem*)m_tree->GetItemData(parent);
			
			CaplDocTreeItem::MoveDocument(m_doc, d_item, parent_item, this);
		}
		// Вставка характеристики
		else if (res == ID_CHARACTERISTIC_COPY)
		{
			if(item->m_type == APL_TREE_ITEM_CHARACTERISTIC)
			{
				CaplInstance *i_val=((CaplCharacteristicTreeItem *)item)->m_val;
				CreateCharacteristic(i_val);
			}
			else if(item->m_type == APL_TREE_ITEM_CHARACTERISTICGROUP)
			{
				CreateCharacteristicGroup(((CaplCharacteristicGroupTreeItem*)item)->m_group);
			}

		}
		
	}
	m_tree->RedrawWindow();
	return true;
}

//****************************************************************
void CaplBPTreeItem::CreateBP(CaplInstance *inst_for_id)
{
	if(m_tree==0) return;
	if(m_doc==0) return;
	if(m_inst==0)return;
	if(m_inst->GetType()==0)return;

	m_doc->m_api.m_bp_mgr.LoadBPInfo(m_inst);
	if(m_inst->GetAccessmode()>aplRW){AfxMessageBox(ID_NO_ACCESS_RIGHT,MB_OK|MB_ICONSTOP); return;}
	
	CaplInstance *lock=0;	
	if(m_doc->m_api.m_bp_mgr.m_bUseVersions)
	{
		if(!m_doc->m_api.m_bp_mgr.CheckMyLockAndCheckOut(m_inst))
			return;
		lock=m_doc->m_api.m_bp_mgr.CheckMyLock(m_inst,true);
		if(!lock) return;
	}

	CaplInstance *act_inst=m_doc->m_api.m_bp_mgr.CreateBP(m_inst,0,0,0,0,APL_MODE_CREATE_BP);
	
	if(act_inst!=0)
	{
		m_doc_data.NET_SaveChanges();
		CaplBPTreeItem *act_item= new CaplBPTreeItem(m_tree,m_doc,act_inst);
		CaplAggr aggr0;
		if(lock) m_doc_data.GetAttr(lock,m_doc->m_api.m_bp_mgr.a_bp_ver_elements,aggr0);
		else m_doc_data.GetAttr(m_inst,m_doc->m_api.m_bp_mgr.a_bp_elements,aggr0);
				
		act_item->m_index=aggr0.GetSize();
		act_item->CreateTreeItem(m_item);
		m_sub_bps.Add(act_inst);
		
	}
	bool has_version=m_has_version;
	Expand(1);
	Expand(2);
	m_has_version=has_version;
	RefreshAllThisBPItem();
	MyExpand();
}
//****************************************************************
void CaplBPTreeItem::CreateBPInst()
{
	if(m_tree==0) return;
	if(m_doc==0) return;
	if(m_inst==0)return;
	if(m_inst->GetType()==0)return;

	if(m_inst->GetAccessmode()>aplRW){AfxMessageBox(ID_NO_ACCESS_RIGHT,MB_OK|MB_ICONSTOP); return;}

	CaplInstance *bp_inst=m_doc->m_api.m_bp_mgr.CreateBPInst(0,0,0,0,m_inst);
	
	if(bp_inst!=0)
	{
		CaplBPInstTreeItem *new_item=0;
		InsertInstInTree(bp_inst,m_item,m_doc,m_tree,m_all_bp_inst,0,(CaplTreeItem **)(&new_item));
		MyExpand();
	}
	
}

void CaplBPTreeItem::CreateBPResource()
{
	if(m_rev) return;
	if(m_inst->GetAccessmode()>aplRW){AfxMessageBox(ID_NO_ACCESS_RIGHT,MB_OK|MB_ICONSTOP);return;}

	CaplInstance *new_res=m_doc->m_api.m_bp_mgr.CreateBPResource(m_inst);
	if(new_res)
	{
		RefreshAllThisBPItem();
		CaplBPResourceTreeItem *item= new CaplBPResourceTreeItem(m_tree,m_doc,new_res);
		m_all_res.Add(new_res);
		item->CreateTreeItem(m_item);
		item->RefreshItem();
		MyExpand();
	}

}
//****************************************************************
bool CaplBPTreeItem::PasteFile(LPCTSTR file, CPoint *point)
{
	if(file==0) return false;
	CreateDoc(m_inst,file);
	return true;
}
//****************************************************************
void CaplBPTreeItem::CreateCharacteristicGroup(CaplInstance *group)
{
	CaplInstance *group_new=0;
	CaplInstance *lock=0,*char_lock=0;
	if(m_doc->m_api.m_charact_mgr.m_bUseVersions)
	{
	
		if(!m_doc->m_api.m_bp_mgr.CheckMyLockAndCheckOut(m_inst))
			return;
		RefreshItem();
		lock=m_doc->m_api.m_bp_mgr.CheckMyLock(m_inst,false);
		if(!lock) return;
	}
	if(m_doc->m_api.m_charact_mgr.CreateCharacteristicGroup(m_inst,&group_new,group))
	{
		CaplCharacteristicGroupTreeItem *characteristic_group_item=
			new CaplCharacteristicGroupTreeItem(m_tree,m_doc,group_new);
		characteristic_group_item->CreateTreeItem(m_item);
		m_all_caracteristic.Add(group_new);
		MyExpand();
		m_doc->ChangeItem(0);m_doc->ChangeItem(this);
	}
}
//****************************************************************
void CaplBPTreeItem::GetAllSubBP(CaplInstance *inst, aplExtent &ext)
{
	if(!m_doc_data.IsConnected()) return;

	CaplAggr aggr0;
	CaplInstance *inst1;

	CaplInstance *ver=0,*lock=0;
	if(m_doc->m_api.m_bp_mgr.m_bUseVersions)
	{
		lock=m_doc->m_api.m_bp_mgr.CheckMyLock(m_inst,false);
		if(m_rev) 
		{
			m_doc->m_api.m_bp_mgr.LoadBPInfo(m_rev);
			ver=m_rev;
		}
		else 
			ver=lock;
	}
	int i;
	//m_doc->m_api.m_bp_mgr.LoadBPInfo(inst);

	CaplLoadData ld(&(m_doc->m_api.m_data),DEF_SOURCE);
	
	if(ver)
	{
		i=ld.AddQuery(-1,ver);
		ld.AddQuery(_T('d'), i, 0,m_doc->m_api.m_bp_mgr.a_bp_elements, true);
	}
	else
	{
		i=ld.AddQuery(-1,inst);
		ld.AddQuery(_T('d'), i, 0,m_doc->m_api.m_bp_mgr.a_bp_ver_elements, true);
	}
	ld.LoadEx();

	if(ver)
		m_doc_data.GetAttr(ver,m_doc->m_api.m_bp_mgr.a_bp_ver_elements,aggr0);
	else
		m_doc_data.GetAttr(inst,m_doc->m_api.m_bp_mgr.a_bp_elements,aggr0);
	for(i=0;i<aggr0.GetSize();i++)
	{
		aggr0.GetByIndex(i,inst1);
		if(inst1==0) continue;
		if(inst1->GetType()==0) continue;
		if(ext.Find(inst1)>=0) continue;
		ext.Add(inst1);
		GetAllSubBP(inst1,ext);
	}	
}

//****************************************************************
void CaplBPTreeItem::ShowAllVersion(bool showMsg)
{
	_APL_TREE_ITEM_CHEK_PARAM_VOID
	if(m_inst==0) return;

#ifdef _DEBUG
	if(m_inst->GetId()==23822)
	{
		int a=0;
	}
#endif
	if(m_has_version) HideAllVersion();

	aplExtent ext_rev,top_rev;
	int i;
	if(m_inst->GetAccessmode()>aplRO) return;
	if(m_rev) return;
	

	StartBusy();
	// чтение из базы
	SetStatusString( APL_T("Чтение из базы"));
	if(m_rev)
	{
		m_doc->m_api.m_bp_mgr.LoadBPInfo(m_rev);
		m_doc->m_api.m_bp_mgr.GetAllBPVersion(m_rev,ext_rev);
	}
	else
	{
		m_doc->m_api.m_bp_mgr.LoadBPInfo(m_inst);
		m_doc->m_api.m_bp_mgr.GetAllBPVersion(m_inst,ext_rev);
	}
	CaplInstance *lock=0,*bp_ver_bp=0;
	if(!m_rev)
		m_doc_data.GetAttr(m_inst,m_doc->m_api.m_bp_mgr.a_bp_lock,lock);
	else 
	{
		m_doc_data.GetAttr(m_rev,m_doc->m_api.m_bp_mgr.a_bp_ver_bp,bp_ver_bp);
		if(bp_ver_bp) m_doc_data.GetAttr(bp_ver_bp,m_doc->m_api.m_bp_mgr.a_bp_lock,lock);
	}

	SetStatusString(_T(""));
	StopBusy();
	if(ext_rev.Size<=0) {if(showMsg) AfxMessageBox( APL_T("Нет версий !")); return;}
	// отображение версий

	// Определение верхнего уровня
	CaplInstance *inst=0;
	
	for(i=0;i<ext_rev.Size;i++)
	{
		if(ext_rev[i]==0) continue;
		if(ext_rev[i]->GetType()==0) continue;
		m_doc_data.GetAttr(ext_rev[i],m_doc->m_api.m_bp_mgr.a_bp_ver_base,inst);
		if(inst==0) 
		{
			if(ext_rev[i]!=lock) top_rev.Add(ext_rev[i]);
			ext_rev.Remove(i);
			i--;
		}
		else if(inst->GetAccessmode()>aplRO) 
		{
			top_rev.Add(ext_rev[i]);
			ext_rev.Remove(i);
			i--;
		}
		if(ext_rev[i]==lock) //не будем отображать редактируемую версию
		{
			ext_rev.Remove(i);
			i--;
		}
	}
	if(ext_rev.Size<=0 && top_rev.Size<=0) {if(showMsg) AfxMessageBox( APL_T("Нет версий !")); return;}
	
	if(m_bShowNoFoundMessage) {m_tree->SetRedraw(FALSE);}
	// Составление дерева
	bool oldShowContents=m_ShowContentsOnExpand;
	m_ShowContentsOnExpand=false;
	for(i=0;i<top_rev.Size;i++)
	{
		CaplBPTreeItem *bp_item=
			new CaplBPTreeItem(m_tree,m_doc,m_inst);
		bp_item->m_rev=top_rev[i];
		bp_item->m_parent_bp_item=this;
		bp_item->CreateTreeItem(m_item);
		m_all_version.Add(top_rev[i]);
		
		bp_item->RefreshItem();
		bp_item->InsertRevisionInTree(ext_rev,this);
		m_tree->Expand(bp_item->m_item,TVE_EXPAND);

	}
	m_ShowContentsOnExpand=oldShowContents;
	m_has_version=true;
	if(m_ExecMyExpand)
		MyExpand(false);
	Sort();
	StopBusy();
	if(m_bShowNoFoundMessage) {m_tree->SetRedraw(TRUE);}
	m_tree->Select(m_item,TVGN_FIRSTVISIBLE);
}

//****************************************************************
void CaplBPTreeItem::ShowAllBPInst()
{
	CaplLoadData ld(&m_doc_data,DEF_SOURCE);
	int i=ld.AddQuery(_T('b'), m_inst->GetId(), m_doc->m_api.m_bp_mgr.e_apl_bp_inst,m_doc->m_api.m_bp_mgr.a_bp_inst_process, true);
	      ld.AddQuery(_T('d'), i, 0,m_doc->m_api.m_bp_mgr.a_bp_inst_process, true);
	if (!ld.LoadEx())
		AfxMessageBox(IDS_ERROR_LOAD_DATA_APL,MB_OK|MB_ICONSTOP);
	// Поиск связанных экземпляров бп
	aplExtent out_ext,ext_bp_inst;
	m_doc_data.GetEntityExtent(m_doc->m_api.m_bp_mgr.e_apl_bp_inst,out_ext);
	CaplInstance *inst=0;
	for(i=0;i<out_ext.Size;i++)
	{
		if(!out_ext[i]) if(out_ext[i]->GetAccessmode()>aplRO) continue;
		m_doc_data.GetAttr(out_ext[i],m_doc->m_api.m_bp_mgr.a_bp_inst_process,inst);
		if(inst==m_inst) 
			ext_bp_inst.Add(out_ext[i]);
	}
	m_doc->m_api.m_bp_mgr.LoadBPInstInfo(ext_bp_inst);
	for(i=0;i<ext_bp_inst.GetSize();i++)
	{
		CaplBPInstTreeItem *new_item=0;
		InsertInstInTree(ext_bp_inst[i],m_item,m_doc,m_tree,m_all_bp_inst,0,(CaplTreeItem **)(&new_item));
	}
	if(m_ExecMyExpand)
		MyExpand(false);
	if(!ext_bp_inst.GetSize())
		if(m_bShowNoFoundMessage) 
			AfxMessageBox( APL_T("Нет экземпляров!"));
}

CaplBPTreeItem* CaplBPTreeItem::GetParentBPItem(CaplBPTreeItem *item)
{
	HTREEITEM par_item=	m_tree->GetParentItem(item->m_item);
	for(int i=0;i<m_doc->m_items.Size;i++)
	{
		if(m_doc->m_items[i]->m_item==par_item && m_doc->m_items[i]->m_type==APL_TREE_ITEM_BP)
		{
			return (CaplBPTreeItem*)m_doc->m_items[i];
		}
	}
	return 0;
}

//*********************************************************************
void CaplBPTreeItem::ShowAllCharacteristic(bool showMsg)
{
	if(m_doc==0) return;
	if(!m_doc->m_api.m_bp_mgr.m_bUseVersions || !m_doc->m_api.m_charact_mgr.m_bUseVersions) 
	{
		CaplTreeItem::ShowAllCharacteristic(true);
		return;
	}
	
	CaplInstance *inst=0,*inst1=0;
	if(m_inst==0) return ;
	if(m_inst->GetType()==0) return ;
	if(m_inst->GetAccessmode()>aplRO)
	{if(m_bShowNoFoundMessage) aplErrorMessage(S::NoAccessRight(),m_inst);return;};

	int i,count0=m_all_caracteristic.Size;
	aplExtent ext,extGroup;

	if(m_bShowNoFoundMessage){ m_tree->SetRedraw(FALSE);}

	m_doc->m_api.m_bp_mgr.LoadBPInfo(m_inst);
	CaplInstance *ver=0;
	if(m_rev) ver=m_rev;
	else ver=m_doc->m_api.m_bp_mgr.CheckMyLock(m_inst,false);

	if(!ver) 
	{
		CaplTreeItem::ShowAllCharacteristic(showMsg);
		if(m_bShowNoFoundMessage) {m_tree->SetRedraw(TRUE);}
		return;
	}

	CaplAggr aggr;
	m_doc_data.GetAttr(ver,m_doc->m_api.m_bp_mgr.a_bp_ver_char_val_versions,aggr);
	
	m_doc->m_api.m_charact_mgr.LoadCharacteristic(aggr);

	if(!m_rev) m_doc->m_api.m_charact_mgr.FindAssociatedCharacteristic(m_inst, ext,extGroup);
	for(i=0;i<aggr.GetSize();i++)
	{
		CaplInstance *char_ver=0,*char_val=0;
		aggr.GetByIndex(i,char_ver);
		if(!char_ver) continue;if(char_ver->GetAccessmode()>aplRO) continue;
		m_doc_data.GetAttr(char_ver,m_doc->m_api.m_charact_mgr.a_apl_charact_val_ver_char_value,char_val);
		if(!char_val) continue;if(char_val->GetAccessmode()>aplRO) continue;
		if(m_all_caracteristic.Find(char_val)>=0) continue;

		m_doc_data.GetAttr(char_val,m_doc->m_api.m_charact_mgr.a_apl_charact_val_group,inst);
		if(inst!=0)
		{
			if(extGroup.Find(inst)>=0) continue;
		}
			
		CaplCharacteristicTreeItem *characteristic_item=
			new CaplCharacteristicTreeItem(m_tree,m_doc,char_val);
		if(m_rev)
		{
			characteristic_item->m_rev=char_ver;
			characteristic_item->m_bp_rev=m_rev;
		}
		characteristic_item->CreateTreeItem(m_item);
		m_all_caracteristic.Add(char_val);

	}
	for(i=0;i<extGroup.Size;i++)
	{
		if(m_all_caracteristic.Find(extGroup[i])==-1)
		{
			CaplCharacteristicGroupTreeItem *characteristic_group_item=
				new CaplCharacteristicGroupTreeItem(m_tree,m_doc,extGroup[i]);
			characteristic_group_item->CreateTreeItem(m_item);
			m_all_caracteristic.Add(extGroup[i]);
		}
	}
	if(m_bShowNoFoundMessage){ m_tree->SetRedraw(TRUE);}
	if(count0==m_all_caracteristic.Size)
	{
		if(m_bShowNoFoundMessage && showMsg) AfxMessageBox(APL_T("Новые характеристики не найдены !"));
	}
	else if(m_ExecMyExpand)MyExpand(false);

	return;
}

//****************************************************************
void CaplBPTreeItem::InsertRevisionInTree(aplExtent &ext_rev,CaplBPTreeItem *parent_bp_item)
{
	_APL_TREE_ITEM_CHEK_PARAM_VOID
	// вызов подверсий
	CaplInstance *inst=0;
	//m_pDocItem=docitem;
	bool b=false;
	for(int i=0;i<ext_rev.Size;i++)
	{

		if(ext_rev[i]==0) continue;
		if(ext_rev[i]->GetType()==0) continue;

		m_doc_data.GetAttr(ext_rev[i],m_doc->m_api.m_bp_mgr.a_bp_ver_base,inst);
		if(inst==m_rev)
		{
			b=true;
			CaplBPTreeItem *bp_item=
				new CaplBPTreeItem(m_tree, m_doc, m_inst);
			bp_item->m_rev=ext_rev[i];
			bp_item->m_parent_bp_item=parent_bp_item;
			bp_item->CreateTreeItem(m_item);
			m_all_version.Add(ext_rev[i]);
			bp_item->RefreshItem();	
			bp_item->InsertRevisionInTree(ext_rev,parent_bp_item);
		}
	}
	if(b)
	{
		Sort();
		bool oldShowContents=m_ShowContentsOnExpand;
		m_ShowContentsOnExpand=false;
		m_tree->Expand(m_item,TVE_EXPAND);
		m_ShowContentsOnExpand=oldShowContents;
	}
}

void CaplBPTreeItem::HideAllVersion()
{
	_APL_TREE_ITEM_CHEK_PARAM_VOID

	int i;
	m_tree->SetRedraw(FALSE);
	for(i=0;i<m_doc->m_items.Size;i++)
	{
		if(m_doc->m_items[i]->m_type==APL_TREE_ITEM_BP)
		{
			CaplBPTreeItem *item=(CaplBPTreeItem*)m_doc->m_items[i];
			if(item->m_parent_bp_item==this) 
			{
				m_doc->m_items.Remove(i); i--;
			}
		}
	}
	m_all_version.Clear();
	m_tree->SetRedraw(TRUE);
	m_has_version=false;
}

void CaplBPTreeItem::CheckOut()
{
	bool check_out_result=false;
	bool recursive=false;
	if(m_rev) check_out_result=m_doc->m_api.m_bp_mgr.CheckOutWithRequest(m_rev,recursive);
	else check_out_result=m_doc->m_api.m_bp_mgr.CheckOutWithRequest(m_inst,recursive);
	if(check_out_result) 
	{
		Expand(1);
		Expand(2);
		RefreshItem();
		if(m_rev)
		{
			if(m_parent_bp_item)
			{
				CaplBPTreeItem *p_item=m_parent_bp_item;
				p_item->Expand(1);
				p_item->Expand(2);
				p_item->RefreshItem();
			}
		}
	}
	if(recursive) m_doc->RefreshAllItemsByType(APL_TREE_ITEM_BP);
}
void CaplBPTreeItem::CheckIn()
{
	bool recursive=true;
	if(m_doc->m_api.m_bp_mgr.CheckInWithRequest(m_inst,recursive)) 
	{ 
		Expand(1);
		Expand(2);
		if(recursive)
			m_doc->RefreshAllItemsByType(APL_TREE_ITEM_BP);
		else
			RefreshAllThisBPItem();
	}
}
void CaplBPTreeItem::UndoCheckOut()
{
	bool recursive=false;
	if(m_doc->m_api.m_bp_mgr.UndoCheckOutWithRequest(m_inst,recursive)) 
	{ 
		Expand(1);
		Expand(2);
		if(recursive)
			m_doc->RefreshAllItemsByType(APL_TREE_ITEM_BP);
		else
			RefreshAllThisBPItem();
	}
}

void CaplBPTreeItem::RemoveRelation()
{
	if(!m_rel && !m_par_bp && !m_project) return;
	if(m_rel)
	{
		if(m_rel->GetAccessmode()>aplOWN)
		{
			AfxMessageBox(ID_NO_ACCESS_RIGHT,MB_OK|MB_ICONSTOP);return;
		}
		if(!m_rel->GetType()) return;
		CaplInstance *inst;
		m_doc_data.GetAttr(m_rel,m_doc->m_api.m_bp_mgr.a_bp_ref_item,inst);
		if(inst>0)
		{
			if(inst->GetAccessmode()>aplRW)
			{
				AfxMessageBox(ID_NO_ACCESS_RIGHT,MB_OK|MB_ICONSTOP);
				return;
			}
		}
		if(AfxMessageBox( APL_T("Вы действительно хотите удалить связь ?"),MB_YESNO)==IDNO) return;
		for(int i=0;i<m_doc->m_items.Size;i++)
		{
			if(m_doc->m_items[i]!=this)
			{
				if(m_doc->m_items[i]->m_type==m_type)
				{
					CaplBPTreeItem *item1=
						(CaplBPTreeItem*)m_doc->m_items[i];
					{
						if(item1->m_rel==m_rel)
						{m_doc->m_items.Remove(i); i--;}
					}
				}
			}
		}
		CaplProductTreeItem *prd_item=(CaplProductTreeItem*)GetParentItem(this);
		if(prd_item) prd_item->m_all_bp.Remove(prd_item->m_all_bp.Find(m_inst));
		m_doc_data.DeleteInstance(m_rel);
		if(m_doc->m_api.m_bp_mgr.m_AutoSave) m_doc_data.NET_SaveChanges();
			
	}
	else if(m_par_bp)
	{
		m_doc->m_api.m_bp_mgr.LoadBPInfo(m_par_bp);
		CaplInstance *lock;
		if(m_doc->m_api.m_bp_mgr.m_bUseVersions)
		{
			if(!m_doc->m_api.m_bp_mgr.CheckMyLockAndCheckOut(m_par_bp))
				return;
			CaplBPTreeItem *parent_item=GetParentBPItem(this);
			if(parent_item) parent_item->RefreshItem();
				lock=m_doc->m_api.m_bp_mgr.CheckMyLock(m_par_bp,true);
			if(!lock) return;
		}
					
		if(AfxMessageBox( APL_T("Вы действительно хотите удалить связь ?"),MB_YESNO)==IDNO) return;
		
		if(!m_doc->m_api.m_bp_mgr.DeleteBPRelation(m_inst,m_par_bp)) return;
		
	}
	else if(m_project)
	{
		if(!m_inst) return;
		if(AfxMessageBox( APL_T("Вы уверены ?"),MB_YESNO|MB_DEFBUTTON2)!=IDYES) return;
	
		if(!m_doc->m_project_mgr->DeleteAssociation(m_project,m_inst)) return;
		CaplProjectTreeItem *prj_item=(CaplProjectTreeItem*)GetParentItem(this);
		if(prj_item) prj_item->m_all_items.Remove(prj_item->m_all_items.Find(m_inst));
	}
	m_doc->m_items.Remove(m_doc->m_items.Find(this));
}	

//**************************************************************************************
bool CaplBPTreeItem::ConvertToCustomizedCopy()
{
	if(0==m_inst) return false;
	if(m_inst->IsDeleted()) return false;
	if(m_inst->GetAccessmode()>=aplRO) return false;
	if(0!=m_rev) return false;
	if(0!=m_rel) return false;

	aplExtent extBpIerarhy;

	bool bCustomized=false;
	CaplTreeItem *ti=this;

	CaplBPTreeItem *parentCustomizedItem=0;

	// Проверяем цепочку она должна быть унифицированной
	while(true)
	{
		if(0==ti) break;
		if(ti->m_type!=APL_TREE_ITEM_BP) break;

		CaplInstance *bp=((CaplBPTreeItem*)ti)->m_inst;
		if(0==bp) break;
		if(bp->IsDeleted()) break;
		if(bp->GetAccessmode()>=aplRO) break;

		extBpIerarhy.Add(bp);

		m_doc->m_api.m_data.GetAttr(bp, m_doc->m_api.m_bp_mgr.a_bp_customized, bCustomized);
		if(bCustomized) 
		{
			parentCustomizedItem=(CaplBPTreeItem*)ti;
			break;
		}

		HTREEITEM hitem=m_tree->GetParentItem(ti->m_item);
		if(0==hitem) break;
		ti=(CaplTreeItem *)m_tree->GetItemData(hitem);
	}

	if(0==parentCustomizedItem)
	{
		AfxMessageBox(APL_T("Замена невозможна!\n\nДля замены необходимо чтобы цепочка вышестоящих БП заканчивалась индивидуальным БП.\n\nВозможно, в дереве объектов показана только часть дерева БП. В этом случае для замены раскройте весь БП начиная в корневого."),MB_ICONSTOP);
		return false;
	}

	int i,j,k;

	// Определение суффикса для новых обозначений
	CString sParentId;
	m_doc->m_api.m_data.GetAttr(parentCustomizedItem->m_inst, m_doc->m_api.m_bp_mgr.a_bp_id, sParentId);
	i=sParentId.Find(_T("___"));
	if(i<0) i=sParentId.ReverseFind(_T('/'));
	if(i<0) i=sParentId.ReverseFind(_T('_'));
	if(i<0) i=sParentId.ReverseFind(_T('-'));
	if(i<0) i=sParentId.ReverseFind(_T(' '));
	if(i>=0) m_doc->m_api.m_bp_mgr.m_sIdPostfixForCreateBPCopy=sParentId.Right(sParentId.GetLength()-i);

	aplExtent extForExpand;

	for(i=extBpIerarhy.GetSize()-1; i>0; i--)
	{
		CaplInstance *topbp=extBpIerarhy[i];
		CaplInstance *subbp=extBpIerarhy[i-1];

		aplExtent extContent;
		CaplInstance * locker=0;
		m_doc->m_api.m_data.GetAttr(topbp, m_doc->m_api.m_bp_mgr.a_bp_lock, locker);
		if(locker) m_doc->m_api.m_data.GetAttr(locker, m_doc->m_api.m_bp_mgr.a_bp_ver_elements, extContent);
		else m_doc->m_api.m_data.GetAttr(topbp, m_doc->m_api.m_bp_mgr.a_bp_elements, extContent);
	
		k=-1; // индекс заменяемого в массиве
		for(j=0; j<extContent.GetSize(); j++)
		{
			if(extContent[j]==subbp) {k=j; break;}
		}
		if(k<0) 
		{
			AfxMessageBox(APL_T("Некорректные данные в структуре бизнес-процессов.\n\nОперация прервана!"),MB_ICONSTOP);
			return false;
		}		

		CaplInstance *subbpcopy=m_doc->m_api.m_bp_mgr.CreateBPCopy(subbp);
		extForExpand.Add(subbpcopy);
		m_doc->m_api.m_bp_mgr.CheckIn(subbpcopy,false,true);

		extContent.SetAt(k,subbpcopy);
		if(locker)  m_doc->m_api.m_data.PutAttr(locker, m_doc->m_api.m_bp_mgr.a_bp_ver_elements, extContent);
		else m_doc->m_api.m_data.PutAttr(topbp, m_doc->m_api.m_bp_mgr.a_bp_elements, extContent);

		extBpIerarhy.SetAt(i-1,subbpcopy);
	}

	m_doc->m_api.m_bp_mgr.m_sIdPostfixForCreateBPCopy.Empty();
	m_doc->m_api.SaveChanges();

	parentCustomizedItem->Expand(TVE_COLLAPSE);
	parentCustomizedItem->ExpandTree(extForExpand, 0);
	// После этого ничего вызывать нельзя, т.к. текущего Item-a уже нет.
	return true;
}

	