//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "MainForm.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TRNStuff *RNStuff;

int RandomInt(int low, int high)
{
	return rand() % (high - low + 1) + low;
}

void TRNStuff::EnableGrid(bool enable)
{
	gridPier->Enabled = enable;
}

void TRNStuff::UpdateCurrentCell(void)
{
	lblCurrentRow->Caption = IntToStr(RowCurr);
	lblCurrentColumn->Caption = IntToStr(ColumnCurr);
	lblTotalSteps->Caption = IntToStr(TotalSteps);
}

//---------------------------------------------------------------------------
__fastcall TRNStuff::TRNStuff(TComponent* Owner) : TForm(Owner)
{
	pnlPier->DoubleBuffered = true;
	gridPier->DoubleBuffered = true;
	Init();
}
//---------------------------------------------------------------------------

void __fastcall TRNStuff::FormCreate(TObject *Sender)
{
	pgePier->Align = alClient;
	pnlPier->Align = alClient;
	gridPier->Align = alClient;

	pnlWaterLeft->BevelOuter = bvNone;
	pnlWaterRight->BevelOuter = bvNone;
	pnlWaterBottom->BevelOuter = bvNone;
	pnlBeach->BevelOuter = bvNone;

	spnRows->Max = MaxRows;
	spnColumns->Max = MaxColumns;

	Rows = spnRows->Position;
	Columns = spnColumns->Position;

	RowStart = Rows / 2;
	ColumnStart = Columns / 2;

	RowCurr = RowStart;
	ColumnCurr = ColumnStart;

	CellState[RowCurr][ColumnCurr] = 1;

	Width = 800;
	Height = 800;
}
//---------------------------------------------------------------------------

void TRNStuff::AdjustGrid(void)
{
	gridPier->ColCount = Columns;
	gridPier->RowCount = Rows;

	CellWidth = gridPier->Width / Columns;
	CellHeight = gridPier->Height / Rows;

	if (gridPier->GridLineWidth)
	{
		CellWidth--;
		CellHeight--;
	}

	gridPier->DefaultColWidth = CellWidth;
	gridPier->DefaultRowHeight = CellHeight;
	TGridRect rect = {{ColumnCurr, RowCurr}, {ColumnCurr, RowCurr}};
	gridPier->Selection = rect;
}

void __fastcall TRNStuff::shtPierResize(TObject *Sender)
{
	AdjustGrid();
}
//---------------------------------------------------------------------------

void __fastcall TRNStuff::OnCellCountChange(TObject *Sender)
{
	Rows = spnRows->Position;
	Columns = spnColumns->Position;
	AdjustGrid();
}
//---------------------------------------------------------------------------

void __fastcall TRNStuff::OnPercentageChange(TObject *Sender)
{
	RangeF = spnForward->Position;
	RangeFB = RangeF + spnBack->Position;
	RangeFBL = RangeFB + spnLeft->Position;
}

//---------------------------------------------------------------------------
void __fastcall TRNStuff::btn800x600Click(TObject *Sender)
{
	Width = 800;
	Height = 600;
}
//---------------------------------------------------------------------------
void __fastcall TRNStuff::btn1024x768Click(TObject *Sender)
{
	Width = 1024;
	Height = 768;
}
//---------------------------------------------------------------------------

void TRNStuff::TakeStep(void)
{
	int OldRow = RowCurr;
	int OldColumn = ColumnCurr;


	TotalSteps++;

	int step = RandomInt(1, 100);
	if (step >= 1 && step <= RangeF)
	{
		RowCurr--;
		lblStepDirection->Caption = "Forward";
	}
	else if (step > RangeF && step <= RangeFB) // Back
	{
		RowCurr++;
		lblStepDirection->Caption = "Back";
	}
	else if (step > RangeFB && step <= RangeFBL) // Left
	{
		ColumnCurr--;
		lblStepDirection->Caption = "Left";
	}
	else
	{
		ColumnCurr++;
		lblStepDirection->Caption = "Right";
	}

		// Stepped off of the pier
	if (RowCurr < 0 || RowCurr > Rows || ColumnCurr < 0 || ColumnCurr > Columns)
	{
		Timer1->Enabled = false;
		CellState[OldRow][OldColumn] = 1;
		UpdateCurrentCell();
		TRect rect = gridPier->CellRect(OldColumn, OldRow);
		TGridDrawState state;
		state << gdSelected;
		gridPierDrawCell(this, OldColumn, OldRow, rect, state);
		EnableGrid(true);
		return;
	}

	CellState[RowCurr][ColumnCurr] = 1;
	UpdateCurrentCell();

	#if 0
	TGridRect rect = {ColumnCurr, RowCurr, ColumnCurr, RowCurr};
	gridPier->Selection = rect;
	#else
	{
	TRect rect = gridPier->CellRect(OldColumn, OldRow);
	TGridDrawState state;
	state << gdSelected;
	gridPierDrawCell(this, OldColumn, OldRow, rect, state);
	}

	{
	TRect rect = gridPier->CellRect(ColumnCurr, RowCurr);
	TGridDrawState state;
	state << gdSelected;
	gridPierDrawCell(this, ColumnCurr, RowCurr, rect, state);
	}
	#endif
}

void __fastcall TRNStuff::btnStepClick(TObject *Sender)
{
	TakeStep();
}
//---------------------------------------------------------------------------

void __fastcall TRNStuff::Timer1Timer(TObject *Sender)
{
	TakeStep();
}
//---------------------------------------------------------------------------

void __fastcall TRNStuff::gridPierDrawCell(TObject *Sender, int ACol, int ARow,
		TRect &Rect, TGridDrawState State)
{
	Rect.Left = Rect.Left - 1;
	Rect.Right = Rect.Right;
	Rect.Top = Rect.Top - 1;
	Rect.Bottom = Rect.Bottom;

	if (CellState[ARow][ACol])
	{
		gridPier->Canvas->Brush->Color = clGray;
		gridPier->Canvas->Rectangle(Rect);
	}
	else
	{
		gridPier->Canvas->Brush->Color = clMedGray;
		gridPier->Canvas->Rectangle(Rect);
	}

	if (ARow == RowCurr && ACol == ColumnCurr)
	{
		gridPier->Canvas->Brush->Color = clWhite;
		gridPier->Canvas->Rectangle(Rect);
	}
}
//---------------------------------------------------------------------------

void __fastcall TRNStuff::btnRunClick(TObject *Sender)
{
		// Toggles between running and paused
	Timer1->Enabled = !Timer1->Enabled;
	EnableGrid(!Timer1->Enabled);
}
//---------------------------------------------------------------------------

void TRNStuff::Init(void)
{
	for (int i = 0; i < MaxRows; i++)
		for (int j = 0; j < MaxColumns; j++)
			CellState[i][j] = 0;

	TotalSteps = 0;
	FreqForward = 40;
	FreqBack = 20;
	FreqLeft = 20;
	FreqRight = 20;

	Rows = spnRows->Position;
	Columns = spnColumns->Position;

	RowStart = Rows / 2;
	ColumnStart = Rows / 2;

	RowCurr = RowStart;
	ColumnCurr = ColumnStart;

	CellState[RowCurr][ColumnCurr] = 1;

	AdjustGrid();
	EnableGrid(true);
	UpdateCurrentCell();
}

void __fastcall TRNStuff::btnResetClick(TObject *Sender)
{
	Init();
}
//---------------------------------------------------------------------------

void __fastcall TRNStuff::gridPierSelectCell(TObject *Sender, int ACol,	int ARow, bool &CanSelect)
{
	CellState[RowCurr][ColumnCurr] = 0;

	RowStart = ARow;
	ColumnStart = ACol;

	RowCurr = RowStart;
	ColumnCurr = ColumnStart;

	CellState[RowCurr][ColumnCurr] = 1;
	UpdateCurrentCell();
}
//---------------------------------------------------------------------------

void __fastcall TRNStuff::splitBottomMoved(TObject *Sender)
{
	AdjustGrid();
}
//---------------------------------------------------------------------------

void __fastcall TRNStuff::btnResetValuesClick(TObject *Sender)
{
	spnForward->Position = 25;
	spnBack->Position = 25;
	spnLeft->Position = 25;
	spnRight->Position = 25;
}
//---------------------------------------------------------------------------

/*
[C++] Code completion: Identifiers starting with "~" match a leading underscore.

1. Type an underscore
2. Invoke CC (Ctrl-Space)
3. There are several destructors displayed at the top of the list


[C++] Code completion: Some code templates are shown matching a leading underscore

1. Type an underscore in the code editor.
2. Invoke Code Completion (Ctrl-Space)
3. At the end of the list, you'll see these code templates

for
fors
if
ife
ifeb
ifs
switch
try
while
whileb

11.0.2491.19869

A quicker way to see this is to type four or more underscores and then invoke code completion.
You'll see just the code templates.

*/

