{*=====================================================================
  Project:   WinCubVCL.bdsproj

  File:      WinCubVCL_.pas

  Summary:
             WinCubVCL is a Delphi implementation of the dotNETCub
             project, which is a simple game for your fun.
             On other hand it could demonstrate creating
             VCL - objects in run time and using them.

-----------------------------------------------------------------------
  This file is submitted by:

  endresy@axelero.hu
  Endre I. Simay,
  Hungary


THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND / OR FITNESS FOR A
PARTICULAR PURPOSE.
=====================================================================*}
unit WincubVCL_;

interface
uses
  Borland.Vcl.Classes,
  Borland.Vcl.Graphics,
  Borland.Vcl.Controls,
  Borland.Vcl.Forms,
  Borland.Vcl.Dialogs,
  Borland.Vcl.Buttons,
  Borland.Vcl.ExtCtrls,
  Borland.Vcl.StdCtrls,
  Borland.Vcl.Menus,
  Borland.Vcl.Windows,
  Borland.Vcl.WinUtils;

type
  TColorMatrix = array[1..4, 1..4] of TColor;

type
  TForm1 = class(TForm)
  private
    pnlHost: TPanel;
    pnlCubs: array[1..4, 1..4] of TPanel;
    btnUp: array[1..4] of TButton;
    btnDown: array[1..4] of TButton;
    btnLeft: array[1..4] of TButton;
    btnRight: array[1..4] of TButton;

    btnShuffle: TButton;

    lblComplett: TLabel;

    pnlSteps: TPanel;
    lblStep1: TLabel;
    lblStep2: TLabel;

  public
    complet,
      first,
      block,
      sp,
      steps: Integer;
    ColorMatrix: TColorMatrix;
    Ciklus: LongInt;
    ifNew,
      ifRandom: Boolean;

    constructor Create(AOwner: TComponent); override;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);

    procedure ButtonClick(Sender: TObject);
    procedure btnShuffle_Click(Sender: TObject);
    procedure SetupForm;

    procedure LineUp(j: Integer);
    procedure LineDown(j: Integer);
    procedure LineLeft(j: Integer);
    procedure LineRight(j: Integer);
    function ifComplet: Integer;
    procedure CompParams;

  published

  end;

var
  Form1: TForm1;

implementation
{$R icon.RES}

var
  StdCols: array[1..4] of TColor;

constructor TForm1.Create(AOwner: TComponent);
var
  i, j: Integer;

begin
  inherited CreateNew(AOwner);

  pnlHost := TPanel.Create(Self);
  pnlHost.Parent := Self;

  btnShuffle := TButton.Create(Self);
  btnShuffle.Parent := Self;

  lblComplett := TLabel.Create(Self);
  lblComplett.Parent := Self;

  pnlSteps := TPanel.Create(Self);
  pnlSteps.Parent := Self;

  lblStep1 := TLabel.Create(pnlSteps);
  lblStep1.Parent := pnlSteps;

  lblStep2 := TLabel.Create(pnlSteps);
  lblStep2.Parent := pnlSteps;

  for i := 1 to 4 do
  begin

    btnUp[i] := TButton.Create(pnlHost);
    btnUp[i].Parent := pnlHost;
    btnDown[i] := TButton.Create(pnlHost);
    btnDown[i].Parent := pnlHost;
    btnLeft[i] := TButton.Create(pnlHost);
    btnLeft[i].Parent := pnlHost;
    btnRight[i] := TButton.Create(pnlHost);
    btnRight[i].Parent := pnlHost;

    for j := 1 to 4 do
    begin
      pnlCubs[i, j] := TPanel.Create(pnlHost);
      pnlCubs[i, j].Parent := pnlHost;
    end;
  end;

  complet := 1;
  first := 40;
  block := 40;
  sp := 5;
  steps := 0;

  Application.Icon.Handle := LoadIcon(MainInstance, 'BIGCUB');

  SetupForm;

end;

procedure TForm1.SetupForm;
var
  i, j: Integer;

begin
  StdCols[1] := clRed;
  StdCols[2] := clLime;
  StdCols[3] := clYellow;
  StdCols[4] := clBlue;

  ClientWidth := 397;
  ClientHeight := 401;
  Color := clSilver;
  Caption := 'ColorCub for Delphi by E. I. Simay';

  pnlHost.Top := 16;
  pnlHost.Left := 16;
  pnlHost.Name := 'pnlHost';
  pnlHost.Caption := '';
  pnlHost.Width := 2 * first + 4 * block + 3 * sp;
  pnlHost.Height := 2 * first + 4 * block + 3 * sp;
  pnlHost.ParentColor := False;
  pnlHost.Color := clSilver;

  for i := 0 to 3 do
  begin
    btnUp[i + 1].Left := first + i * block + i * sp;
    btnUp[i + 1].Top := first - 25;
    btnUp[i + 1].Width := block;
    btnUp[i + 1].Height := 20;
    btnUp[i + 1].OnClick := ButtonClick;

    btnDown[i + 1].Left := first + i * block + i * sp;
    btnDown[i + 1].Top := first + 3 * block + 3 * sp + block + 5;
    btnDown[i + 1].Width := block;
    btnDown[i + 1].Height := 20;
    btnDown[i + 1].OnClick := ButtonClick;

    btnLeft[i + 1].Left := first - 25;
    btnLeft[i + 1].Top := first + i * block + i * sp;
    btnLeft[i + 1].Width := 20;
    btnLeft[i + 1].Height := block;
    btnLeft[i + 1].OnClick := ButtonClick;

    btnRight[i + 1].Left := first + 3 * block + 3 * sp + block + 5;
    btnRight[i + 1].Top := first + i * block + i * sp;
    btnRight[i + 1].Width := 20;
    btnRight[i + 1].Height := block;
    btnRight[i + 1].OnClick := ButtonClick;

    for j := 0 to 3 do
    begin
      pnlCubs[j + 1, i + 1].Width := block;
      pnlCubs[j + 1, i + 1].Height := block;
      pnlCubs[j + 1, i + 1].Color := StdCols[i + 1];
      pnlCubs[j + 1, i + 1].Left := first + (j) * block + (j) * sp;
      pnlCubs[j + 1, i + 1].Top := first + (i) * block + (i) * sp;
    end;
  end;

  btnShuffle.Name := 'btnShuffle';
  btnShuffle.Width := 72;
  btnShuffle.Height := 24;
  btnShuffle.Caption := 'Shuffle';
  btnShuffle.OnClick := btnShuffle_Click;
  btnShuffle.Top := pnlHost.Top;
  btnShuffle.Left := pnlHost.BoundsRect.Right + (ClientWidth - pnlHost.BoundsRect.Right - btnShuffle.Width) div 2;

  pnlSteps.Left := pnlHost.Left;
  pnlSteps.Top := pnlHost.BoundsRect.Bottom + 20;
  pnlSteps.Name := 'pnlSteps';
  pnlSteps.Width := pnlHost.Width;
  pnlSteps.ParentColor := True;
  pnlSteps.BorderStyle := bsNone;
  pnlSteps.Caption := '';

  lblStep1.Top := 8;
  lblStep1.Left := 8;
  lblStep1.Name := 'lblStep1';
  lblStep1.Caption := ' Number of steps: ';
  lblStep1.AutoSize := True;
  lblStep1.AutoSize := False;
  lblStep1.Width := 90;
  pnlSteps.ClientHeight := lblStep1.Height + 16;

  lblStep2.Top := 8;
  lblStep2.Left := lblStep1.BoundsRect.Right + 10;
  lblStep2.Name := 'lblStep2';
  lblStep2.Width := 90;
  lblStep2.Height := lblStep2.Height;
  lblStep2.Caption := steps.ToString();

  btnShuffle.Enabled := (complet = 1);
  lblComplett.Left := pnlHost.Left;
  lblComplett.Font.Color := clBlue;
  lblComplett.Visible := False;

  lblComplett.Font.Name := 'Microsoft Sans Serif';
  lblComplett.Font.Size := 24;
  lblComplett.Font.Color := clBlue;
  lblComplett.Top := 336;
  lblComplett.Left := 16;
  lblComplett.Name := 'lblComplett';
  lblComplett.Width := 304;
  lblComplett.Height := 40;
  lblComplett.Caption := 'Congratulation!!!';

end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
  i, j: Integer;
begin

  for i := 1 to 4 do
  begin

    btnUp[i].Free;
    btnDown[i].Free;
    btnLeft[i].Free;
    btnRight[i].Free;

    for j := 1 to 4 do
    begin
      pnlCubs[i, j].Free;
    end;
  end;

  pnlHost.Free;
  btnShuffle.Free;

  lblComplett.Free;

  lblStep1.Free;
  lblStep2.Free;
  pnlSteps.Free;

  inherited;
end;

procedure TForm1.ButtonClick(Sender: TObject);
var
  i: Integer;
begin
  if complet <> 1 then
  begin
    for i := 1 to 4 do
    begin
      if Sender = btnUp[i] then
      begin
        LineUp(i);
      end
      else
        if Sender = btnDown[i] then
        begin
          LineDown(i);
        end
        else
          if Sender = btnLeft[i] then
          begin
            LineLeft(i);
          end
          else
            if Sender = btnRight[i] then
            begin
              LineRight(i);
              Break;
            end;
    end;
    steps := steps + 1;
    CompParams;
  end;
end;

function TForm1.ifComplet: Integer;
var
  i,
    tried: Integer;
begin
  tried := 1;
  for i := 1 to 4 do
  begin
    if (
      (pnlCubs[i, 1].Color <> StdCols[1])
      or (pnlCubs[i, 2].Color <> StdCols[2])
      or (pnlCubs[i, 3].Color <> StdCols[3])
      or (pnlCubs[i, 4].Color <> StdCols[4])
      )
      then
    begin
      tried := 0;
      Break;
    end;
  end;
  result := tried;
end;

procedure TForm1.LineUp(j: Integer);
var
  tempColor: TColor;
begin
  tempColor := pnlCubs[j, 1].Color;
  pnlCubs[j, 1].Color := pnlCubs[j, 2].Color;
  pnlCubs[j, 2].Color := pnlCubs[j, 3].Color;
  pnlCubs[j, 3].Color := pnlCubs[j, 4].Color;
  pnlCubs[j, 4].Color := tempColor;
end;

procedure TForm1.LineDown(j: Integer);
var
  tempColor: TColor;
begin
  tempColor := pnlCubs[j, 4].Color;
  pnlCubs[j, 4].Color := pnlCubs[j, 3].Color;
  pnlCubs[j, 3].Color := pnlCubs[j, 2].Color;
  pnlCubs[j, 2].Color := pnlCubs[j, 1].Color;
  pnlCubs[j, 1].Color := tempColor;
end;

procedure TForm1.LineLeft(j: Integer);
var
  tempColor: TColor;
begin
  tempColor := pnlCubs[1, j].Color;
  pnlCubs[1, j].Color := pnlCubs[2, j].Color;
  pnlCubs[2, j].Color := pnlCubs[3, j].Color;
  pnlCubs[3, j].Color := pnlCubs[4, j].Color;
  pnlCubs[4, j].Color := tempColor;
end;

procedure TForm1.LineRight(j: Integer);
var
  tempColor: TColor;
begin
  tempColor := pnlCubs[4, j].Color;
  pnlCubs[4, j].Color := pnlCubs[3, j].Color;
  pnlCubs[3, j].Color := pnlCubs[2, j].Color;
  pnlCubs[2, j].Color := pnlCubs[1, j].Color;
  pnlCubs[1, j].Color := tempColor;
end;

procedure TForm1.CompParams;
begin
  lblStep2.Caption := steps.ToString;
  complet := ifComplet;
  btnShuffle.Enabled := (complet = 1);
  lblComplett.Visible := (complet = 1);
end;


procedure TForm1.btnShuffle_Click(Sender: TObject);
var
  shuffleVoid,
    i: Integer;

begin
  complet := 0;
  Randomize;
  for i := 1 to 20 do
  begin
    shuffleVoid := 1 + Random(3);
    case shuffleVoid of
      1:
        begin
          LineUp(1 + Random(3));
        end;
      2:
        begin
          LineDown(1 + Random(3));
        end;
      3:
        begin
          LineLeft(1 + Random(3));
        end;
      4:
        begin
          LineRight(1 + Random(3));
        end;
    end;
  end;
  steps := 0;
  btnShuffle.Enabled := (complet = 1);
  lblComplett.Visible := (complet = 1);
  lblStep2.Caption := steps.ToString;
end;

end.
