// aplPersonTreeItem.cpp: implementation of the CaplPersonTreeItem class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "psmdoc.h"
#include "aplPersonTreeItem.h"
#include "psm.h"
#include "aplDocTreeItem.h"
#include "aplTreeCharacteristicItem.h"
#include "aplCharacteristicGroupTreeItem.h"
#include "aplOrganizationTreeItem.h"
#include "aplMessageTreeItem.h"
#include "TabView.h"

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

#define docdata m_doc->m_api.m_data
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CaplPersonTreeItem::CaplPersonTreeItem(CTreeCtrl *tree, CPSMDoc *pDoc, CaplInstance *inst, CaplInstance *m_po)
{
	m_folder = 0;
	m_type = APL_TREE_ITEM_PERSON;
	m_tree = tree;
	m_doc = pDoc;
	m_official = 0;
	m_person = 0;
	m_person_organization = m_po;
	if(m_doc->m_api.m_data.IsKindOf(inst,pDoc->m_api.m_appr_mgr.e_person))
		m_person = inst;
	if(m_doc->m_api.m_data.IsKindOf(inst,pDoc->m_api.m_appr_mgr.e_official))
	{
		m_official = inst;
		m_doc->m_api.m_data.GetAttr(inst,m_doc->m_api.m_appr_mgr.a_official_act_person,m_person);
	}
	if(m_person || m_official) m_doc->m_items.Add(this);
	if(m_official) m_type = APL_TREE_ITEM_OFFICIAL;
}

CaplPersonTreeItem::~CaplPersonTreeItem()
{

}

bool CaplPersonTreeItem::GetName(CString &name)
{
	_APL_TREE_ITEM_CHEK_PARAM_BOOL
	name = _T("Person");
	if(m_official!=0)
	{
		m_doc->m_api.GetItemName(m_official,name);
	}
	else if(m_person!=0){
		m_doc->m_api.GetItemName(m_person,name);
	}
	if(m_person_organization!=0)
	{
		CString pos;
		m_doc->m_api.m_data.GetAttr(m_person_organization, m_doc->m_api.m_appr_mgr.a_po_person_pos, pos);
		if(pos!=_T("")) { name+=_T(" : "); name+=pos;}
	}
	if(name==_T("")) name=_T("???");
	return true;
}

bool CaplPersonTreeItem::CreateTreeItem(HTREEITEM parent_item)
{
    if(m_tree==0) return false;
    if(m_doc==0) return false;
	if(m_person_organization!=0) 
	{
		CString val,val2;
		if(m_person_organization) m_doc->m_api.m_data.GetAttr(m_person_organization,
			m_doc->m_api.m_appr_mgr.a_po_end_date,val);
		COleDateTime curtime = COleDateTime::GetCurrentTime();
		aplDate2String(curtime,val2);
 		if(val<val2 && val>_T("")) 
		{ 
			font_style|=APL_FONT_STRIKEOUT;
			color=RGB(128,128,128);
		}
	}

	CString name;
	GetName(name);
	int ico = -1;
	if(m_official)
		ico = m_doc->m_api.GetInstIco(m_official);
	else if(m_person)
		ico = m_doc->m_api.GetInstIco(m_person);
	InsetItem(name,ico,parent_item);
	SetItemImage(ico, IDX_IL_TREE_ITEM);
	m_fictive_item=m_tree->InsertItem(_T("fictive"),ICON_ORGANIZATION,ICON_ORGANIZATION,m_item);
	m_expanded=false;
	
	return true;
}

bool CaplPersonTreeItem::Expand(UINT action)
{
	if(m_fictive_item) 
	{
		m_tree->DeleteItem(m_fictive_item);
		m_fictive_item = 0;
	}
	if(action==2)
	{
		if(m_ShowContentsOnExpand)
		{
			UINT state = 0;
			if(m_type==APL_TREE_ITEM_OFFICIAL)
			{
				state = m_doc->m_auto_expand_items.m_showintree_official;
				if(m_contents.Find(m_person)<0)
				{
					if(m_person!=0)
					{
						CaplPersonTreeItem *pers = new CaplPersonTreeItem(m_tree,m_doc,m_person);
						pers->CreateTreeItem(m_item);
						m_contents.Add(m_person);
					}
				}
			}
			else 
				state = m_doc->m_auto_expand_items.m_showintree_person;
			bool old = m_bShowNoFoundMessage;
			m_bShowNoFoundMessage = old;
			m_ExecMyExpand = true;
			if(state&APL_SHOW_DOC)
				ShowAllDocs(false, false);
			if(state&APL_SHOW_CHARACT)
				ShowAllCharacteristic(false);
			m_bShowNoFoundMessage = old;
			m_ExecMyExpand = true;
		}
	}
	else if(action==1)
	{
		CollapseItem();
		m_all_parents.Clear();
		m_contents.Clear();
	}
	return true;
}

bool CaplPersonTreeItem::ShowInListCtrl(CListCtrl *list)
{

	aplExtent ext;
	CStringArray  comment;
	CString id, name,descr,access;
	if(m_type==APL_TREE_ITEM_OFFICIAL)
	{
		CHECK_SHOW_LIST_CTRL(m_official);
		CaplInstance *inst;
		int ind = list->InsertItem(0, APL_T("Обозначение:"));
		m_doc->m_api.m_data.GetAttr(m_official,m_doc->m_api.m_appr_mgr.a_official_id,id);
		m_doc->m_api.m_data.GetAttr(m_official,m_doc->m_api.m_appr_mgr.a_official_descr,descr);
		m_doc->m_api.m_data.GetAttr(m_official,m_doc->m_api.m_appr_mgr.a_official_owner,inst);
		if(inst) m_doc->m_api.GetItemName(inst,name);
		else name =  APL_T("Не определен");
		list->SetItemText(ind,1,id);
		ind = list->InsertItem(list->GetItemCount(), APL_T("Владелец:"));
		list->SetItemText(ind,1,name);
		m_doc->m_api.m_data.GetAttr(m_official,m_doc->m_api.m_appr_mgr.a_official_act_person,inst);
		if(inst) m_doc->m_api.GetItemName(inst,name);
		else name =  APL_T("Не определен");
		ind = list->InsertItem(list->GetItemCount(), APL_T("Исполнитель:"));
		list->SetItemText(ind,1,name);
		ind = list->InsertItem(list->GetItemCount(), APL_T("Описание:"));
		list->SetItemText(ind,1,descr);
		list->InsertItem(list->GetItemCount(),_T(""));
		ind = list->InsertItem(list->GetItemCount(), APL_T("Доступ:"));
		GetAccessName(m_official,access);
		list->SetItemText(ind,1,access);
		
	}
	else if(m_type==APL_TREE_ITEM_PERSON)
	{
		CHECK_SHOW_LIST_CTRL(m_person);
		int ind = list->InsertItem(0, APL_T("Обозначение:"));
		m_doc->m_api.m_data.GetAttr(m_person,m_doc->m_api.m_appr_mgr.a_pers_id,id);
		m_doc->m_api.m_data.GetAttr(m_person,m_doc->m_api.m_appr_mgr.a_pers_last_name,name);
		list->SetItemText(ind,1,id);
		ind = list->InsertItem(list->GetItemCount(), APL_T("Фамилия:"));
		list->SetItemText(ind,1,name);
		m_doc->m_api.m_data.GetAttr(m_person,m_doc->m_api.m_appr_mgr.a_pers_first_name,name);
		ind = list->InsertItem(list->GetItemCount(), APL_T("Имя:"));
		list->SetItemText(ind,1,name);
		CaplAggr aggr;
		m_doc->m_api.m_data.GetAttr(m_person,m_doc->m_api.m_appr_mgr.a_pers_middle_names,aggr);
		aggr.GetByIndex(0,name);
		ind = list->InsertItem(list->GetItemCount(), APL_T("Отчество:"));
		list->SetItemText(ind,1,name);

		m_doc->m_api.m_data.GetAttr(m_person,m_doc->m_api.m_appr_mgr.a_pers_descr,descr);
		descr.Replace(_T("\r\n"), _T(" ")); 
		ind = list->InsertItem(list->GetItemCount(),  APL_T("Описание:"));
		list->SetItemText(ind,1,descr);

		list->InsertItem(list->GetItemCount(),_T(""));

		CString buf;
		m_doc->m_api.m_data.GetAttr(m_person,m_doc->m_api.m_appr_mgr.a_pers_phone,buf);
		if(buf!=_T(""))
		{
			ind = list->InsertItem(list->GetItemCount(),  APL_T("Телефон:"));
			list->SetItemText(ind,1,buf);
		}

		m_doc->m_api.m_data.GetAttr(m_person,m_doc->m_api.m_appr_mgr.a_pers_e_mail,buf);
		if(buf!=_T(""))
		{
			ind = list->InsertItem(list->GetItemCount(),  APL_T("e-mail:"));
			list->SetItemText(ind,1,buf);
		}

		m_doc->m_api.m_data.GetAttr(m_person,m_doc->m_api.m_appr_mgr.a_pers_actual_address,buf);
		if(buf!=_T(""))
		{
			ind = list->InsertItem(list->GetItemCount(),  APL_T("Адрес:"));
			list->SetItemText(ind,1,buf);
		}

		list->InsertItem(list->GetItemCount(),_T(""));
		ind = list->InsertItem(list->GetItemCount(), APL_T("Дата зачисления"));
		if(m_person_organization) m_doc->m_api.m_data.GetAttr(m_person_organization,
			m_doc->m_api.m_appr_mgr.a_po_start_date,name);
		COleDateTime time;
		aplString2Date(name,time);
		name = time.Format(_T("%d.%m.%Y"));
		list->SetItemText(ind,1,name);
		ind = list->InsertItem(list->GetItemCount(), APL_T("Дата исключения"));
		if(m_person_organization) m_doc->m_api.m_data.GetAttr(m_person_organization,
			m_doc->m_api.m_appr_mgr.a_po_end_date,name);
		aplString2Date(name,time);
		name = time.Format(_T("%d.%m.%Y"));
		list->SetItemText(ind,1,name);
		
	}
	if(m_person!=0){
		comment.Add(_T("m_person"));
		ext.Add(m_person);
	}
	
	if(m_official!=0){
		comment.Add(_T("m_official"));
		ext.Add(m_official);
	}
	
	ShowInstanceInfoInListCtrl(ext,list,&comment);
	return true;
}

bool CaplPersonTreeItem::PasteFile(LPCTSTR file, CPoint *point)
{
	if(file==0) return false;
	if(m_person!=0) CreateDoc(m_person,file);
	return true;
}

bool CaplPersonTreeItem::PasteItem(CaplTreeItem *item, CPoint *point)
{
	if(item->m_type!=APL_TREE_ITEM_DOCUMENT &&
		item->m_type!=APL_TREE_ITEM_CHARACTERISTIC &&
		item->m_type!=APL_TREE_ITEM_CHARACTERISTICGROUP)
	{
		CaplInstance *inst = 0;
		if(m_type==APL_TREE_ITEM_OFFICIAL) inst = m_official;
		else if(m_type==APL_TREE_ITEM_PERSON) inst = m_person;
		aplExtent ext;
		item->GetAccessedInstances(ext);
		CaplMessageTreeItem::CreateMessage(m_doc,inst,ext);
		return true;
	}
	CMenu menu;  gSetPsmResourceHandle();
	CMenu *Popup;
	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_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;
		Popup = menu.GetSubMenu(2);
	}
	else if(item->m_type==APL_TREE_ITEM_CHARACTERISTIC || item->m_type==APL_TREE_ITEM_CHARACTERISTICGROUP)
		Popup = menu.GetSubMenu(3);

	if(Popup!=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 = Popup->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON|TPM_RETURNCMD,pnt.x,pnt.y,m_tree);
		
		CaplInstance *m_inst=0;
		if(m_type==APL_TREE_ITEM_PERSON) m_inst = m_person;
		else if(m_type==APL_TREE_ITEM_OFFICIAL) m_inst = m_official;
		// Вставка документа
		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()>0)
					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))
				ShowAllDocs();
		}
		//создание по образцу
		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]))
				ShowAllDocs();
		}
		//премещение документа
		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(m_inst,i_val);
			}
			else if(item->m_type == APL_TREE_ITEM_CHARACTERISTICGROUP)
			{
				CreateCharacteristicGroup(m_inst,((CaplCharacteristicGroupTreeItem*)item)->m_group);

			}
		}
	}
	return true;
}

bool CaplPersonTreeItem::TrackPopupMenu(CWnd *wnd, CPoint &point, UINT view_mode)
{ 
	CaplInstance *m_inst=0;
	if(m_type==APL_TREE_ITEM_OFFICIAL) m_inst = m_official;
	else if(m_type==APL_TREE_ITEM_PERSON) m_inst=m_person;
	if(m_inst==0) return false;
	CMenu menu;  gSetPsmResourceHandle();
	CMenu *Popup=NULL;
	VERIFY(menu.LoadMenu(IDR_TREE_CONTEXT_MENU));
// 	VERIFY(menu.LoadToolBar(IDR_MENU_ICONS));
	CaplMenu::Install(m_tree); // 	VERIFY(CaplMenu::Install(m_tree, ePopupMenu ));
	Popup = menu.GetSubMenu(25);
	if(Popup!=0)
	{
		AppendAddIn((CMenu*)Popup);
		UpdateMenu((CMenu**)&Popup, view_mode);

		if(m_folder==0)
			Popup->EnableMenuItem(ID_REMOVE_FROM_FOLDER, MF_BYCOMMAND | MF_GRAYED);
		
		if(m_type==APL_TREE_ITEM_PERSON) Popup->EnableMenuItem(ID_FREZEE_ALL_PRODUCT_CONTENTS,MF_BYCOMMAND|MF_GRAYED);
		BOOL res = Popup->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON|TPM_RETURNCMD,point.x,point.y,wnd);
		if(res==ID_CREATE_DOC) CreateDoc();
		else if(res==ID_CREATE_CHARACTERISTIC) CreateCharacteristic(m_inst);
		else if(res==ID_CREATE_CHARACTERISTIC_GROUP) CreateCharacteristicGroup(m_inst);
		else if(res==ID_SHOW_PROPERTIES) m_doc->m_api.m_appr_mgr.ShowPersonProperties(m_inst);
		else if(res==ID_OPEN_ITEM_IN_NEW_WINDOW) m_doc->OpenInstanceInNewWindow(m_inst);
		else if(res==ID_NEW_MESSAGE_CREATE) 
		{
			aplExtent ext;
			GetAccessedInstances(ext);
			CaplInstance *resp = ext[0];
			ext.Clear();
			CaplMessageTreeItem::CreateMessage(m_doc,resp,ext);
		}
		else if(res==ID_WHERE_USED_PERORG)
		{
			ShowAllParentOrgs();
		}
		else if(res==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));
			}				
		}
		else PrepareContextMenu(res);
	}
	return true;
}

void CaplPersonTreeItem::GetAccessedInstances(aplExtent &ext)
{
	ext.Clear();
	if(m_type==APL_TREE_ITEM_PERSON){if(m_person!=0){if(m_person->GetType()!=0)ext.Add(m_person);}}
	else if(m_type==APL_TREE_ITEM_OFFICIAL){if(m_official!=0){if(m_official->GetType()!=0)ext.Add(m_official);}}
}

void CaplPersonTreeItem::ShowCmd(long cmd)
{
	if(cmd == ID_CREATE_CHARACTERISTIC) 
	{
		aplExtent ext;			
		GetAccessedInstances(ext);
		CreateCharacteristic(ext[0]);
	}
	else PrepareContextMenu(cmd);
}

BOOL CaplPersonTreeItem::ShowToolBarButton(CCmdUI *pCmdUI)
{
	if(m_type==APL_TREE_ITEM_PERSON){
		if(m_person==0) return FALSE;
		if(m_person->GetType()==0) return FALSE;
	}
	if(m_type==APL_TREE_ITEM_OFFICIAL){
		if(m_official==0) return FALSE;
		if(m_official->GetType()==0) return FALSE;
	}
	switch(pCmdUI->m_nID)
	{
		case ID_SHOW_ALL_DOCS:
		case ID_SHOW_ALL_CHARACTERISTIC:
		case ID_CREATE_DOC:
		case ID_CREATE_CHARACTERISTIC:
		case ID_SHOW_NOTES:
		case ID_CREATE_NOTE:
			pCmdUI->Enable(TRUE); return TRUE; break;
	}
	return FALSE;
}

void CaplPersonTreeItem::ShowProperties()
{
	CaplInstance *m_inst=0;
	if(m_type==APL_TREE_ITEM_PERSON) m_inst = m_person;
	else if(m_type==APL_TREE_ITEM_OFFICIAL) m_inst = m_official;
	if(m_inst!=0) m_doc->m_api.m_appr_mgr.ShowPersonProperties(m_inst);
}

void CaplPersonTreeItem::ShowAllParentOrgs()
{
	if(m_doc==0) return;
	StartBusy();
	m_tree->SetRedraw(FALSE);
	
	aplExtent ext;
	aplExtent orgs;
	CaplInstance* inst;
	CString end_date;
	int i;

	CaplAPI* api= &m_doc->m_api;
	
	if(api->m_data.IsKindOf(m_person, api->m_appr_mgr.e_person) || api->m_data.IsKindOf(m_person, api->m_appr_mgr.e_official))
	{
		api->m_data.GetEntityExtent(api->m_appr_mgr.e_pers_org, ext);

		for(i=0; i<ext.GetSize(); i++)
		{
			api->m_data.GetAttr(ext[i], api->m_appr_mgr.a_po_the_pers, inst);
			if(inst==m_person)
			{
				api->m_data.GetAttr(ext[i], api->m_appr_mgr.a_po_end_date, end_date);
				if(end_date!=_T("")) continue;

				api->m_data.GetAttr(ext[i], api->m_appr_mgr.a_po_the_org, inst);
				CaplOrganizationTreeItem* org_Item= NULL;
				if(InsertInstInTree(inst, m_item, m_doc, m_tree, m_all_parents, 0, ((CaplTreeItem**)&org_Item)))
				{
					org_Item->m_used_inst_rel= ext[i];
					org_Item->RefreshItem();
				}
			}
		}
	}

	MyExpand(false);
	StopBusy();
	m_tree->SetRedraw(TRUE);
}


bool CaplPersonTreeItem::RefreshItem()
{
	_APL_TREE_ITEM_CHEK_PARAM_BOOL
		
	int ico = -1;
	if(m_official)
		ico = m_doc->m_api.GetInstIco(m_official);
	else if(m_person)
		ico = m_doc->m_api.GetInstIco(m_person);
	SetItemImage(ico, IDX_IL_TREE_ITEM);
	CString name;
	GetName(name);
	m_tree->SetItemText(m_item,name);
	m_tree->RedrawWindow();
	if(m_doc->m_tab_view->m_item_old==this) m_doc->ChangeItem(this);
	return true;
}