/// <summary>
                /// 变形
                /// </summary>
                public void Rotate()
                {
                        if (GameStatus != GameStatus.Play) return;

                        if (!IsBoundary(_currentPiece.GetRotate(), 0, 0))
                        {
                                RemovePiece();
                                _currentPiece.Rotate();
                                AddPiece(0, 0);
                        }
                }

                /// <summary>
                /// 清除俄罗斯方块容器
                /// </summary>
                public void Clear()
                {
                        for (int x = 0; x < _columns; x++)
                        {
                                for (int y = 0; y < _rows; y++)
                                {
                                        Container[y, x].Color = null;
                                }
                        }
                }

                /// <summary>
                /// 边界判断(是否超过边界)
                /// </summary>
                /// <param name="matrix">当前操作的形状的4×4矩阵</param>
                /// <param name="offsetX">矩阵 X 方向的偏移量</param>
                /// <param name="offsetY">矩阵 Y 方向的偏移量</param>
                /// <returns></returns>
                private bool IsBoundary(int[,] matrix, int offsetX, int offsetY)
                {
                        RemovePiece();

                        for (int i = 0; i < 4; i++)
                        {
                                for (int j = 0; j < 4; j++)
                                {
                                        if (matrix[i, j] == 1)
                                        {
                                                if (j + _positionX + offsetX > _columns - 1 // 超过列的右边界
                                                        || i + _positionY + offsetY > _rows - 1 // 超过行的下边界
                                                        || j + _positionX + offsetX < 0 // 超过列的左边界
                                                        || Container[i + _positionY + offsetY, j + _positionX + offsetX].Color != null) // matrix 所需偏移的地方已经有 Block 占着了
                                                {
                                                        AddPiece(0, 0);
                                                        return true;
                                                }                                                
                                        }
                                }
                        }

                        AddPiece(0, 0);
                        return false;
                }

                /// <summary>
                /// 设置“下一个形状的容器”的 UI
                /// </summary>
                private void SetNextContainerUI()
                {
                        // 清空
                        foreach (Block block in NextContainer)
                        {
                                block.Color = null;
                        }

                        // 根据 _nextPiece 的矩阵设置相对应的 Block 对象的呈现
                        for (int x = 0; x < 4; x++)
                        {
                                for (int y = 0; y < 4; y++)
                                {
                                        if (_nextPiece.Matrix[x, y] == 1)
                                        {
                                                NextContainer[x, y].Color = _nextPiece.Color;
                                        }
                                }
                        }
                }

                /// <summary>
                /// 移除 _currentPiece 在界面上的呈现
                /// </summary>
                private void RemovePiece()
                {
                        for (int i = 0; i < 4; i++)
                        {
                                for (int j = 0; j < 4; j++)
                                {
                                        if (_currentPiece.Matrix[i, j] == 1)
                                        {
                                                Container[i + _positionY, j + _positionX].Color = null;
                                        }
                                }
                        }
                }

                /// <summary>
                /// 增加 _currentPiece 在界面上的呈现
                /// </summary>
                /// <param name="offsetX">X 方向上的偏移量</param>
                /// <param name="offsetY">Y 方向上的偏移量</param>
                private void AddPiece(int offsetX, int offsetY)
                {
                        for (int i = 0; i < 4; i++)
                        {
                                for (int j = 0; j < 4; j++)
                                {
                                        if (_currentPiece.Matrix[i, j] == 1)
                                        {
                                                Container[i + _positionY + offsetY, j + _positionX + offsetX].Color = _currentPiece.Color;
                                        }
                                }
                        }

                        _positionX += offsetX;
                        _positionY += offsetY;
                }

                /// <summary>
                /// 根据游戏规则,如果某行出现连续的直线则将其删除,该线以上的部分依次向下移动
                /// </summary>
                private void RemoveRow()
                {
                        // 删除的行数
                        int removeRowCount = 0;

                        // 行的遍历(Y 方向)
                        for (int y = 0; y < _rows; y++)
                        {
                                // 该行是否是一条连续的直线
                                bool isLine = true;

                                // 列的遍历(X 方向)
                                for (int x = 0; x < _columns; x++)
                                {
                                        if (Container[y, x].Color == null)
                                        {
                                                // 出现断行,则继续遍历下一行
                                                isLine = false;
                                                break;
                                        }
                                }

                                // 该行是一条连续的直线则将其删除,并将该行以上的部分依次向下移动
                                if (isLine)
                                {
                                        removeRowCount++;

                                        // 删除该行
                                        for (int x = 0; x < _columns; x++)
                                        {
                                                Container[y, x].Color = null;
                                        }

                                        // 将被删除行的以上行依次向下移动
                                        for (int i = y; i > 0; i--)
                                        {
                                                for (int x = 0; x < _columns; x++)
                                                {
                                                        Container[i, x].Color = Container[i - 1, x].Color;
                                                }
                                        }
                                }
                        }

                        // 加分,计算方法: 2 的 removeRowCount 次幂 乘以 10
                        if (removeRowCount > 0)
                                Score += 10 * (int)Math.Pow(2, removeRowCount);                                

                        // 更新总的已消行数
                        RemoveRowCount += removeRowCount;

                        // 根据已消行数计算级别,依据丁学的建议,计算方法: 已消行数/5 的平方根 取整
                        Level = (int)Math.Sqrt(RemoveRowCount / 5);

                        // 根据级别计算速率,计算方法: 初始速率 减 (每多一个级别所需增加的速率 乘以 当前级别)
                        _timer.Interval = TimeSpan.FromMilliseconds(_initSpeed - _levelSpeed * Level > _levelSpeed ? _initSpeed - _levelSpeed * Level : _levelSpeed);
                }

                private int _score = 0;
                /// <summary>
                /// 得分
                /// </summary>
                public int Score
                {
                        get { return _score; }
                        set
                        {
                                _score = value;
                                if (PropertyChanged != null)
                                {
                                        PropertyChanged(this, new PropertyChangedEventArgs("Score"));
                                }
                        }
                }

                private int _removeRowCount = 0;
                /// <summary>
                /// 总共被消除的行数
                /// </summary>
                public int RemoveRowCount
                {
                        get { return _removeRowCount; }
                        set
                        {
                                _removeRowCount = value;
                                if (PropertyChanged != null)
                                {
                                        PropertyChanged(this, new PropertyChangedEventArgs("RemoveRowCount"));
                                }
                        }
                }

                private int _level = 0;
                /// <summary>
                /// 级别(游戏难度)
                /// </summary>
                public int Level
                {
                        get { return _level; }
                        set
                        {
                                _level = value;
                                if (PropertyChanged != null)
                                {
                                        PropertyChanged(this, new PropertyChangedEventArgs("Level"));
                                }
                        }
                }

                public event PropertyChangedEventHandler PropertyChanged;

                /// <summary>
                /// 游戏结束的事件委托
                /// </summary>
                public event EventHandler GameOver;

                /// <summary>
                /// 游戏结束后所调用的方法,并触发游戏结束事件
                /// </summary>
                /// <param name="e"></param>
                private void OnGameOver(EventArgs e)
                {
                        GameStatus = GameStatus.Over;
                        _timer.Interval = TimeSpan.FromMilliseconds(_initSpeed);
                        _timer.Stop();

                        EventHandler handler = GameOver;
                        if (handler != null)
                                handler(this, e);
                }
        }
}