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

#include "scr.h"
#include "ai/aibase/gsparam.h"
#define ACTIVE_EDITOR /* we don't want optimized arrays in editors, but defining ACTIVE_EDITOR in the project's settings doesn't work... */
#include "ai/aibase/array.h"
#undef ACTIVE_EDITOR
#include "ai/aigame/enumVar.h"

#include "CTL_Dga.hpp"

#include "Controls\CTL_Ctl.hpp"
#include "Controls\Ctl_Ctla.hpp"
#include "Controls\Ctl_Cnst.hpp"
//#include "Others\CTL_Mask.hpp"
#include "Data\CTL_Data.hpp"
#include "Others\CTL_Pri.hpp"
#include "WControls\Ctl_vBas.hpp"
#include "WControls\Ctl_wsta.hpp"

#include "dialogs\ctl_aevw.hpp"

#include "Main\Inc\_EditID.h"

//External Modules
#include "CTL_ErO.hpp"
//End of External Modules

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

#define EdActors_C_FirstIDForListBoxCheckButtons	1000

#define C_COLOR_UNSEL		RGB( 50,200, 50)
#define C_COLOR_SEL			RGB(200, 70, 30)

#define C_ARRAY_DIALOG	"Array"

/////////////////////////////////////////////////////////////////////////////
// CTL_DialogArrayDataEdition dialog

BEGIN_MESSAGE_MAP(CTL_DialogArrayDataEdition, CDialog)
	//{{AFX_MSG_MAP(CTL_DialogArrayDataEdition)
	ON_WM_SIZE()
	ON_BN_CLICKED(IDC_BUTTON_INSERT, OnButtonInsert)
	ON_BN_CLICKED(IDC_BUTTON_DELETE, OnButtonDelete)
	ON_BN_CLICKED(IDC_BUTTON_UP, OnButtonUp)
	ON_BN_CLICKED(IDC_BUTTON_DOWN, OnButtonDown)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


//***************************************************************************
CTL_DialogArrayDataEdition::CTL_DialogArrayDataEdition(CTL_Editor_ArrayControl *_pclParentControl,
														CWnd* _pParent /*= NULL*/)
											: CDialog(CTL_DialogArrayDataEdition::IDD, _pParent)
{
	hOldInstance = AfxGetResourceHandle();
	AfxSetResourceHandle(CTL_g_hModule);

	//{{AFX_DATA_INIT(CTL_DialogArrayDataEdition)
	//}}AFX_DATA_INIT

	m_pclParentControl = _pclParentControl;
	m_csDataName = m_pclParentControl->m_fn_pclGetEditedData()->m_pub_fn_csGetDataName();

	m_pclSelectedControl = NULL;
}

//***************************************************************************
CTL_DialogArrayDataEdition::~CTL_DialogArrayDataEdition()
{
	AfxSetResourceHandle(hOldInstance);
}

//***************************************************************************
void CTL_DialogArrayDataEdition::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CTL_DialogArrayDataEdition)
	//}}AFX_DATA_MAP
}

/////////////////////////////////////////////////////////////////////////////
// CTL_DialogArrayDataEdition message handlers

#define M_ADD_ONE_DSG_VAR(Name,TypeControl,TypeData,ParmsData,EngineStruct)	\
	

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

	m_pclFrameControl = new CFrameWnd ();
	
	CRect rect = CRect (0,0, 200, 150);
	BOOL bRes = m_pclFrameControl -> Create (NULL,
									 	     "Titlu",
											 WS_CHILD | WS_VISIBLE,
											 rect,
											 this,
											 0,
											 NULL);

	CCreateContext CreateContext;

	CreateContext . m_pNewViewClass = RUNTIME_CLASS (CArrayElementsView);
	CreateContext . m_pCurrentDoc = NULL;
	CreateContext . m_pNewDocTemplate = NULL;
	CreateContext . m_pLastView = NULL;
	CreateContext . m_pCurrentFrame = NULL;


	CWnd *pView = m_pclFrameControl -> CreateView (& CreateContext, AFX_IDW_PANE_FIRST);
	pView->ShowWindow(TRUE);
	pView->ModifyStyle(WS_BORDER, 0);
	m_pclFrameControl -> SetActiveView ((CView *) pView, TRUE);

	m_pclView = (CTL_Editor_BaseFormView *) m_pclFrameControl -> GetActiveView ();
	
	// the array
	CTL_Editor_Data *pclParentData= m_pclParentControl -> m_fn_pclGetEditedData ();
	tdstArray *pstArray = (tdstArray *) pclParentData -> m_pub_fn_pvGetMotorData ();

	// save
	M_ARRAY_COPY (& m_stSavedArray, pstArray);

	// for all elements
	for (int i = 0; i < pstArray -> ucMaxSize; i ++)
		m_fn_vCreateElementControl (pstArray, i);

	m_pclSelectedControl = m_clControlList . GetHead ();

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


//***************************************************************************
void CTL_DialogArrayDataEdition::OnOK() 
{
	// We are fine ;-)
	// cleanup
	m_fn_vCleanup ();

	CDialog::OnOK ();
}

//***************************************************************************
void CTL_DialogArrayDataEdition::OnCancel() 
{
	//cleanup
	m_fn_vCleanup ();

	// restore
	CTL_Editor_Data *pclParentData= m_pclParentControl -> m_fn_pclGetEditedData ();
	tdstArray *pstArray = (tdstArray *) pclParentData -> m_pub_fn_pvGetMotorData ();
	M_ARRAY_COPY (pstArray, & m_stSavedArray);

	
	CDialog::OnCancel();
}

//***************************************************************************
#define SPACING 8
void CTL_DialogArrayDataEdition::m_fn_vResize()
{
	// Move Buttons
	CRect rect;
	GetClientRect (& rect);
	
	CRect rectNew = rect;
	CRect rectSize;
	CWnd *pButton = GetDlgItem (IDOK);
	if (! pButton)
		return;
	pButton -> GetClientRect (& rectSize);
	rectNew . left = rectNew . right - rectSize . right;
	rectNew . bottom  = rectNew . top + rectSize . bottom;
	pButton -> MoveWindow (rectNew);

	rectNew . top = rectNew . bottom + C_SPACE_BETWEEN_CONTROLS;
	rectNew . bottom  = rectNew . top + rectSize . bottom;
	pButton = GetDlgItem (IDCANCEL);
	pButton -> MoveWindow (rectNew);

	rectNew . top = rectNew . bottom + 2 * C_SPACE_BETWEEN_CONTROLS;
	rectNew . bottom  = rectNew . top + rectSize . bottom;
	pButton = GetDlgItem (IDC_BUTTON_INSERT);
	pButton -> MoveWindow (rectNew);

	rectNew . top = rectNew . bottom + C_SPACE_BETWEEN_CONTROLS;
	rectNew . bottom  = rectNew . top + rectSize . bottom;
	pButton = GetDlgItem (IDC_BUTTON_DELETE);
	pButton -> MoveWindow (rectNew);

	rectNew . top = rectNew . bottom + C_SPACE_BETWEEN_CONTROLS;
	rectNew . bottom  = rectNew . top + rectSize . bottom;
	pButton = GetDlgItem (IDC_BUTTON_UP);
	pButton -> MoveWindow (rectNew);

	rectNew . top = rectNew . bottom + C_SPACE_BETWEEN_CONTROLS;
	rectNew . bottom  = rectNew . top + rectSize . bottom;
	pButton = GetDlgItem (IDC_BUTTON_DOWN);
	pButton -> MoveWindow (rectNew);

	// Resize frame
	rectNew = rect;
	rectNew . right = rectNew . right - rectSize . right - C_SPACE_BETWEEN_CONTROLS;
	m_pclFrameControl -> MoveWindow (rectNew);

	// Resize view
	m_fn_vUpdateView ();
}

//***************************************************************************
void CTL_DialogArrayDataEdition::m_fn_vUpdateView (void)
{
	/*
	CPoint cpTopLeft = rect . TopLeft ();
	CPoint cpTopRight;
	cpTopRight . x = rect . right;
	cpTopRight . y = cpTopLeft . y;
	*/
	CPoint	cpOffset=m_pclView->GetScrollPosition();
	CPoint	cpTopLeft(0,-cpOffset.y);
	CRect rect ;
	m_pclFrameControl -> GetClientRect (& rect);
	CPoint	cpTopRight(rect.Width() + 20,-cpOffset.y);
	
	m_clControlList. m_pub_fn_vDisplayControlsInZone(cpTopLeft, cpTopRight);
	m_clControlList. m_pub_fn_vUpdateControlsWithListOfData(& m_clDataList);

	m_pclView -> m_fn_vSetViewHeight ((unsigned short) (cpTopLeft . y + m_pclView -> GetScrollPosition () . y));

	m_fn_vUpdateColors ();
}


void CTL_DialogArrayDataEdition::OnSize(UINT nType, int cx, int cy) 
{
	CDialog::OnSize(nType, cx, cy);
	
	m_fn_vResize ();
}

void CTL_DialogArrayDataEdition::OnButtonInsert() 
{
	// the array
	CTL_Editor_Data *pclParentData= m_pclParentControl -> m_fn_pclGetEditedData ();
	tdstArray *pstArray = (tdstArray *) pclParentData -> m_pub_fn_pvGetMotorData ();

	if (pstArray -> ucMaxSize == 255)
	{
		AfxMessageBox ("Maximum 255 elements");
		return;
	}

	if (pstArray -> ucMaxSize == 0)
	{
		AfxMessageBox ("Minimum 1 element");
		return;
	}

	POSITION pos = m_clControlList . GetHeadPosition ();
	POSITION posCtrl = pos;
	POSITION posData = m_clDataList . GetHeadPosition ();
	int i = 0;
	int lSelectedControlIndex = -1;
	while (pos)
	{
		CTL_Editor_Control *pclCtrl = m_clControlList . GetNext (pos);

		if (pclCtrl == m_pclSelectedControl)
		{
			lSelectedControlIndex = i;
			break;
		}
		posCtrl = pos;
		m_clDataList . GetNext (posData);
		i ++;
	}

	if (lSelectedControlIndex < 0)
		return;
	
	// move elements
	pos = m_clDataList . GetTailPosition ();
	for (i = pstArray -> ucMaxSize - 1; i > lSelectedControlIndex; i --)
	{
		CTL_Editor_Data *pclData = m_clDataList . GetPrev (pos);
		pclData -> m_fn_vSetMotorDataPtr (M_ARRAY_ELEMENT (pstArray, i));

		* M_ARRAY_ELEMENT (pstArray,  i) = * M_ARRAY_ELEMENT (pstArray,  i - 1);
	}

	// BEGIN ROMTEAM Cristi Petrescu 98-12-
	// Do not increase size, last element will be lost
	//pstArray -> ucMaxSize ++;
	// clear
	memset (M_ARRAY_ELEMENT (pstArray, lSelectedControlIndex), 0, C_SizeOfArrayElement);

	// create control
	m_fn_vCreateElementControl (pstArray, lSelectedControlIndex);

	// move it into place
	CTL_Editor_Control *pclCtrl = m_clControlList . RemoveTail ();
	m_clControlList . InsertBefore (posCtrl, pclCtrl);
	m_pclSelectedControl = pclCtrl;
	// remove last element
	pclCtrl = m_clControlList . RemoveTail ();
	delete pclCtrl;


	CTL_Editor_Data *pclData = m_clDataList . RemoveTail ();
	m_clDataList . InsertBefore (posData, pclData);
	// remove last element
	pclData = m_clDataList . RemoveTail ();
	delete pclData;
	// END ROMTEAM Cristi Petrescu 98-12-

	m_fn_vUpdateView ();	
}

void CTL_DialogArrayDataEdition::OnButtonDelete() 
{
	// the array
	CTL_Editor_Data *pclParentData= m_pclParentControl -> m_fn_pclGetEditedData ();
	tdstArray *pstArray = (tdstArray *) pclParentData -> m_pub_fn_pvGetMotorData ();

	if (pstArray -> ucMaxSize == 1)
	{
		AfxMessageBox ("Minimim 1 element");
		return;
	}

	POSITION pos = m_clControlList . GetHeadPosition ();
	POSITION posCtrl = pos;
	POSITION posData = m_clDataList . GetHeadPosition ();
	int i = 0;
	int lSelectedControlIndex = -1;
	while (pos)
	{
		CTL_Editor_Control *pclCtrl = m_clControlList . GetNext (pos);

		if (pclCtrl == m_pclSelectedControl)
		{
			lSelectedControlIndex = i;
			break;
		}
		posCtrl = pos;
		m_clDataList . GetNext (posData);
		i ++;
	}

	if (lSelectedControlIndex < 0)
		return;

	// BEGIN ROMTEAM Cristi Petrescu 98-12-
	// Do not decrease size, last element will be cleared
	//pstArray -> ucMaxSize --;
	
	// move elements
	pos = posData;
	m_clDataList . GetNext (pos);
	for (i = lSelectedControlIndex; i < pstArray -> ucMaxSize - 1; i ++)
	{
		CTL_Editor_Data *pclData = m_clDataList . GetNext (pos);
		pclData -> m_fn_vSetMotorDataPtr (M_ARRAY_ELEMENT (pstArray, i));

		* M_ARRAY_ELEMENT (pstArray,  i) = * M_ARRAY_ELEMENT (pstArray,  i + 1);
	}

	// clear
	memset (M_ARRAY_ELEMENT (pstArray, pstArray -> ucMaxSize - 1), 0, C_SizeOfArrayElement);

	// delete controls
	pos = posCtrl;
	CTL_Editor_Control *pclCtrl = m_clControlList . GetNext (posCtrl);
	if (! posCtrl)
	{
		posCtrl = pos;
		m_clControlList . GetPrev (posCtrl);
	}
	m_pclSelectedControl = m_clControlList . GetAt (posCtrl);
	m_clControlList . RemoveAt (pos);
	//delete pclCtrl;
	// add at last position
	m_clControlList . AddTail (pclCtrl);

	CTL_Editor_Data *pclData = m_clDataList . GetAt (posData);
	m_clDataList . RemoveAt (posData);
	//delete pclData;
	// add at last position
	m_clDataList . AddTail (pclData);
	// the engine pointer
	pclData -> m_fn_vSetMotorDataPtr (M_ARRAY_ELEMENT (pstArray, pstArray -> ucMaxSize - 1));
	// END ROMTEAM Cristi Petrescu 98-12-
	
	m_fn_vUpdateView ();	
}

void CTL_DialogArrayDataEdition::OnButtonUp() 
{
	// the array
	CTL_Editor_Data *pclParentData= m_pclParentControl -> m_fn_pclGetEditedData ();
	tdstArray *pstArray = (tdstArray *) pclParentData -> m_pub_fn_pvGetMotorData ();

	POSITION pos = m_clControlList . GetHeadPosition ();
	POSITION posCtrl = pos;
	POSITION posData = m_clDataList . GetHeadPosition ();
	int i = 0;
	int lSelectedControlIndex = -1;
	while (pos)
	{
		CTL_Editor_Control *pclCtrl = m_clControlList . GetNext (pos);

		if (pclCtrl == m_pclSelectedControl)
		{
			lSelectedControlIndex = i;
			break;
		}
		posCtrl = pos;
		m_clDataList . GetNext (posData);
		i ++;
	}

	if (lSelectedControlIndex < 0)
		return;

	if (lSelectedControlIndex == 0)
		return;

	// switch engine
	tduGetSetParam stTemp = * M_ARRAY_ELEMENT (pstArray, lSelectedControlIndex);
	* M_ARRAY_ELEMENT (pstArray, lSelectedControlIndex) = * M_ARRAY_ELEMENT (pstArray, lSelectedControlIndex - 1);
	* M_ARRAY_ELEMENT (pstArray, lSelectedControlIndex - 1) = stTemp;

	// switch ctrl
	pos = posCtrl;
	CTL_Editor_Control *pclCtrl = m_clControlList . GetAt (posCtrl);
	m_clControlList . GetPrev (posCtrl);
	m_clControlList . InsertBefore (posCtrl, pclCtrl);
	m_clControlList . RemoveAt (pos);

	// switch data
	pos = posData;
	CTL_Editor_Data *pclData = m_clDataList . GetAt (posData);
	m_clDataList . GetPrev (posData);
	posData = m_clDataList . InsertBefore (posData, pclData);
	m_clDataList . RemoveAt (pos);

	// set engine pointers
	pclData = m_clDataList . GetNext (posData);
	pclData -> m_fn_vSetMotorDataPtr (M_ARRAY_ELEMENT (pstArray, lSelectedControlIndex - 1));
	pclData = m_clDataList . GetNext (posData);
	pclData -> m_fn_vSetMotorDataPtr (M_ARRAY_ELEMENT (pstArray, lSelectedControlIndex ));

	m_fn_vUpdateView ();
}

void CTL_DialogArrayDataEdition::OnButtonDown() 
{
	// the array
	CTL_Editor_Data *pclParentData= m_pclParentControl -> m_fn_pclGetEditedData ();
	tdstArray *pstArray = (tdstArray *) pclParentData -> m_pub_fn_pvGetMotorData ();

	POSITION pos = m_clControlList . GetHeadPosition ();
	POSITION posCtrl = pos;
	POSITION posData = m_clDataList . GetHeadPosition ();
	int i = 0;
	int lSelectedControlIndex = -1;
	while (pos)
	{
		CTL_Editor_Control *pclCtrl = m_clControlList . GetNext (pos);

		if (pclCtrl == m_pclSelectedControl)
		{
			lSelectedControlIndex = i;
			break;
		}
		posCtrl = pos;
		m_clDataList . GetNext (posData);
		i ++;
	}

	if (lSelectedControlIndex < 0)
		return;

	if (lSelectedControlIndex == pstArray -> ucMaxSize - 1)
		return;

	// switch engine
	tduGetSetParam stTemp = * M_ARRAY_ELEMENT (pstArray, lSelectedControlIndex);
	* M_ARRAY_ELEMENT (pstArray, lSelectedControlIndex) = * M_ARRAY_ELEMENT (pstArray, lSelectedControlIndex + 1);
	* M_ARRAY_ELEMENT (pstArray, lSelectedControlIndex + 1) = stTemp;

	// switch ctrl
	pos = posCtrl;
	CTL_Editor_Control *pclCtrl = m_clControlList . GetAt (posCtrl);
	m_clControlList . GetNext (posCtrl);
	m_clControlList . InsertAfter (posCtrl, pclCtrl);
	m_clControlList . RemoveAt (pos);

	// switch data
	pos = posData;
	CTL_Editor_Data *pclData = m_clDataList . GetAt (posData);
	m_clDataList . GetNext (posData);
	posData = m_clDataList . InsertAfter (posData, pclData);
	m_clDataList . RemoveAt (pos);

	// set engine pointers
	pclData = m_clDataList . GetPrev (posData);
	pclData -> m_fn_vSetMotorDataPtr (M_ARRAY_ELEMENT (pstArray, lSelectedControlIndex + 1));
	pclData = m_clDataList . GetPrev (posData);
	pclData -> m_fn_vSetMotorDataPtr (M_ARRAY_ELEMENT (pstArray, lSelectedControlIndex ));

	m_fn_vUpdateView ();
}

void fn_vNameClicked (CTL_Editor_Static *pclSender, enum CTL_eClickType tdeClickType)
{
	CTL_Editor_Control *pclElement = pclSender -> m_pub_fn_pclGetParentControl ();

	CTL_DialogArrayDataEdition *pclDlg = (CTL_DialogArrayDataEdition *) (pclElement -> m_pub_fn_pclGetOwnerDataWithName (C_ARRAY_DIALOG)  -> m_pub_fn_pvGetDataPtr ());

	pclDlg -> m_fn_vSetSelectedControl (pclElement);
	pclDlg -> m_fn_vUpdateColors ();
	//pclDlg -> RedrawWindow ();
}

void CTL_DialogArrayDataEdition::m_fn_vCreateElementControl (tdstArray *pstArray, int i)
{
	CTL_Editor_Control *pclCtrl = m_pclParentControl -> m_fn_pctrlCreateElementControl (& m_clControlList);				

	m_clControlList . AddTail (pclCtrl);									
	pclCtrl -> m_fn_bCreateControl (m_pclView);								

	CTL_Editor_Data *pclData = m_pclParentControl -> m_fn_pdataCreateElementData (& m_clDataList, pclCtrl);

	void *pvElem = M_ARRAY_ELEMENT (pstArray, i);
	tduGetSetParam *pvTElem = (tduGetSetParam *)pvElem;
	pclData -> m_fn_vSetMotorDataPtr (pvElem);							
	m_clDataList . AddTail (pclData);										
	pclCtrl->m_fn_vSetEditedData(pclData);									
	pclData->m_fn_vGetMotorData();											

	pclCtrl -> m_pub_fn_pclGetNameStatic () -> m_pub_fn_vSetStaticHasBeenClicked_CallBack (fn_vNameClicked);
	pclCtrl -> m_pub_fn_pclAddOwnerData (this, C_ARRAY_DIALOG);
	
	pclCtrl->m_fn_vUpdate ();
}

void CTL_DialogArrayDataEdition::m_fn_vUpdateColors (void)
{
	POSITION pos = m_clControlList . GetHeadPosition ();
	int i = 0;

	while (pos)
	{
		CTL_Editor_Control *pclCtrl = m_clControlList . GetNext (pos);
		static char szName[100];
		itoa (i, szName,10);

		if (pclCtrl == m_pclSelectedControl)
			pclCtrl -> m_pub_fn_pclGetNameStatic () -> m_pub_fn_vSetBackGroundColor (C_COLOR_SEL);
		else
			pclCtrl -> m_pub_fn_pclGetNameStatic () -> m_pub_fn_vSetBackGroundColor (C_COLOR_UNSEL);

		pclCtrl -> m_pub_fn_pclGetNameStatic () -> m_fn_vSetTextToDisplay (szName, TRUE);

		i ++;
	}
}

int CTL_DialogArrayDataEdition::m_fn_lGetIndexOfControl (CTL_Editor_Control *pclSeekCtrl)
{
	POSITION pos = m_clControlList . GetHeadPosition ();
	int i = 0;

	while (pos)
	{
		CTL_Editor_Control *pclCtrl = m_clControlList . GetNext (pos);

		if (pclCtrl == pclSeekCtrl)
			return i;
		i ++;
	}

	return -1;
}
