//ClassifierTreeItem.h
#include "stdafx.h"
#include "ClassifierTreeView.h"

int CALLBACK CClassifierTreeItem::CompareHtreeItem(LPARAM lParam1, LPARAM lParam2,LPARAM lParamSort)
{
	if(lParam1==0) return 0;
	if(lParam2==0) return 0;
	CTreeCtrl *tree=((CClassifierTreeItem*)lParam1)->m_tree;
	if(tree==0) return 0;
	HTREEITEM item1=((CClassifierTreeItem*)lParam1)->m_item;
	HTREEITEM item2=((CClassifierTreeItem*)lParam2)->m_item;
	int img1,img2,img0;
	tree->GetItemImage(item1,img1,img0);
	tree->GetItemImage(item2,img2,img0);
	
	if(img1<img2) return -1;
	if(img2<img1) return 1;
	CString str1, str2;
	str1 = tree->GetItemText(item1);
	str2 = tree->GetItemText(item2);
	str1.MakeLower();
	str2.MakeLower();
	//	return str1.CompareNoCase(str2);
	//return str1.Compare(str2);
	return aplCompare2StringAsClassifier(str1,str2); 
}

CClassifierTreeItem::CClassifierTreeItem(CaplAPI *api, TClassifierItemsArray* array, CaplTreeView* pTreeView)
{
	m_fictive_item = NULL;

	ASSERT(api);
	ASSERT(array);
	ASSERT(pTreeView);
	ASSERT(pTreeView->IsKindOf(RUNTIME_CLASS(CaplTreeView)));

	m_api = api;
	m_pTreeView = pTreeView;
	m_ItemsArray = array;

	m_ItemsArray->Add(this);

	m_tree = &m_pTreeView->GetTreeCtrl();
	m_bExpanded = false;
}

CClassifierTreeItem::~CClassifierTreeItem()
{
    if(m_tree==0) return;
    if(m_item==0) return;
	
	int cnt = m_ItemsArray->GetSize();
	for(int i=0; i<cnt; i++)
	{
		if(m_ItemsArray->GetAt(i)==this)
		{
			m_ItemsArray->RemoveAt(i);
			break;
		}
	}
	
    if(!::IsWindow(m_tree->m_hWnd)) return;
	HTREEITEM item = 0;
	while(1)
	{
		item=m_tree->GetChildItem(m_item);
		if(item==0) break;
        CClassifierTreeItem*treeitem=(CClassifierTreeItem*)m_tree->GetItemData(item);
		if(treeitem==this) continue;
        if(treeitem!=0) 
		{
			delete treeitem;
		}
        else m_tree->DeleteItem(item);
	}
    m_tree->DeleteItem(m_item);
}

bool CClassifierTreeItem::Create(CaplInstance *inst, HTREEITEM parent)
{
	if(inst==NULL) return false;
	if(!m_api->m_data.IsKindOf(inst, m_api->m_classifier_mgr.e_apl_classifier_system) &&
		!m_api->m_data.IsKindOf(inst, m_api->m_classifier_mgr.e_apl_classifier_level))
		return false;//Не наш клиент
	
	m_inst = inst;
	
	CString name;
	int ico = -1;
	
	m_api->GetItemName(m_inst, name);
	ico = m_api->GetInstIco(inst);
	
	m_item = m_tree->InsertItem(name, ico, ico, parent);
	m_fictive_item = m_tree->InsertItem(_T("fictive"), 0, 0, m_item);

	m_tree->SetItemData(m_item, (DWORD)this);
	
	return true;
}

bool CClassifierTreeItem::Expand(UINT action)
{
	if(action==TVE_EXPAND)
	{
		if(m_bExpanded) return true;

		m_pTreeView->BeginWaitCursor();

		CollapseItems();
		
		if(m_fictive_item)
			m_tree->DeleteItem(m_fictive_item);
		m_fictive_item = NULL;
		
		aplExtent ext, ext1;
		m_api->m_classifier_mgr.LoadSubClassifierSystems(m_inst, ext1);
		m_api->m_classifier_mgr.LoadSubClassifierLevels(m_inst, ext);
		ext.Append(ext1);
		ext1.Clear();

		m_pTreeView->SetRedraw(FALSE);
		
		for(int i=0; i<ext.Size; i++)
		{
			CClassifierTreeItem* item = new CClassifierTreeItem(m_api, m_ItemsArray, m_pTreeView);
			if(!item->Create(ext[i], m_item))
				delete item;
		}
		
		m_bExpanded = true;

		Sort();

		m_pTreeView->SetRedraw();

		m_pTreeView->EndWaitCursor();
	}
	else //COLLAPSE
	{
		CollapseItems();
	}
	return true;
}

void CClassifierTreeItem::CollapseItems()
{
	HTREEITEM item = 0;
	m_pTreeView->SetRedraw(FALSE);
	while(1)
	{
		item=m_tree->GetChildItem(m_item);
		if(item==0) break;
        CClassifierTreeItem *treeitem=(CClassifierTreeItem*)m_tree->GetItemData(item);
		if(treeitem==this) continue;
        if(treeitem!=0) 
		{
			delete treeitem;
		}
        else m_tree->DeleteItem(item);
	}
	if(m_fictive_item==0)
		m_fictive_item = m_tree->InsertItem(_T("fictive"), 0, 0, m_item);
	m_bExpanded = false;
	m_pTreeView->SetRedraw(TRUE);
}


void CClassifierTreeItem::Sort()
{
	if(m_tree==0) return;
	if(m_item==0) return;
	
	TVSORTCB sortcb;
	sortcb.hParent=m_item;
	sortcb.lpfnCompare=CompareHtreeItem;
	sortcb.lParam=1;
	m_tree->SortChildrenCB(&sortcb);
}

void CClassifierTreeItem::Sort(CTreeCtrl* tree)
{
	if(tree==NULL) return;
	
	TVSORTCB sortcb;
	sortcb.hParent=TVI_ROOT;
	sortcb.lpfnCompare=CompareHtreeItem;
	sortcb.lParam=1;
	tree->SortChildrenCB(&sortcb);
}


bool CClassifierTreeItem::Refresh()
{
	CString name;
	m_api->GetItemName(m_inst, name);
	
	m_tree->SetItemText(m_item, name);
	
	return true;
}
