public TetrisGame(MainMenuForm mainMenu)
        {
            InitializeComponent();
            this.mainMenu = mainMenu;

            tetrisGamePanel.Hide();
            nextFigurePanel.Hide();
            ScoreHeaderLabel.Hide();

            StartGameButton.Show();
            InfoButton.Show();

            Size = new Size(280, 280);
        }
        private void BackgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            while (true)
            {
                if (backgroundWorker1.CancellationPending)
                {
                    return;
                }

                if (currentFigure.isStay)
                {
                    if (currentFigure.GetTopmostCoordinate() <= 0)
                    {
                        MessageBox.Show("You lose");
                        StartGameButton.Location = new Point(nextFigurePanel.Location.X, nextFigurePanel.Location.Y + nextFigurePanel.Height + 20);
                        StartGameButton.Size     = new Size(5 * Figure.CUBE_SIZE, 2 * Figure.CUBE_SIZE);
                        StartGameButton.Font     = new Font("Microsoft Sans Serif", Figure.CUBE_SIZE / 2);
                        StartGameButton.Enabled  = true;
                        StartGameButton.Show();
                        return;
                    }

                    int rows_to_del = 0;

                    // add current figure cubes into panel cubes list
                    for (int i = 0; i < currentFigure.cubes.Count; i++)
                    {
                        KeyValuePair <Point, Brush> cube = new KeyValuePair <Point, Brush>(currentFigure.cubes[i], currentFigure.GetBrushByFigureType());
                        occupatedMap[cube.Key.Y / Figure.CUBE_SIZE, cube.Key.X / Figure.CUBE_SIZE] = 1;
                        cubes.Add(cube);
                    }

                    // find 10 cubes in a row
                    // and shift upper cubes down
                    for (int i = occupatedMap.GetLength(0) - 1; i > 0; i--)
                    {
                        int cubes_in_row = 0;
                        for (int j = 0; j < occupatedMap.GetLength(1); j++)
                        {
                            if (occupatedMap[i, j] == 1)
                            {
                                cubes_in_row++;
                            }
                            else
                            {
                                break;
                            }
                        }
                        if (cubes_in_row == occupatedMap.GetLength(1))
                        {
                            rows_to_del++;

                            for (int k = 0; k < occupatedMap.GetLength(1); k++)
                            {
                                occupatedMap[i, k] = 0;
                                occupatedMap[0, k] = 0;
                            }

                            cubes.RemoveAll(x => x.Key.Y == i * Figure.CUBE_SIZE);

                            //shift upper cubes down
                            for (int u = 0; u < cubes.Count; u++)
                            {
                                var item = cubes[u];
                                if (item.Key.Y < i * Figure.CUBE_SIZE)
                                {
                                    cubes[u] = new KeyValuePair <Point, Brush>(new Point(cubes[u].Key.X, cubes[u].Key.Y + Figure.CUBE_SIZE), cubes[u].Value);
                                }
                            }

                            //change map
                            for (int x = i; x > 0; x--)
                            {
                                for (int y = 0; y < occupatedMap.GetLength(1); y++)
                                {
                                    occupatedMap[x, y] = occupatedMap[x - 1, y];
                                }
                            }

                            i++;
                        }
                    }

                    switch (rows_to_del)
                    {
                    case 1:
                        gameScore += 100;
                        break;

                    case 2:
                        gameScore += 300;
                        break;

                    case 3:
                        gameScore += 700;
                        break;

                    case 4:
                        gameScore += 1500;
                        break;

                    default:
                        break;
                    }

                    if (gameScore > 5000)
                    {
                        gameSpeed = (int)GAME_SPEED.INCREDIBLE;
                    }
                    else if (gameScore >= 3000)
                    {
                        gameSpeed = (int)GAME_SPEED.HIGH;
                    }
                    else if (gameScore >= 1000)
                    {
                        gameSpeed = (int)GAME_SPEED.MEDIUM;
                    }
                    else
                    {
                        gameSpeed = (int)GAME_SPEED.LOW;
                    }

                    Random random = new Random();
                    currentFigure = nextFigure;
                    nextFigure    = new Figure(tetrisGamePanel, FIGURE_TYPE.I + random.Next() % Enum.GetNames(typeof(FIGURE_TYPE)).Length);

                    if (rows_to_del > 0)
                    {
                        tetrisGamePanel.Invalidate();
                        ScoreLabel.Text = gameScore.ToString();
                    }
                    nextFigurePanel.Invalidate();
                }

                Thread.Sleep(gameSpeed);
                currentFigure.StepDown(cubes);

                Point     startRedrawPoint = new Point(currentFigure.GetLeftmostCoordinate(), currentFigure.GetTopmostCoordinate() - Figure.CUBE_SIZE);
                Size      sizeRedraw       = new Size(currentFigure.GetRightmostCoordinate() - currentFigure.GetLeftmostCoordinate() + Figure.CUBE_SIZE, currentFigure.GetBottommostCoordinate() - currentFigure.GetTopmostCoordinate() + Figure.CUBE_SIZE);
                Rectangle invRect          = new Rectangle(startRedrawPoint, sizeRedraw);

                tetrisGamePanel.Invalidate(invRect);
            }
        }