// CPACDgUL.cpp : implementation file
/////////////////////////////////////////////////////////////////////////////
#include "StdAfx.h"

#include "EDACDgUL.hpp"
#include "EDACActr.hpp"
#include "EDACVwAc.hpp"
#include "_AInterf.hpp"

//External Modules
#include "ErO.h"
#include "IncTUT.h"
//End of External Modules

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

/////////////////////////////////////////////////////////////////////////////
// EdActors_UndoRedoListDialog dialog

BEGIN_MESSAGE_MAP(EdActors_UndoRedoListDialog, CDialog)
	//{{AFX_MSG_MAP(EdActors_UndoRedoListDialog)
	ON_LBN_SELCHANGE(IDC_LIST_UNDO, OnSelchangeListUndo)
	ON_WM_LBUTTONUP()
	ON_WM_LBUTTONDOWN()
	ON_WM_MOUSEMOVE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


//***************************************************************************
EdActors_UndoRedoListDialog::EdActors_UndoRedoListDialog(	CPoint clUpAndLeftPoint,
																													m_eUndoRedoListType eType,
																													CWnd* pParent /*=NULL*/)
	: CDialog(EdActors_UndoRedoListDialog::IDD, &g_oBaseFrame)
{
	//{{AFX_DATA_INIT(EdActors_UndoRedoListDialog)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT

	m_hOldInstance = AfxGetResourceHandle();
	AfxSetResourceHandle(g_stActorEditorIdentity.hModule);

	m_clUpAndLeftPoint = clUpAndLeftPoint;
	m_eType = eType;

	//Gets current Actor
	m_pclEditorActor = g_pclInterface->m_clDocument.m_pclSelectedActor;
}

//***************************************************************************
EdActors_UndoRedoListDialog::~EdActors_UndoRedoListDialog()
{
	AfxSetResourceHandle(m_hOldInstance);
}
	
//***************************************************************************
void EdActors_UndoRedoListDialog::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(EdActors_UndoRedoListDialog)
	DDX_Control(pDX, IDC_LIST_UNDO, m_clListBox);
	//}}AFX_DATA_MAP
}

/////////////////////////////////////////////////////////////////////////////
// EdActors_UndoRedoListDialog message handlers

//***************************************************************************
BOOL EdActors_UndoRedoListDialog::OnInitDialog() 
{
	CDialog::OnInitDialog();

	//Moves the Window
	CRect crWindowRect;
	GetWindowRect(crWindowRect);
	crWindowRect.OffsetRect(m_clUpAndLeftPoint.x - crWindowRect.left,
													m_clUpAndLeftPoint.y - crWindowRect.top);

	MoveWindow(crWindowRect);
	ShowWindow(SW_SHOW);

	SetCapture();

	//Fills the List
	CPA_List<CPA_Modif> *pclListOfModifs = &(m_pclEditorActor->m_clUndoManager.ListOfModifs);
	CPA_Modif *pclModif;
	if ( m_eType == EDCAR_UNDOREDO_LIST_TYPE_UNDO )
	{
		POSITION pos = pclListOfModifs->GetTailPosition();
		while ( pos != NULL )
		{
			pclModif = pclListOfModifs->GetPrev(pos);
			
				if ( pclModif->HasBeenDone() )
					m_clListBox.AddString(pclModif->GetName());
		}
	}
	else
	{
		POSITION pos = pclListOfModifs->GetHeadPosition();
		while ( pos != NULL )
		{
			pclModif = pclListOfModifs->GetNext(pos);
			
				if ( !pclModif->HasBeenDone() )
					m_clListBox.AddString(pclModif->GetName());
		}
	}

	//////////////
	//////////////
	//Registers for TUT Module
	TUT_M_vGetTutDll();
	
	TUT_M_vRegisterControlID(IDC_LIST_UNDO, "OAc_UndoRedoDialog_ListBox", TUT_e_ListBox);
	TUT_M_vRegisterControlID(IDC_STATIC_STATUS, "OAc_UndoRedoDialog_CancelStatic", TUT_e_Window);

	//End of Registers for TUT Module
	//////////////

	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

//***************************************************************************
void EdActors_UndoRedoListDialog::OnDestroy() 
{
	//////////////
	//////////////
	//UnRegisters for TUT Module
	TUT_M_vGetTutDll();
	
	TUT_M_vUnregisterControlID(IDC_LIST_UNDO);
	TUT_M_vUnregisterControlID(IDC_STATIC_STATUS);
	
	//End of UnRegisters for TUT Module
	//////////////
	
	CDialog::OnDestroy();
}

//***************************************************************************
void EdActors_UndoRedoListDialog::OnSelchangeListUndo() 
{
	//Gets the Selected Undo action
	unsigned short uwIndex = m_clListBox.GetCurSel();
	
	if ( (m_clListBox.m_bMustUndo) && (uwIndex != LB_ERR) )
	{
		//Makes (uwIndex + 1) undo in the reversed list
		CPA_List<CPA_Modif> *pclListOfModifs = &(m_pclEditorActor->m_clUndoManager.ListOfModifs);
		unsigned short c_uwI;
		CPA_Modif *pclModif;
		
		if ( m_eType == EDCAR_UNDOREDO_LIST_TYPE_UNDO )
		{
			POSITION pos = pclListOfModifs->GetTailPosition();

			for (c_uwI = 0; c_uwI < (uwIndex+1); )
			{
				ERROR_ASSERT( pos != NULL );
				
				pclModif = pclListOfModifs->GetPrev(pos);

				if ( pclModif->HasBeenDone() )
				{
					ERROR_VERIFY( m_pclEditorActor->m_clUndoManager.Undo() );
					c_uwI ++;
				}
			}
		}
		else
		{
			POSITION pos = pclListOfModifs->GetHeadPosition();

			for (c_uwI = 0; c_uwI < (uwIndex+1); )
			{
				ERROR_ASSERT( pos != NULL );
				
				pclModif = pclListOfModifs->GetNext(pos);

				if ( !pclModif->HasBeenDone() )
				{
					ERROR_VERIFY( m_pclEditorActor->m_clUndoManager.Redo() );
					c_uwI ++;
				}
			}
		}
	}

	//Updates buttons
	g_pclInterface->m_clDocument.m_pclActorsView->m_fn_vUpdateUndoRedoButtons();

	//Ends Dialog
	ReleaseCapture();
	EndDialog(IDOK);
}

//***************************************************************************
void EdActors_UndoRedoListDialog::OnLButtonUp(UINT nFlags, CPoint point) 
{
	CPoint cpPoint(point);
	ClientToScreen(&cpPoint);
	CRect crWindowRect;
	GetWindowRect(crWindowRect);

	//If user clicks elsewhere, closes Dialog
	if ( !crWindowRect.PtInRect(cpPoint) )
	{
		ReleaseCapture();
		EndDialog(IDCANCEL);
	}
	//else looks if user clicked in the ListBox
	else
		m_clListBox.OnLButtonUp(nFlags, point);
	
	CDialog::OnLButtonUp(nFlags, point);
}

//***************************************************************************
void EdActors_UndoRedoListDialog::OnLButtonDown(UINT nFlags, CPoint point) 
{
	m_clListBox.OnLButtonDown(nFlags, point);

	CDialog::OnLButtonDown(nFlags, point);
}

//***************************************************************************
void EdActors_UndoRedoListDialog::OnMouseMove(UINT nFlags, CPoint point) 
{
	m_clListBox.OnMouseMove(nFlags, point);
	
	CDialog::OnMouseMove(nFlags, point);
}


/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// EdActors_UndoListBox

BEGIN_MESSAGE_MAP(EdActors_UndoListBox, CListBox)
	//{{AFX_MSG_MAP(EdActors_UndoListBox)
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONDOWN()
	ON_WM_DESTROY()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

//****************************************************************************
EdActors_UndoListBox::EdActors_UndoListBox()
										: CListBox()
{
	m_bMustUndo = FALSE;
}

//****************************************************************************
EdActors_UndoListBox::~EdActors_UndoListBox()
{

}

/////////////////////////////////////////////////////////////////////////////
// EdActors_UndoListBox message handlers

//****************************************************************************
void EdActors_UndoListBox::OnMouseMove(UINT nFlags, CPoint point) 
{
	if ( nFlags & MK_LBUTTON )
	{
		BOOL bInside;
		short wIndex = ItemFromPoint(point, bInside);
		CString csTextToDisplay;

		//Re-computes bOutside
		GetClientRect(m_crWindowRect);
		bInside = m_crWindowRect.PtInRect(point);

		if ( bInside )
		{
			//Selects first items
			SelItemRange(TRUE, 0, wIndex+1);
			//Unselects others
			SelItemRange(FALSE, wIndex+1, GetCount()-1);
			CString csTextPart = "undo";
			if ( ((EdActors_UndoRedoListDialog *)GetParent())->m_eType == EdActors_UndoRedoListDialog::EDCAR_UNDOREDO_LIST_TYPE_REDO )
				csTextPart = "redo";
			csTextToDisplay.Format("Will %s %i %s", csTextPart,
																							wIndex+1,
																							(wIndex > 0) ? "actions" : "action");

			m_bMustUndo = TRUE;
		}
		else
		{
			//Unselects all
			SelItemRange(FALSE, 0, GetCount()-1);

			csTextToDisplay = "Cancel";
		
			m_bMustUndo = FALSE;
		}

		//Updates static text
		GetParent()->GetDlgItem(IDC_STATIC_STATUS)->SetWindowText(csTextToDisplay);
	}
	
	CListBox::OnMouseMove(nFlags, point);
}

//****************************************************************************
void EdActors_UndoListBox::OnLButtonDown(UINT nFlags, CPoint point) 
{
	CListBox::OnLButtonDown(nFlags, point);

	BOOL bInside;
	short wIndex = ItemFromPoint(point, bInside);
	CString csTextToDisplay;
	
	//Selects first items
	SelItemRange(TRUE, 0, wIndex+1);
	//Unselects others
	SelItemRange(FALSE, wIndex+1, GetCount()-1);

	CString csTextPart = "undo";
	if ( ((EdActors_UndoRedoListDialog *)GetParent())->m_eType == EdActors_UndoRedoListDialog::EDCAR_UNDOREDO_LIST_TYPE_REDO )
		csTextPart = "redo";
	csTextToDisplay.Format("Will %s %i %s", csTextPart,
																					wIndex+1,
																					(wIndex > 0) ? "actions" : "action");

	m_bMustUndo = TRUE;

	//Updates static text
	GetParent()->GetDlgItem(IDC_STATIC_STATUS)->SetWindowText(csTextToDisplay);
}
