// aplCategoryItem.cpp

#include "stdafx.h"
#include <time.h>
#include "PSMDoc.h"
#include "resource.h"
#include "Defence.h"

#include "aplTopLevelItem.h"
#include "TreeProductItem.h"
#include "aplDocTreeItem.h"
#include "apl_prd_inst_item.h"
#include "aplTreeCharacteristicItem.h"
#include "aplCharacteristicGroupTreeItem.h"
#include "ProductCategoryDlg.h"
#include "aplTreeApprovalItem.h"

#include "NavigatorView.h"


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

bool CaplTreeItem::m_def_context_menu=false;
bool CaplTreeItem::m_LbDblClick_Open=true;
bool CaplCategoryTreeItem::m_bShowName=true;
bool CaplCategoryTreeItem::m_bShowID=false;

bool CaplTreeItem::m_bShowNoFoundMessage=true;

CaplProductTreeItem *baseitem1;
CaplCategoryTreeItem *b;

//****************************************************************
//****************************************************************
//****************************************************************
CaplCategoryTreeItem::CaplCategoryTreeItem(CTreeCtrl *tree, CPSMDoc *doc,
				CaplCategoryTreeItem *parent, CaplInstance *instance)
{ 
	m_type=APL_TREE_ITEM_CATEGORIES;
	m_tree=tree;
	m_doc=doc;
	m_parent=parent;
	m_inst=instance;
	m_folder=0;
	m_classifier=0;
	m_bIsPArent=false;
	if(doc!=0) doc->m_items.Add(this);

	m_pLockInfo=0;
	m_rev=0;
}
//****************************************************************
bool CaplCategoryTreeItem::TrackPopupMenu(CWnd *wnd, CPoint &point, UINT view_mode)
{
   if(m_inst==0) return false;
   if(m_inst->GetAccessmode()>aplRO) {aplErrorMessage(S::NoAccessRight(),m_inst);return false;};

	CMenu menu;  gSetPsmResourceHandle();
	VERIFY(menu.LoadMenu(IDR_TREE_CONTEXT_MENU));
// 	VERIFY(menu.LoadToolBar(IDR_MENU_ICONS));
	CaplMenu::Install(wnd); // 	VERIFY(CaplMenu::Install(wnd, ePopupMenu ));
	CMenu *pPopup = menu.GetSubMenu(INDEX_CAGEGORY_MENU);
	if(pPopup!=0)
	{
		AppendAddIn((CMenu*)pPopup);
		UpdateMenu((CMenu**)&pPopup, view_mode);
		
// 		if(m_inst==0)
// 		{
// 			pPopup->EnableMenuItem(ID_SHOW_CONTAINED_FOLDER, MF_BYCOMMAND | MF_GRAYED);
// 			pPopup->EnableMenuItem(ID_SHOW_CONTAINED_CLASSIFIER, MF_BYCOMMAND | MF_GRAYED);
// 			pPopup->EnableMenuItem(ID_CREATE_PRODUCT,MF_BYCOMMAND|MF_GRAYED);
// 			pPopup->EnableMenuItem(ID_FREZEE_INST, MF_BYCOMMAND | MF_GRAYED);
// 			pPopup->EnableMenuItem(ID_SET_INST_ACCSESS, MF_BYCOMMAND | MF_GRAYED);
// 			pPopup->EnableMenuItem(ID_SHOW_PROPERTIES, MF_BYCOMMAND | MF_GRAYED);
// 			pPopup->EnableMenuItem(ID_SHOW_ALL_DOCS, MF_BYCOMMAND | MF_GRAYED);
// 			pPopup->EnableMenuItem(ID_CREATE_DOC, MF_BYCOMMAND | MF_GRAYED);
// 			pPopup->EnableMenuItem(ID_SHOW_PARENT_CATEGORIES, MF_BYCOMMAND | MF_GRAYED);
// 			pPopup->EnableMenuItem(ID_EDIT_COPY, MF_BYCOMMAND | MF_GRAYED);
// 			pPopup->EnableMenuItem(ID_EDIT_PASTE, MF_BYCOMMAND | MF_GRAYED);
// 			pPopup->EnableMenuItem(ID_SHOW_ALL_CHARACTERISTIC, MF_BYCOMMAND | MF_GRAYED);
// 			pPopup->EnableMenuItem(ID_CREATE_CHARACTERISTIC, MF_BYCOMMAND | MF_GRAYED);
// 			pPopup->EnableMenuItem(ID_OPEN_ITEM_IN_NEW_WINDOW, MF_BYCOMMAND | MF_GRAYED);
// 			pPopup->EnableMenuItem(ID_SHOW_CATEGORY_HISTORY, MF_BYCOMMAND | MF_GRAYED);
// 			pPopup->EnableMenuItem(ID_VIEW_CONTENT_IN_TABLE, MF_BYCOMMAND | MF_GRAYED);
// 		}
		if(!m_rev)pPopup->EnableMenuItem(ID_REVISION_MAKE_ACTIVE, MF_BYCOMMAND | MF_GRAYED);
//#ifndef _DEBUG
//		pPopup->EnableMenuItem(ID_VIEW_CONTENT_IN_TABLE, MF_BYCOMMAND | MF_GRAYED);
//#endif

		if (m_pLockInfo != NULL)
		{
			//pPopup->EnableMenuItem(ID_ITEM_CHECK_OUT, MF_BYCOMMAND | MF_GRAYED);
			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);
			//pPopup->EnableMenuItem(ID_ITEM_CHECK_IN, MF_BYCOMMAND | MF_GRAYED);
			//pPopup->EnableMenuItem(ID_ITEM_UNDO_CHECK_OUT, MF_BYCOMMAND | MF_GRAYED);
		}
		if(m_inst->GetAccessmode()>aplRW) pPopup->EnableMenuItem(ID_REVISION_MAKE_ACTIVE, MF_BYCOMMAND | 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_doc->m_api.m_prd_mgr.bNoCreateAndChangePDF)
		{
			pPopup->EnableMenuItem(ID_CREATE_PRODUCT,MF_BYCOMMAND|MF_GRAYED);
		}

		#ifdef _UNICODE
			pPopup->RemoveMenu(ID_SHOW_PARENT_CATEGORIES, MF_BYCOMMAND);
		#endif


		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_ITEM_CHECK_IN:
			if(m_doc->m_api.m_categ_mgr.CheckIn(m_inst)) { Expand(1);Expand(2); }
			RefreshAllThisCategItem();
			break;
		case ID_ITEM_CHECK_OUT:
			m_doc->m_api.m_categ_mgr.CheckOut(m_inst);
			RefreshAllThisCategItem();
			break;
		case ID_ITEM_UNDO_CHECK_OUT:
			if(m_doc->m_api.m_categ_mgr.UndoCheckOut(m_inst)) { Expand(1);Expand(2); }
			RefreshAllThisCategItem();
			break;
		case ID_CREATE_PRODUCT: CreateProduct();break;
		case ID_CREATE_CHARACTERISTIC: CreateCharacteristic(m_inst); break;
		case ID_CREATE_CHARACTERISTIC_GROUP: CreateCharacteristicGroup(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_OPEN_ITEM_IN_NEW_WINDOW:
			m_doc->OpenInstanceInNewWindow(m_inst);
			break;
		case ID_VIEW_CONTENT_IN_TABLE:
			m_doc->m_api.m_categ_mgr.MakeTable(m_inst,true);
			break;
		case ID_SHOW_PARENT_CATEGORIES:
			if(m_inst!=0)
			{
				aplExtent ext;
				m_doc->m_api.m_categ_mgr.GetAllParentCategory(m_inst,ext);
				if(ext.Size==0) AfxMessageBox( APL_T("Нет родительских категорий"));
				else
				{
					for(int i=0;i<ext.Size;i++)
					{
						if(m_all_category.Find(ext[i])!=-1) continue;
						CaplCategoryTreeItem *categ_item=
							new CaplCategoryTreeItem(m_tree,m_doc,0,ext[i]);
						categ_item->m_bIsPArent=true;
						categ_item->CreateTreeItem(m_item);
						m_all_category.Add(ext[i]);
					}
					MyExpand(false);
				}
			}
			break;
		case ID_SHOW_CATEGORY_HISTORY:
				m_doc->m_api.m_categ_mgr.CategoryHistory(m_inst);
			break;
//		case ID_SET_ACCESS_CATEGORY_CONTENT:
//			{
//				aplExtent ext;
//				ext.Add(m_inst);
//				GetCategoryExtent(&m_doc->m_api,m_inst,ext);
//				bool bContinue= false;
//				
//				for(int i=0; i<ext.Size;i++)
//				{
//					if(ext.GetAt(i)->GetAccessmode()>aplOWN)
//					{
//						CString sMes, sName;
//						m_doc->m_api.m_data.GetAttr(ext[i], m_doc->m_api.m_categ_mgr.a_categ_name, sName);
//						
//						sMes.Format(CaplTramslate::Translate(_T("Нет прав доступа на категорию \"%s\"\n")
//							_T("Доступ на данную категорию назначен не будет.\n\n")
//							_T("Пропустить подобные категории и продолжить выполнение?")), sName);
//
//						if(!bContinue)
//						{
//							if(IDNO==MessageBox(NULL, sMes, APL_T("Назначение прав доступа"), MB_YESNO|MB_ICONQUESTION)) return false;
//							else bContinue= true;
//						}
//
//						ext.Remove(i);
//						i--;
//					}
//				}
//				if(ext.Size>0)
//				{
//					if(m_doc->m_api.m_data.NET_SetInstancesAccess(&ext))
//						MessageBox(NULL,APL_T("Права доступа на входящие изделия назначены!"),APL_T("Права доступа всем входящим"),MB_ICONINFORMATION | MB_OK);
//				}
//				if(m_doc->m_api.SetRecursiveAccess(m_inst)){
//					AfxMessageBox(APL_T("Права доступа успешно изменены!"),MB_ICONINFORMATION | MB_OK);
//				}
//			}
//			break;
		case ID_SUBSCRIPTION:
				m_doc->m_api.m_message_mgr.EditItemSubscribeList(m_inst);
			break;
		case ID_REVISION_MAKE_ACTIVE:
			{
				if(m_doc->m_api.m_categ_mgr.MakeCategoryVersionActive(m_rev))
				{
					RefreshAllThisCategItem();
				}
		}
		break;
		default: PrepareContextMenu(res);
		}
	}
	return true;
}
//****************************************************************
bool CaplCategoryTreeItem::GetName(CString &name)
{
	_APL_TREE_ITEM_CHEK_PARAM_BOOL
	if(m_inst==0) name= APL_T("Категории");
	else
	{
/*		CString buf;
		if(m_rev!=0)
		{
			m_doc_data.GetAttr(m_rev,m_doc->m_api.m_categ_mgr.a_categ_ver_num,name);
			name+=_T(": ");
		}
		
		if(m_bShowID)m_doc_data.GetAttrBN(m_inst,S::id,buf);
		name+=buf;
		if(m_bShowName)
		{
			if(name!=_T("")) name+=_T(" : ");
			m_doc_data.GetAttrBN(m_inst,S::name,buf);
			name+=buf;
		}*/
		m_doc->m_api.GetItemName(m_inst,name);
	}
	return true;
}
//****************************************************************
bool CaplCategoryTreeItem::CreateTreeItem(HTREEITEM parent_item)
{
	_APL_TREE_ITEM_CHEK_PARAM
	CString buf;
	GetName(buf);

	InsetItem(buf,ICON_CATEGORIES,parent_item);

	int ico=ICON_CATEGORIES;
	if(m_inst)
	{
		if(m_rev)
		{
			ico = m_doc->m_api.GetInstIco(m_rev);
			CaplInstance *act;
			m_doc_data.GetAttr(m_inst,m_doc->m_api.m_categ_mgr.a_categ_act,act);
			SetItemImage(ICO_REL_VER, IDX_IL_TREE_REL_TYPE);
			if(m_rev==act) 
				SetItemImage(ICO_REL_ACTIVE_VER, IDX_IL_TREE_REL_TYPE);
		}
		else
		{
			ico = m_doc->m_api.GetInstIco(m_inst);
			if(m_bIsPArent)
				SetItemImage(ICO_REL_WHERE_USED, IDX_IL_TREE_REL_TYPE);
			m_doc_data.GetAttr(m_inst, m_doc->m_api.m_categ_mgr.a_categ_lock, m_pLockInfo);
		}
	}
	SetItemImage(ico, IDX_IL_TREE_ITEM);
	m_fictive_item=m_tree->InsertItem(_T("fictive"),0,0,m_item);
	m_expanded=false;
	return true;
}

//****************************************************************
bool CaplCategoryTreeItem::Expand(UINT action)
{
	// action = 2 -> развертывание 
	// action = 1 -> свертывание
	_APL_TREE_ITEM_CHEK_PARAM
	if(action==2)
	{
		if(m_expanded) return true;
		if(m_hasSubItem)Expand(1);
		if(m_bShowNoFoundMessage) m_tree->SetRedraw(FALSE);
		if(m_fictive_item!=0)
		{
			m_tree->DeleteItem(m_fictive_item);
			m_fictive_item=0;
		}
		m_expanded=true;
		
		StartBusy();
		ExpandSubCategory();
		if(m_ShowContentsOnExpand)
		{

			if(m_inst!=0)
			{
				aplExtent ext;
				if(m_rev==0) m_doc->m_api.m_categ_mgr.GetCategoryContents(m_inst,ext,false,true);
				else  m_doc->m_api.m_categ_mgr.GetCategoryContents(m_rev,ext,false,true);
				for(int i=0;i<ext.GetSize();i++)
				{
					if(!ext[i] || !ext[i]->GetId() || !ext[i]->GetType()) continue;
					if(ext[i]->GetAccessmode()>aplRO) continue;
					
					InsertInstInTree(ext[i],m_item,m_doc,m_tree,m_products,0, 0);
				}
			}
		}
		StopBusy();
		RefreshItem();
		bool old = m_bShowNoFoundMessage;
		m_bShowNoFoundMessage = false;
		m_ExecMyExpand = true;
		if(m_doc->m_auto_expand_items.m_showintree_categ&APL_SHOW_DOC)
			ShowAllDocs(false,false);
		if(m_doc->m_auto_expand_items.m_showintree_categ&APL_SHOW_CHARACT)
			ShowAllCharacteristic(false);
		if(m_doc->m_auto_expand_items.m_showintree_categ&APL_SHOW_VER)
			ShowAllVersion(false);
		m_bShowNoFoundMessage = old;
		m_ExecMyExpand = true;
		if(m_bShowNoFoundMessage) m_tree->SetRedraw(TRUE);
	}
	else if(action==1)
	{
		CollapseItem();
		m_products.Clear();
		m_all_category.Clear();
	}
	return true;
}
//****************************************************************
void CaplCategoryTreeItem::ShowCmd(long cmd)
{
	switch (cmd)
	{
	case ID_CREATE_PRODUCT: CreateProduct(); break;
	case ID_SHOW_ALL_CONTENTS:  Expand(2); MyExpand(); break;
	case ID_EXPAND_ALL: {int i=1; ExpandAll(i);} break;
	case ID_CREATE_CHARACTERISTIC: CreateCharacteristic(m_inst); break;
	case ID_ITEM_VIEW: ShowProperties(); RefreshAllThisCategItem();break;
	case ID_ITEM_CHECK_IN:
		if(m_doc->m_api.m_categ_mgr.CheckIn(m_inst)) { Expand(1);Expand(2); }
		RefreshAllThisCategItem();
		break;
	case ID_ITEM_CHECK_OUT:
		m_doc->m_api.m_categ_mgr.CheckOut(m_inst);
		RefreshAllThisCategItem();
		break;
	case ID_ITEM_UNDO_CHECK_OUT:
		if(m_doc->m_api.m_categ_mgr.UndoCheckOut(m_inst)) { Expand(1);Expand(2); }
		RefreshAllThisCategItem();
		break;
	default: PrepareContextMenu(cmd);break;
	}
}
BOOL CaplCategoryTreeItem::ShowToolBarButton(CCmdUI* pCmdUI)
{
	if(m_inst==0) return FALSE;
	if(m_inst->GetType()==0) return FALSE;

	if(m_doc->m_api.m_prd_mgr.bNoCreateAndChangePDF)
	{
		if(pCmdUI->m_nID==ID_CREATE_PRODUCT) return false;
	}

	if(pCmdUI->m_nID==ID_SHOW_ALL_VERSION)
	{
		if(m_rev!=0) return FALSE;
		pCmdUI->Enable(TRUE); return TRUE;
	}

	if (m_pLockInfo != NULL)
	{
		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;
	}

	
	switch(pCmdUI->m_nID)
	{
	case ID_SHOW_NOTES:
	case ID_CREATE_NOTE:
	case ID_SHOW_ALL_DOCS:
	case ID_SHOW_ALL_CHARACTERISTIC:
//	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:
		pCmdUI->Enable(TRUE); return TRUE; break;
	}
	return FALSE;
}
//****************************************************************
bool CaplCategoryTreeItem::ShowInListCtrl(CListCtrl *list)
{
	if(list==0) return false;
	CHECK_SHOW_LIST_CTRL_TOP(m_inst, APL_T("Категории"));
	if(m_inst->GetAccessmode()>aplRO)return false;
	if(m_doc==0)return false;
	if(m_doc->m_BShowInListCtrl==false) return true;
	//LoadProperties();

	int i;
	CString buf;
	if(m_inst!=0)
	{
		i=list->InsertItem(0, APL_T("Обозначение:"));
		m_doc_data.GetAttr(m_inst,m_doc->m_api.m_categ_mgr.a_categ_id,buf);
		list->SetItemText(i,1,buf);

		i=list->InsertItem(1, APL_T("Наименование:"));
		m_doc_data.GetAttr(m_inst,m_doc->m_api.m_categ_mgr.a_categ_name,buf);
		list->SetItemText(i,1,buf);

		i=list->InsertItem(2, APL_T("Описание:"));
		m_doc_data.GetAttr(m_inst,m_doc->m_api.m_categ_mgr.a_categ_descr,buf);
		list->SetItemText(i,1,buf);

		list->InsertItem(3,_T(""));
		i=list->InsertItem(4, APL_T("Доступ:"));
		GetAccessName(m_inst,buf);
		list->SetItemText(i,1,buf);

	}

	if(m_pLockInfo!=0)
	{
		i=list->InsertItem(5,_T(""));

		buf=_T("");
		CaplInstance *user,*po;
		m_doc_data.GetAttr(m_pLockInfo,m_doc->m_api.m_categ_mgr.a_categ_ver_author,user);
		if(user!=0)
		{
			i=list->InsertItem(6, 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,buf);
			//else m_doc->m_api.m_appr_mgr.GetPersonName(po,buf);
			else m_doc->m_api.GetItemName(po,buf);
			list->SetItemText(i,1,buf);
		}
		
		m_doc_data.GetAttr(m_pLockInfo,m_doc->m_api.m_categ_mgr.a_categ_ver_start,buf);
		if(buf!=_T(""))
		{
			i=list->InsertItem(7, APL_T("Начало редактирования:"));
			COleDateTime odt;
			aplString2Date(buf,odt);	
			buf=odt.Format(_T("%d.%m.%Y  %H:%M:%S"));
			list->SetItemText(i,1,buf);
		}
	}
	else if(m_rev!=0)
	{
		i=list->InsertItem(5,_T(""));

		buf=_T("");
		CaplInstance *user,*po;
		m_doc_data.GetAttr(m_rev,m_doc->m_api.m_categ_mgr.a_categ_ver_author,user);
		if(user!=0)
		{
			i=list->InsertItem(6, 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,buf);
			//else m_doc->m_api.m_appr_mgr.GetPersonName(po,buf);
			else m_doc->m_api.GetItemName(po,buf);
			list->SetItemText(i,1,buf);
		}
		
		m_doc_data.GetAttr(m_rev,m_doc->m_api.m_categ_mgr.a_categ_ver_start,buf);
		if(buf!=_T(""))
		{
			i=list->InsertItem(7, APL_T("Начало редактирования:"));
			COleDateTime odt;
			aplString2Date(buf,odt);	
			buf=odt.Format(_T("%d.%m.%Y  %H:%M:%S"));
			list->SetItemText(i,1,buf);
		}
		m_doc_data.GetAttr(m_rev,m_doc->m_api.m_categ_mgr.a_categ_ver_end,buf);
		if(buf!=_T(""))
		{
			i=list->InsertItem(8, APL_T("Завершение редактирования:"));
			COleDateTime odt;
			aplString2Date(buf,odt);	
			buf=odt.Format(_T("%d.%m.%Y  %H:%M:%S"));
			list->SetItemText(i,1,buf);
		}
	}

	aplExtent ext;
	list->InsertItem(9,_T(""));
	i=list->InsertItem(10, APL_T("Содержит изделий:"));
	m_doc->m_api.m_categ_mgr.GetCategoryContents(m_inst,ext);
	//m_doc_data.GetAttr(m_inst,m_doc->m_api.m_categ_mgr.a_categ_products,ext);
	buf.Format(_T("%i"),ext.GetSize());
	list->SetItemText(i,1,buf);


	CStringArray comment;
	ext.Clear();
	if(m_inst!=0){ comment.Add( APL_T("Категория")); ext.Add(m_inst);}
	if(m_rev!=0){ comment.Add( APL_T("Версия")); ext.Add(m_rev);}
	if(m_pLockInfo!=0){ comment.Add( APL_T("Блокировка")); ext.Add(m_pLockInfo);}
	if(m_folder!=0){ comment.Add(_T("m_folder")); ext.Add(m_folder);}
	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;
}
//****************************************************************
bool CaplCategoryTreeItem::RefreshItem()
{
	int ico=ICON_CATEGORIES;
//	if(m_bIsPArent) ico+=2;
	if(m_inst)
	{
		if(m_rev)
		{
			ico = m_doc->m_api.GetInstIco(m_rev);
			CaplInstance *act;
			m_doc_data.GetAttr(m_inst,m_doc->m_api.m_categ_mgr.a_categ_act,act);
			SetItemImage(ICO_REL_VER, IDX_IL_TREE_REL_TYPE);
			if(m_rev==act) 
				SetItemImage(ICO_REL_ACTIVE_VER, IDX_IL_TREE_REL_TYPE);
		}
		else
		{
			ico = m_doc->m_api.GetInstIco(m_inst);
			if(m_bIsPArent)
				SetItemImage(ICO_REL_WHERE_USED, IDX_IL_TREE_REL_TYPE);
			m_doc_data.GetAttr(m_inst, m_doc->m_api.m_categ_mgr.a_categ_lock, m_pLockInfo);
		}
	}
	SetItemImage(ico, IDX_IL_TREE_ITEM);
	CString name;
	GetName(name);
	m_tree->SetItemText(m_item,name);
	Sort();
	m_tree->RedrawWindow();
	return true;
}
//****************************************************************
bool CaplCategoryTreeItem::RefreshAllThisCategItem()
{
	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)
			{
				CaplCategoryTreeItem *item=(CaplCategoryTreeItem*)m_doc->m_items[i];
				if(item->m_inst==m_inst) 
					item->RefreshItem();
			}
		}
	}
	RefreshItem();
	return true;
}
//****************************************************************
void CaplCategoryTreeItem::ShowProperties()
{
    if(m_doc==0) return;
    if(m_inst==0) return;
	if(m_inst->GetAccessmode()>aplRO) {aplErrorMessage(S::NoAccessRight(),m_inst);return;};
   
	m_doc_data.ClearLastQuery();
    LoadProperties();    
	
	CString buf;
    CProductCategoryDlg dlg;
    m_doc_data.GetAttrBN(m_inst,S::id,buf);
    dlg.m_id=buf;
    m_doc_data.GetAttrBN(m_inst,S::name,buf);
    dlg.m_name=buf;
    m_doc_data.GetAttrBN(m_inst,S::description,buf);
    dlg.m_descr=buf;
	dlg.m_inst=m_inst;
    dlg.DoModal();
}
//****************************************************************
void CaplCategoryTreeItem::GetAccessedInstances(aplExtent &ext)
{
	ext.Clear();
	if(m_inst!=0){if(m_inst->GetType()!=0)ext.Add(m_inst);}
}

//****************************************************************
void CaplCategoryTreeItem::ExpandSubCategory()
{
	int i;
	if(m_rev!=0) return;
	if(m_inst==0)
	{
		if(m_doc_data.entities.Size<1) return;
	}
	else
	{
		if(m_inst->GetType()==0)return;
		if(m_inst->GetAccessmode()>aplRO) {aplErrorMessage(S::NoAccessRight(),m_inst);return;};
	}

	// Запись категорий
	aplExtent categ, rels;
	bool has_child=false;
	m_doc->m_api.m_categ_mgr.GetAllSubCategory2(m_inst,categ,rels);
	for(i=0;i<categ.Size;i++)
	{
		if(!categ[i] || !categ[i]->GetId() || !categ[i]->GetType()) continue;
		if(categ[i]->GetAccessmode()>aplRO) continue;
		
		CaplCategoryTreeItem *categ_item=
			new CaplCategoryTreeItem(m_tree,m_doc,this,categ[i]);
		categ_item->CreateTreeItem(m_item);
		has_child=true;
	}
//	if(!has_child) SetItemImage(ICON_CATEGORIES, IDX_IL_TREE_ITEM);
}

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

void CaplCategoryTreeItem::CreateProduct(CaplProductTreeItem *baseitem)
{
	if(m_doc==0) return;
	if(m_inst==0) return;

	if(m_doc->m_api.m_prd_mgr.bNoCreateAndChangePDF)
	{
		AfxMessageBox(IDS_NO_CREATE_PDF,MB_OK|MB_ICONSTOP);
		return;
	}
	
	if(m_inst->GetAccessmode()>aplRW)	{AfxMessageBox(ID_NO_ACCESS_RIGHT,MB_OK|MB_ICONSTOP); return;}

	CaplInstance *lock,*user;
	m_doc_data.GetAttr(m_inst,m_doc->m_api.m_categ_mgr.a_categ_lock,lock);
	if(lock==0)
	{
		if(IDNO==AfxMessageBox( APL_T("Категория не заблокирована !\n\nЗаблокировать ?"),MB_YESNO|MB_ICONQUESTION))
		{RefreshAllThisCategItem();	return ;}
		if(!m_doc->m_api.m_categ_mgr.CheckOut(m_inst))
		{RefreshAllThisCategItem(); return ;}
	}
	else
	{
		m_doc_data.GetAttr(lock,m_doc->m_api.m_categ_mgr.a_categ_ver_author,user);
		if(user!=m_doc_data.GetCurrUser())
		{
			AfxMessageBox( APL_T("Категория заблокирована другим пользователем !"),MB_OK|MB_ICONSTOP);
			RefreshAllThisCategItem();
			return ;
		}
	}

	CString buf;
	CaplInstance* BaseItem = NULL;

	if(baseitem!=0)
		BaseItem = baseitem->m_pdf;
	else
		BaseItem = m_inst;

	CaplInstance* tmp_inst = m_doc->m_api.m_prd_mgr.CreateProduct(BaseItem, aplModeCreateProduct);
	if(tmp_inst!=0)
	{
		if(m_doc->m_api.m_categ_mgr.AddPrdToCategory(tmp_inst, m_inst))
		{
			InsertInstInTree(tmp_inst, m_item, m_doc, m_tree, m_products, 0, 0);
		}
		RefreshAllThisCategItem();
		m_tree->RedrawWindow();
	}
}
//****************************************************************
bool CaplCategoryTreeItem::PasteItem(CaplTreeItem *item, CPoint *point)
{
	if(item==0) return false;
	if((item->m_type!=APL_TREE_ITEM_PRODUCT)
		&&(item->m_type!=APL_TREE_ITEM_CHARACTERISTICGROUP)
		&&(item->m_type!=APL_TREE_ITEM_CHARACTERISTIC)
		&&(item->m_type!=APL_TREE_ITEM_DOCUMENT)
		&&(item->m_type!=APL_TREE_ITEM_PRDINST)) 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_inst->GetAccessmode()>aplRO) {aplErrorMessage(S::NoAccessRight(),m_inst);return false;};

	
	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;
	}

	if(item->m_type==APL_TREE_ITEM_PRODUCT || item->m_type==APL_TREE_ITEM_PRDINST)
	{
		if(m_inst->GetAccessmode()>aplRW)
			{AfxMessageBox(ID_NO_ACCESS_RIGHT,MB_OK|MB_ICONSTOP); return true;}

		aplExtent ext;
		item->GetAccessedInstances(ext);
		CString state=_T("");
		if(m_doc_data.IsKindOf(ext[0],m_doc->m_api.m_prd_mgr.e_pdf))
			m_doc_data.GetAttr(ext[0],m_doc->m_api.m_prd_mgr.a_apl_pdf_state,state);
		if(state==_T("canceled")) return false;

		bool bIsPrdInst=false;
		CaplInstance *pasted_inst=0;
		if(item->m_type==APL_TREE_ITEM_PRODUCT)
			pasted_inst=((CaplProductTreeItem*)item)->m_prd;
		else if(item->m_type==APL_TREE_ITEM_PRDINST)
		{
			pasted_inst=((CaplPrdInstTreeItem*)item)->m_inst;
			bIsPrdInst=true;
		}

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

		CMenu menu;  gSetPsmResourceHandle();
		VERIFY(menu.LoadMenu(IDR_PASTE_ITEM_MENU));
// 		VERIFY(menu.LoadToolBar(IDR_MENU_ICONS));
		CaplMenu::Install(m_tree); // 		VERIFY(CaplMenu::Install(m_tree, ePopupMenu ));
		CMenu *pPopup = menu.GetSubMenu(INDEX_CAGEGORY_MENU);
		if(pPopup!=0)
		{
			if(m_inst==0) pPopup->EnableMenuItem(ID_CREATE_PRODUCT,MF_BYCOMMAND|MF_GRAYED);
			if(bIsPrdInst)pPopup->EnableMenuItem(ID_CATEGORY_ITEM_CREATE_PRODUCT,MF_BYCOMMAND|MF_GRAYED);
			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_CATEGORY_ITEM_INSERT_PRODUCT)
			{
				if(pasted_inst!=0)
				{
					CaplInstance *lock,*user;
					m_doc_data.GetAttr(m_inst,m_doc->m_api.m_categ_mgr.a_categ_lock,lock);
					if(lock==0)
					{
						if(IDNO==AfxMessageBox( APL_T("Категория не заблокирована !\n\nЗаблокировать ?"),MB_YESNO|MB_ICONQUESTION))
						{
							RefreshAllThisCategItem();
							return false;
						}
						if(!m_doc->m_api.m_categ_mgr.CheckOut(m_inst)) return false;
						RefreshAllThisCategItem();
					}
					else
					{
						m_doc_data.GetAttr(lock,m_doc->m_api.m_categ_mgr.a_categ_ver_author,user);
						if(user!=m_doc_data.GetCurrUser())
						{
							AfxMessageBox( APL_T("Категория заблокирована другим пользователем !"),MB_OK|MB_ICONSTOP);
							RefreshAllThisCategItem();
							return false;
						}
					}
					if(m_doc->m_api.m_categ_mgr.AddPrdToCategory(pasted_inst,m_inst))
					{
						InsertInstInTree(pasted_inst,m_item,m_doc,m_tree,m_products,0, 0);
					}
				}
				m_tree->RedrawWindow();
			}
			else if(res==ID_CATEGORY_ITEM_CREATE_PRODUCT) CreateProduct((CaplProductTreeItem*)item);
		}
	}
	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_doc_mgr.a_apl_doc_wf_state,state);
		if(state==_T("canceled")) return false;

		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 ));

		pPopup = menu.GetSubMenu(INDEX_DOCUMENT_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;
			}

			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);
					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 ((item->m_type==APL_TREE_ITEM_CHARACTERISTIC)||(item->m_type==APL_TREE_ITEM_CHARACTERISTICGROUP))
	{
		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 ));

		pPopup = menu.GetSubMenu(INDEX_CHARACTERISTIC_MENU);
		
		if(pPopup!=0)
		{
			BOOL res=pPopup->TrackPopupMenu(TPM_LEFTALIGN|
				TPM_RIGHTBUTTON|TPM_RETURNCMD,pnt.x,pnt.y,m_tree);

			// Вставка характеристики
			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 CaplCategoryTreeItem::LoadProperties()
{
	if(m_PropertiesLoaded) return;
    if(m_doc==0) return;
	m_doc->m_api.m_categ_mgr.LoadCategoryInfo(m_inst);
}
//****************************************************************
bool CaplCategoryTreeItem::PasteFile(LPCTSTR file, CPoint *point)
{
	if(file==0) return false;
	if(m_inst==0) return false;
	CreateDoc(m_inst,file);
	return true;
}/*
//****************************************************************
void CaplCategoryTreeItem::CreateCharacteristic(CaplInstance *val)
{
	if(m_inst==0) return;
	if(m_inst->GetType()==0) return;
	if(m_inst->GetAccessmode()>aplRO) {aplErrorMessage(S::NoAccessRight,m_inst);return;};
	CaplInstance *new_val=0;
	if(m_doc->m_api.m_charact_mgr.CreateCharacteristic(m_inst,val, &new_val,0,0,true))
	{

		if(CaplTreeItem::m_AutoUzurpireCharacteristic)
		{
			aplExtent ext; ext.Add(new_val);
			m_doc_data.NET_BecomeInstancesOwner(&ext);
		}

		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 CaplCategoryTreeItem::CreateCharacteristicGroup(CaplInstance *group)
{
	CaplInstance *group_new=0;
	if(m_doc->m_api.m_charact_mgr.CreateCharacteristicGroup(m_inst,&group_new,group))
	{
		if(group!=0)
		{
			if(CaplTreeItem::m_AutoUzurpireCharacteristic)
			{
				aplExtent ext; ext.Add(group);
				m_doc_data.NET_BecomeInstancesOwner(&ext);
			}
		}
		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 CaplCategoryTreeItem::ShowAllVersion(bool showMsg)
{
	if(m_inst==0) return;
	aplExtent ext0;
	int i;
	if(m_inst->GetAccessmode()>aplRO) return;
	if(m_rev!=0) return;

	StartBusy();
	// чтение из базы
	SetStatusString( APL_T("Чтение из базы"));
	m_doc->m_api.m_categ_mgr.LoadCategoryInfo(m_inst,false);
	m_doc->m_api.m_categ_mgr.GetAllCategoryVersion(m_inst,ext0);
	SetStatusString(_T(""));
	StopBusy();
	if(ext0.Size<=0 ) {if(showMsg)AfxMessageBox( APL_T("Нет версий !")); return;}
	// отображение версий
	if(m_bShowNoFoundMessage) m_tree->SetRedraw(FALSE);
	
	CaplInstance *lock=m_doc->m_api.m_categ_mgr.CheckMyLock(m_inst,false);
	for(i=0;i<ext0.Size;i++)
	{
		if(ext0[i]==lock) continue;
		bool flag=true;
		for(int j=0;j<m_all_version.Size;j++)
		{
			if(m_all_version[j]==ext0[i])
			{
				flag=false;
				break;
			}
		}
		if(flag)
		{
			CaplCategoryTreeItem *categ_item=
				new CaplCategoryTreeItem(m_tree,m_doc,this,m_inst);
			categ_item->CreateTreeItem(m_item);
			categ_item->m_rev=ext0[i];
			m_all_version.Add(ext0[i]);
			categ_item->RefreshItem();
		}
	}	
	if(m_ExecMyExpand)
		MyExpand(false);

	StopBusy();
	if(m_bShowNoFoundMessage) m_tree->SetRedraw(TRUE);

}

bool CaplCategoryTreeItem::GetCategoryExtent(CaplAPI *api, CaplInstance *inst, aplExtent &ext)
{
	aplExtent t_ext, rels;
	api->m_categ_mgr.GetAllSubCategory2(inst,t_ext, rels);
	if(t_ext.Size==0) return false;
	ext.Append(t_ext);
	for(int i=0; i<t_ext.Size; i++)
		GetCategoryExtent(api,t_ext[i],ext);
	t_ext.Clear();
	return true;
}