// OrganizerView.cpp : implementation file
//
#include "stdafx.h"
#include "PSM.h"
#include "MainFrm.h"
#include "TabView.h"
#include "PSMDoc.h"
#include "aplTreeItem.h"
#include "NavigatorView.h"
#include "aplQueryItem.h"
#include "aplTopLevelItem.h"
#include "aplFolderTreeItem.h"
#include "PersonalFolderItem.h"
#include "aplMessageFolderTreeItem.h"
#include "aplTreeWfFolderItem.h"
#include "aplOrganizationTreeItem.h"
#include "aplRecAlertTreeItem.h"
#include "aplClassifierTreeItem.h"
#include "ClipboardTreeItem.h"
#include "aplDocTreeItem.h"


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

const TCHAR CF_HINST_NAME[]=APL_INSTANCE_CLIPBOARDFORMAT;
const TCHAR CF_HINST_EXT[]=_T("CF_APL_H_EXT");
const TCHAR CF_HTREEITEN_NAME[]=_T("CF_APL_H_TREE_ITEM");

/////////////////////////////////////////////////////////////////////////////
// CNavigatorView
bool CNavigatorView::AutoCloseItem=false;
bool CNavigatorView::DblclickViewDoc=false;

IMPLEMENT_DYNCREATE(CNavigatorView, CaplTreeView)

CNavigatorView::CNavigatorView()
{
	m_LastLeftDownTreeItem=0;
	m_queries_item=0;
	m_cur_categ_item=0;
	m_last_tic_count=GetTickCount();
	m_cur_item=0;
}

CNavigatorView::~CNavigatorView()
{
	CPSMDoc *doc=(CPSMDoc*)GetDocument();
	VERIFY(doc!=0);

	CTreeCtrl *tree=&GetTreeCtrl();
	int i;
	for(i=0;i<doc->m_items.Size;i++)
	{
		if(doc->m_items[i]->m_tree==tree)
		{
			doc->m_items.Remove(i);
			i--;
		}
	}
	for(i=0; i<doc->m_additional_views.GetSize();i++)
	{
		if(doc->m_additional_views[i]==this)
		{
			doc->m_additional_views.RemoveAt(i);
			break;
		}
	}
}

CTreeCtrl& CNavigatorView::aplGetTreeCtrl()	{return CTreeView::GetTreeCtrl();};
CTreeCtrl& CNavigatorView::GetTreeCtrl()	{return CTreeView::GetTreeCtrl();};


BEGIN_MESSAGE_MAP(CNavigatorView, CaplTreeView)
	//{{AFX_MSG_MAP(CNavigatorView)
	ON_WM_CREATE()
	ON_WM_RBUTTONDOWN()
	ON_WM_RBUTTONUP()
	ON_WM_RBUTTONDBLCLK()
	ON_NOTIFY_REFLECT(TVN_BEGINLABELEDIT, OnBeginlabeledit)
	ON_NOTIFY_REFLECT(TVN_ENDLABELEDIT, OnEndlabeledit)
	ON_NOTIFY_REFLECT(TVN_ITEMEXPANDING, OnItemexpanding)
	ON_NOTIFY_REFLECT(TVN_SELCHANGING, OnSelchanging)
	ON_WM_LBUTTONDBLCLK()
	ON_NOTIFY_REFLECT(TVN_BEGINDRAG, OnBegindrag)
	ON_COMMAND(ID_REAL_CREATE_PRODUCT, OnRealCreateProduct)
//	ON_COMMAND(ID_EDIT_COPY, OnCopy)
	ON_WM_CONTEXTMENU()
	ON_WM_LBUTTONDOWN()
	ON_WM_KEYDOWN()
	ON_WM_CHAR()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CNavigatorView drawing

/////////////////////////////////////////////////////////////////////////////
// CNavigatorView diagnostics

#ifdef _DEBUG
void CNavigatorView::AssertValid() const
{
	CaplTreeView::AssertValid();
}

void CNavigatorView::Dump(CDumpContext& dc) const
{
	CaplTreeView::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CNavigatorView message handlers

int CNavigatorView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CaplTreeView::OnCreate(lpCreateStruct) == -1)
		return -1;

	// TODO: Add your specialized creation code here
	m_dropTarget.Register(this);
//	GetTreeCtrl().ModifyStyle(WS_VSCROLL,TVS_HASLINES|TVS_HASBUTTONS|/*TVS_SINGLEEXPAND|*/
		//TVS_FULLROWSELECT| 
//		TVS_LINESATROOT|TVS_SHOWSELALWAYS|WS_CHILD|WS_VISIBLE);

	GetTreeCtrl().SetImageList(aplGetInstImageList(), TVSIL_NORMAL);

	m_StrikeOutPen.CreatePen(PS_SOLID,1,RGB(128,128,128));

	//GetTreeCtrl().SetItemHeight(18);

	
	SetImageList(aplGetRelImageList(),IDX_IL_TREE_REL_TYPE);	
	SetImageList(aplGetEffImageList(),IDX_IL_TREE_EFF);
	SetImageList(aplGetInstImageList(),IDX_IL_TREE_ITEM);
	SetImageList(aplGetStateImageList(),IDX_IL_TREE_STATE);
	SetImageList(aplGetObjStateImageList(),IDX_IL_TREE_OBJ_STATE);
	SetImageList(aplGetItemSubtypeImageList(),IDX_IL_TREE_ITEM_SUBTYPE);

	return 0;
}


//*************************************************************************
void CNavigatorView::OnInitialUpdate() 
{
	//AfxMessageBox(_T("DEBUG CNavigatorView::OnInitialUpdate();"));
	CaplTreeView::OnInitialUpdate();
	//m_dropTarget.Register(this);	
	
	// TODO: Add your specialized code here and/or call the base class
	//CPSMDoc *doc=(CPSMDoc*)((CMainFrame*)AfxGetMainWnd())->m_last_open_doc;
	CPSMDoc *doc=(CPSMDoc*)GetDocument();
	VERIFY(doc!=0);

	CTreeCtrl& m_tree=GetTreeCtrl();
	m_tree.SetRedraw(FALSE);
	m_tree.DeleteAllItems();
	m_tree.SetRedraw(TRUE);
	
	if(doc->m_navigator==0)
	{
		if(m_pDocument!=doc) doc->AddView(this);
		doc->m_navigator=this;

		CMainFrame *mf=(CMainFrame*)AfxGetMainWnd();
		if(mf)((CTabView*)(mf->m_InfoBar.m_MyWnd))->AttachToDoc(doc);

		((CMDIChildWnd*)GetParentFrame())->MDIMaximize( );

		if(doc->m_show_prd!=_T("") || doc->m_show_doc!=_T("")){
			if(m_queries_item==0)m_queries_item= new CaplQueryTreeItem(&m_tree,doc);
			m_queries_item->CreateTreeItem(TVI_ROOT);
		}
		
		if(doc->m_show_prd!=_T(""))doc->ShowItem(_T("product"),doc->m_show_prd);
		if(doc->m_show_doc!=_T(""))doc->ShowItem(_T("document"),doc->m_show_doc);
	}
	
	if(0==doc->m_inserted_instances_in_new_window.GetSize()) // Если главное окно делится пополам, часть корневых эл-тов добавляем
	{
		m_desk_item = GetTreeCtrl().InsertItem( APL_T("Мой рабочий стол"),ICON_DESKTOP,ICON_DESKTOP,TVI_ROOT);
		SetItemImage(m_desk_item, ICON_DESKTOP, IDX_IL_TREE_ITEM);
		if(doc->m_navigator==this)
		{
			HTREEITEM work_item= GetTreeCtrl().InsertItem( APL_T("Работы"), ICON_PROCESS, ICON_PROCESS, m_desk_item);
			SetItemImage(work_item, ICON_PROCESS, IDX_IL_TREE_ITEM);
			
			CaplWfFolderTreeItem* pTFolder= new CaplWfFolderTreeItem(
				&m_tree, doc);
			pTFolder->m_name=  APL_T("Задания");
			pTFolder->CreateTreeItem(work_item);
			
			CaplWfFolderTreeItem* pPFolder= new CaplWfFolderTreeItem(
				&m_tree, doc);
			pPFolder->m_name=  APL_T("Процессы");
			pPFolder->CreateTreeItem(work_item);

			CaplWfFolderTreeItem* pPTFolder= new CaplWfFolderTreeItem(
				&m_tree, doc);
			pPTFolder->m_name=  APL_T("Шаблоны");
			pPTFolder->CreateTreeItem(work_item);

			work_item= GetTreeCtrl().InsertItem( APL_T("Диспетчер напоминаний"), ICON_ALERT, ICON_ALERT, m_desk_item);
			SetItemImage(work_item, ICON_ALERT, IDX_IL_TREE_ITEM);
			
			CaplAlertTreeItem* pRecAlert = new CaplAlertTreeItem(&m_tree, doc);
			doc->m_RecAlert=pRecAlert;
			pRecAlert->m_type = _T("received");
			pRecAlert->CreateTreeItem(work_item);
			
			CaplAlertTreeItem* pDisAlert = new CaplAlertTreeItem(&m_tree, doc);
			doc->m_DisAlert=pDisAlert;
			pDisAlert->m_type = _T("distributed");
			pDisAlert->CreateTreeItem(work_item);
			
			CaplMessageFolderTreeItem *pMailRootFolder= new CaplMessageFolderTreeItem(
				&m_tree, doc);
			pMailRootFolder->m_name=  APL_T("Почта");
			pMailRootFolder->CreateTreeItem(m_desk_item);
//			doc->m_user_incoming_folder= (CaplTreeItem*)pIncFolder;
			
//			HTREEITEM mail_item=GetTreeCtrl().InsertItem(APL_T("Почта"), ICON_MESSAGES, ICON_MESSAGES, desk);
//			SetItemImage(mail_item, ICON_MESSAGES, IDX_IL_TREE_ITEM);
				
//			CaplMessageFolderTreeItem *pIncFolder= new CaplMessageFolderTreeItem(
//				&m_tree, doc);
//			pIncFolder->m_name= APL_T("Входящие");
//			pIncFolder->CreateTreeItem(pMailRootFolder->m_item);
//			doc->m_user_incoming_folder= (CaplTreeItem*)pIncFolder;
//
//			CaplMessageFolderTreeItem *pSendFolder= new CaplMessageFolderTreeItem(
//				&m_tree, doc);
//			pSendFolder->m_name= APL_T("Отправленные");
//			pSendFolder->CreateTreeItem(pMailRootFolder->m_item);
//			doc->m_user_sended_folder= (CaplTreeItem*)pSendFolder;
//			
//			CaplMessageFolderTreeItem *pDraftFolder= new CaplMessageFolderTreeItem(
//				&m_tree, doc);
//			pDraftFolder->m_name= APL_T("Черновики");
//			pDraftFolder->CreateTreeItem(pMailRootFolder->m_item);
//			doc->m_user_drafted_folder= (CaplTreeItem*)pDraftFolder;
		}
		else doc->m_additional_views.Add(this);

		CaplPersonalFolderTreeItem *pPersonalFolder= 
			new CaplPersonalFolderTreeItem(&m_tree, doc, 0);
		pPersonalFolder->CreateTreeItem(m_desk_item);

		//Мои заблокированные обекты;
		CaplFolderTreeItem *lock_objects = new CaplFolderTreeItem(&m_tree,doc);
		lock_objects->m_type = _T("Super_type");
		lock_objects->CreateTreeItem(m_desk_item);

		CClipboardTreeItem *pClipItem = new CClipboardTreeItem(&m_tree, doc);
		pClipItem->CreateTreeItem(m_desk_item);
		m_clipboard_item = pClipItem->m_item;

		//Папки
		CaplFolderTreeItem * pRootFolder = new CaplFolderTreeItem(&m_tree, doc, 0);
		pRootFolder->CreateTreeItem(TVI_ROOT);
		
		//Категории
		if(doc->m_b_show_categ)
		{
			CaplCategoryTreeItem *categ_item= new CaplCategoryTreeItem(&m_tree,doc);
			categ_item->CreateTreeItem(TVI_ROOT);
		}
		
		//Классификаторы
		if(doc->m_api.m_show.m_show_classificators)
		{
			CaplClassifierTreeItem *classif_item= new CaplClassifierTreeItem(&m_tree,doc);
			classif_item->CreateTreeItem(TVI_ROOT);
		}
		
		//Орг. структура
		if(doc->m_api.m_show.m_show_org_struct)
		{
			CaplOrganizationTreeItem *org = new CaplOrganizationTreeItem(&m_tree, doc);
			org->CreateTreeItem(TVI_ROOT);
		}
		
		if(m_queries_item==0)m_queries_item= new CaplQueryTreeItem(&m_tree,doc);
		m_queries_item->CreateTreeItem(TVI_ROOT);
		
		if(doc->m_bShowMonitor)
		{
			doc->CheckNewMonitorEvents(doc->m_hMonitorFlag, doc->m_sMonitorText);
		}
	}
	else
	{
		aplExtent ext;
		CaplTreeItem *newiem=0;
		int i;
		SetRedraw(FALSE);
		for(i=0; i<doc->m_inserted_instances_in_new_window.GetSize();i++)
		{
			CaplTreeItem::InsertInstInTree(doc->m_inserted_instances_in_new_window[i],TVI_ROOT,
				doc, &GetTreeCtrl(),ext,0,&newiem);
		}
		SetRedraw(TRUE);
		if(newiem!=0  && doc->m_inserted_instances_in_new_window.GetSize()==1) // был только один
		{
			GetTreeCtrl().Expand(newiem->m_item,TVE_EXPAND);
		}
		doc->m_inserted_instances_in_new_window.Clear();
	}
	Invalidate();
	aplInstallFindInCtrl(this);
}
//*************************************************************************
void CNavigatorView::OnDragLeave() 
{
	// TODO: Add your specialized code here and/or call the base class
	CaplTreeView::OnDragLeave();
}
//*************************************************************************
DROPEFFECT CNavigatorView::OnDragEnter(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point) 
{
	// TODO: Add your specialized code here and/or call the base class
	return	DROPEFFECT_LINK|DROPEFFECT_COPY;
	//return CaplTreeView::OnDragEnter(pDataObject, dwKeyState, point);
}
//*************************************************************************
DROPEFFECT CNavigatorView::OnDragOver(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point) 
{
	// Сделать активным
	CMDIChildWnd *act_frm=((CMDIFrameWnd*)AfxGetMainWnd())->MDIGetActive();
	CWnd *my_frm=this->GetParentFrame();
	if(my_frm!=act_frm)((CMDIFrameWnd*)AfxGetMainWnd())->MDIActivate(my_frm);

	// Разрешить
	UINT flag=TVHT_ONITEM|TVHT_ONITEMRIGHT;
	m_LastLeftDownTreeItem=GetTreeCtrl().HitTest(point,&flag);
	if(m_LastLeftDownTreeItem!=0)GetTreeCtrl().SelectDropTarget(m_LastLeftDownTreeItem);
	return	DROPEFFECT_LINK|DROPEFFECT_COPY;
	//return CaplTreeView::OnDragOver(pDataObject, dwKeyState, point);
}

void CNavigatorView::OnRButtonUp(UINT nFlags, CPoint point) 
{
	//
}

void CNavigatorView::OnRButtonDblClk(UINT nFlags, CPoint point) 
{
	OnRButtonDown(nFlags, point);
}
 
//*************************************************************************
void CNavigatorView::OnRButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
    UINT flag=TVHT_ONITEM|TVHT_ONITEMRIGHT;
    HTREEITEM cur_item=GetTreeCtrl().HitTest(point,&flag);
    if (cur_item!=NULL) 
	{
		GetTreeCtrl().SelectItem(cur_item);
		GetTreeCtrl().SelectDropTarget(cur_item);
	}
    CaplTreeView::OnRButtonDown(nFlags, point);
	ClientToScreen(&point);
	if(cur_item!=0)
	{
		CaplTreeItem *item=(CaplTreeItem*)GetTreeCtrl().GetItemData(cur_item);
		if(item!=0) item->TrackPopupMenu(this,point);
	}
}
//****fhfhf*********************************************************************
void CNavigatorView::OnBeginlabeledit(NMHDR* pNMHDR, LRESULT* pResult) 
{
	TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
	// TODO: Add your control notification handler code here
	*pResult = 1;
	HTREEITEM sel_item=GetTreeCtrl().GetSelectedItem();
	int i=0,j=0;
	if(GetTreeCtrl().GetItemImage(sel_item,i,j))
	{
		if(i==ICON_FOLDERS)
		{
			*pResult = 0;
		}
	}
}
//*************************************************************************
void CNavigatorView::OnEndlabeledit(NMHDR* pNMHDR, LRESULT* pResult) 
{
	TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
	// TODO: Add your control notification handler code here

	*pResult = 1;
}
//*************************************************************************
void CNavigatorView::OnCopy() 
{
	HTREEITEM item=GetTreeCtrl().GetSelectedItem();
	CMyOleDataSource*	pSource = PrepareCOleDataSource(item);
	if(pSource==0) return;
	pSource->SetClipboard();
	//delete pSource;
}
//*************************************************************************
void CNavigatorView::OnLButtonDown(UINT nFlags, CPoint point) 
{
	UINT flag=TVHT_ONITEM|TVHT_ONITEMRIGHT;
	m_LastLeftDownTreeItem=GetTreeCtrl().HitTest(point,&flag);
	if(m_LastLeftDownTreeItem!=0)
	{
		/*Когда выскакивает какие-нибудь сообщение, то выделяется не текущий Item, 
		а Item под курсором мышки (в районе кнопки на сообщении).*/
		GetTreeCtrl().SelectItem(m_LastLeftDownTreeItem);
		GetTreeCtrl().SelectDropTarget(m_LastLeftDownTreeItem);
		
	}
//a	m_lbtn_down=true;
	CTreeView::OnLButtonDown(nFlags, point);
}
//*************************************************************************
CMyOleDataSource* CNavigatorView::PrepareCOleDataSource(HTREEITEM item)
{
	if(item==0) return 0;
	int item_data=(int)GetTreeCtrl().GetItemData(item);
	CaplTreeItem *tr_item=(CaplTreeItem *)item_data;
	if(tr_item==0) return 0;

	aplExtent ext;
	tr_item->GetMainInstances(ext);
	if(ext.Size<1) return 0;
	if(ext[0]->GetType()==0)  return 0;
	if(ext[0]->GetAccessmode()>aplRO)  return 0;
	if(ext.Size>1)
	{
		if(ext[1]->GetType()==0)  return 0;
		if(ext[1]->GetAccessmode()>aplRO)  return 0;
	}
	CMyOleDataSource*	pSource = new CMyOleDataSource();
	if(pSource==0) return 0;
	HGLOBAL hMem;
	UINT cf_htree=RegisterClipboardFormat(CF_HTREEITEN_NAME);	
 	UINT cf_hinst=RegisterClipboardFormat(CF_HINST_NAME);	
	UINT cf_hrel=RegisterClipboardFormat(CF_HINST_EXT);	
	
	CString		text=GetTreeCtrl().GetItemText(item);
	hMem=GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE|GMEM_ZEROINIT,(text.GetLength()+1)*sizeof(TCHAR));
	if (!hMem) return 0;
	TCHAR *xxx=(TCHAR*)GlobalLock(hMem);
	memcpy(xxx,LPCTSTR(text),(text.GetLength()+1)*sizeof(TCHAR));		
	GlobalUnlock(hMem);
	pSource->CacheGlobalData(CF_TEXT, hMem);

	if(item_data!=0)
	{
		hMem=GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE|GMEM_ZEROINIT,8);
		if (!hMem) return pSource;
		DWORD procid=GetCurrentProcessId();

		int* phItem=(int*)GlobalLock(hMem);
		phItem[0]=procid;	
		phItem[1]=item_data;
		GlobalUnlock(hMem);
		pSource->CacheGlobalData(cf_htree, hMem);

		tr_item->CopyDataToDataSource(pSource);

		if(ext.GetSize()>0)
		{
			hMem=GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE|GMEM_ZEROINIT,8);
			if (!hMem) return pSource;
			
			phItem=(int*)GlobalLock(hMem);
			phItem[0]=procid;	
			phItem[1]= (DWORD)ext[0]->GetId();
			GlobalUnlock(hMem);
			pSource->CacheGlobalData(cf_hinst, hMem);

			if(ext.GetSize()>1)
			{
				int size = sizeof(DWORD)*(2+ext.GetSize());

				hMem=GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE|GMEM_ZEROINIT,size);
				if (!hMem) return pSource;

				phItem=(int*)GlobalLock(hMem);
				phItem[0]=procid;	
				phItem[1]= (DWORD)ext.GetSize();
				for(int i=0; i<ext.GetSize(); i++)
					phItem[2+i] = ext[i]->GetId();

				GlobalUnlock(hMem);
				pSource->CacheGlobalData(cf_hrel, hMem);
			}
		}
	}
	return pSource;
}
//*************************************************************************
void CNavigatorView::OnPaste() 
{
//	UINT cf_hinst=RegisterClipboardFormat(CF_HTREEITEN_NAME);
	COleDataObject pDataObject;
	if(!pDataObject.AttachClipboard()) return;
	if(!OnPaste(pDataObject))
		MessageBeep(MB_ICONEXCLAMATION);
	pDataObject.Release();
}
//*************************************************************************
void CNavigatorView::OnItemexpanding(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
	// TODO: Add your control notification handler code here
	HTREEITEM cur_item=pNMTreeView->itemNew.hItem;
	if(pNMTreeView->action==2)
	{
		if(AutoCloseItem)
		{
			HTREEITEM hNextItem,par_0=cur_item;	
			HTREEITEM par_1=GetTreeCtrl().GetParentItem(cur_item);
			while(1)
			{
			   HTREEITEM hChildItem = GetTreeCtrl().GetChildItem(par_1);
			   while (hChildItem != NULL)
			   {
					hNextItem = GetTreeCtrl().GetNextItem(hChildItem, TVGN_NEXT);
					if(hChildItem!=par_0)
					{
						CaplTreeItem *item=(CaplTreeItem*)(GetTreeCtrl().GetItemData(hChildItem));
						if(item!=0)item->Expand(1);
						GetTreeCtrl().Expand(hChildItem,TVE_COLLAPSE);
					}
					hChildItem = hNextItem;
			   }
			   if(par_1==0) break;
			   par_0=par_1;
			   par_1=GetTreeCtrl().GetParentItem(par_1);
			}
		}
	}
	CaplTreeItem *item=(CaplTreeItem*)(GetTreeCtrl().GetItemData(cur_item));
	if(item!=0)item->Expand(pNMTreeView->action);
	else //чтобы пустые элементы в папках Почта и Работы сворачивались (+)
	{
		if(pNMTreeView->action==1)//например, при закрытиии...
		{
			HTREEITEM hChildItem = GetTreeCtrl().GetChildItem(cur_item);
			while(hChildItem!=NULL)
			{
				CaplTreeItem *item=(CaplTreeItem*)(GetTreeCtrl().GetItemData(hChildItem));
				if(item!=0)item->Expand(1);
				GetTreeCtrl().Expand(hChildItem,TVE_COLLAPSE);
				hChildItem = GetTreeCtrl().GetNextItem(hChildItem, TVGN_NEXT);
			}
		}
	}
	*pResult = 0;
}
//*************************************************************************
void CNavigatorView::ShowProperties() 
{
	// TODO: Add your command handler code here
	HTREEITEM sel_item=GetTreeCtrl().GetSelectedItem();
	CaplTreeItem *item=(CaplTreeItem*)GetTreeCtrl().GetItemData(sel_item);
	if(item!=0)item->ShowProperties();
}

//*************************************************************************
BOOL CNavigatorView::OnDrop(COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point) 
{
	// TODO: Add your specialized code here and/or call the base class
	UINT flag=TVHT_ONITEM|TVHT_ONITEMRIGHT;
	m_LastLeftDownTreeItem=GetTreeCtrl().HitTest(point,&flag);
	if(pDataObject!=0)
		if(!OnPaste(*pDataObject,&point)) MessageBeep(MB_ICONEXCLAMATION);
	if(m_LastLeftDownTreeItem!=0)GetTreeCtrl().SelectItem(m_LastLeftDownTreeItem);
	return CaplTreeView::OnDrop(pDataObject, dropEffect, point);
}


//*************************************************************************
bool CNavigatorView::OnPaste(COleDataObject &pDataObject, CPoint *point)
{
	// Определение Item назначения
	HTREEITEM treeitem=0;
	bool res=false;
	CPoint *pnt=0;
	CString fname;
	if(point!=0)
	{
		pnt=point;
		UINT flag=TVHT_ONITEM|TVHT_ONITEMRIGHT;
		treeitem=GetTreeCtrl().HitTest(*point,&flag);
		ClientToScreen(pnt);
	}else 
		treeitem=GetTreeCtrl().GetSelectedItem();
	
	CaplTreeItem *item=0;
	if(treeitem!=0) item=(CaplTreeItem*)GetTreeCtrl().GetItemData(treeitem);
	if(item==0) return false;

	// Тестовый кусок
	FORMATETC FormatEtc;
	TCHAR cfbuf[4096];
	pDataObject.BeginEnumFormats();
	while(pDataObject.GetNextFormat(&FormatEtc))
	{
		int kk=GetClipboardFormatName(FormatEtc.cfFormat,(TCHAR*)cfbuf,4096);
		int a=1;
	}
	// Конец теста	
	CPSMDoc *doc=(CPSMDoc*)GetDocument();

	UINT cf_hinst=RegisterClipboardFormat(CF_HTREEITEN_NAME);
	if(pDataObject.IsDataAvailable(cf_hinst))
	{
		// Вставка TreeItem
		HGLOBAL hGlob=pDataObject.GetGlobalData(cf_hinst);
		if(hGlob!=0)
		{
			int *phItem=(int*)GlobalLock(hGlob);
			DWORD procid;
			procid=phItem[0];
			CaplTreeItem *item_data=(CaplTreeItem*)phItem[1];
			GlobalUnlock(hGlob);
			if(procid!=GetCurrentProcessId())return false;
			if(item==item_data) return true;
			if(doc->m_items.Find(item_data)>-1)
			{
				return item->PasteItem(item_data,pnt);
			}
			else
				return false;
		}
	}
	cf_hinst=RegisterClipboardFormat(CF_HINST_NAME);
	if(pDataObject.IsDataAvailable(cf_hinst))
	{
		// Вставка Instance
		HGLOBAL hGlob=pDataObject.GetGlobalData(cf_hinst);
		if(hGlob!=0)
		{
			int *phItem=(int*)::GlobalLock(hGlob);
			DWORD procid;
			procid=phItem[0];
			int item_id = phItem[1];
			::GlobalUnlock(hGlob);
			if(procid!=GetCurrentProcessId())return false;
			CaplInstance *inst = ((CPSMDoc*)GetDocument())->m_api.m_data.GetInstById(item_id);
			aplExtent ext;
			item->GetAccessedInstances(ext);
			if(ext.Find(inst)>-1) return true;
			CaplTreeItem *pItem;
			aplExtent cont;
			CaplTreeItem::InsertInstInTree(inst, m_clipboard_item, doc, item->m_tree, cont, NULL, &pItem);
			if(pItem)
			{
				bool bRes = item->PasteItem(pItem, pnt);
				doc->m_items.Remove(doc->m_items.Find(pItem));
				return bRes;
			}
			return false;
		}
	}
	if(pDataObject.IsDataAvailable(CF_HDROP))
	{
		CString name;
		TCHAR str[4096];
		HDROP hdrop;
		HGLOBAL hGlob=pDataObject.GetGlobalData(CF_HDROP);
		if(hGlob!=0)
		{
			hdrop =(HDROP )GlobalLock(hGlob);
			
			int i,col;
			int size = DragQueryFile( hdrop, 0xFFFFFFFF, NULL, 0 );
			for(i=0;i<size;i++){
				col= DragQueryFile( hdrop, ( UINT )i, str, 4096 );
				str[col]=0;
				fname=str;
				res=item->PasteFile(fname,pnt);
				if(!res){
					GlobalUnlock(hGlob);
					return false;
				}
			}
			
			GlobalUnlock(hGlob);
			return true;
		}
	}
	
	cf_hinst=RegisterClipboardFormat(_T("FileName"));
	if(pDataObject.IsDataAvailable(cf_hinst))
	{

		TCHAR* str;
		HGLOBAL hGlob=pDataObject.GetGlobalData(cf_hinst);
		str=(TCHAR*)GlobalLock(hGlob);
		GetLongPathName(str, fname.GetBuffer(MAX_PATH), MAX_PATH);
		fname.ReleaseBuffer();
		res=item->PasteFile(fname,pnt);
		GlobalUnlock(hGlob);
		return res;
	}

	return res;
}
//*************************************************************************
void CNavigatorView::OnSelchanging(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
	*pResult = 0;
	// TODO: Add your control notification handler code here
	CPSMDoc *doc=(CPSMDoc*)GetDocument();
	if(doc==0) return;
	HTREEITEM cur_item=pNMTreeView->itemNew.hItem;;
	CaplTreeItem *item=(CaplTreeItem*)GetTreeCtrl().GetItemData(cur_item);
	doc->ChangeItem(item);
}
//*************************************************************************
void CNavigatorView::OnLButtonDblClk(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	if(CNavigatorView::DblclickViewDoc)
	{
		CaplTreeItem *item=(CaplTreeItem*)GetTreeCtrl().GetItemData(m_LastLeftDownTreeItem);
		if(item!=0)
		{
			if(item->m_type==APL_TREE_ITEM_DOCUMENT)
			{
				((CaplDocTreeItem*)item)->View(false);
				return;
			}
		}
	}

	if(CaplTreeItem::m_LbDblClick_Open)	CaplTreeView::OnLButtonDblClk(nFlags, point);
	else 
	{
		if(m_LastLeftDownTreeItem!=0)
		{
			CaplTreeItem *item=(CaplTreeItem*)GetTreeCtrl().GetItemData(m_LastLeftDownTreeItem);
			if(item!=0)item->ShowProperties();
		}
	}
}
//*************************************************************************
void CNavigatorView::OnBegindrag(NMHDR* pNMHDR, LRESULT* pResult) 
{
//	OutputDebugString(_T("\n CNavigatorView::OnBegindrag "));
	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
	// TODO: Add your control notification handler code here
	*pResult = 0;
	if (m_LastLeftDownTreeItem==NULL) return;
	CMyOleDataSource*	pSource = PrepareCOleDataSource(m_LastLeftDownTreeItem);
	if(pSource)
	{
		pSource->DoDragDrop();
		delete pSource;
	}
}
//*************************************************************************
//*************************************************************************
void  CNavigatorView::OnRealCreateProduct()
{
	if(m_cur_categ_item==0) return;
	m_cur_categ_item->CreateProduct();
	m_cur_categ_item=0;
}

void CNavigatorView::RunToolCmd(long cmd)
{
		HTREEITEM cur_item=GetTreeCtrl().GetSelectedItem();
		if(cur_item==0) return;
		CaplTreeItem *item=(CaplTreeItem*)GetTreeCtrl().GetItemData(cur_item);
		if(item!=0)item->ShowCmd(cmd);	
}

BOOL CNavigatorView::ShowToolBarButton(CCmdUI* pCmdUI)
{
	HTREEITEM cur_item=GetTreeCtrl().GetSelectedItem();
	if(cur_item==0) return false;
	CaplTreeItem *item=(CaplTreeItem*)GetTreeCtrl().GetItemData(cur_item);
	if(item==0)return false;
	CPSMDoc *doc=(CPSMDoc*)GetDocument();
	if(!doc) return false;
// 	if(-1==doc->m_items.Find(item)) return false;
	return item->ShowToolBarButton(pCmdUI);	
}

BOOL CNavigatorView::OnScroll(UINT nScrollCode, UINT nPos, BOOL bDoScroll) 
{
	// TODO: Add your specialized code here and/or call the base class
	if(GetTickCount()-m_last_tic_count<100) return FALSE;
	m_last_tic_count=GetTickCount();
	switch(nScrollCode)
	{
	case 0x0ff: SendMessage( WM_VSCROLL, SB_LINEUP); break;
	case 0x1ff: SendMessage( WM_VSCROLL, SB_LINEDOWN); break;
	case 0xff01: SendMessage( WM_HSCROLL, SB_LINERIGHT); break;
	case 0xff00: SendMessage( WM_HSCROLL, SB_LINELEFT); break;
	}
	return TRUE;
	
	//return CaplTreeView::OnScroll(nScrollCode, nPos, bDoScroll);
}

void CNavigatorView::OnContextMenu(CWnd* pWnd, CPoint point) 
{
	if(point.x>0 && point.y>0) {OnRButtonDown(0,point); return;}

	HTREEITEM cur_item=GetTreeCtrl().GetSelectedItem();
	if(cur_item!=0)
	{
		RECT r; 
		GetTreeCtrl().GetItemRect(cur_item,&r,TRUE);
		CPoint pnt(r.left,r.bottom+1);
		ClientToScreen(&pnt);
		CaplTreeItem *item=(CaplTreeItem*)GetTreeCtrl().GetItemData(cur_item);
		if(item!=0) item->TrackPopupMenu(this,pnt);
	}
}

void CNavigatorView::OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView) 
{
	// TODO: Add your specialized code here and/or call the base class
	CaplTreeView::OnActivateView(bActivate, pActivateView, pDeactiveView);

	if(bActivate!=TRUE) return;
	CPSMDoc *doc=(CPSMDoc*)GetDocument();
	if(doc==0) return;
	HTREEITEM cur_item=GetTreeCtrl().GetSelectedItem();
	CaplTreeItem *item=0;
	if(cur_item!=0) item=(CaplTreeItem*)GetTreeCtrl().GetItemData(cur_item);
	if(m_cur_item!=item)
	{
		doc->ChangeItem(item);
		m_cur_item=item;
	}
}

void CNavigatorView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{	
	TRACE(_T("%i --> %i --> %i \n"), nChar, nRepCnt, nFlags);
	
	HTREEITEM cur_item= GetTreeCtrl().GetSelectedItem();
	CaplTreeItem *item= NULL;
	if(cur_item!=0)
	{
		RECT itemRect; 
		GetTreeCtrl().GetItemRect(cur_item, &itemRect, TRUE);
		CPoint point(itemRect.left,itemRect.bottom+1);
		ClientToScreen(&point);
		item= (CaplTreeItem*)GetTreeCtrl().GetItemData(cur_item);
		if(item!=0)
		{
			switch (nChar)
			{
				case 45: item->TrackPopupMenu(this, point, APLICM_INSERT);return;
				case 46: item->TrackPopupMenu(this, point, APLICM_DELETE);return;
				case 32: item->TrackPopupMenu(this, point, APLICM_REFERENCES);return;
				case 13: item->ShowProperties(); return;
			}
		}
	}
	
	CaplTreeView::OnKeyDown(nChar, nRepCnt, nFlags);
}

void CNavigatorView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
{	
	CaplTreeView::OnChar(nChar, nRepCnt, nFlags);
}

