// aplBaseTreeItem.cpp: implementation of the CaplBaseTreeItem class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "aplBaseTreeItem.h"
#include "SetupShowonExpand.h"

CaplTreeExpandOptions::CaplTreeExpandOptions(UINT value)
{
	m_showintree_prd =		0;
	m_showintree_pdf =		0;
	m_showintree_prdinst =	0;
	m_showintree_doc =		0;
	m_showintree_charact =	APL_SHOW_CHARACT|APL_SHOW_APPROVAL;
	m_showintree_change =	APL_SHOW_APPROVAL;
	m_showintree_bp =		0;
	m_showintree_bpres =	0;
	m_showintree_bpinst =	0;
	m_showintree_categ =	0;
	m_showintree_lot =		0;
	m_showintree_org =		0;
	m_showintree_official = 0;
	m_showintree_person =	0;
	m_showintree_project =	0;
	m_showintree_classif_s =	0;
	m_showintree_classif_l =	0;	
}

void CaplTreeExpandOptions::EditTreeExpandOptions()
{
	CaplSetResourceHandle setres(module_inst);
	CTreeExpandOptionsDlg dlg;	
	if(IDOK==dlg.DoModal()) InitializeTreeExpandOptions();
}

void CaplTreeExpandOptions::InitializeTreeExpandOptions()
{
	CWinApp *app=AfxGetApp(); // При вызове из ActiveX возвращает 0
	if(0==app) return;
	m_showintree_prd =		(UINT)app->GetProfileInt(_T("ShowInTree"),_T("Prd"),0);
	m_showintree_pdf =		(UINT)app->GetProfileInt(_T("ShowInTree"),_T("Pdf"),0);
	m_showintree_prdinst =	(UINT)app->GetProfileInt(_T("ShowInTree"),_T("PrdInst"),0);
	m_showintree_doc =		(UINT)app->GetProfileInt(_T("ShowInTree"),_T("Doc"),0);
	m_showintree_charact =	(UINT)app->GetProfileInt(_T("ShowInTree"),_T("Charact"),APL_SHOW_CHARACT|APL_SHOW_APPROVAL);
	m_showintree_change =	(UINT)app->GetProfileInt(_T("ShowInTree"),_T("Change"),APL_SHOW_APPROVAL);
	m_showintree_bp =		(UINT)app->GetProfileInt(_T("ShowInTree"),_T("BP"),0);
	m_showintree_bpres =	(UINT)app->GetProfileInt(_T("ShowInTree"),_T("BPRes"),0);
	m_showintree_bpinst =	(UINT)app->GetProfileInt(_T("ShowInTree"),_T("BPInst"),0);
	m_showintree_categ =	(UINT)app->GetProfileInt(_T("ShowInTree"),_T("Categ"),0);
	m_showintree_lot =		(UINT)app->GetProfileInt(_T("ShowInTree"),_T("Lot"),0);
	m_showintree_org =		(UINT)app->GetProfileInt(_T("ShowInTree"),_T("Organization"),0);
	m_showintree_official = (UINT)app->GetProfileInt(_T("ShowInTree"),_T("Official"),0);
	m_showintree_person =	(UINT)app->GetProfileInt(_T("ShowInTree"),_T("Person"),0);
	m_showintree_project =	(UINT)app->GetProfileInt(_T("ShowInTree"),_T("Project"),0);
	m_showintree_classif_s=	(UINT)app->GetProfileInt(_T("ShowInTree"),_T("ClassifierSystem"),0);
	m_showintree_classif_l=	(UINT)app->GetProfileInt(_T("ShowInTree"),_T("ClassifierLevel"),0);	
}

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CaplTreeExpandOptions CaplBaseTreeItem::m_ExpandOption= (UINT)0;

CaplBaseTreeItem::CaplBaseTreeItem(CaplAPI* api/* = NULL */, CTreeCtrl* tree/* = NULL */, aplTIArray* items/* = NULL */, CaplInstance* inst/* = NULL */, CaplInstance* rel/* = NULL */)
{
	m_api= api;
	m_tree= tree;
	m_ItemsArray= items;
	
	if(m_ItemsArray)m_ItemsArray->Add(this);

	m_inst= inst;
	m_rel= rel;
}

CaplBaseTreeItem::~CaplBaseTreeItem()
{
    HTREEITEM item;
	
	if(!m_tree) return;
	if(!m_item) return;
	if(!IsWindow(m_tree->m_hWnd)) return;

    while(1)
    {
        item=m_tree->GetChildItem(m_item);
        if(item==0) break;
        CaplBaseTreeItem *treeitem= (CaplBaseTreeItem*)m_tree->GetItemData(item);
		if(treeitem==this) continue;
        if(treeitem!=0) 
		{
			int index= m_ItemsArray->Find(treeitem);
			m_ItemsArray->Remove(index);
		}
        else m_tree->DeleteItem(item);
    }
	m_tree->DeleteItem(m_item);
}

void CaplBaseTreeItem::CollapseItem(bool bInsertFictive/* = true */)
{
	if(!m_tree) return;
	if(!m_item) return;
	
	while(1)
	{
		HTREEITEM item1=m_tree->GetChildItem(m_item);
		if(item1==0) break;
		CaplBaseTreeItem *item=(CaplBaseTreeItem*)m_tree->GetItemData(item1);
		if(item!=0) m_ItemsArray->Remove(m_ItemsArray->Find(item));
		else m_tree->DeleteItem(item1);
	}
	
	m_relatedItems.Clear();
	m_relatedInstances.Clear();

	if(bInsertFictive)m_fictive_item=m_tree->InsertItem(_T("fictive"),0,0,m_item);
}

bool CaplBaseTreeItem::GetChilds(aplTIArray &childs)
{
	if(!m_tree) return false;
	if(!m_item) return false;

	HTREEITEM hItem= m_tree->GetChildItem(m_item);
	
	while(1)
	{
		if(!hItem) break;
		CaplBaseTreeItem *item=(CaplBaseTreeItem*)m_tree->GetItemData(hItem);
		if(item) childs.Add(item);
		hItem= m_tree->GetNextItem(m_item, TVGN_NEXT);
	}
	return true;
}

CaplBaseTreeItem* CaplBaseTreeItem::GetParent()
{
	if(!m_tree) return 0;
	if(!m_item) return 0;
	
	HTREEITEM hPItem= m_tree->GetParentItem(m_item);
	return (CaplBaseTreeItem*)m_tree->GetItemData(hPItem);
}

bool CaplBaseTreeItem::RefreshAllItems()
{
	if(!m_ItemsArray) return false;
	if(!m_tree) return false;

	for(int i= 0; i<m_ItemsArray->GetSize(); i++)
		m_ItemsArray->GetAt(i)->RefreshItem();

	return true;
}

void CaplBaseTreeItem::Sort(bool bRefreshParent/* =false */)
{
	if(m_tree==0) return;
	if(m_item==0) return;

	if(bRefreshParent)
	{
		if (m_tree->ItemHasChildren(m_item))
		{
		   HTREEITEM hChildItem = m_tree->GetChildItem(m_item);

		   while (hChildItem != NULL)
		   {
				CaplBaseTreeItem *item=(CaplBaseTreeItem*)m_tree->GetItemData(hChildItem);
				if(item!=0)item->RefreshItem();
				hChildItem = m_tree->GetNextItem(hChildItem, TVGN_NEXT);
		   }
		}
	}
	
	TVSORTCB sortcb;
	sortcb.hParent=m_item;
	sortcb.lpfnCompare=CompareHtreeItem;
	sortcb.lParam=1;
	m_tree->SortChildrenCB(&sortcb);
}

int CALLBACK CaplBaseTreeItem::CompareHtreeItem(LPARAM lParam1, LPARAM lParam2,LPARAM lParamSort)
{
	if(lParam1==0) return 0;
	if(lParam2==0) return 0;
	CTreeCtrl *tree=((CaplBaseTreeItem*)lParam1)->m_tree;
	if(tree==0) return 0;
	HTREEITEM item1=((CaplBaseTreeItem*)lParam1)->m_item;
	HTREEITEM item2=((CaplBaseTreeItem*)lParam2)->m_item;
	int img1,img2,img0;
	tree->GetItemImage(item1,img1,img0);
	tree->GetItemImage(item2,img2,img0);

	CaplAPI* api = ((CaplBaseTreeItem*)lParam2)->m_api;

	int rel1=0,rel2=0;
	int eff1=0,eff2=0;
	int state1=0,state2=0;
	
	CaplTreeItemData *itemdata1=(CaplTreeItemData*) tree->GetItemData(item1);
	if(itemdata1!=0)
	{
		if(itemdata1->icons[IDX_IL_TREE_ITEM]>0)
			img1=itemdata1->icons[IDX_IL_TREE_ITEM];
		if(itemdata1->icons[IDX_IL_TREE_REL_TYPE]>=0)
			rel1=itemdata1->icons[IDX_IL_TREE_REL_TYPE];
		if(itemdata1->icons[IDX_IL_TREE_EFF]>=0)
			eff1=itemdata1->icons[IDX_IL_TREE_EFF];
		if(itemdata1->icons[IDX_IL_TREE_STATE]>=0)
			state1=itemdata1->icons[IDX_IL_TREE_STATE];
	}
	
	CaplTreeItemData *itemdata2=(CaplTreeItemData*) tree->GetItemData(item2);
	if(itemdata2!=0)
	{
		if(itemdata2->icons[IDX_IL_TREE_ITEM]>0)
			img2=itemdata2->icons[IDX_IL_TREE_ITEM];
		if(itemdata2->icons[IDX_IL_TREE_REL_TYPE]>=0)
			rel2=itemdata2->icons[IDX_IL_TREE_REL_TYPE];
		if(itemdata2->icons[IDX_IL_TREE_EFF]>=0)
			eff2=itemdata2->icons[IDX_IL_TREE_EFF];
		if(itemdata2->icons[IDX_IL_TREE_STATE]>=0)
			state2=itemdata2->icons[IDX_IL_TREE_STATE];
	}
	
	int compare = api->aplCompareItemsImage(img1, img2);
	
	if(compare!=0) return compare;

	if(rel1<rel2) return -1;
	if(rel1>rel2) return  1;
	if(eff1>eff2) return 1;
	if(eff1<eff2) return -1;
	if(state1<state2) return -1;
	if(state1>state2) return 1;

	//Сравнение версий документов
	CaplInstance *inst1=((CaplBaseTreeItem*)lParam1)->m_inst;
	CaplInstance *inst2=((CaplBaseTreeItem*)lParam2)->m_inst;
	if(0!=inst1 && 0!=inst2)
	{
		if(api->m_data.IsKindOf(inst1,api->m_doc_mgr.e_apl_doc_rev) &&
		   api->m_data.IsKindOf(inst2,api->m_doc_mgr.e_apl_doc_rev))
		{
			CString v1, v2;
			api->m_data.GetAttr(inst1,api->m_doc_mgr.a_apl_doc_rev_id,v1);
			api->m_data.GetAttr(inst2,api->m_doc_mgr.a_apl_doc_rev_id,v2);
			int inum1=_atoi(v1);
			int inum2=_atoi(v2);
			return (inum1>inum2);
		}
	}

	// Изменено 27.09.2023 для нормальной сортировки проектов по просьбе Созвездия
	if((img1>=ICON_DOC_INDEX && img1<ICON_CHARACT_INDEX) ||
		(img1>=ICON_PRODUCT_INDEX && img1<ICON_CONTINUE_INDEX+2))  // тут изделия и проекты
		return aplCompareNumericStr(tree->GetItemText(item1),tree->GetItemText(item2));
	
	return (tree->GetItemText(item1)).Compare(tree->GetItemText(item2));
}
