public void SplitCombinedPuzzlePiece(CombinedPuzzlePiece combinedPuzzlePiece)
        {
            RemovePuzzlePieceFromLevelMatrix(combinedPuzzlePiece);
            drawings.Remove(combinedPuzzlePiece);
            puzzlePieces.Remove(combinedPuzzlePiece);

            puzzlePieces.Add(combinedPuzzlePiece.Piece1);
            PlacePuzzlePieceOutOfGrid(combinedPuzzlePiece.Piece1);
            combinedPuzzlePiece.Piece1.isInitialised = true;

            puzzlePieces.Add(combinedPuzzlePiece.Piece2);
            PlacePuzzlePieceOutOfGrid(combinedPuzzlePiece.Piece2);
            combinedPuzzlePiece.Piece2.isInitialised = true;
        }
        public override void TryToMovePuzzlePiece(PuzzlePiece piece, int newXIndex, int newYIndex, Point?p)
        {
            int oldX = piece.XIndex;
            int oldY = piece.YIndex;

            RemovePuzzlePieceFromLevelMatrix(piece);
            piece.XIndex = newXIndex;
            piece.YIndex = newYIndex;

            PuzzlePiece overlapedPiece;

            if (IsPieceInsideOfGrid(piece))
            {
                if (!IsPieceOverlapingWithOthers(piece, out overlapedPiece))
                {
                    piece.IsAdded = true;
                    piece.X       = (piece.XIndex + gridWidth) * CellSize;
                    piece.Y       = (piece.YIndex + gridHeight) * CellSize;
                    AddPuzzlePieceTolLevelMatrix(piece);
                    IsLevelSolved();
                    return;
                }
            }
            else if (IsPieceOutsideOfGrid(piece))
            {
                if (IsPieceInsideOfLevel(piece))
                {
                    if (!IsPieceOverlapingWithOthers(piece, out overlapedPiece))
                    {
                        piece.IsAdded = false;
                        piece.X       = (piece.XIndex + gridWidth) * CellSize;
                        piece.Y       = (piece.YIndex + gridHeight) * CellSize;
                        AddPuzzlePieceTolLevelMatrix(piece);
                        return;
                    }
                    else
                    {
                        //element is trying to be placed over another outside of grid
                        if (GetNumberOfOverlapingPieces(piece) <= 1 &&
                            piece.GetType() != typeof(CombinedPuzzlePiece) &&
                            overlapedPiece.GetType() != typeof(CombinedPuzzlePiece))
                        {
                            //create combined piece
                            CombinedPuzzlePiece newPuzzlePiece = CreateUnionPuzzlePiece(piece, overlapedPiece);

                            //remove dragged piece
                            RemovePuzzlePieceFromLevelMatrix(piece);
                            drawings.Remove(piece);
                            puzzlePieces.Remove(piece);

                            //remove overlaped piece
                            RemovePuzzlePieceFromLevelMatrix(overlapedPiece);
                            drawings.Remove(overlapedPiece);
                            puzzlePieces.Remove(overlapedPiece);

                            //add combined puzzle piece to level
                            newPuzzlePiece.PaintShape(this);
                            drawings.Add(newPuzzlePiece);
                            puzzlePieces.Add(newPuzzlePiece);
                            AddPuzzlePieceTolLevelMatrix(newPuzzlePiece);
                            newPuzzlePiece.isInitialised = true;
                            return;
                        }
                    }
                }
            }

            piece.XIndex = oldX;
            piece.YIndex = oldY;
            AddPuzzlePieceTolLevelMatrix(piece);
        }
        private CombinedPuzzlePiece CreateUnionPuzzlePiece(PuzzlePiece p1, PuzzlePiece p2)
        {
            CombinedPuzzlePiece retVal = null;

            int minX, minY, maxX, maxY;

            if (p1.XIndex < p2.XIndex)
            {
                minX = p1.XIndex;
            }
            else
            {
                minX = p2.XIndex;
            }

            if (p1.YIndex < p2.YIndex)
            {
                minY = p1.YIndex;
            }
            else
            {
                minY = p2.YIndex;
            }

            if (p1.XIndex + p1.Width > p2.XIndex + p2.Width)
            {
                maxX = p1.XIndex + p1.Width;
            }
            else
            {
                maxX = p2.XIndex + p2.Width;
            }

            if (p1.YIndex + p1.Height > p2.YIndex + p2.Height)
            {
                maxY = p1.YIndex + p1.Height;
            }
            else
            {
                maxY = p2.YIndex + p2.Height;
            }


            Field[,] newPieceMatrix = StaticHelper.GetEmptyMatrix(maxX - minX, maxY - minY);
            FillType fill1;
            FillType fill2;
            FillType newFill = FillType.Empty;

            for (int y = 0; y < maxY - minY; y++)
            {
                for (int x = 0; x < maxX - minX; x++)
                {
                    fill1 = GetPieceFillInWorld(x + minX, y + minY, p1);
                    fill2 = GetPieceFillInWorld(x + minX, y + minY, p2);

                    if (fill1 == FillType.Full || fill2 == FillType.Full)
                    {
                        newFill = FillType.Full;
                    }
                    else if (fill1 != FillType.Empty && fill2 != FillType.Empty)
                    {
                        newFill = CellStateRules.GetUnion(fill1, fill2);
                    }
                    else if (fill1 == FillType.Empty)
                    {
                        newFill = fill2;
                    }
                    else if (fill2 == FillType.Empty)
                    {
                        newFill = fill1;
                    }

                    newPieceMatrix[y, x].Fill = newFill;
                }
            }

            LinearGradientBrush myBrush = new LinearGradientBrush();

            myBrush.GradientStops.Add(new GradientStop(((SolidColorBrush)p1.Brush).Color, 0.0));
            myBrush.GradientStops.Add(new GradientStop(((SolidColorBrush)p2.Brush).Color, 1.0));

            retVal        = new CombinedPuzzlePiece(newPieceMatrix, myBrush);
            retVal.XIndex = minX;
            retVal.YIndex = minY;
            retVal.Piece1 = p1;
            retVal.Piece2 = p2;


            return(retVal);
        }