/*=========================================================================
* 
* LPSdLoad.cpp :  Load dialog - Implementation file
* 
*
* Version			1.0
* Creation date		16/08/97	
* Revision date		18/08/97
*
* Shaitan
*=======================================================================*/

#include "stdafx.h"
#define HieFriend
#include "acp_base.h"

#include "LPSinter.hpp"
#include "LPSobj.hpp"
#include "LPSdLoad.hpp"

#include "TLS/LPSconst.hpp" 


//#################################################################################
// LPS_DialogLoad dialog
//#################################################################################

/*----------------------------------------
----------------------------------------*/
LPS_DialogLoad::LPS_DialogLoad(LipSync_Interface *pOwnerEditor, CWnd* pParent /*=NULL*/)
	: CDialog(LPS_DialogLoad::IDD, pParent)
{
	// init editor
	m_pOwnerEditor = pOwnerEditor;
	// init icon list
	m_oIconList.Create(16, 16, ILC_MASK, 0, 6);
	m_oIconList.Add(LoadIcon(pOwnerEditor->GetDLLIdentity()->hModule, MAKEINTRESOURCE(LPS_IDI_FAMILY)));
	m_oIconList.Add(LoadIcon(pOwnerEditor->GetDLLIdentity()->hModule, MAKEINTRESOURCE(LPS_IDI_UNLOAD)));
	m_oIconList.Add(LoadIcon(pOwnerEditor->GetDLLIdentity()->hModule, MAKEINTRESOURCE(LPS_IDI_LIPSYNC)));
	m_oIconList.Add(LoadIcon(pOwnerEditor->GetDLLIdentity()->hModule, MAKEINTRESOURCE(LPS_IDI_UNLOADB)));
	m_oIconList.Add(LoadIcon(pOwnerEditor->GetDLLIdentity()->hModule, MAKEINTRESOURCE(LPS_IDI_LIPSYNCB)));
}


/*----------------------------------------
----------------------------------------*/
void LPS_DialogLoad::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(LPS_DialogLoad)
	DDX_Control(pDX, LPS_IDC_TREECONTROL, m_cTree);
	//}}AFX_DATA_MAP
}


/*----------------------------------------
----------------------------------------*/
BEGIN_MESSAGE_MAP(LPS_DialogLoad, CDialog)
	//{{AFX_MSG_MAP(LPS_DialogLoad)
	ON_NOTIFY(TVN_SELCHANGED, LPS_IDC_TREECONTROL, OnSelchangeTreeControl)
	ON_NOTIFY(NM_RCLICK, LPS_IDC_TREECONTROL, OnRightClkTreeControl)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

//#################################################################################
// LPS_DialogLoad message handlers
//#################################################################################

/*----------------------------------------
----------------------------------------*/
BOOL LPS_DialogLoad::OnInitDialog() 
{
	CPA_BaseObjectList			*pListObjects;
	CPA_BaseObject				*pObject;
	LipSync_Object				*pLipSync;
	HTREEITEM					hFamilyItem, hLipsItem;
	Position					Pos;
	CString						csName;

	CDialog::OnInitDialog();

	m_hFirstItem = NULL;
	
	m_cTree.DeleteAllItems();
	m_cTree.SetImageList(&m_oIconList, TVSIL_NORMAL);

	// fill ListBox with invalid Lips Synchros
    pListObjects = m_pOwnerEditor->GetInvalidObjectList(C_szLipSyncTypeName);
	
	// only unloaded lips synchro must be dispayed
	for (pObject = pListObjects->GetHeadElement(Pos); pObject;
		 pObject = pListObjects->GetNextElement(Pos))
	{
		pLipSync = (LipSync_Object *)pObject;
		if (!pLipSync->fn_bIsAvailable())
		{
			// if necessary, create family item
			hFamilyItem = GetCorrespondingItem(pLipSync->GetFamily());
			if (!hFamilyItem)
			{
				hFamilyItem = m_cTree.InsertItem(pLipSync->GetFamily()->GetName(), 0, 0, TVI_ROOT, TVI_SORT);
				m_cTree.SetItemData(hFamilyItem, (DWORD) pLipSync->GetFamily());
			}
			// add lip synchro item
			hLipsItem = m_cTree.InsertItem(pLipSync->GetName(), 1, 1, hFamilyItem, TVI_SORT);
			m_cTree.SetItemData(hLipsItem, (DWORD) pLipSync);
		}
	}
	
	return TRUE;  
}


/*----------------------------------------
----------------------------------------*/
void LPS_DialogLoad::OnSelchangeTreeControl (NMHDR* pNMHDR, LRESULT* pResult)
{
	CPA_BaseObject	*pObject;
	HTREEITEM		hCurItem;
	POSITION		pos;

	LPNM_TREEVIEW pNMTreeView = (LPNM_TREEVIEW)pNMHDR;

	if (pNMTreeView->action)
	{
		// get selected item
		hCurItem = m_cTree.GetSelectedItem();
		if (hCurItem != NULL)
		{
			// get corresponding object
			pObject = (CPA_BaseObject *) m_cTree.GetItemData(hCurItem);
			// Lip Synchro => update list
			if (pObject->GetType() == C_szLipSyncTypeName)
			{
				pos = m_oObjectsToLoad.Find(pObject);
				// if object is already in the list, remove it
				if (pos != NULL)
				{
					m_oObjectsToLoad.RemoveAt(pos);
					m_cTree.SetItemImage(hCurItem, 1, 1);
				}
				// else add it
				else
				{
					m_oObjectsToLoad.AddTail(pObject);
					m_cTree.SetItemImage(hCurItem, 2, 2);
				}
				// remove selection
				m_cTree.SelectItem(NULL);
			}

		}
	}

	*pResult = 0;
}


/*----------------------------------------
----------------------------------------*/
void LPS_DialogLoad::OnRightClkTreeControl(NMHDR* pNMHDR, LRESULT* pResult) 
{
	LipSync_Object	*pLipSync = NULL;
	LipSync_Object	*pFirstLips;
	CPA_BaseObject	*pObject;
	HTREEITEM		hCurItem;
	POSITION		pos;
	POINT			mousePos;
	BOOL			bAdd, bPrev;


	// get selected item
	GetCursorPos(&mousePos);
	m_cTree.ScreenToClient(&mousePos);
	hCurItem = m_cTree.HitTest(mousePos);
	if (hCurItem != NULL)
	{
		pObject = (CPA_BaseObject *) m_cTree.GetItemData(hCurItem);
		// Lip Synchro => update list
		if (pObject->GetType() == C_szLipSyncTypeName)
			pLipSync = (LipSync_Object *) pObject;
	}
	if (!pLipSync)
		return;
	
	// first click => get first selected object
	if (!m_hFirstItem)
	{
		// register first item
		m_hFirstItem = hCurItem;
		m_cTree.SelectItem(m_hFirstItem);
		// update icon & state
		pFirstLips = (LipSync_Object *) m_cTree.GetItemData(m_hFirstItem);
		if (m_oObjectsToLoad.Find(pFirstLips) != NULL)
			m_cTree.SetItemImage(m_hFirstItem, 3, 3);
		else
			m_cTree.SetItemImage(m_hFirstItem, 4, 4);
	}
	// next click => get last selection and update
	else
	{
		pFirstLips = (LipSync_Object *) m_cTree.GetItemData(m_hFirstItem);
		if (pLipSync->GetFamily() == pFirstLips->GetFamily())
		{
			bAdd = (m_oObjectsToLoad.Find(pFirstLips) == NULL);
			bPrev = (pLipSync->GetName() > pFirstLips->GetName());
			// update all items
			while (pLipSync)
			{
				// update list and icon
				pos = m_oObjectsToLoad.Find(pLipSync);
				if (bAdd && !pos)
				{
					m_oObjectsToLoad.AddTail(pLipSync);
					m_cTree.SetItemImage(hCurItem, 2, 2);
				}
				else if (!bAdd && pos)
				{
					m_oObjectsToLoad.RemoveAt(pos);
					m_cTree.SetItemImage(hCurItem, 1, 1);
				}
				// get previous item
				if (pLipSync != pFirstLips)
				{
					if (bPrev)
						hCurItem = m_cTree.GetPrevSiblingItem(hCurItem);
					else
						hCurItem = m_cTree.GetNextSiblingItem(hCurItem);
					pLipSync = (LipSync_Object *) m_cTree.GetItemData(hCurItem);
				}
				else
					pLipSync = NULL;
			}
			m_hFirstItem = NULL;
			m_cTree.SelectItem(m_hFirstItem);
		}
	}
//	*pResult = 0;
}

/*----------------------------------------
	Get Item
----------------------------------------*/
HTREEITEM LPS_DialogLoad::GetCorrespondingItem (CPA_BaseObject *pObject, HTREEITEM hElem)
{
	CPA_BaseObject	*pData;
	HTREEITEM		hChild, hResult;

	// test hElem name
	if (hElem)
	{
		// get item data
		pData = (CPA_BaseObject *) m_cTree.GetItemData(hElem);
		// check item data
		if (pData == pObject)
			return hElem;
	}
	// test all childs
	hChild = (hElem) ? m_cTree.GetChildItem(hElem) : m_cTree.GetRootItem();
	while (hChild)
	{
		hResult = GetCorrespondingItem(pObject, hChild);
		if (hResult)
			return hResult;
		hChild = m_cTree.GetNextSiblingItem(hChild);
	}
	
	return NULL;
}
